skip to Main Content

I have several dates/times that I need to display, in local time – but I’d also like to have the time elapsed in days/hours for each date:

2024-11-22 04:03:59 (4 days 17 hours ago)

The data I have from the json file I am working with is:

dateUpdated         | localTimeOffset
                    |
2024-11-21 12:05:32 | -05:00:00
2024-11-21 17:02:45 |  00:00:00
2024-11-22 04:03:59 |  11:00:00

These should all be around the same length of time ago, but obviously the local date/time doesn’t make that obvious unless you factor in the offset; hence the request for time elapsed.

I am using vanilla JS.

Thanks in advance, if you require any further info please let me know.

2

Answers


  1. The function formatDaysHours will format elapsed time in full days and full hours:

    const formatDaysHours = elapsed => {
        const seconds = 1000;
        const minutes = seconds * 60;
        const hours = minutes * 60;
        const days = hours * 24;
        const elapsedDays = Math.floor(elapsed/days);
        const remainingTime = elapsed - elapsedDays * days;
        const elapsedHours = Math.floor(remainingTime/hours);
        const pluralDays = elapsedDays == 1 ? "" : "s";
        const pluralHours = elapsedHours == 1 ? "" : "s";
        return `${elapsedDays} day${pluralDays}, ${elapsedHours} hour${pluralHours}`;
    };
        
    // Usage example:
       
    const startTime = new Date('November 23, 2024 23:55:55 GMT+10:00');
    const endTime = new Date();
        
    const elapsed = endTime - startTime; //milliseconds
    console.log(formatDaysHours(elapsed));

    If you need the nearest hour, you can replace Math.floor(remainingTime/hours) with Math.round(/* ... */). Note that multiplicity of nouns is taken into account: depending on the values, you can get “day” or “days”, “hour” or “hours”.

    More importantly, look at my comments. Think of what is the end time of your intervals. If this is a really “present” time, you may want to handle timing events and update the view, say, every second. For hour accuracy, you would need a timing interval of about half an hour. Also, you should better store everything in UTC and present local time only locally in the UI.

    Login or Signup to reply.
  2. I presume that the timestamps in the OP are local values, with the offset to be deducted to get UTC. I.e.

    2024-11-21 12:05:32 | -05:00:00
    

    is

    2024-11-21 17:05:32 UTC
    

    Given the timestamp format, they’ll need to be parsed manually. A library can help, but isn’t necessary for single cases.

    // Parse timestamp yyyy-MM-DD HH:mm:ss, offset ±HH:mm:ss
    // No offset is treated as +
    function parseUTCwOffset(timestamp, offset) {
      // Parse timestamp
      let [yr, mon, day, hr, min, sec] = timestamp.split(/D/);
      // Parse offset - subtract +ve, add -ve offsets
      let sign = offset.substring(0, 1) == '-' ? 1 : -1;
      let [oH, oM, oS] = offset.match(/d+/g);
      // Create Date using UTC values
      return new Date(Date.UTC(yr, mon - 1, day, +hr + sign * oH, +min + sign * oM, +sec + sign * oS));
    }
    
    // Elapsed time difference in UTC, may be different to local where
    // DST observed
    // Returns an array of values: [sign(±), days, hours, mins, secs, millisecs]
    function elapsedDiffUTC(d1, d2) {
      let diff = d2 - d1;
      let sign = diff < 0? '-' : '+';
      diff = Math.abs(diff);
      let days = diff/8.64e7 | 0; // Whole days
      let hrs  = diff % 8.64e7 / 3.6e6 | 0; // Whole hours
      let mins = diff % 3.60e6 / 6.0e4 | 0; // Whole minutes
      let secs = diff % 6.00e4 / 1.0e3 | 0; // Whole seconds
      return [sign, days, hrs, mins, secs];
    }
    
    // Example
    [{
        dateUpdated: '2024-12-10 19:32:00',
        localTimeOffset: '10:00:00'
      },
      {
        dateUpdated: '2024-12-25 00:00:00', // Christmas day
        localTimeOffset: '-05:00:00'
      },
      {
        dateUpdated: '2024-11-21 12:05:32',
        localTimeOffset: '-05:00:00'
      },
      {
        dateUpdated: '2024-11-21 17:02:45',
        localTimeOffset: '+00:00:00'
      },
      {
        dateUpdated: '2024-12-22 04:03:59',
        localTimeOffset: '+11:00:00'
      }
    ].forEach(({dateUpdated, localTimeOffset}) => {
      let date = parseUTCwOffset(dateUpdated, localTimeOffset);
      let [sign, day, hr, min, sec] = elapsedDiffUTC(Date.now(), date);
      // Initial values + equivalent UTC timestamp
      console.log(dateUpdated + ' | ' + localTimeOffset + 'n' + date.toISOString());
      // Elapsed time, exclude zero values
      let elapsedString = sign + (day == 0? '' : day + 'days, ') +
                                 (hr == 0? '' : hr + 'hr, ') +
                                 (min == 0? '' : min + 'min, ') +
                                 (sec == 0? '' : sec + 'sec, ');
                                 
      console.log(elapsedString);
    });
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search