skip to Main Content

With APIs like Intl, I can obtain the date and time of any Unix timestamp in any time zone. How can I do the reverse?

I’d like to be able to convert any particular triplet of <calendar-date> (YYYY-MM-DD), <local-time> (HH:MM:SS), and <time-zone> (IANA timezone) (which do not necessarily correspond with fixed timezone offsets) to a Unix timestamp. I am not looking to just convert the current timestamp (which is trivial) or looking for solutions that presuppose I have a Javascript Date object; what we have is only the calendar date, local time, and time zone.

Solutions such as adding time zone offsets do not work reliably (eg in cases of DST). I had hoped Intl allowed for easy calculation of this problem.

2

Answers


  1. Does this work for you?

    It was not trivial

    /**
     * Converts a calendar date and local time to a Unix timestamp.
     *
     * @param {string} calendarDate - The calendar date in the format 'YYYY-MM-DD'.
     * @param {string} localTime - The local time in the format 'HH:mm:ss'.
     * @param {string} timeZone - The IANA time zone identifier.
     * @returns {number} The Unix timestamp in seconds.
     */
    const convertToUnixTimestamp = (calendarDate, localTime, timeZone) => {
      const [hourStr, minuteStr, secondStr] = localTime.split(':');
      let hour = parseInt(hourStr, 10);
      const minute = parseInt(minuteStr, 10);
      const second = parseInt(secondStr, 10);
    
      const dateTimeString = `${calendarDate}T00:00:00`;
    
      // Set the locale to 'en-US' for consistent formatting
      const dtf = new Intl.DateTimeFormat('en-US', {
        year: 'numeric',
        month: '2-digit',
        day: '2-digit',
        hour: '2-digit',
        minute: '2-digit',
        second: '2-digit',
        timeZoneName: 'short',
        timeZone
      });
    
      // Format the date portion of the datetime string
      const formattedDate = dtf.format(new Date(dateTimeString));
    
      // Determine if it's in the afternoon based on the hour
      const isAfternoon = hour >= 12;
    
      // Replace "AM" or "PM" without appending when needed
      const formattedDateTime = formattedDate.replace(
        /(AM|PM)/,
        isAfternoon ? 'PM' : 'AM'
      );
    
      // Subtract 12 from the hour if it's in the afternoon (PM)
      if (isAfternoon) {
        hour -= 12;
      }
    
      // Combine the formatted date with the provided local time
      const formattedDateTimeWithTime = formattedDateTime.replace(
        /d{2}:d{2}:d{2}/,
        `${hour.toString().padStart(2, '0')}:${minuteStr}:${secondStr}`
      );
      
      // Create a Date object with the formatted datetime string
      const date = new Date(formattedDateTimeWithTime);
      console.log(formattedDateTimeWithTime, "->", date);
    
      // Get the Unix timestamp in seconds
      const unixTimestamp = Math.floor(date.getTime() / 1000);
      return unixTimestamp;
    };
    
    // Example usages:
    const calendarDate = '2023-04-15';
    
    let timeZone = 'America/New_York'; 
    let localTime = '00:30:00'; // Example with '00'
    let unixTimestamp = convertToUnixTimestamp(calendarDate, localTime, timeZone);
    console.log(unixTimestamp);
    
    localTime = '15:30:00'; // Example with military time
    unixTimestamp = convertToUnixTimestamp(calendarDate, localTime, timeZone);
    console.log(unixTimestamp);
    
    timeZone = 'Europe/Amsterdam'; // another IANA timezone
    localTime = '15:30:00';
    unixTimestamp = convertToUnixTimestamp(calendarDate, localTime, timeZone);
    console.log(unixTimestamp);
    Login or Signup to reply.
  2. Does the Luxon version work for you?

    // const { DateTime } = require('luxon');
    
    // Define your input values
    const calendarDate = '2023-04-15';
    const localTime = '12:30:00';
    const timeZone = 'America/New_York'; // Example timezone, replace with your desired IANA timezone
    
    // Combine calendar date and local time
    const dateTimeString = `${calendarDate}T${localTime}`;
    
    // Create a Luxon DateTime object in the specified timezone
    const luxonObj = luxon.DateTime.fromISO(dateTimeString, { zone: timeZone }); // remove luxon. if you have required DateTime
    console.log(luxonObj)
    // Get the Unix timestamp
    const unixTimestamp = luxonObj.toSeconds();
    
    console.log(unixTimestamp);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/luxon/3.4.3/luxon.min.js"></script>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search