Im trying to find if the current time and date is equal to a date coming from an API.
The api data is in the following format: 2021-01-02T08:00:00 01:00
The code i currently have is:
if (new Date() === new Date(apiData) {
alert('its the current time accurate to seconds')
}
The problem is that i don't think that this takes in account different timezones, I only want to run the code if the time is exactly as the one from api, no matter where the client is coming from.
CodePudding user response:
The timestamp 2021-01-02T08:00:00 01:00 represents a unique moment in time. If parsed according to ECMA-262, it will produce a time value that is a millisecond offset from the ECMAScript epoch: 1970-01-01T00:00:00Z.
The generated time value is independent of host system settings, i.e. the host offset has no effect. So:
Date.parse('2021-01-02T08:00:00 01:00');
will produce exactly the same value (1609570800000) in every implementation consistent with ECMA-262.
If passed to the Date constructor, the timestamp will be parsed in exactly the same way, with the time value being used for a Date instance such that:
let ts = '2021-01-02T08:00:00 01:00';
Date.parse(ts) == new Date(ts).getTime();
As mentioned in comments, ECMAScript time values have millisecond precision, so the chance that the above will return true is extremely small. Reducing precision to one second (say by rounding or truncating the decimal seconds) won't help much.
If you want to run some code at the time indicated by the timestamp, you are best to work out the time left and, if it's in the future, set a timeout, something like:
let timeLeft = Date.parse(timestamp) - Date.now();
if (timeLeft >= 0) {
setTimeout(doStuff, timeLeft);
}
E.g.
/* Create timestamp in future with specified offset
* @param {string} timeAhead - time in future in H[:m[:s[.sss]]] format
* @param {string} offset - offset as [-]H[:mm]
* @returns {string} ISO 8601 formatted timestamp with offset
*/
function getFutureTimestamp(timeAhead, offset) {
let pad = n => ('0' n).slice(-2);
let [h, m, s, ms] = timeAhead.split(/\D/);
let timems = (h||0)*3.6e6 (m||0)*6e4 (s||0)*1e3 (ms||0)*1;
let oSign = /^-/.test(offset)? -1 : 1;
let [oH, om] = offset.match(/\d /g) || [];
let oms = oSign * (oH*3.6e6 (om||0)*6e4);
let d = new Date(Date.now() oms timems);
return d.toISOString().replace('Z', `${oSign < 0? '-':' '}${pad(oH)}:${pad(om||0)}`);
}
// timestamp for 5 seconds from now with offset 1
let ts = getFutureTimestamp('0:0:5','1');
// Calculate ms from now to ts
let delay = Date.parse(ts) - Date.now();
console.log('Run at ' ts);
// Show timestamp after lag
if (delay >= 0) {
setTimeout(()=>console.log('done: ' new Date().toISOString()), delay);
}
Note that in the above, the first displayed timestamp will be 1, the second 0 so they will be 1 hour different.
Timeouts don't necessarily run after exactly the time specified. However, the above seems to be a few milliseconds. As far as I know, the accuracy of the timeout (based on the system clock) isn't dependent on the length of the delay but on how busy the system is when it's elapsed.
CodePudding user response:
Use This Code
if (new Date().getTime() === new Date(apiData).getTime()) {
alert('its the current time accurate to seconds')
}