Wiki

    Contact support:

    Email: support@erply.com

    23 Sep, 2022
    Permalink:
    Also available in:EstonianFinnish

      Javascript math with time zones

      Question: 

      As a developer, I need to query for records from a specific date — but the API call requires the time range to be specified as Unix timestamps.

      From user's perspective, “records from a specific date” is everything with a creation datetime between 12:00am and 11:59pm. Therefore, the exact time range depends on the time zone. 

      Usually, you will want to rely on the account time zone, not the browser's local time zone. (Example: the manager of an American company will still want to get a report for their “American business day”, even if they are currently on a holiday in Tokyo and have changed their computer timezone accordingly.) 

      Account time zone can be retrieved from API call getConfParameters; API returns the time zone's IANA name (eg. 'America/Toronto' or 'America/Vancouver').

      This StackOverflow article might be helpful: https://stackoverflow.com/questions/15141762/how-to-initialize-a-javascript-date-to-a-particular-time-zone

      The top comment explains the problem in general, and recommends the Luxon library.

      If you do not want to include extra libraries, comment #2 provides a pure-Javascript function  — although for our use case, you would need to flip the subtraction around.

      Here is a slightly modified function:

      /**
       * @param dateTimeString A relative date and time, for example '2021-03-01 00:00:00'
       * @param tz User's timezone
       * @returns {number} The datetime + timezone converted into a Unix timestamp
       */
      function toTimestamp(dateTimeString, tz) {
        // Let the input be midnight, 'America/New_York'
      
        // The browser will initially interpret this datetime as being in its _local_
        // timezone, which may or may not be what we want.
        // Let's say the local time zone is London, UK; this statement will produce
        // midnight in London
        const localDate = new Date(dateTimeString);
      
        // Midnight in London = 7pm in New York
        // But calling new Date("7pm") gives us *London 7pm*, which means
        // that we will have two different Date objects we can then directly compare.
        const convertedDate = new Date(localDate.toLocaleString('en-US', {timeZone: tz}));
      
        // Midnight - 7pm = +5 hours
        const diff = localDate.getTime() - convertedDate.getTime();
        
        // London time + 5 hours (5am) is equal to New York midnight, which is what we wanted
        return new Date(localDate.getTime() + diff).getTime() / 1000;
      }
      

      Test cases:

      toTimestamp('2021-03-01 00:00:00', 'America/Toronto'); 
      1614574800 
      
      toTimestamp('2021-03-26 00:00:00', 'America/Toronto'); 
      1616731200