Skip to content

Automatic date storing / inflation has issues around timezones #635

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

Closed
iarna opened this issue Nov 12, 2013 · 2 comments
Closed

Automatic date storing / inflation has issues around timezones #635

iarna opened this issue Nov 12, 2013 · 2 comments

Comments

@iarna
Copy link
Contributor

iarna commented Nov 12, 2013

In some circumstances a mismatch in timezones between Node and MySQL can result in incorrect date handling.

First, node-mysql always uses the system timezone when storing and inflating dates, due, I'm sure, to the limitations in JavaScript's date objects.

Second, MySQL has a somewhat schizophrenic relationship with timezones. It has one that it tracks to decide how to return TIMESTAMP columns (which are stored in UTC but displayed based on the value of time_zone). By contrast, DATEs and DATETIMEs are stored without a timezone and its up to the application to manage them. Best practices is to use store with UTC and convert to the local timezone either with CONVERT_TZ or in the application.

This means that if my database stores its dates in UTC, I have to:

  1. Always convert my Date objects into strings before storing them.
  2. Always use CONVERT_TZ to convert them back into whatever timezone Node is using so that they're inflated properly.

It's 2 that I'm concerned about.

I think that in the case of date/time related data, there should be an option to get it back as a string just like there is with bignums. This is for the same reason– MySQL date/time's don't fully map to any JavaScript datatype. As such, I'd like an option to opt out of the lossy date and datetime conversion.

iarna added a commit to iarna/node-mysql that referenced this issue Nov 12, 2013
@dougwilson
Copy link
Member

This library defaults to local time zone intentionally, as other language's MySQL libraries do as well, to match the MySQL server default of local time zone. This works out-of-the-box if both the client and server are in the same time zone. When you use this library, you should set the timezone option to be the time zone your MySQL server is set up to. This makes the date inflation/deflation works just fine.

So if your server is configured so the default connection time zone is UTC, then just pass timezone: 'Z' to the constructor and then it should work correctly.

You also have the option to "opt out" of the datetime conversion just by setting up your own type cast function:

var connection = mysql.createConnection({
  ...,
  typeCast: function (field, next) {
    if (field.type === 'DATE' || field.type === 'DATETIME' || field.type === 'TIMESTAMP' || field.type === 'NEWDATE') {
      return field.string();
    }
    return next();
  }
});

You can also pass the typeCast to individual query calls if you only want to change the typecast on certain queries.

@iarna
Copy link
Contributor Author

iarna commented Nov 12, 2013

I missed the timezone connect option. Thank you.

As far as the typeCast argument goes, that's very clearly called out as experimental in the documentation and I wouldn't want to rely on it. "It is not recommended (and may go away / change in the future) to disable type casting, but you can currently do so"

@iarna iarna closed this as completed Nov 12, 2013
felixge added a commit that referenced this issue Nov 13, 2013
dveeden pushed a commit to dveeden/mysql that referenced this issue Jan 31, 2023
* Remove strict mode

Fixes mysqljs#556 mysqljs#602 mysqljs#635
Closes mysqljs#609

* dsn: panic in case of strict mode
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants