Try   HackMD

After some time kicking the tyers on date-fns + date-fns-tz with timezones, I don't think we can rely upon it for our usecase. Here's why and please test my logic, I've been in the weeds a little on this.

A good example of an issue can be summed up with thedateFns.startOfDay():

export function startOfDay<DateType extends Date>(
  date: DateType | number | string,
): DateType {
  const _date = toDate(date);
  _date.setHours(0, 0, 0, 0);
  return _date;
}

where a Date::setHours() is used to set the hours to zero.

According to MDN:

The setHours() method of Date instances changes the hours, minutes, seconds, and/or milliseconds for this date according to local time.

this is done according to local time, not any particular timezone. So it's not possible to unfloat the time before-hand, pass that Date object to this function and expect to get the correct behaviour out of the library.

I propose that this is too nieve, as it does not consider a day relative the timezone in question, only from our current client TZ.

We can also test this by doing:

var zonedTime = new Date('2023-06-04T00:00:00.000-06:00')
new Date(zonedTime.setHours(0, 0, 0, 0))
// 2023-06-03T22:00:00.000Z
// should be 2023-06-03T18:00:00.000Z for -06:00

Datefns allows you to use custom Date() implementations, such as date-fns/utc I don't want to write another library to make this work.

So in summary

date-fns is nice but it's philosophy of relying upon native Date() obj means it offers no timezone aware logic, as the Date obj does not hold any TZ information.