-
Notifications
You must be signed in to change notification settings - Fork 376
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Time zone is double-shifted when saving #303
Comments
How do you have mysql server configured? Using local time or utc? |
I'm at work now, I can check when I get home. But it doesn't really matter, if I save the date and then read it again, the seconds since the epoch should always be the same regardless of how mysql is configured. |
From the mysql manual: |
Which is... local? I'm not sure if mysql does any kind of translation when storing/fetching... |
Yeah I think when they say "System" they mean the timezone on the computer. So on my laptop that would be New York time (EDT). Note that if you think in terms of unix timestamp, you can ignore time zones because a unix timestamp is in seconds since the epoch UTC, regardless of what system you're on. So in my example above, I send the unix timestamp |
Whilst working on something I also hit timezone issues but with postgres. Gonna see if I can get postgres working right. Edit1: Edit2: |
Yes, looking at the code the problems seem to be:
|
An alternative to attempting to store timezone information in the database is to just standardize the way we handle this case, say we always store in UTC and all returned date objects are initialized using UTC as the baseline. That way you can allow the Node runtime to handle localizing the time information, you remove any DB engine specific behavioral constraints etc. For example:
|
As far as I can tell from the code that's pretty much how it works already. It just has a few things missing that I outlined above. It's not a problem for timestamp, because (in mysql at least) that includes the timezone. But for datetime it doesn't include timezone. |
I should qualify my previous comment - timestamp stores timezone information, but I just checked and it seems the same bug exists whether the column is datetime or timestamp |
Also Ben would the scheme you're describing above work with a legacy database? I'm porting a rails project to node so I don't have much control over how the existing data has been stored |
Hmm, that's a good point. I think, if you were looking to run off a legacy database which made use of a different timezone offset, it would be best to use a custom plugin to provide that functionality. Wouldn't be difficult to write one which could pre/post process the data if we get this implemented. I currently don't have the time to do so, but when I do it is on my TODO list. |
In practice I don't think it's that complicated. The main issue seems to be that by default orm assumes a UTC timezone database, whereas the vanilla install of mysql is local time. If I just hardcode timezone to be 'local' in |
When I first added the timezone support it was intended for mysql. I added the timezone support code in mysql module and so I added the possibility for people to define it too. What it should do is convert a date to the timezone you want and store in database and when fetching it should do the opposite. |
It seems to do that fine. The only problem is that it assumes that the timezone of the database is UTC, but the vanilla install of mysql uses the system time zone (eg EDT for me). So it probably makes sense for that to be the default, and if the user wants to have his database in UTC time he can set an option in orm. Did you look at my message about where in the code the problems are?
|
Should be possible to specify the timezone as something along the lines of (not actually implemented yet): db.define('dates', {
utc_date: { type: 'date', time: true, timezone: 'utc' },
local_date: { type: 'date', time: true, timezone: 'local' },
explicit_tz: { type: 'date', time: true, timezone: +2 }
}); |
@dirkmc your points are valid, those 3 zones must match their behaviour. @spartan563 I'm not sure if people want that entropy, we can add it, but first we need to make all dates behave correctly for the global tz option. |
Sounds good to me, thinking over it again - it should be possible for the functionality I've defined to be provided by a plugin anyway. Will look into that when I get a chance. |
As long as the local time zone is configured correctly when the session is initiated, and the time stamp is stored as a timestamptz, at least Postgres will automatically convert to GMT on the way in and from GMT (to the session TZ) on the way out. Currently date values are being stored without timezone. Am I wrong in thinking that simply changing that will fix this issue or am I missing something? |
Yes it will fix it; I've tried and it worked. |
@dxg, excellent news! I just happened to have run into that issue with pg a few months ago. Fix is inbound? |
I'm not comfortable enough writing tests at this scale, but I can confirm that changing this line to:
Did indeed fix my issue. |
I merged your PR and added a few tests. Should be all good now. |
Sounds good, thanks |
|
It does work for postgres, but the tests fail for sqlite and I haven't had time to investigate why yet. |
I pulled the latest code and the tests pass for me. I'm in UTC+1 now (DST). What is the test that is failing? Can you show me the error? |
The failing tests are disabled for sqlite: |
Note that I ran this code at
19:21:01
EDT (New York time), which is23:21:01
UTC (NY is four hours behind UTC). But when the value is stored to the database it has been shifted four hours again, to03:21:01
UTC.Taking the unix timestamp value above and putting it into the browser console shows that it is
23:21:01
EDT (NY time) when it should be19:21:01
EDT:The text was updated successfully, but these errors were encountered: