"During the "energy crisis" years, Congress enacted earlier starting dates for daylight time. In 1974, daylight time began on 6 January and in 1975 it began on 23 February. After those two years the starting date reverted back to the last Sunday in April. "
(via http://aa.usno.navy.mil/faq/docs/daylight_time.php )
There appears to be a bug in the Javascript date object for these dates. If you convert 127627200000 milliseconds to a date, it should be Thu Jan 17 00:00:00 EDT 1974. This is correct on http://www.fileformat.info/tip/java/date2millis.htm, but incorrect on
http://www.esqsoft.com/javascript_examples/date-to-epoch.htm, which says it converts to Wed Jan 16 1974 23:00:00 GMT-0500 (Eastern Standard Time). If you create a new Date(127627200000) object in javascript, it gives the latter date conversion. This happens in all major browsers.
I can't imagine this is first time this has been a problem for anyone, but I can't find any other cases of this problem with a few searches online. Does anyone know if there is an existing fix for this or an easier fix than manually checking the dates Javascript has the conversion wrong? Are there other dates this is a problem?
As ever, it's best to check the spec :)
In this case, I was pretty shocked to see this in section 15.9.1.9 of ECMA-262:
The implementation of ECMAScript
should not try to determine whether
the exact time was subject to daylight
saving time, but just whether daylight
saving time would have been in effect
if the current daylight saving time
algorithm had been used at the time.
This avoids complications such as
taking into account the years that the
locale observed daylight saving time
year round.
In other words, a conformant ECMAScript implementation is not allowed to be historically accurate.
Now whether all implementations follow this or not, I'm not sure... but it does suggest you'd need some kind of separate library if you wanted to get historically accurate time zones... where "historically accurate" doesn't have to be nearly as far back as 1974, of course: the US changed its DST schedule in 2007, and other countries have done so more recently than that (and with less warning).
1 The first occurrence of 15.9.1.9. For some reason it occurs twice - once for "Daylight Saving Time Adjustment" and once for "Local Time". Wow.
Java does historical time zones (back to about 1920), JavaScript apparently does not.
Related
I'm using Node v16.17 on MacBook Pro M1.
I want to use microsecond timestamps, so I tried process.hrtime().
But this is very strange, as the first array element (which should be seconds when multiplied by 1000) is like some date in 2017:
> new Date().getTime();
1669997280728
> process.hrtime();
[ 1486038, 90680583 ]
So, if I take 1486038000 --> it is Thu, 02 Feb 2017 12:20:00 GMT
If I take out the milliseconds from new Date().getTime() -> it is correctly Fri, 02 Dec 2022 16:08:00 GMT
What it the issue here? I thought process.hrtime() will be the high resolution time, but why is this so off?
Thanks
Fritz
Per the docs,
These times are relative to an arbitrary time in the past, and not related to the time of day and therefore not subject to clock drift. The primary use is for measuring performance between intervals
https://nodejs.org/api/process.html#processhrtimetime
It is only a coincidence that you got a somewhat relevant date.
You should be using process.hrtime.bigint(), however, because process.hrtime() has been legacy for a while (even in Node v16.17).
What?
process.hrtime() has nothing do to with the real-time clock, as is explained by the docs:
These times are relative to an arbitrary time in the past, and not related to the time of day and therefore not subject to clock drift.
(emphasis mine)
And,
The primary use is for measuring performance between intervals:
When I use
a custom zoneinfo file for TAI or /usr/share/zoneinfo-leaps and
a modified NTP client (currently it just adds 27 seconds; and waits for a time stamp that is about 1 second off)
on my ArchLinux box,
the system time behaves nicely:
> date
Tue Oct 23 17:10:34 TAI 2018
> date -d #1483228827
Sun Jan 1 00:00:00 UTC 2017
> date -d #1483228826
Sat Dec 31 23:59:60 UTC 2016
> date -d #1483228825
Sat Dec 31 23:59:59 UTC 2016
but: JavaScript does not:
test page
screenshot
Does Mozilla/Firefox/Javascript use its own zoneinfo files
somewhere?
How can i fix it?
Not even websites dedicated to time seem to get it right... Or am i missing something?
-arne
The JavaScript Date object specifically adheres to the concept of Unix Time (albeit with higher precision). This is part of the POSIX specification, and thus is sometimes called "POSIX Time". It does not count leap seconds, but rather assumes every day had exactly 86,400 seconds. You can read about this in section 20.3.1.1 of the current ECMAScript specification, which states:
Time is measured in ECMAScript in milliseconds since 01 January, 1970 UTC. In time values leap seconds are ignored. It is assumed that there are exactly 86,400,000 milliseconds per day.
JavaScript is not unique in this regard. This is what the vast majority of other languages do, including Python, Ruby, .NET, the typical implementation of time_t in C, and many others.
Because you have altered your system to track TAI instead of UTC, and there is an implementation of a leap second table on your system that the date command understands, then on your system time_t isn't a Unix timestamp, but rather a TAI-based variant masquerading as a Unix timestamp. Just because the date command and the other underlying functions recognize this, doesn't mean that carries through to all platforms and runtimes on your machine.
The fact is, that the unpredictable nature of leap seconds makes them very difficult to work with in APIs. One can't generally pass timestamps around that need leap seconds tables to be interpreted correctly, and expect that one system will interpret them the same as another. For example, while your example timestamp 1483228826 is 2017-01-01T00:00:00Z on your system, it would be interpreted as 2017-01-01T00:00:26Z on POSIX based systems, or systems without leap second tables. So they aren't portable. Even on systems that have full updated tables, there's no telling what those tables will contain in the future (beyond the 6-month IERS announcement period), so I can't produce a future timestamp without risk that it may eventually change.
To be clear - to support leap seconds in a programming language, the implementation must go out of its way to do so, and must make tradeoffs that are not always acceptable. Though there are exceptions, the general position is to not support them - not because of any subversion or active countermeasures, but because supporting them properly is much, much harder.
That said, there is hope for you if you really care about leap seconds in JavaScript. You can add your thoughts to TC39 Temporal proposal (of which I am one of the champions). This won't change the behavior of the Date object - that is baked and has been for decades. But we are developing a new set of standard objects for date and time in JavaScript, and would love your feedback and participation. There is a thread where we have been considering various ways that leap seconds could be part of this in issue #54. At the moment, we haven't put much thought into TAI-based systems. If this is an area that you have experience in, please add your thoughts there. Keep in mind we'll need to balance this with the general needs of the community, but we'd like your thoughts. Thanks!
I am receiving a MySQL Timestamp in UTC and trying to covert it to the client's local timezone. However, When i do this I get the wrong time zone.
Ive formatted my DateTime String to be: var utcTime = 2014-05-15T13:00:00Z
However when after my conversion my dateObject is: Date {Thu May 15 2014 09:00:00 GMT-0400 (EDT)}. However, I want my Timezone to be GMT -0500 (EST).
I've searched online and saw there is a way to do this by appending "UTC" to a MYSQL formatted Timestamp.. However, this method does not work in all browsers.
If anyone has any insight on converting timezones i would appreciate it.
The D in EDT stands for Daylight and the S in EST stands for Standard. EDT should be used during Summer in the U.S. and EST in the Winter (list of countries here). Is it possible that GMT -4 (EDT) is actually the right local time? If it would be more towards winter it would switch automatically to GMT -5 (EST). The client timezone together with daylight savings is handled automatically by Javascript.
For example, the default string representation of a certain date in Javascript should correctly choose between Standard time and Daylight Savings time based on the date object itself and the machine timezone:
var date = new Date(millisSinceUnixEpoch);
alert(date.toDateString() + ' ' + date.toTimeString());
Note: there's room for a lot of assumption though. E.g. not sure exactly how your 'conversion to local timezone' code looks like
I've seen something similar to this. This MSDN article may explain it.
Handling daylight saving time using JavaScript
http://msdn.microsoft.com/en-us/library/ie/jj863688%28v=vs.85%29.aspx
In Windows Internet Explorer 9 and previous versions of Windows
Internet Explorer, dates are customized by applying the ECMAScript
specification's rules for storing daylight saving time adjusted times
internally. To improve accuracy, especially with dates in the past
(historical dates), Internet Explorer 10 relies on the system's rules
for storing daylight saving time adjusted times. This topic contains
the following sections:
var d = new Date();
// returns correct value "Fri Sep 26 2014 01:16:31 GMT+0300 (E. Europe Daylight Time)"
d.toString();
// returns incorrect value one hour behind "9/26/2014 12:16:31 AM"
d.toLocaleString();
It seems toLocaleString() is not taking DST into account for this test case.
How are local times calculated by Date (eg, does Chrome apply DST rules itself or via OS) and how/why does the algorithm differ between toString() and toLocaleString()?
Is this a bug or intended behavior?
Tested on Chrome/37.0.2062.120 with location Nicosia, Cyprus (http://www.timeanddate.com/time/zone/cyprus/nicosia)
On a hunch, I tried changing my Windows time zone to:
TZ Key / ID: "E. Europe Standard Time"
Display name: "(UTC+02:00) E. Europe"
After restarting Chrome, I was then able to get the same thing you showed:
Taking a closer look, at the localization properties:
So it would seem that there is no time zone understood by Chrome. This is because Chrome uses ICU, which uses the CLDR mappings for Windows time zones. That particular time zone is now considered "unmappable" - as there is no IANA time zone identifier that matches this Windows zone.
Note that this zone used to be mapped to Asia/Nicosia, but it was changed in the last revision of CLDR, as described in CLDR #6973
The reason for the discrepancy is that the toLocaleString function uses the ECMAScript Internationalization API, while toString does not. The prior is dependent on ICU and CLDR, while the latter just asks the OS for a time zone string.
The fix is for the user to switch their time zone to the correct setting. For Cyprus, it should be:
TZ Key / ID: "GTB Standard Time"
Display name: "(UTC+02:00) Athens, Bucharest"
When looking at the options in the Windows Time Zone Control Panel:
Be sure to close all Chrome windows completely after making the time zone change, as Chrome will not properly initialize time zones until it is restarted.
Now, the issue I mentioned earlier in comments is still a problem, as Intl.DateTimeFormat().resolvedOptions().timeZone now returns Europe/Kiev, and it should return either Asia/Nicosia, or Europe/Bucharest. But it is good enough to return the correct value for toLocaleString - at least most of the time.
This question already has answers here:
Create a Date with a set timezone without using a string representation
(29 answers)
How to initialize a JavaScript Date to a particular time zone
(20 answers)
Closed 8 years ago.
I have a timezone string, for example, "Pacific Time (US & Canada)". I need to get the equivalent of 3pm in that timezone in UTC for particular dates, including daylight savings time. How can I go about this?
For example, I need to find 3pm on December 3rd, PDT in UTC time.
That time zone identifier looks like it came from Rails, or from Twitter (which uses Rails). You first need to convert it to a standard IANA zone identifer such as "America/Los_Angeles". See the MAPPING declaration in the ActiveSupport::TimeZone docs.
Then you can use one of the libraries I mentioned here.
In particular, you may want to try moment-timezone. You'll need the latest develop version for this particular feature, as it was added in issue #25 which is not yet in the current release. Then you can do something like this:
moment.tz("2013-12-03T15:00:00","America/Los_Angeles").utc().format()
You can adjust the input/output format to whatever makes sense for you and is supported by moment.js.
The other time zone libraries I mentioned may also offer similar features without as much overhead, so they are worth a look.
This seems to work for me though it does feel a little fragile
new Date('2013-12-03 15:00:00 PDT').toUTCString()
-> "Tue, 03 Dec 2013 22:00:00 GMT"