The Date and Time Pickers do not allow you to select the date/time in UTC (or any other timezone), it always defaults to local time.
Create a Date/Time Picker, there is no prop to change the timezone.
@brucedlukens This sounds like a feature request rather than an issue. Could you explain your use case in a bit more detail?
Sure, basically what I'm doing is I have a "Date Time Picker" input in our app. This "Date Time Picker" provides the user with a disabled text field showing the currently selected date/time in a specific format, in UTC (everything in the system must be UTC). I have 2 buttons where the user can select a new date, and another button where they can select a new time. Since there's no option in the Date and Time Pickers to set a timezone, there's obviously a difference between the text field that displays UTC date/time and the pickers. I would think displaying UTC in the pickers would be a pretty common use case, especially since a Javascript Date object has the functionality to convert to UTC very easily.
So, the TimePicker currently returns a Date object with the selected time in the user's timezone, but you want to be able to use that Date object as if it were UTC when displaying it your other text field? So if a user selects say 4:30pm, it gets treated as 4:30pm UTC, regardless of their timezone?
I have a similar problem.
In following picture, "10:55pm" is shown in the text field.
If I click the field it shows 10:55pm which is expected.
On the other hand, If I change value to "12:55pm" and click "Ok" button, then it suddenly shows 9:55pm.
this is log message from onChanged handler. (ignore "year","month","day". I only need "hour" and "minute")
Finally, If I click the field again, then it show 9:55pm
I think it is inconsistent.
v.0.15.0, react, redux-form
@mbrookes My issue is similar to @SunJang. Essentially what I'm saying is that the date and time pickers will ALWAYS show the user's current time zone, I believe that it should display the time zone that we pass in. So if I want the user to choose a UTC date/time, it should use UTC time when they select the date/time, not their local time zone.
@SunJang your issue sounds like a bug, but I wasn't able to reproduce it after setting my timezone to CST and following your screenshots. If you can reliably reproduce this with 0.15.1, please open a new issue if there isn't one already.
@brucedlukens I understand what you're asking for, but something like Moment Timezone may be your best bet for now.
Same Issue
if I pass Tue, 28 Jun 2016 00:00:00 GMT
to datepicker and my timezone is -9 GMT it will show
Mon, 27 Jun 2016 15:00:00-09:00 GMT
@mbrookes I'm not sure what Moment Timezone would do for me. I don't have an issue getting the correct timezone and formatting it from a date object. The issue I have is just that the Date/Time Pickers do not support anything beyond local timezone. This seems like an oversight in the implementation of the components. I already have workarounds in place but they aren't what anyone would call "correct".
@brucedlukens could you please share your workarounds?
@vorlov I just create a second date object that is offset by the time zone, so the "local time" is the same as whatever it would be UTC. In the unlikely event that a user changes time zones while they're using the application it will obviously be incorrect but I don't think that's really a high risk.
This seems like an oversight in the implementation of the components.
It's an oversight in the implementation of JavaScript - that's what Moment Timezone would help with, but it sounds like you already have a solution.
Just to update this issue, Moment timezone does not seem to solve this issue. It is definitely an issue in the implementation of the DatePicker and TimePicker. I may submit a pull request in the future that fixes this problem, but the basic issue in the code is this: no matter what date object gets passed in, the date and time pickers convert it to local time. The doesn't allow the user to pick the dates/times in anything except local time. If the pickers accepted a timezone prop (what I'd like to do in the pull request when I get around to it), the pickers could base the Date/Time off of that timezone instead of local time.
@brucedlukens Are you working on the PR?
Man just hit this today...the datepicker is surely beautiful but could use some love under the hood...
This is a pretty major issue. The component needs a way to pass in UTC date / times so that we can decide as application authors how to interpret the date / time.
I agree. For our usecase, we show reports in the user's organization timezone. I beleive it is not a rare use case at all.
Unfortunately this simple workflow is made quite difficult because:
It's not as simple as just doing a timezone conversion. This is actually modifying the point in time that is returned, and then doing a timezone conversion (for display). And also doing the reverse, to populate the value prop from the parent component.
This would be so much easier with a customizable timezone prop. This logic is not easy to implement, and requires wrapping the DatePicker with crazy logic. I think the use-case would be fairly common in any b2b, or organizational application.
I ended up here because I figured it would actually be easier for me to add the timezone prop myself, than doing all these conversions on the fly (it's not easy to think about, debug, or get right (at least for me))
I will admit I was surprised when there wasn't a timezone prop, for a datetime component, not that my surprisedness matters :p.
Any help would be appreciated, as I'm banging my head against the wall in order to get these date's to math right. :)
As far as I know, moment.js doesn't have a function like: ModifyByTimezoneOffset(tz1, tz2) function. So it's crazy nutsness to figure out how to implement :).
You can use moment-timezone
to handle timezone offsets.
I think I've gotten it to work with the following code
Wrap the component with a component like the following (where TZ is the custom timezone):
shiftPickerDateToTZDate(pickerDate) {
let pickerOffset = pickerDate.getTimezoneOffset()
let utcDate = new Date()
utcDate.setTime(pickerDate.getTime() - pickerOffset * 60000)
let tzOffset = moment.tz(pickerDate, TZ).utcOffset()
let tzDate = new Date()
tzDate.setTime(utcDate.getTime() - tzOffset * 60000)
return tzDate
}
shiftTzDateToPickerDate(tzDate) {
let tzUTCOffset = moment.tz(tzDate, TZ).utcOffset()
let utcDate = new Date()
utcDate.setTime(tzDate.getTime() + tzUTCOffset * 60000)
let pickerDate = new Date()
let pickerOffset = pickerDate.getTimezoneOffset()
pickerDate.setTime(utcDate.getTime() + pickerOffset * 60000)
return pickerDate
}
// ...
<DatePicker
value={this.shiftTzDateToPickerDate(this.props.start)}
onChange={(ev, date) => this.setStartDate(this.shiftPickerDateToTZDate(date))}
// ...
/>
For all y'all that ~struggle~ get confuzzled with timezone math like me.
Closing for #4787
I think I've gotten it to work with the following code
Wrap the component with a component like the following (where TZ is the custom timezone):
shiftPickerDateToTZDate(pickerDate) { let pickerOffset = pickerDate.getTimezoneOffset() let utcDate = new Date() utcDate.setTime(pickerDate.getTime() - pickerOffset * 60000) let tzOffset = moment.tz(pickerDate, TZ).utcOffset() let tzDate = new Date() tzDate.setTime(utcDate.getTime() - tzOffset * 60000) return tzDate } shiftTzDateToPickerDate(tzDate) { let tzUTCOffset = moment.tz(tzDate, TZ).utcOffset() let utcDate = new Date() utcDate.setTime(tzDate.getTime() + tzUTCOffset * 60000) let pickerDate = new Date() let pickerOffset = pickerDate.getTimezoneOffset() pickerDate.setTime(utcDate.getTime() + pickerOffset * 60000) return pickerDate } // ... <DatePicker value={this.shiftTzDateToPickerDate(this.props.start)} onChange={(ev, date) => this.setStartDate(this.shiftPickerDateToTZDate(date))} // ... />
For all y'all that ~struggle~ get confuzzled with timezone math like me.
Had to make a few edits. There were some cases where a Date function was used on a moment object and vice-versa. Once those were fixed, it worked great!! Thanks!!
import moment from "moment-timezone";
export const shiftPickerDateToTimezoneDate = (pickerDate, timezone) => {
let pickerOffset = moment(pickerDate).utcOffset();
let utcDate = new Date();
utcDate.setTime(moment(pickerDate).valueOf() + pickerOffset * 60000);
let tzOffset = moment.tz(pickerDate, timezone).utcOffset();
let tzDate = new Date();
tzDate.setTime(utcDate.getTime() - tzOffset * 60000);
return tzDate;
};
export const shiftTimezoneDateToPickerDate = (tzDate, timezone) => {
let tzUtcOffset = moment.tz(tzDate, timezone).utcOffset();
let utcDate = new Date();
utcDate.setTime(moment(tzDate).valueOf() + tzUtcOffset * 60000);
let pickerDate = new Date();
let pickerOffset = pickerDate.getTimezoneOffset();
pickerDate.setTime(utcDate.getTime() + pickerOffset * 60000);
return pickerDate;
};
@mbrookes
I am sending data as Tue Aug 20 2019 10:56:00 GMT-0700 (Pacific Daylight Time) but it is displaying
Mon Aug 19 2019.Any help would be appreciated.
thank you
@deeptikanta v0 is no longer supported.
Not strictly off-topic, but GitHub doesn't have a better choice for locking out-of date issues.
Most helpful comment
I think I've gotten it to work with the following code
Wrap the component with a component like the following (where TZ is the custom timezone):
For all y'all that ~struggle~ get confuzzled with timezone math like me.