I have three separate variables I want to use to construct an ISO 8601 datetime string in UTC (without offsets). The three variables are:
2024-7-31
format)14:00
format)America/New_York
, America/Chicago
, America/Denver
, America/Los_Angeles
)The timezone of the current user (current browser + operating system) should be irrelevant. The user can be in one of the above 4 timezones or any timezone in the world.
I've tried using:
import moment from 'moment';
import 'moment-timezone';
const startDate = '2024-7-31';
const startTime = '14:00';
const startTimezone = 'America/Chicago'
console.log(moment.tz(startDate + ' ' + startTime, startTimezone).utc().format());
The above generates 2024-07-31T14:00:00Z
- which equals to 9:00 AM Chicago time on 7-31. The time should be 2:00 PM Chicago time on 7-31. If I change startTimezone
to America/New_York
, I get the same ISO 8601 result (9:00 AM Chicago time).
From the looks of it, it seems like Moment isn't taking into account the timezone I am feeding it. How do I get Moment to take into account the timezone it is being given?
Here is your code snippet. Run it and you will see the problem immediately.
const startDate = '2024-7-31';
const startTime = '14:00';
const startTimezone = 'America/Chicago'
console.log(moment.tz(startDate + ' ' + startTime, startTimezone).utc().format());
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.30.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.45/moment-timezone-with-data-10-year-range.js"></script>
Moment's warning is as follows:
Deprecation warning: value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are discouraged.
Indeed, the string you're parsing "2024-7-31 14:00"
is not ISO 8601 compliant, because months are required to be two digits. (It's not RFC2822 compliant either.)
You can solve this by changing the input date to "2024-07-31"
.
const startDate = '2024-07-31';
const startTime = '14:00';
const startTimezone = 'America/Chicago'
console.log(moment.tz(startDate + ' ' + startTime, startTimezone).utc().format());
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.30.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.45/moment-timezone-with-data-10-year-range.js"></script>
Alternatively, you can leave the input date as-is, and supply a format string to Moment:
const startDate = '2024-7-31';
const startTime = '14:00';
const inputFormat = 'YYYY-M-DD H:mm'
const startTimezone = 'America/Chicago'
console.log(moment.tz(startDate + ' ' + startTime, inputFormat, startTimezone).utc().format());
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.30.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.45/moment-timezone-with-data-10-year-range.js"></script>