Open scscgit opened 3 years ago
The documentation is confusing on this. The examples for formatISO
imply that it yields a date string in UTC time, but on my Windows machine at least, it always yields a data string in local time (i.e., the operating system's time zone setting).
Conversely, the built-in toISOString
appears to always yield a date string in UTC regardless of the OS's time zone setting.
Taking a quick look at the ISO 8601 standard, either of these approaches appear to be acceptable:
Time zones in ISO 8601 are represented as local time (with the location unspecified), as UTC, or as an offset from UTC.
What's really bizarre is if you use utcToZonedTime
(a function in date-fns-tz) to produce a date in a time zone other than your local setting and run formatISO
on that, you'll get a blatantly incorrect UTC offset. What I think is happening is that it converts the date to the desired time zone, but the JS Date
object has no way of knowing that, so when you pass it into formatISO
, it just assumes local time. I guess this is why date-fns-tz has it's own format
method (though it doesn't have it's own formatISO
method, which would be helpful).
I posted similar question in discussion https://github.com/date-fns/date-fns/discussions/2366
So, in the meantime, should I just use this instead?
format(date, "yyyy-MM-dd'T'HH:mm:ss'Z'")
I believe that solution should be to at least put warning regarding this in the documentation. I had a bug in my app that was caused by getting in new versions of Chrome something else than it was expected based on docs. This is how it is looking currently in Chrome 89.0.4 image
I just ran into this. It would be great to get this fixed. Otherwise formatISO is completely unusable
A lot of methods are affected by timezone problems. https://github.com/date-fns/date-fns/pull/2619
let date = new Date()
"Wed Sep 08 2021 18:34:02 GMT+0200 (Central European Summer Time)"
date.toISOString()
"2021-09-08T16:34:02.400Z"
_.endOfMonth(date).toISOString()
"2021-09-30T21:59:59.999Z"
new Date(_.endOfMonth(date).getTime() - date.getTimezoneOffset() * 60000).toISOString()
"2021-09-30T23:59:59.999Z"
Hi guys, any update on this?
I just found out the formatISO
output is different between actual value and the value stated in the documentation.
I'm surprised that such a critical bug has not been addressed for over a year!
I'm surprised that such a critical bug has not been addressed for over a year!
Same here, but it's still not fixed lol.
Will this ever be addressed?
it there any solution?
format(value, "yyyy-MM-dd'T'HH:mm:ss'Z'")
gives response
localhost: 2030-12-20T00:52:30Z
gitlabs CI: 2030-12-20T00:00:00Z
+1
I just got caught with this discrepancy between formatISO()
and the native .toISOString()
.
It would be useful if the documentation was updated to reflect that the ISO string returned by formatISO
is the local timezone. It's as simple as showing something like this
const result = formatISO(new Date(2019, 8, 18, 19, 0, 52))
//=> '2019-09-18T19:00:52+01:00'
//note that the timezone is local
I'm using UTCDate
as provided by https://github.com/date-fns/utc
formatISO(new UTCDate('2024-04-16'), {})
you dont need to use formatISO. I simply do this instead:
const currentDate = new Date();
const oneMonthAgo = subMonths(currentDate, 1);
const lastMonth = oneMonthAgo.toISOString();
console.log("One month ago:", lastMonth);
based on https://github.com/date-fns/date-fns/issues/2151#issuecomment-806452928 this helped to me
const localDate = utcToZonedTime(
format(new Date(analyticsData.generatedAt), "yyyy-MM-dd'T'HH:mm:ss'Z'"),
// get user local timezone
Intl.DateTimeFormat().resolvedOptions().timeZone
);
// example of formatting
const formattedDate = `Last refresh: ${formatDistanceToNow(localDate, {
addSuffix: true,
})}, ${format(localDate, 'HH:mm')} (Local Time)`;
This bug is a huge problem and has to be fixed immediately. It can be compared to Date.prototype.toISOString()
which gives the correct output.
I just got this today..
output..
Well it's not a bug, browsers use a simplified format based on ISO 8601 and date-fns
implements the actual standard ISO 8601 they are not supposed to be the same, blame it on the guys that implemented Date.prototype.toISOString()
in a simplified way...
When making a sanity check of
now.toISOString() === formatISO(now)
(withconst now = new Date()
), it fails due to a timezone difference, as the formatISO doesn't match the browser's toISOString, which explicitly claims thatThe timezone is always zero UTC offset, as denoted by the suffix "Z".
. The formatISO docs \@v2.16.1 doesn't mention anything about this - it actually doesn't even seem to support configuring UTC to be used - and it has an example, which is thus incorrect (non-deterministic):Actual result:
This may be related to closed issues of https://github.com/date-fns/date-fns/issues/1672 and https://github.com/date-fns/date-fns/issues/1559 where the problem was the opposite, as the 'Z' wasn't previously included at all.
Is anyone up to a quest of finding a proper way to use
{ representation: 'time' }
at least with the originaltoISOString()
?Tested on
v2.16.1
in: