Im trying to work out how long a game character has existed for... or apply it to anything. Length of time user has existed.
I understand how to get my two values. Either from state or the database track when i user joins.
But how to work out the difference efficiently is my real question.
My idea has been to get the two time in seconds since 1970 form. Then convert the difference into second mins hours days etc.
Is there any other ideas people have or a plugin i can use?
You can calculate time diffs using the built-in Date class.
async function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
(async () => {
let t1 = new Date();
console.log({ t1 })
await sleep(3000);
let t2 = new Date();
console.log({ t2 })
let dt = new Date(t2 - t1);
console.log(dt.getSeconds());
})();
Related
I have a TIMER (JSFiddle), that takes a date and time and then counts the hours from the starting date / time the current date / time.
In my fiddle it just counts away from January 01, 2020 14:00:00, but on my website the user is able to change this date. – When he enters invalid information the timer outputs NaN.
When the users enters information, the timer is run again and the user get a new output. – When this happens, I would like to check, if the output is NaN, if so, I would like for another function to ben run, let's call it: timerError() – With this I will reset the timer and tell the user, that his input was invalid.
I know about isNaN(variable), but I don't really have a variable here, so don't know how to check, if the timer output is NaN…
This is my JS:
// TIMER Styling START
function styleChars(targetEl) {
const val = targetEl.textContent;
const chars = val.split('');
targetEl.innerHTML = chars.map(c => `<span class="digit">${c}</span>`).join('');
}
const target = document.querySelector('.value_timer');
console.log(target);
styleChars(target);
// TIMER Styling END
// TIMER START
var timerDate = "January 01, 2020 14:00:00";
function setTimer() {
// Month Day, Year Hour:Minute:Second, id-of-element-container.
countUpFromTime(timerDate, 'countup1');
};
window.onload = setTimer();
function countUpFromTime(countFrom, id) {
let countDate = new Date(countFrom);
let now = new Date();
let timeDifference = (now.getTime() - countDate.getTime());
let value_timer = Math.floor(timeDifference / 1000 / 60 / 60);
let idEl = document.getElementById(id);
idEl.innerHTML = value_timer;
styleChars(idEl); // Pass element to styling function.
clearTimeout(countUpFromTime.interval);
countUpFromTime.interval = setTimeout(function () {
countUpFromTime(countFrom, id);
}, 1000);
}
// TIMER END
The problem is that if timerDate is not a valid date string format, new Date(timerDate) will return an InvalidDate.
In your code, you need to check if countDate which is new Date(timerDate) is an Invalid Date. If so, handle the error accordingly.
You can check by verifying isNaN(countDate.getTime()). It should be true if the Date is invalid.
EDIT: I have created a Fiddle that makes your code compliant with the changes.
I need to make request three times a day at a certain time (8 AM, 12 AM, 4 PM).
What is the best way to implement this?
This feels a bit like a strange requirement for a JS task and I think you should rather look into making a Cron task for that. But for the sake of example, here's how you can do it:
import { of, Observable, timer, EMPTY } from "rxjs";
import { map, filter, timestamp, switchMap } from "rxjs/operators";
type Hour = number;
type Minutes = number;
const atTimes = (times: [Hour, Minutes][]): Observable<[Hour, Minutes]> =>
timer(0, 1000 * 60).pipe(
switchMap(() => {
const date: Date = new Date();
const [currentHour, currentMinutes] = [
date.getHours(),
date.getMinutes()
];
const time = times.find(
([hour, minutes]) => hour === currentHour && minutes === currentMinutes
);
if (!time) {
return EMPTY;
}
return of(time);
})
);
atTimes([[11,48]]).subscribe(x => console.log(x));
Live demo: https://stackblitz.com/edit/rxjs-sxxe41
PS: I've assumed that the update doesn't need to be triggered as soon as the new minute starts. If that's the case, then timer should tick every second and you should use distinctUntilChanged on the current hour/minutes to wait until they're differents.
You should look into asyncScheduler from RxJS which uses setInterval for time based operations.
Refer to this link: https://rxjs-dev.firebaseapp.com/guide/scheduler
Ideally cron jobs are best on the server side to deal with functions need executing at different times, might be worth looking in that as well.
This question already has answers here:
Convert a Unix timestamp to time in JavaScript
(34 answers)
Closed 4 years ago.
I have this code:
v.d = new Date().toLocaleTimeString();
it yields something like this:
20:11:40
So this is the time of day to the second, without milliseconds.
My question is: is there a built in call that can show just the time with milliseconds?
I am looking for something like this (to the millisecond):
20:11:40.124
This works, but I am looking for something more compact if possible:
const d = new Date();
v.d = d.toLocaleTimeString() + `.${d.getMilliseconds()}`;
this yields:
20:17:30.744
note that to make this work well, you need to add this part:
Formatting milliseconds to always 3 digits for d.getMilliseconds() call
There’s to ISOString(). But stepping back a level, with that exception there’s no standard for formatting dates in js. So you can use toISOString or build up your own string with individual date functions.
I did find one issue with your original solution. When I perform it it yields hh:mm:ss PM.mil. I assume you want hh:mm:ss.mil Here is that solution written as a function so you can pass the date object in and get the proper format:
const d = new Date()
const getTimeWithMilliseconds = date => {
const t = d.toLocaleTimeString();
return `${t.substring(0,8)}.${date.getMilliseconds() + t.substring(8,11)}`;
}
console.log(getTimeWithMilliseconds(d));
Or if you want it in 24 hour format:
const d = new Date()
const getTimeWithMilliseconds = date => {
return `${date.toLocaleTimeString('it-US')}.${date.getMilliseconds()}`;
}
console.log(getTimeWithMilliseconds(d));
You can't depend on toLocaleTimeString returning a specific format as it's implementation dependent. It's much more reliable to build the format yourself, e.g.:
function getFormattedTime(date) {
var d = date || new Date();
var z = n => ('0'+n).slice(-2);
var zz = n => ('00'+n).slice(-3);
return `${z(d.getHours())}:${z(d.getMinutes())}:${z(d.getSeconds())}.${zz(d.getMilliseconds())}`;
}
console.log(getFormattedTime());
console.log(getFormattedTime(new Date(2018,1,1)));
console.log(getFormattedTime(new Date(2018,4,30,23,51,12,89)));
Also see Where can I find documentation on formatting a date in JavaScript?
I'm a bit of a newbie so please bear with me. I've created a date object in javascript every time someone opens a new page. I want to save the time the user opened the page and create another date object exactly one day later to create a countdown timer showing time elapsed from date 1 to date 2.
To accomplish this, I tried subtracting the two dates using .getTime; I want to keep the second date static instead of one day ahead of the current time. Unfortunately, this is not happening even though I have confined d2 (Date 2) to a condition that only runs once and is stored in variable nextday. Here's my JS
$(function (){
localStorage.clear()
var ran = JSON.parse(localStorage.getItem('run'))
d1 = new Date()
var i = 0
if(!ran){
i+=1
d2 = new Date(d1)
nextday = d2.setHours(d1.getHours()+24)
console.log(i)
console.log(typeof(nextday))
localStorage.setItem('run',JSON.stringify('ran'))
localStorage.setItem('nextday',JSON.stringify(nextday))
}
console.log(localStorage)
nday = JSON.parse(localStorage.getItem('nextday'))
console.log(nday)
var seconds = (nday - d1.getTime())
console.log(seconds)
console.log(localStorage)
})
Your script is clearing local storage every time the page is loaded:
localStorage.clear()
This will prevent anything from being stored across runs. Remove it.
You're clearing your localStorage before you access your locally-stored data. Thus, your ran variable is always empty. Remove that one call to clear(), and everything should work fine.
$(function() {
// localStorage.clear() <= the offending code!
var ran = JSON.parse(localStorage.getItem('run'))
d1 = new Date()
var i = 0
if (!ran) {
i += 1
d2 = new Date(d1)
nextday = d2.setHours(d1.getHours() + 24)
console.log(i)
console.log(typeof(nextday))
localStorage.setItem('run', JSON.stringify('ran'))
localStorage.setItem('nextday', JSON.stringify(nextday))
}
console.log(localStorage)
nday = JSON.parse(localStorage.getItem('nextday'))
console.log(nday)
var seconds = (nday - d1.getTime())
console.log(seconds)
console.log(localStorage)
})
I'm looking for a way to shift the browser's Date to a specified one without freezing time. Let's pretend I have some function shiftDate() which does just that. The following outlines the behavior I'm seeking:
// Here's the current time.
new Date().getTime(); //=> 1391109350382
//
// Now let's call the function to shift/travel back in time and _immediately_
// check the time afterwards
shiftDate('2014-01-01');
new Date().getTime(); //=> 1388534400000
//
// Now let's wait 1111 ms and then check the time again
new Date().getTime(); //=> 1388534401111
//
// Let's wait another 1111 ms
new Date().getTime(); //=> 1388534402222
//
// Let's shift/travel back in time once more
shiftDate('2014-01-01');
new Date().getTime(); //=> 1388534400000
//
// Then wait 1111 ms again
new Date().getTime(); //=> 1388534401111
//
// And wait 1111 ms again
new Date().getTime(); //=> 1388534402222
Notice time keeps ticking after each shift. Most solutions that I've found entirely freeze time through a mock or stub of some sort. However, freezing time is not an appropriate solution: doing so disrupts other time-dependent features such as animations. Below is an example, which freezes time:
new Date().getTime(); //=> 1391109350382
var oldDate = Date;
Date = function() { return new oldDate('2014-01-01'); };
var testDate = new Date();
new Date().getTime(); //=> 1388534400000
// Wait 1111 ms, ten minutes, or an hour: time will never change
new Date().getTime(); //=> 1388534400000
Check out Momentjs for handy date and time manipulation.
http://momentjs.com/
// Let's shift/travel back in time once
shiftDate('2014-01-01');
new Date().getTime(); //=> 1388534400000
I'm not sure why you don't simply do new Date('2014-01-01').getTime(); in your custom, shifted logic?
However, you can get the desired behaviour with the following function:
function shiftDate(to) {
var realDate = Date;
Date = function frozenDate() {
Date = realDate;
return new Date(to);
};
}
When you call shiftDate, the next - and only the next - call to Date will yield a date from a confused timeline.
I dont think there is any way you can change the date objects internal time pointer (if you want to call it that) without going deep into the OS. I think you'd have to write your own little library, similar to this:
var myDate = function(dateStr){
var initTime = new Date().getTime()
var dateObj = new Date(dateStr);
var myDateTime = dateObj.getTime();
// subtract the init time from the time this method is called
// to get a difference, then add it to your "old" time to get
// the updated millisecond value
this.getTime = function(){
var currentTime = new Date().getTime();
var dif = currentTime - initTime;
return myDateTime + dif;
};
};
You could of course get fancy with the methods and implement all of the native Date object methods.
I've got it! The trick is to keep track of the time change within a new Date prototype. Here's a rough implementation:
function shiftDate(date) {
window.trueDate = window.trueDate || Date;
var trueStart = new trueDate().getTime();
var shiftedStart = new Date(date).getTime();
Date = function() {
var timeChange = new trueDate() - trueStart;
return new trueDate(shiftedStart + timeChange);
}
}
And here's a simple test:
shiftDate('2014-01-01')
testDate = new Date();
setInterval(function(){
console.log(new Date().toString());
}, 1000);