Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does moment.js handle leap seconds?

I need a way to always add a whole minute to a timestamp, even if the minute is 61 seconds long due to a planned leap second. Does anyone know if moment().add(1, 'minute') adds a minute regardless of leap seconds? Or does it just always add sixty seconds?

I've found how it handles addition over daylight savings time and leap years, but nothing at all for leap seconds.

To give some background as to why this is important:

I need to create a CSV file with a bunch of minute-by-minute sensor data for various sensors, formatted like:

time,sensor1,sensor2
1491329921800,20,21
1491329981800,22,21

My data is stored with with the timestamp for the start of an hour, then an array of sixty data points for the hour.

{
    timestamp: Date(2017,2,24,12,0,0),
    temperature: [20, 22, 23, ... <60 elements total>]
}

I turn this into a bunch of timestamp'd data by giving the first data point the hour's timestamp and adding sixty seconds to that value for each subsequent data point (as leap seconds always happen at the end of the hour and I only ever do an hour at a time, this should be fine).

I then will need to build a dictionary mapping each timestamp to the value at that minute. This is necessary so that I can have the right data in the right row of the CSV; sensors may have started at different times or may have been powered off for a certain hour or not reported for a certain part of the hour; I can't just assume that all sensors have the same data.

I'm finding all of the timestamps over which the CSV will be created with the following code:

    var date = moment(startDate);
    var end = endDate.getTime();

    var timestamps = [];

    while(date.valueOf() < end) {
        timestamps.push(date.valueOf());
        date.add(1, 'minute')
    }
    timestamps.push(date.valueOf());

But I'm not sure if it's safe. If I need to, I could just change date.add(1, 'minute') to date.add(1, 'minute').startOf('minute'), but this could add a lot to the execution time and I'd like to avoid it if possible.

like image 509
Zachary Jacobi Avatar asked Apr 04 '17 19:04

Zachary Jacobi


1 Answers

You don't need to worry about this, because JavaScript is unaware of leap-seconds. Consider this piece of code :-

var newDate = new Date('1 March 1972 11:30:00');
//Convert to milliseconds and add 20 years
var msec = Date.parse(newDate) + 631152000000;
//Convert milliseconds back to normal date format
newDate = new Date(msec);

The big number on the second line is the number of milliseconds in 20 years, as given by the equation ((15 x 365) + (5 x 366)) x 24 x 60 x 60 x 1000; 15 years @ 365 days per year plus 5 years @ 366 days per year, 24 hours per day, 60 minutes per hour, 60 seconds per minute, 1000 milliseconds per second.

After execution the answer given is '1 March 1992 11:30:00'. If JavaScript took account of leap-seconds it would be '1 March 1992 11:30:16', because 16 extra seconds had happened (or '1 March 1992 11:29:44' depending how you look at it).

Summarily, if you need to know how many milliseconds have actually passed between two dates, then you need to write some code to do a lookup of how many leap-seconds occurred within the period they span (you can find the raw data for that here), but for normal time logging we can happily ignore this unwelcome little complication.

like image 162
user3506285 Avatar answered Sep 21 '22 08:09

user3506285