Where does GMT-0456 Timezone Come From?
Tags: javascript, timezone
Published: 2020-11-01 08:30:23

> This post is originally published on yoursunny.com blog https://yoursunny.com/t/2020/GMT-0456/

Recently, someone on the [DCTech Slack](http://dctech.chat/) community asked why the `Date.prototype.toDateString` function is having an off-by-one error:

```js
new Date("2020-10-17").toDateString();
"Fri Oct 16 2020"
```

My immediate response was: timezone.
The group then proceeded to discover that the `Date` constructor would interpret a date-only string as being in UTC timezone.
Washington, DC uses Eastern Daylight Time that is four hours behind UTC, so the timezone of the constructed `Date` object is 20:00:00 local time on the previous date.
Since `toDateString` uses local time, it prints as the previous date.

After that, I started testing some boundary conditions:

```js
new Date("0001-01-01").toString()
"Sun Dec 31 0000 19:03:58 GMT-0456 (Eastern Standard Time)"

new Date("0000-01-01").toString()
"Fri Dec 31 -0001 19:03:58 GMT-0456 (Eastern Standard Time)"
```

One problem is that, the [year zero](https://en.wikipedia.org/wiki/Year_zero) should not exist, but it's understandable that JavaScript has not been invented around that time.
What really puzzles me is, why does the timezone show up as **GMT-0456**, instead of the usual **GMT-0500**.

I did a binary search to find when did the timezone change from GMT-0456 to GMT-0500:

```js
new Date("1883-11-18 12:03:57").toString();
"Sun Nov 18 1883 12:03:57 GMT-0456 (Eastern Standard Time)"

new Date("1883-11-18 12:03:58").toString();
"Sun Nov 18 1883 12:03:58 GMT-0500 (Eastern Standard Time)"
```

The magic timestamp turns out to be between 1883-11-18 12:03:57 and 1883-11-18 12:03:58.
Something must have happened on that day!

An Internet search of the date turned up this article: [Today in History: November 18, 1883: Time zones standardized in Canada and USA](https://medium.com/@peterflom/today-in-history-november-18-1883-time-zones-standardized-in-canada-and-usa-7a6fec2eb873).
Basically,

* Until 1883-11-18, each town sets its own time, based on their own estimation of solar time.
* Having different local time in each town was causing problems with the railroads, so that the railroad companies established five timezones for Canada and the United States.
* 1883-11-18 marks the date when Eastern Standard Time was established.

This explains the date 1883-11-18, but still doesn't explain why the cut-off time was 12:03:57 and why the previous timezone is GMT-0456.
I started looking for answers in the computer source code.

Since I was testing on Chrome browser, I started with the [V8 JavaScript engine](https://v8.dev/).
I [located the code related to `Date` and timezone](https://github.com/v8/v8/blob/5f24a451b09c5804c91abcc2e1030acd3d43f844/src/date/date.h#L77-L98), but didn't find GMT-0456 in there.
Instead, V8 invokes `GetLocalOffsetFromOS` function, suggesting that the timezone information comes from the operating system.
I don't have access to Windows source code, but I recall that Linux uses **tzdata** for timezone information.

I downloaded the current [Time Zone Database](https://www.iana.org/time-zones).
In the `northamerica` data file, I found the following records:

```text
# US eastern time, represented by New York

# From Paul Eggert (2014-09-06):
# Monthly Notices of the Royal Astronomical Society 44, 4 (1884-02-08), 208
# says that New York City Hall time was 3 minutes 58.4 seconds fast of
# Eastern time (i.e., -4:56:01.6) just before the 1883 switch.  Round to the
# nearest second.

# Rule  NAME  FROM  TO    -  IN   ON       AT    SAVE  LETTER
Rule    NYC   1920  only  -  Mar  lastSun  2:00  1:00  D
Rule    NYC   1920  only  -  Oct  lastSun  2:00  0     S
Rule    NYC   1921  1966  -  Apr  lastSun  2:00  1:00  D
Rule    NYC   1921  1954  -  Sep  lastSun  2:00  0     S
Rule    NYC   1955  1966  -  Oct  lastSun  2:00  0     S
# Zone  NAME              STDOFF    RULES  FORMAT  [UNTIL]
Zone    America/New_York  -4:56:02  -      LMT     1883     Nov  18  12:03:58
                          -5:00     US     E%sT    1920
                          -5:00     NYC    E%sT    1942
                          -5:00     US     E%sT    1946
                          -5:00     NYC    E%sT    1967
                          -5:00     US     E%sT
```

So the answer to this GMT-0456 mystery is:

* Eastern Time is really "time in New York".
* Before Eastern Standard Time was established on the noon of Nov 18, 1883, the local time in New York was 12:03:58.
* That time was 4 hours and 56 minute (04:56) behind Greenwich Mean Time, so that it shows up as GMT-0456.