Reactjs get 5 day names from date

I have an issue trying to get the logic done with getting the dayName of a date. The API has a format which gives you the date-time of 5 days(openweathermap api). But it doesn’t give you only 5 dates. It gives 8 dates per day which means it gives you a date per 3 hours. Here is the json example:

"cod": "200",
"message": 0,
"cnt": 40,
"list": [
{
"dt": 1628856000,
"main": {
"temp": 18.91,
"feels_like": 18.81,
"temp_min": 18.91,
"temp_max": 21.98,
"pressure": 1022,
"sea_level": 1022,
"grnd_level": 1018,
"humidity": 75,
"temp_kf": -3.07
},
"weather": [
{
"id": 803,
"main": "Clouds",
"description": "broken clouds",
"icon": "04d"
}
],
"clouds": {
"all": 75
},
"wind": {
"speed": 5.75,
"deg": 249,
"gust": 8.59
},
"visibility": 10000,
"pop": 0,
"sys": {
"pod": "d"
},
"dt_txt": "2021-08-13 12:00:00"
},
{
"dt": 1628866800,
"main": {
"temp": 20.1,
"feels_like": 19.89,
"temp_min": 20.1,
"temp_max": 22.48,
"pressure": 1022,
"sea_level": 1022,
"grnd_level": 1017,
"humidity": 66,
"temp_kf": -2.38
},
"weather": [
{
"id": 803,
"main": "Clouds",
"description": "broken clouds",
"icon": "04d"
}
],
"clouds": {
"all": 80
},
"wind": {
"speed": 5.39,
"deg": 262,
"gust": 7.97
},
"visibility": 10000,
"pop": 0,
"sys": {
"pod": "d"
},
"dt_txt": "2021-08-13 15:00:00"
},
...

I need to get the date for each day which means I get 5 different dates. Then I need to convert these dates to dayName such as Sunday, Monday…
Here is what I have tried so far:

// weatherDay1 is basically the api response. example
// "list": [
//  {
//   "dt": 1628877600,
//   "dt_txt": "2021-08-13 18:00:00"
//  },
//  {
//   "dt": 1628888400,
//   "dt_txt": "2021-08-13 21:00:00"
//  },
// {
//  "dt": 1628899200,
//  "dt_txt": "2021-08-14 00:00:00"
// },
// .....

// I can convert dates to day but I don't know how I can get day1, day2, day3, day4 and day5
function getDayName(dateStr, locale) {
  var date = new Date(dateStr);
  return date.toLocaleDateString(locale, {
    weekday: "long"
  });
}

// for (let i = 0; i < weatherDay1?.length; i++) {
// const dt = new Date(weatherDay1?[i].dt_txt);
// const day = dt.getDay();
// if(day === 0){
//   const dayName = getDayName(weatherDay1?[i].dt_txt, "en-US");
//   console.log(dayName);
// }
// console.log(weatherDay1?.[i].dt_txt);
// }

var dateStr = weatherDay1 ? .["0"].dt_txt;
var dayName = getDayName(dateStr, "en-EN");

Here is an image of the api response for more clarity: api

Answer

You didn’t specify the exact data structure you preferred, but here is a general implementation that should suffice your needs.

getDays returns a Map instance whose keys will be the dayName and each value will be an array with the corresponding data (theoretically you should end with 5 entries whose values will be arrays with 8 elements).

Please note that I’m using dt property instead of dt_text because it represents the number of seconds since January 1, 1970, 00:00:00 UTC and it is the purest representation of a date in JavaScript (more info here). You have to multiply the value by 1000 to convert it to milliseconds.

Please also note that if you get data for the same day, but different dates, data will be grouped under the same name. This should not be a problem if you get forecast for less than 7 days.

const list = [
    {
        dt: 1628877600,
        dt_txt: '2021-08-13 18:00:00'
    },
    {
        dt: 1628888400,
        dt_txt: '2021-08-13 21:00:00'
    },
    {
        dt: 1628899200,
        dt_txt: '2021-08-14 00:00:00'
    }
];

const getDayName = (value, locale) => {
    return new Date(value).toLocaleDateString(locale, {
        weekday: 'long'
    });
};

const getDays = (input) => {
    const output = new Map();

    input.forEach((item) => {
        const dayName = getDayName(item.dt * 1000, 'en-US');
        output.set(dayName, (output.get(dayName) || []).concat(item));
    });

    return output;
};

const days = getDays(list); // THIS RETURNS A MAP!

days.forEach((value, dayName) => {
    console.log(dayName, value);
});