You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Note that I ran this code at 19:21:01 EDT (New York time), which is 23: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, to 03:21:01 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.
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 1376868061 and get back the unix timestamp 1376882461.
Whilst working on something I also hit timezone issues but with postgres. Gonna see if I can get postgres working right.
Edit1:
It seems to be double shifting time with postgres too.
Time goes into database as time - offset and then when it comes back out, time - offset is applied again..
Edit2:
My postgres is running in UTC, node is running in local time.
Creating a timestamp field with timezone in the database makes it work correctly, but without it it fails.
Will investigate more another day, but I think the escapeVal function will need to be aware of if the property is defined as with timezone or without..
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:
We get 2013-06-02 20:16:05 +02:00 as our input (Node.js runtime assignment to an ORM property)
When storing into the database, we adjust to UTC 2013-06-02 18:16:05 +00:00
When retrieving from the database, we create the date object explicitly using UTC 2013-06-02 18:16:05 UTC
When accessing the property through Node.js, it will appear in the local time format
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 Dialect.escapeVal() everything works fine.
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.
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?
@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?
I merged your PR and added a few tests. Should be all good now.
For anyone else reading, this is only fixed in mysql for now. Edit: Now fixed for both mysql & postgres.
Activity
dresende commentedon Aug 20, 2013
How do you have mysql server configured? Using local time or utc?
dirkmc commentedon Aug 20, 2013
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.
dirkmc commentedon Aug 20, 2013
From the mysql manual:
The value 'SYSTEM' indicates that the time zone should be the same as the system time zone.
dresende commentedon Aug 21, 2013
Which is... local? I'm not sure if mysql does any kind of translation when storing/fetching...
dirkmc commentedon Aug 21, 2013
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
1376868061and get back the unix timestamp1376882461.dxg commentedon Aug 22, 2013
Whilst working on something I also hit timezone issues but with postgres. Gonna see if I can get postgres working right.
Edit1:
It seems to be double shifting time with postgres too.
Time goes into database as
time - offsetand then when it comes back out,time - offsetis applied again..Edit2:
My postgres is running in UTC, node is running in local time.
Creating a timestamp field with timezone in the database makes it work correctly, but without it it fails.
Will investigate more another day, but I think the
escapeValfunction will need to be aware of if the property is defined as with timezone or without..dirkmc commentedon Aug 24, 2013
Yes, looking at the code the problems seem to be:
ORM.connect()the timezone option is not being read from the connect stringhttps://github.com/dresende/node-orm2/blob/master/lib/ORM.js#L64
See https://github.com/felixge/node-mysql
https://github.com/dresende/node-orm2/blob/master/lib/Drivers/DML/mysql.js#L13
InsertQueryclass doesn't pass the timezone toDialect.escapeVal(val, tz)https://github.com/dresende/node-sql-query/blob/master/lib/Insert.js#L17
notheotherben commentedon Aug 24, 2013
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:
dirkmc commentedon Aug 25, 2013
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.
dirkmc commentedon Aug 25, 2013
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
dirkmc commentedon Aug 25, 2013
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
notheotherben commentedon Aug 25, 2013
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.
dirkmc commentedon Aug 25, 2013
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
Dialect.escapeVal()everything works fine.dresende commentedon Aug 26, 2013
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.
dirkmc commentedon Aug 26, 2013
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?
ORM.connect()the timezone option is not being read from the connect stringhttps://github.com/dresende/node-orm2/blob/master/lib/ORM.js#L64
See https://github.com/felixge/node-mysql
https://github.com/dresende/node-orm2/blob/master/lib/Drivers/DML/mysql.js#L13
InsertQueryclass doesn't pass the timezone toDialect.escapeVal(val, tz)https://github.com/dresende/node-sql-query/blob/master/lib/Insert.js#L17
notheotherben commentedon Aug 26, 2013
Should be possible to specify the timezone as something along the lines of (not actually implemented yet):
dresende commentedon Aug 26, 2013
@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.
notheotherben commentedon Aug 26, 2013
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.
dkushner commentedon Sep 5, 2013
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?
dxg commentedon Sep 6, 2013
Yes it will fix it; I've tried and it worked.
dkushner commentedon Sep 6, 2013
@dxg, excellent news! I just happened to have run into that issue with pg a few months ago. Fix is inbound?
dkushner commentedon Sep 7, 2013
I'm not comfortable enough writing tests at this scale, but I can confirm that changing this line to:
def += " TIMESTAMP WITH TIME ZONE";Did indeed fix my issue.
dxg commentedon Sep 10, 2013
I merged your PR and added a few tests. Should be all good now.
For anyone else reading, this is only fixed in mysql for now.
Edit: Now fixed for both mysql & postgres.
dirkmc commentedon Sep 10, 2013
Sounds good, thanks
dresende commentedon Sep 11, 2013
sql-query@0.1.15fixes date timezones in sqlite and postgresql.dxg commentedon Sep 12, 2013
It does work for postgres, but the tests fail for sqlite and I haven't had time to investigate why yet.
dresende commentedon Sep 12, 2013
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?
dxg commentedon Sep 12, 2013
The failing tests are disabled for sqlite:
https://github.com/dresende/node-orm2/blob/master/test/integration/property-timezones.js#L7
If you re-enable, they should fail.