Angular Date pipe, and a simple timer with Momentjs - javascript

I've got the following code, which is supposed to find the difference in milliseconds from one date, to another. It's meant to get the elapsed time since a view has been opened:
this.timer.start = new Date();
this.timer.intervalRef = setInterval(() => {
this.timer.elapsedTime = moment(new Date()).diff(this.timer.start)
}, 1000);
Then, in the template, it's shown as this:
{{ timer?.elapsedTime | date: 'hh:mm:ss' }}
It should display something like:
00:00:01
00:00:02
00:00:03
...
And the minutes and seconds part, work well. But the "hours" part, is starting always with 1, therefore giving me this output:
01:00:01
01:00:02
01:00:03
...
Can someone explain me what I've got wrong, and why it's working like this?

moment.diff return a duration and not a Date object.
You can use .duration and format with the desired output.
this.timer = {};
let start = moment(new Date());
let intervalRef = setInterval(() => {
let elapsedTime = moment(new Date()).diff(start)
let time = moment.duration(elapsedTime)
let hrs = ('0' + time.hours()).slice(-2);
let mins = ('0' + time.minutes()).slice(-2);
let secs = ('0' + time.seconds()).slice(-2);
this.timer.elapsedTime = `${hrs}:${mins}:${secs}`
console.log(this.timer.elapsedTime)
}, 1000);
<script src="https://momentjs.com/downloads/moment.js"></script>

Related

Difference between two dates. react-native (js)

I am trying to get the time that has happened between two dates.
Example:
oldDate = "4/16/2020, 12:00:00"
today = "5/17/2021, 1:00:50"
Result that a need:
years = 1
months = 1
days = 1
hours = 1
minutes = 0
seconds = 50
I also would like to refresh it every second, so that, the user can see it running.
Thanks.
Use Date.parse() to get a Date object from a string, subtract two dates using the - operator, and get the number of years, months, days, etc. using the corresponding methods. Then use setInterval to run it every second, and Date.now() to get the current time.
const oldDate = Date.parse("4/10/2020, 12:00:00");
// weird but seems to work with all dates
const getYear = (date) => date.getFullYear() - 1970;
const timeBetweenDates = (date1, date2) => {
const date = new Date(date1 - date2);
return {
years: getYear(date),
months: date.getMonth(),
days: date.getDay(),
hours: date.getHours(),
minutes: date.getMinutes(),
seconds: date.getSeconds(),
}
}
const pre = document.getElementById("display");
setInterval(() => {
pre.textContent = JSON.stringify(
timeBetweenDates(Date.now(), oldDate),
0,
2
);
}, 1000);
<pre id="display">Wait a second...</pre>

How can I round time to hours and minutes instead of hours, minutes and seconds?

My function returns the time like this 10:43:22 for example. How can I round the time to the closest minute so 10:43:22 becomes 10:43 and 10:43:44 becomes 10:44.
function time (){
let date = new Date()
let time = date.toLocaleTimeString("it-IT");
}
I would get the milliseconds of that date and then round that value to minutes (1 minute = 60,000 milliseconds).
function createRoundedDate(date) {
var ts = date.getTime();
ts = Math.round(ts / 60000) * 60000;
return new Date(ts);
}
console.log(createRoundedDate(new Date()))
we can use the below code to create the new Date by removing the seconds part
var d = new Date()
var d1 = new Date(d.getYear(),d.getMonth(),d.getDate(),d.getHours(),d.getMinutes())
console.log(d1.toLocaleTimeString('it-IT'))
This should do it, and handle going over hours etc. (60,000 ticks is 1 min)
function time(){
let date = new Date()
let dateMins = new Date(date.getYear(),date.getMonth(),date.getDay(),date.getHours(),date.getMinutes())
let roundedDate = new Date(dateMins.getTime() + date.getSeconds() > 30 ? 60000 : 0 )
let time = roundedDate.toLocaleTimeString("it-IT");
}

Check if the time difference is less than 1 second in moment

