4

I am using the react DateTimePicker widget and want to store date in ISO irregardless of the timezone and DST. The current setup of the localisation is en-GB.

I have tried suggestions from the following posts and gone through the documentation of moment.js Converting date UTC gives wrong date

moment.utc('Wed Sep 08 1999 00:00:00 GMT+0100').toJSON() 

But the end result was but the result was 1999-09-07T23:00:00.000Z thus not storing the correct input date.

I am now formatting the date with the following formatDate function however when I changed my timezone on my machine to Chile, the date 1999-09-07 GMT-0200 becomes 1999-09-08T00:00:00.000Z.

const formatDate = (v) => { console.log(v) const date = moment(v).format('YYYY-MM-DD') console.log(moment.utc(date).toJSON()) return moment.utc(date).toJSON() } 

Is there something that I am missing?

5
  • Always provide formatting string when constructing moment objects. This will significantly decrease errors. Commented Jul 18, 2019 at 13:25
  • "1999-09-07T23:00:00.000Z" is the UTC equivalent of "Wed Sep 08 1999 00:00:00 GMT+0100", why do you think it's wrong (and 1999-09-07 GMT-0200 is 1999-09-08T00:00:00.000Z)? Perhaps you mean you want ISO 8601 with the local timezone? Commented Jul 18, 2019 at 22:31
  • The default formatting for moment.js is ISO 8601 with local timezone, so moment('Wed Sep 08 1999 00:00:00 GMT+0100').format() produces a string like "1999-09-08T00:00:00+0100" if the host is in timezone +0100. Commented Jul 18, 2019 at 22:55
  • If you want to format a date in a specific timezone, see Format date in a specific timezone. Commented Jul 18, 2019 at 23:05
  • @RobG yes, you are correct with the second statement. I have now similiar approach as you have stated on the last point. Using the moment().utcOffset() to store the correct value of local time in utc Commented Jul 19, 2019 at 11:03

1 Answer 1

1

I tried different workarounds of this issue but at the end most workable variant I created you can find below.

The main idea of this variant is to show the wanted TZ inside the input field, but display local TZ inside the calendar and timeList.

I would be grateful for your feedback.

Also see: https://github.com/jquense/react-widgets/issues/467 and https://github.com/jquense/react-widgets/issues/515

enter image description here

enter image description here

import React, { useState, useMemo, useCallback } from 'react'; import moment from 'moment-timezone'; import DateTimePickerOrigin from 'react-widgets/lib/DateTimePicker'; const monthShortNames = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', ]; const dayShortNames = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']; const DateTimePicker = (props) => { const { tz, // <-- tz you want to display, eg 'Etc/UTC' min, max, value, onChange, ...tail } = props; const [localTz] = useState(moment.tz.guess()); const fixedParse = useCallback( (dateStr) => (dateStr ? new Date(dateStr) : null), [], ); const fixedFormat = 'MMM D, YYYY HH:mm z'; const fixedTimeFormat = useCallback( (date) => { if (localTz !== tz) { return `${moment.tz(date, localTz).format('HH:mm z')} (${moment.tz(date, tz).format('HH:mm z')})`; } return moment.tz(date, localTz).format('HH:mm'); }, [tz, localTz, fixedFormat], ); const fixedDateFormat = useCallback( (date) => String(date.getDate()), [], ); const fixedYearFormat = useCallback( (date) => String(date.getFullYear()), [], ); const fixedMonthFormat = useCallback( (date) => monthShortNames[date.getMonth()], [], ); const fixedDayFormat = useCallback( (date) => dayShortNames[date.getDay()], [], ); const fixedMin = useMemo( () => (min === null ? undefined : min), [min], ); const fixedMax = useMemo( () => (max === null ? undefined : max), [max], ); return ( <DateTimePickerOrigin {...tail} parse={fixedParse} format={fixedFormat} timeFormat={fixedTimeFormat} dateFormat={fixedDateFormat} yearFormat={fixedYearFormat} monthFormat={fixedMonthFormat} dayFormat={fixedDayFormat} min={fixedMin} max={fixedMax} value={value} onChange={onChange} /> ); }; 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.