javascriptmomentjsmoment-timezone

Moment TimeZone returns incorrect UTC Offset in minutes


I need to calculate the Offset in Minutes from UTC for a future appointment.

The date and time of the appointment is entered by a user in their Local date and time.

I need the Offset from UTC so my server can email a remainder an hour before the appointment.

I'm using Moment TimeZone and it returns the correct overall TimeZone but when it calculates the Offset in minutes it's wrong.

It returns that I'm in Daylight Savings Time which is an hour ahead - but that's incorrect.

    var startDateTime = moment("2022-11-20 14:00");
    var startTimeStamp = startDateTime.format('X');
    
    // offset from UTC in minutes 
    var offsetMinutes = moment.tz.zone(moment.tz.guess(true)).utcOffset(startTimeStamp); 

    // abbreviated timezone name
    var timeZoneAbbr = moment.tz.zone(moment.tz.guess(true)).abbr(startTimeStamp);  


// Specific scenario is...
// TimeZone = Europe/London
// Date = 2022-11-20
// Time = 14:00

// Moment TimeZone returns...
// TimeZone = Europe/London - correct
// Offset in minutes = -60  - wrong it should be 0
// TimeZone abbreviation = BST (British Summer Time) - wrong - day light savings time ended last month

// NB: I am using this TimeZone library
// https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.31/moment-timezone-with-data-1970-2030.min.js

Solution

  • The issue with the above code is the usage of .format('X'), this formats the date as unix time, the number of seconds since 1970-01-01.

    The moment timezone function expects this as a millisecond value. So you can use .format('x') instead, or easier still, just pass the moment instance to the functions as in the code below.

    var timeZone = moment.tz.zone(moment.tz.guess(true));
    var startDateTime = moment("2022-11-20 14:00");
    
    console.log('Timezone:', timeZone.name);
    console.log('Offset (minutes):', timeZone.utcOffset(startDateTime));
    console.log('Timezone abbr:', timeZone.abbr(startDateTime));
    .as-console-wrapper { max-height: 100% !important; }
      
    <script src="https://momentjs.com/downloads/moment.js"></script>
    <script src="https://momentjs.com/downloads/moment-timezone-with-data.js"></script>