In my javascript project, I want to check if the time difference is less than 1 second. I use moment to get this difference. This is the function I have written to achieve it.
const withinOneSecond = (time) => {
const currentTime = moment();
return time + 1000 < currentTime;
};
But this doesn't work as expected. How can I check if the given time is within a second to the current time?
You can use moment#diff.
As an example, I've added a second to a date and taking the difference in with .diff passing seconds as second argument should return the difference in seconds
var a = moment();
var b = moment().add(1, 'seconds');
console.log(b.diff(a, 'seconds'))
<script src="https://momentjs.com/downloads/moment.js"></script>
The supported measurements are years, months, weeks, days, hours, minutes, and seconds. Here
For your particular case, you should be doing something like
const withinOneSecond = (time) => {
const currentTime = moment();
return currentTime.diff(time, 'seconds') == 1
};
var time = moment().add(1, 'seconds');
let results = withinOneSecond(time);
console.log(results);
<script src="https://momentjs.com/downloads/moment.js"></script>
You dont need moment for this. Use vanilla, use .getTime() to get time in milliseconds and compare it with the current time. See the code below:
var date = new Date();
const withinOneSecond = (time) => new Date().getTime() - new Date(time).getTime() < 1000;
setTimeout(() => {
console.log(withinOneSecond(date)); // true
}, 500)
setTimeout(() => {
console.log(withinOneSecond(date)); // false
}, 1500)
You just need to use the duration.asHours() method (see the docs).
const withinOneSecond = (time) => {
const currentTime = moment();
return moment.duration(currentTime.diff(time)).asSeconds() > 1;
};

Proper way to manipulate date string with wrong year, but correct time

