Date array changes when passed from back end to front end

Let me start off by apologizing for the length of this post but I want to be as detailed as possible as this issue is very interesting and weird.

I am rendering a repeater’s date picker with room availability for resorts that my company manages. This is accomplished with two functions (one back end function and one front end function).

The back end function makes a request to an external API, formats the response into an array of date objects and returns the array.

The front end function calls the back end function and then pushes the response onto a repeater that renders the availability.

The array of date objects is not changed or mutated in any way after it is formatted by the back end function. Yet somehow the dates that are rendered on the front end are always one day before the date that is returned from the back end function.

I know that sounds confusing so let me clarify.

Here is the array of date objects that is returned from the back end function:

Here is what is rendered to the date picker:

At first I was almost convinced that the date picker was just getting the dates wrong so I did a bit more digging and found out that the dates that are stored in the array are somehow changing as they are being passed back to the front end function.

Here is the code for the front end function that is applicable:

getAvailAsync(startDate, endDate, attributeId, resortId, room, resort, duration).then(response => {
            console.log("returned to front end", response.res.availability)
            response.res.error ? "" : repeaterData.push(response.res)
            $w("#resortsRepeater").data = repeaterData

            if(repeaterData.length > 12) {
                $w("#loadMore").show()
            }
            if(repeaterData.length > 0) {
                $w("#loadingStrip").collapse()
            }
        })

Here is what is logged to the console from the front end:

[
  {
    "startDate": "Fri Jul 15 2022 17:00:00 GMT-0700 (Pacific Daylight Time)",
    "endDate": "Fri Jul 15 2022 17:00:00 GMT-0700 (Pacific Daylight Time)"
  },
  {
    "startDate": "Sat Jul 16 2022 17:00:00 GMT-0700 (Pacific Daylight Time)",
    "endDate": "Sat Jul 16 2022 17:00:00 GMT-0700 (Pacific Daylight Time)"
  },
  {
    "startDate": "Sun Jul 17 2022 17:00:00 GMT-0700 (Pacific Daylight Time)",
    "endDate": "Sun Jul 17 2022 17:00:00 GMT-0700 (Pacific Daylight Time)"
  },
  {
    "startDate": "Mon Jul 18 2022 17:00:00 GMT-0700 (Pacific Daylight Time)",
    "endDate": "Mon Jul 18 2022 17:00:00 GMT-0700 (Pacific Daylight Time)"
  },
  {
    "startDate": "Tue Jul 19 2022 17:00:00 GMT-0700 (Pacific Daylight Time)",
    "endDate": "Tue Jul 19 2022 17:00:00 GMT-0700 (Pacific Daylight Time)"
  },
  {
    "startDate": "Tue Jul 26 2022 17:00:00 GMT-0700 (Pacific Daylight Time)",
    "endDate": "Tue Jul 26 2022 17:00:00 GMT-0700 (Pacific Daylight Time)"
  }
]

As you can see the first date is July 15th and the last date is July 26th.

Now here is the applicable code from the back end getAvailAsync function:

if(validAvail == undefined) {
                resolve({ res: {error: "No availability found"}})
            } else {
                console.log("Valid avail before passing to the front end", validAvail)
              validAvail.length > 0 
                ? 
                resolve({
                    res: {
                        ...resortInfo,
                        ...roomInfo,
                        availability: validAvail
                    }    
                })
                : resolve({
                    res: {error: "No availability found"}
                })  
            }

Here is what is logged to the console from the back end function:

[
  {
    "startDate": "2022-07-16T00:00:00.000Z",
    "endDate": "2022-07-16T00:00:00.000Z"
  },
  {
    "startDate": "2022-07-17T00:00:00.000Z",
    "endDate": "2022-07-17T00:00:00.000Z"
  },
  {
    "startDate": "2022-07-18T00:00:00.000Z",
    "endDate": "2022-07-18T00:00:00.000Z"
  },
  {
    "startDate": "2022-07-19T00:00:00.000Z",
    "endDate": "2022-07-19T00:00:00.000Z"
  },
  {
    "startDate": "2022-07-20T00:00:00.000Z",
    "endDate": "2022-07-20T00:00:00.000Z"
  },
  {
    "startDate": "2022-07-27T00:00:00.000Z",
    "endDate": "2022-07-27T00:00:00.000Z"
  }
]

As you can see the first date is July 16th and the last date is July 27th.

What’s more is every single date has been decremented by 1 somehow.

I am completely clueless as to why this is happening. The only thing that I can think of is that the back end function has a date object for the start date and end date after being returned from the API (see the first image where it says {“startDate”: {$date: "2022-07-02…}, …}

Could that somehow be messing up the date? And if so how do I resolve this?

Short answer: timezones. The browser renders dates by default according to browser locale settings. Solution: https://www.wix.com/velo/reference/$w/datepicker/timezone

This makes sense, I think it is still weird that it changes after being set through the back end function. But I was able to get it to show the right day by manually setting the hour so that the time zone change does not change the date.

@amotor Welcome to JS-dates hell. I also developed a hotel reservation app and ran into exactly the same problems. Took me a while to wrap my head around it. It’s not weird, it’s more counter-intuitive. JS-dates do not consist of a date and time part. They are milliseconds from an offset, being Jan 1 1970, UTC +0.
So a UTC-date July 16, 00:00 UTC would render July 16:00, 02:00 in Amsterdam (UTC +2 , daylight savings). But the same time would render July 15, 21:00 in Buenos Aires (UTC -3) and July 15, 17:00 in San Francisco.
With reservations, it’s the business owner’s time that rules (you make a reservation in the hotel’s time zone, does not matter if guest is located in Moscow or London.)

I also did the coded correction before the timeZone-setting was added to the datePicker (get local time and add/subtract that from UTC time).

Anyway, glad you got in running.

P.S. Check Content Manager and look at the dates. They might be OK in your app, but CM still uses browser locale. Drives you nuts.

Thanks for the link. I would also like to help you by sharing the https://isaccurate.com/healthcare-translation-services website with you where you can easily find the translation service. I am also using that website whenever I want to translate something.