Selected date is one day behind
Opened this issue · 4 comments
Hi @soulim , I think this could be probably connected with #18 but I'm using 0.5.3
and the problem persists.
I'm actually using this:
{{bootstrap-datepicker value=model.started_at placeholder="Data di avvio" class="form-control" id="projectStartedAt" autoclose=true format="dd/mm/yyyy" language="it" startView="decade" weekStart=1 todayBtn=true}}
I select a date, e.g. 06/07/2015 but model.started_at has the value "2015-07-05T22:00:00.000Z".
Also if I select the "Today" button, the selected day is yesterday.
I tried removing various options, with same results. This has the same problem:
{{bootstrap-datepicker value=model.started_at}}
ember-cli-bootstrap-datepicker sets value (at least if you are using a recent version) to a Date
object (or an array of Date objects if you are using multiple
option). "2015-07-05T22:00:00.000Z" seems to be the conversion of this Date object to an ISO 8601 string in UTC timezone (like toISOString
method of Date does it).
bootstrap-datepicker
supports setting date to midnight in locale timezone (getDate
) or UTC (getUTCDate
). ember-cli-bootstrap-datepicker switched to using locale timezone by replacing getUTCDate
by getDate
a while ago (8058147). This was due to a bug reported in #15. I think this one was much more related to using value as ISO string at that time in ember-cli-bootstrap-datepicker. This is also changed in recent ember-cli-bootstrap-datepicker version (as described above).
So when you select a day in ember-cli-bootstrap-datepicker the Date object is set to midnight in your timezone. If you convert that Date object to UTC the day might be some hours before or after that date - depending on your timezone offset.
You could reproduce this issue easily.
var date = new Date(2015, 7, 1);
date.toString(); // "Sat Aug 01 2015 00:00:00 GMT+0200 (CEST)"
date.toISOString(); // "2015-07-31T22:00:00.000Z"
date.getTimezoneOffset(); // 120
Perhaps it should be configurable if ember-cli-bootstrap-datepicker uses getDate
or getUTCDate
method since both use cases are reasonable.
Thanks for the answer.
The option could really be a great solution. Also something like onlyDate: <boolean>
because, like in this case, it's possible that the user needs only the Date, not DateTime, so locale-related problems are out of his focus. I know that js uses DateTime, but the plugin could "hide" the time with a specific option.
Back to the problem, the conversion is implicitly made by Ember while assigning the value to the model attribute. This is really annoying because the only way I found is to convert the value and set it to the attribute, like this:
actions: {
saveObject: function() {
var model = this.modelFor('projects/edit');
if(model.get('started_at')) {
var started_at = model.get('started_at');
model.set('started_at', new Date(started_at.getFullYear(), started_at.getMonth(), started_at.getDate()+1, 0, 0, 0));
}
model.save();
}
}
This code appears really really bad to me, but I tried various options and this seems the easier solution (also the less elegant...). Not to mention the fact that this works only for UTC+ locales, not for UTC-
Visually the conversion also has a ugly effect: when hitting save the date immediately changes to yesterday, than changes after the conversion.
I really appreciate any suggestion :)
I think this addon should stick to Bootstrap Datepicker behaviour. Bootstrap Datepicker returns a Date object (or an array of Date objects) which is just fine. There could be an option if it should use Bootstrap Datepicker method getDate
or getUTCDate
but should not convert the Date object to a String.
You should just use a computed property as your value for bootstrap-datepicker if the model property should be an ISO 8601 date string:
export default Ember.View.create({
bootstrapDateObject: Ember.computed('model.dateString', {
get: function() {
// ECMAScript 5 interprets ISO 8601 string without time zone as UTC
// therefore we just split it up and use it as parameters
// these behaviour changes in ECMAScript 6
var date = this.get('model.dateString').split('-')
return new Date(date[0], date[1] - 1, date[2]);
// of if you are using momentJS
return moment(this.get('model.dateString'));
},
set: function(key, newDate) {
return this.set('model.dateString', newDate.format('YYYY-mm-dd'));
}
})
});
Update: JavaScript Date
constructor counts month beginning with 0 for January.
is this project still maintained?