I would like to request a new DateOnlyTransform be added so that API attributes that only contain the date value (ie. '2017-01-03') are correctly parsed into Date objects with the same date.
When a browser parses an ISO 8601 string that doesn't include the time information, it assumes the time is 00:00:00.000Z. So 2017-01-03 is treated like 2017-01-03T00:00:00.000Z when it is parsed. This is an issue for people in the western hemisphere who have a negative offset from the UTC time because 2017-01-03T00:00:00.000Z occurs the day before.
For example, if you're in the Central Time Zone and paste the following command in the browser console: new Date('2017-01-03').toString(), it responds with Mon Jan 02 2017 18:00:00 GMT-0600 (CST).
Because of this, the current DateTransform deserializes '2017-01-03' into a Date object that is for the day before (1/2/2107) for people in the western hemisphere. And this causes inaccurate information to be shown in an Ember app.
The DateOnlyTransform will adjust for the current timezone offset the browser has so 2017-01-03 is parsed into a Date representing 1/3/2017.
It's possible to create an addon for this, but I believe it's such a common scenario that it should be included in Ember Data itself.
I already have some working code and tests for this new feature, but I wanted to bring it up for discussion before I put the time into creating a pull request for it.
What will this type be? Date in javascript has a time component already.
I've needed a transform like this before and I think it would be useful. However until there is a compelling tree shaking story I think it would be best if this feature lived in an addon.
@btecu It will still be a Date object.
I would like this transform also.
Build the addon, use it to strengthen your case in an RFC, get to use the addon anyway if the RFC doesn't meet the threshold for new APIs ;)
I'm personally also of the opinion this should live in an addon.
@paulyoder Perhaps I'm missing something obvious, but how does this transform differ from the existing date transform? https://github.com/emberjs/data/blob/master/addon/transforms/date.js
@runspired Here is the code for the date-only transform I have. The pertinent code is in the first if statement.
const millisecondsInHour = 60000;
export default DS.Transform.extend({
// example serialized value is '2018-04-19'
deserialize(serialized) {
let type = typeof serialized;
if (type === 'string') {
// Taken from http://stackoverflow.com/a/17346406/215086
let tIndex = serialized.indexOf('T');
if (tIndex >= 0) {
serialized = serialized.slice(0, tIndex);
}
let date = new Date(serialized);
let offset = date.getTimezoneOffset();
return new Date(date.getTime() + offset * millisecondsInHour);
} else if (type === 'number') {
return new Date(serialized);
} else if (serialized == null) {
// if the value is null return null
// if the value is not present in the data return undefined
return serialized;
} else {
return null;
}
},
// Serialize's a date object into the YYYY-MM-DD format
serialize(deserialized) {
if (deserialized == null) {
return null;
} else if (deserialized instanceof Date) {
let lastTwo = -2;
return `${deserialized.getFullYear()}-${('0' + (deserialized.getMonth() + 1)).slice(lastTwo)}-${('0' + deserialized.getDate()).slice(lastTwo)}`;
} else {
return deserialized.toString();
}
}
});
I think this is very much an app specific (or rather an API specific) issue since it seems your API is failing to include the correct timezone information in the formatted date string. Implementing your own transform as you have is the correct thing, but I don't believe this is a good general pattern.
Thanks for your feedback @runspired and taking the time to consider it. I'll work on creating an addon.
Here's a link to the addon I created for this situation: https://github.com/paulyoder/ember-data-date-only-transform
Most helpful comment
Here's a link to the addon I created for this situation: https://github.com/paulyoder/ember-data-date-only-transform