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


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} /> ); };
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.