OK, so with single dates and date ranges, it's not a big issue, as you can arrange something to change the start and end date, but for the Multiple Date picker, it's a big issue, as you never know how many dates the user may select.
At present, when working with v-date-picker, all variables binded to the calendar with v-model are stored as a date with the local time zone offset.
Is there any way to change this behaviour and make v-date-picker to work with UTC dates? (No timezone offset) This means that all times will be in the GMT + 0 Timezone.
This is a problem even with single datepicker. All my dates are UTC but datepicker parses them as local, on setting the variable gets changed to local, there needs to be a switch to handle date as UTC at all times.
Yes, it would be great if there could be a timeZone or offset prop.
Or maybe some wrapper function before setting the date object so that we can at least fetch the UTC dates from calendar directly rather than getting the output and trying to make it work.
+1
This is definitively what I see as a design anti-pattern : I think when you work with datetimes, you should always work with UTC time, and convert to localtime only for user display.
This is a really nice calendar/datepicker plugin but those local dates are really annoying. Everyone working with dates know the pain with timezones. I'd have to mess with different timezones and another layer to _fix_ those dates.
Currently I'm trying to implement this feature (:is-utc="true") but it needs further testing. It's somewhat hacky as even for this fecha.js thing UTC seems to be something special. As you can input Date objects (where you can already mess with tz) and strings and even date formats with timezone, there come a lot of use cases along.
https://github.com/canidas/v-calendar/commits/feature/is-utc
Here is what I've implemented for now.
Hope it helps someone.
What essentially is happening is I'm converting date to string and then using the string to convert to moment object of whatever timezone I want to. Attaching the two methods for the same. Here I'm converting the string to epoch while given the clients timezone in moment object.
methods: {
// The essential idea is to convert date object to string and then to moment so as to create a wrapper moment object on the set date value
// Here you can chose to use moment utc to get utc always
// Vice versa, convert moment to string and then to date while setting it for v-calendar
// Called when values are changed
setDateValues (event) {
let selectedDate = null
if (event) {
// this.range is just to check if it's a single datepicker or range date picker
if (this.range) {
selectedDate = {
start: Vue.$moment(event.start.toLocaleString(), ISO_FORMAT).startOf('d').valueOf(),
end: Vue.$moment(event.end.toLocaleString(), ISO_FORMAT).endOf('d').valueOf()
}
} else {
selectedDate = Vue.$moment(event.toLocaleString(), ISO_FORMAT).unix()
}
}
this.$emit('input', selectedDate)
},
// called on mounted or when props are changed
getDateRange () {
if (!this.value) {
this.dateRange = null
return
}
if (this.range) {
this.dateRange = {
start: new Date(this.value.start.format(ISO_FORMAT)),
end: new Date(this.value.end.format(ISO_FORMAT))
}
} else {
this.dateRange = new Date(Vue.$moment.unix(this.value).format(ISO_FORMAT))
}
}
}
Ran into this today as well. I guess it's mostly fine on the client side with momentjs, but on the server side there is not necessarily an obvious indicator on what the client timezone is (that I am aware of).
I ended up adding offset: new Date().getTimezoneOffset() to my payload and then manipulating the date server side to get it back to the user selection.
For date picking I think yyyy-mm-dd is the most intuitive format, ideally as a default option out of the box.
Would love to contribute to this myself but TBH this package goes well beyond my JS abilities.
Solved problem with moment.js
var start = moment(this.selectedDate.start)
var utcStart = moment(start).utc().add(start.utcOffset(), 'm').toISOString()
Credits to Matt Johnson-Pint in his answer to the pretty old question Remove timezone from a moment.js object
Hope it will help someone
TIL axios serializes dates to UTC.
Combine this with v-calendar setting the date to midnight of the local timezone, and I was in a situation where the date went backwards by one day to 2pm the previous day (UTC+10) at the time that axios was called.
I managed to solve this with moment-timezone by modifying my axios payload:
this.$moment(this.form.starts_at).tz('UTC', true)
The tz method changes the timezone without changing the time when the second argument is true.
Most helpful comment
+1
This is definitively what I see as a design anti-pattern : I think when you work with datetimes, you should always work with UTC time, and convert to localtime only for user display.