I'm having to hit an API I have no access to fixing and I need to start a timer showing how long someone has been in a queue for. The date I get back is in this format 1556214336.316. The problem is the year always shows up as 1970, but the time is the correct start time. I need to calculate the difference between the time now, and the time the conversation was created at. I have tried this with little success and was wondering if there is an elegant way to only get the difference in time and not the total amount of seconds.
convertDateToTimerFormat = (time) => {
const now = new Date();
const diff = Math.round((now - parseInt(time.toString().replace('.', ''))) / 1000);
const hours = new Date(diff).getHours();
const minutes = new Date(diff).getMinutes();
const seconds = new Date(diff).getSeconds();
return `${hours}:${minutes}:${seconds}`;
}
The weird parseInt(time.toString().replace('.', ''))) seems to fix the 1970 issue, but I still can't get the data to be manipulated how I need.
I tried the momentjs library, but their diff method only appears to allow for days and hours.
Any help/guidance, would be much appreciated.
Edit with working code:
convertDateToTimerFormat = (time) => {
const now = new Date();
// eslint-disable-next-line radix
const diff = new Date(Number(now - parseInt(time.toString().replace(/\./g, ''))));
const hours = diff.getHours();
const minutes = diff.getMinutes();
const seconds = diff.getSeconds();
return `${hours}:${minutes}:${seconds}`;
}
Unix time values are the number of seconds since the Epoch and won't have a decimal like your 1556214336.316
If I take 1556214336 (without the .316) and put it in a converter I get the output 04/25/2019 # 5:45pm (UTC) which is not 1970 — it seems an accurate time (I haven't independently verified)
It seems, then, your 1556214336.316 is the seconds.milliseconds since the epoch.
Javascript uses the same epoch, but is the number of milliseconds since the epoch, not seconds, so if I'm correct about the time you're getting you should be able to just remove the decimal place and use the resulting number string. Indeed
var d = new Date(1556214336316);
console.log('Date is: ' + d.toUTCString());
produces
Date is: Thu, 25 Apr 2019 17:45:36 GMT
which exactly matches the converter's time of "5:45pm"
var d = new Date(1556214336316);
console.log('Date is: ' + d.toUTCString());
Assuming your value 1556214336.316 is a String coming back from a web API, you can remove the decimal and your conversion can be done like this (note you don't have to keep creating new Date objects):
convertDateToTimerFormat = (time) => {
const d = new Date( Number(time.replace(/\./g, '')) );
return `${d.getHours()}:${d.getMinutes()}:${d.getSeconds()}`;
};
console.log( 'time: ' + convertDateToTimerFormat('1556214336.316') );
Depending on your use, you may want to use getUTCHours() etc. instead.
I don't know about elegant, but this calculates and displays the expired time in h:mm:ss format:
console.log(convertDateToTimerFormat(1556215236.316));
function convertDateToTimerFormat(time){
// Converts `time` to milliseconds to make a JS Date object, then back to seconds
const expiredSeconds = Math.floor(new Date()/1000) - Math.floor(new Date(time * 1000)/1000);
// Calculates component values
const hours = Math.floor(expiredSeconds / 3600), //3600 seconds in an hour
minutes = Math.floor(expiredSeconds % 3600 / 60),
seconds = expiredSeconds % 3600 % 60;
// Adds initial zeroes if needed
if (minutes < 10) { minutes = "0" + minutes; }
if (seconds < 10) { seconds = "0" + seconds; }
// Returns a formatted string
return `${hours}:${minutes}:${seconds}`;
}

How To Get The Sum of Two Times Using Moment.js?

I want to add two times like time1 = '00:05' and time2 = '10:00'. I want the result like the following after sum: result='10:05'. I used moment for that, this is what I used:
let x = moment.duration(moment(this.time1, "hh:mm A").add(moment(this.time2, "hh:mm A")));
let result = moment.utc(x.asMilliseconds()).format('HH:mm:ss');
but I got nothing, how can I do it?
You can't add time this way with moment because you are asking it to add two times, not a time plus a duration. If you want to add ten minutes, use the add() function with a duration.
moment(this.time2, "hh:mm A").add(10, 'minutes')
More here: https://momentjs.com/docs/#/manipulating/add/
It's not really clear in your question what 00:05 PM means. That doesn't look like a valid time. Moment will interpret it as 12:05pm, but it looks like you want to interpret it as 5 minutes. (That's the only way you get 10:05 as an answer). You can do this with moment if you don't include the PM part of the string.
moment.duration('00:05')
Is a duration of five minutes. You can add this to your time with:
moment('10:00 PM', '"hh:mm A"').add(moment.duration('00:05'))
// 22:05:00
Adding two periods works but it is currently not obvious in moment, how to format it like you want. Until they add format() to durations this will have to do:
var d = moment.duration('03:10:10').add(moment.duration('01:20:30'))
moment.utc(d.as('milliseconds')).format("HH:mm:ss")
// '04:30:40'
See Example For Add & Diff using moment.js .. cheers😀
// addTimes(["01:00", "00:30", "00:50"]) ---- 02:20
addTimes(times) {
let duration = 0;
times.forEach(time => {
duration = duration + moment.duration(time).as('milliseconds')
});
return moment.utc(duration).format("HH:mm")
}
// subtractTimes(["05:00", "00:30", "00:20"]) --- 04:10
subtractTimes(times) {
let totalDiff = 0
for (let i = 0; i < times.length; i++) {
let duration = moment.duration(times[i]).as('milliseconds')
if (i == 0) {
totalDiff = duration
}
if (i > 0) {
totalDiff = totalDiff - duration
}
}
return moment.utc(totalDiff).format("HH:mm")
}
function addTwoHours(firstTime = "20:40", secondTime = "18:40") {
firstTime = firstTime.split(':');
secondTime = secondTime.split(':');
const now = moment();
const expiration = moment().add({ hour: firstTime[0], minute: firstTime[1] }).add({ hour: secondTime[0], minute: secondTime[1] });
const diff = expiration.diff(now);
const diffDuration = moment.duration(diff);
return {
"years": diffDuration.years(),
"months": diffDuration.months(),
"days": diffDuration.days(),
"hours": diffDuration.hours(),
"minutes": diffDuration.minutes(),
"yourAnswer" : `${expiration.diff(now, 'hours')}:${diffDuration.minutes()}`
}
}
console.log(addTwoHours());
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.min.js"></script>

Categories