pilwon / node-yahoo-finance

Yahoo Finance historical quotes and snapshot data downloader written in Node.js
491 stars 123 forks source link

Handling time zones #16

Open neverfox opened 9 years ago

neverfox commented 9 years ago

The way dates are handled is problematic because of time zones. I have been trying to chase down why my code was acting differently every time I deployed to Heroku (where servers use UTC as local time), and the answer came down to time zones. Here's a summary of what the issue is:

The date strings returned by Yahoo! are just simple strings, e.g. "2015-07-02" or "07/02/2015". There is no indication of time zone. In fact, to make things really interesting, the date represents trading local to the exchange of the requested symbol, so if you ask for "^DJIA" you'll get NY time. If you ask for "^N225," it means Tokyo time.

The problem arises when the code converts these to return Date objects as results. Once the object is a Date, one has to know the time zone intended by the original string if you ever want to correctly convert back to a string, or ask something of the Date like "What date was that again in YYYY-MM-DD?"

A Date object has no concept of a simple date separate from offset so information is essentially lost when this conversion is done. If the date in Yahoo!'s data is a date from the NYSE but the code is run on a server set to UTC, then you get "2015-07-02T00:00:00-00:00" which to people in NY actually "2015-07-01"! If I wrap this Date in moment and do a format("DD") on a East Coast machine, I'll get "01", which isn't what I expect. I need to know the time zone that the machine was using when the conversion was made so that I can account for it first. But that's a problem if I do my development in one time zone and deploy to another. It's a bigger problem if I store these dates all calculated on servers in different time zones and try to compare them.

The best solution from one perspective is to stop using Date objects and simply return strings like the original Yahoo! data and leave it to the user of the library to sort out based on knowledge of the symbols etc. This would be a breaking change however. Another solution might be to let the user pass in a time zone string and use moment-timezone throughout to do conversions. This way you can normalize around a known timezone and account for that in code. This has the disadvantage of not accounting for the different meanings of the date strings for Tokyo vs New York.

Thoughts?