DateTime field type timezone bug
See original GitHub issueHi. We’ve discovered a bug when using a DateTime field type. It occurs when Keystone admin UI is accessed by a client from a timezone different to the one on the server. Say the client machine is 2h ahead of server (EET), and the server itself is in UTC. Steps to reproduce:
- Fill out a DateTime input with any valid value.
- Save the document.
- Edit the document - you’ll see previously saved value change by timezone delta.
This is a presentation thing - the value in the database, and the value returned to Keystone UI view is correct - but it is then rendered in user’s timezone. When you hit “save” - the value rendered (e.g. 2 hours ahead) gets saved down to the database as a new UTC time.
Here’s the model we used:
var Banner = new keystone.List('Banner', {
map: { name: 'imageTitle' },
autokey: { from: 'imageTitle', path: 'key', unique: true },
sortable: true
});
Banner.add({
imageTitle: { type: Types.Text, label: 'Title' },
alt: { type: Types.Text , label: 'Alternative Text'},
filename: { type: Types.LocalFile, dest: 'public/images/uploads' },
inApp: { type: Types.Boolean, default: true },
targetUri: { type: Types.Text },
validityPeriodStart: { type: Types.Datetime, required: true, initial: true },
validityPeriodEnd: { type: Types.Datetime, required: true, initial: true },
disabled: { type: Types.Boolean, default: false , label: 'Inactive'},
uriSmall: { type: Types.Url, hidden: true },
widthSmall: { type: Types.Number, hidden: true },
heightSmall: { type: Types.Number, hidden: true },
uriMedium: { type: Types.Url, hidden: true },
widthMedium: { type: Types.Number, hidden: true },
heightMedium: { type: Types.Number, hidden: true },
categoryId: { type: Types.Relationship, ref: 'sportCategory' },
categoryName: { type: Types.Text, default: 'default', hidden: true },
brand: { type: Types.Text, default: 'bma', hidden: true },
lang: { type: Types.Text, default: 'en', hidden: true }
});
Issue Analytics
- State:
- Created 8 years ago
- Comments:28 (10 by maintainers)
Top Results From Across the Web
How to fix wrong value of Datetime field type Time zone ...
If you open the form of any entity and set the value for the field Time-Zone Independent, you will see the new value...
Read more >Datetime field not working correctly (with timezones?) - Drupal
Problem When I map a datetime field, the date gets mapped correctly, but the time is wrong. It seems that there is some...
Read more >Timezone issue with Datetime field in salesforce
I have a custom field of type datetime on a custom object. I want to show this field as it is regardless of...
Read more >How to fix wrong value of Datetime field type Time...
If you open the form of any entity and set the value for the field Time-Zone Independent, you will see the new value...
Read more >timezone issue in date time field - MSDN - Microsoft
I am using XML Serializer to deserialize the response of the webservice. All these DateTime fields are returning the timezone like 2017-10-10T20 ...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Exactly, but we should display in the browsers timezone. The problem at the moment, which you correctly identified, is that we’re getting UTC dates from Mongo, displaying them as-is but them saving them as if they were in the timezone.
Instead, we should save and get everything from Mongo in UTC, and then only for display purposes convert it to the browsers timezone, and when they save convert it back to UTC.
The big blocker on this issue is that I don’t have a server in another timezone at the moment, so I can’t replicate & fix it. If you have one, please submit a PR with a fix!
There offending line is here (on master): https://github.com/keystonejs/keystone/blob/master/fields/types/datetime/DatetimeField.js#L23
Without
utc: true
, no timezone conversion is supposed to ever happen (this is foolery anyway, but oh well). However, the API returns a formatted date that has a “Z” tacked to the end (meaning UTC), because MongoDB stores UTC dates). Momentjs then converts this to local time and BOOM! It’s arguable whether the date value from the API (it should not have any timezone information because the timezone is unspecified) or the conversion of timezones on the frontend is at fault.Ways to work around this:
Always parse dates as if they were UTC (even when they are not):
https://github.com/keystonejs/keystone/blob/master/fields/types/datetime/DatetimeField.js#L34 Turn
var m = moment(value);
intovar m = moment.utc(value);
Return the date from the API without any timezone information. I have no idea how to do this, but I was able to simulate it by chopping of the ‘Z’ at the end of the time string:
https://github.com/keystonejs/keystone/blob/master/fields/types/datetime/DatetimeField.js#L23
timeValue: this.props.value && this.moment(this.props.value.slice(0, -1)).format(this.timeInputFormat),
I believe, for the future, keystone should abandon the idea of transmitting or storing local time values altogether and switch to UTC. The only other way to do it correctly is to always store and transmit timezone information as well.