Is there any way I can use the moment.js format method on duration objects? I can't find it anywhere in the docs and it doesn't seen to be an attribute on duration objects.
I'd like to be able to do something like:
var diff = moment(end).unix() - moment(start).unix();
moment.duration(diff).format('hh:mm:ss')
Also, if there are any other libraries which can easily accommodate this sort of functionality, I'd be interested in recommendations.
Thanks!
// set up
let start = moment("2018-05-16 12:00:00"); // some random moment in time (in ms)
let end = moment("2018-05-16 12:22:00"); // some random moment after start (in ms)
let diff = end.diff(start);
// execution
let f = moment.utc(diff.asMilliseconds()).format("HH:mm:ss.SSS");
alert(f);
Have a look at the JSFiddle
convert duration to ms and then to moment:
moment.utc(duration.as('milliseconds')).format('HH:mm:ss')
We are looking into adding some kind of formatting to durations in moment.js. See https://github.com/timrwood/moment/issues/463
A couple other libraries that might help out are http://countdownjs.org/ and https://github.com/icambron/twix.js
Use this plugin Moment Duration Format.
Example:
moment.duration(123, "minutes").format("h:mm");
Use this line of code:
moment.utc(moment.duration(4500, "seconds").asMilliseconds()).format("HH:mm:ss")
var diff = moment(end).unix() - moment(start).unix();
moment.utc(moment.duration(diff).asMilliseconds()).format("HH:mm:ss.SSS");
The best scenario for my particular use case was:
var duration = moment.duration("09:30"),
formatted = moment.utc(duration.asMilliseconds()).format("HH:mm");
This improves upon #Wilson's answer since it does not access private internal property _data.
You don't need .format. Use durations like this:
const duration = moment.duration(83, 'seconds');
console.log(duration.minutes() + ':' +duration.seconds());
// output: 1:23
I found this solution here: https://github.com/moment/moment/issues/463
EDIT:
And with padding for seconds, minutes and hours:
const withPadding = (duration) => {
if (duration.asDays() > 0) {
return 'at least one day';
} else {
return [
('0' + duration.hours()).slice(-2),
('0' + duration.minutes()).slice(-2),
('0' + duration.seconds()).slice(-2),
].join(':')
}
}
withPadding(moment.duration(83, 'seconds'))
// 00:01:23
withPadding(moment.duration(6048000, 'seconds'))
// at least one day
I needed to do this for work as a requirement to display the hours in this format.
At first I tried this.
moment.utc(totalMilliseconds).format("HH:mm:ss")
However anything over 24 hours and the hours reset to 0.
But the minutes and seconds were accurate.
So I used only that part for the minutes and seconds.
var minutesSeconds = moment.utc(totalMilliseconds).format("mm:ss")
Now all I need is the total hours.
var hours = moment.duration(totalMilliseconds).asHours().toFixed()
And to get that format that we all want we just glue it together.
var formatted = hours + ":" + minutesSeconds
if totalMilliseconds is 894600000 this will return 249:30:00.
Hope that helped. Leave any questions in the comments. ;)
I use:
var duration = moment.duration("09:30");
var str = moment(duration._data).format("HH:mm");
And I get "09:30" in var str.
if diff is a moment
var diff = moment(20111031) - moment(20111010);
var formated1 = moment(diff).format("hh:mm:ss");
console.log("format 1: "+formated1);
If you're willing to use a different javascript library, numeral.js can format seconds as follows (example is for 1000 seconds):
var string = numeral(1000).format('00:00');
// '00:16:40'
If all hours must be displayed (more than 24) and if '0' before hours is not necessary, then formatting can be done with a short line of code:
Math.floor(duration.as('h')) + moment.utc(duration.as('ms')).format(':mm:ss')
Based on ni-ko-o-kin's answer:
meassurements = ["years", "months", "weeks", "days", "hours", "minutes", "seconds"];
withPadding = (duration) => {
var step = null;
return meassurements.map((m) => duration[m]()).filter((n,i,a) => {
var nonEmpty = Boolean(n);
if (nonEmpty || step || i >= a.length - 2) {
step = true;
}
return step;
}).map((n) => ('0' + n).slice(-2)).join(':')
}
duration1 = moment.duration(1, 'seconds');
duration2 = moment.duration(7200, 'seconds');
duration3 = moment.duration(604800, 'seconds');
withPadding(duration1); // 00:01
withPadding(duration2); // 02:00:00
withPadding(duration3); // 01:07:00:00:00
I use the classic format function in these cases:
var diff = moment(end).unix() - moment(start).unix();
//use unix function instead of difference
moment.unix(diff).format('hh:mm:ss')
This is a hack because the time diff is treated as a standard moment date, an early epoch date time, but it doesn't matter to our goal and you don't need any plugin
Short version (one-liner):
moment.duration(durationInMs).asHours()|0||"00" + ":" + moment.utc(durationInMs).format("mm:ss")
Extended version:
export const formatDuration = (durationInMs) => {
const hours = Math.floor(moment.duration(durationInMs).asHours()) || "00"
return hours + ":" + moment.utc(durationInMs).format("mm:ss")
}
Example cases:
To format moment duration to string
var duration = moment.duration(86400000); //value in milliseconds
var hours = duration.hours();
var minutes = duration.minutes();
var seconds = duration.seconds();
var milliseconds = duration.milliseconds();
var date = moment().hours(hours).minutes(minutes).seconds(seconds).millisecond(milliseconds);
if (is12hr){
return date.format("hh:mm:ss a");
}else{
return date.format("HH:mm:ss");
}
if you use angular add this to your filters:
.filter('durationFormat', function () {
return function (value) {
var days = Math.floor(value/86400000);
value = value%86400000;
var hours = Math.floor(value/3600000);
value = value%3600000;
var minutes = Math.floor(value/60000);
value = value%60000;
var seconds = Math.floor(value/1000);
return (days? days + ' days ': '') + (hours? hours + ' hours ': '') + (minutes? minutes + ' minutes ': '') + (seconds? seconds + ' seconds ': '')
}
})
usage example
<div> {{diff | durationFormat}} </div>
My solution that does not involve any other library and it works with diff > 24h
var momentInSeconds = moment.duration(n,'seconds')
console.log(("0" + Math.floor(momentInSeconds.asHours())).slice(-2) + ':' + ("0" + momentInSeconds.minutes()).slice(-2) + ':' + ("0" + momentInSeconds.seconds()).slice(-2))
How to correctly use moment.js durations?
|
Use moment.duration() in code
First you need to import moment and moment-duration-format.
import moment from 'moment';
import 'moment-duration-format';
Then, use duration function. Let us apply the above example: 28800 = 8 am.
moment.duration(28800, "seconds").format("h:mm a");
🎉Well, you do not have above type error. 🤔Do you get a right value 8:00 am ? No…, the value you get is 8:00 a. Moment.js format is not working as it is supposed to.
💡The solution is to transform seconds to milliseconds and use UTC time.
moment.utc(moment.duration(value, 'seconds').asMilliseconds()).format('h:mm a')
All right we get 8:00 am now. If you want 8 am instead of 8:00 am for integral time, we need to do RegExp
const time = moment.utc(moment.duration(value, 'seconds').asMilliseconds()).format('h:mm a');
time.replace(/:00/g, '')
How about native javascript?
var formatTime = function(integer) {
if(integer < 10) {
return "0" + integer;
} else {
return integer;
}
}
function getDuration(ms) {
var s1 = Math.floor(ms/1000);
var s2 = s1%60;
var m1 = Math.floor(s1/60);
var m2 = m1%60;
var h1 = Math.floor(m1/60);
var string = formatTime(h1) +":" + formatTime(m2) + ":" + formatTime(s2);
return string;
}
Use moment-duration-format.
Client Framework (ex: React)
import moment from 'moment';
import momentDurationFormatSetup from 'moment-duration-format';
momentDurationFormatSetup(moment);
const breakLengthInMinutes = moment.duration(breakLengthInSeconds, 's').format('m');
Server (node.js)
const moment = require("moment-timezone");
const momentDurationFormatSetup = require("moment-duration-format");
momentDurationFormatSetup(moment);
const breakLengthInMinutes = moment.duration(breakLengthInSeconds, 's').format('m');
moment.duration(x).format() has been deprecated.
You can usemoment.utc(4366589).format("HH:mm:ss") to get the desired response.
console.log(moment.utc(4366589).format("HH:mm:ss"))
<script src="https://momentjs.com/downloads/moment.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
const duration = moment.duration(62, 'hours');
const n = 24 * 60 * 60 * 1000;
const days = Math.floor(duration / n);
const str = moment.utc(duration % n).format('H [h] mm [min] ss [s]');
console.log(`${days > 0 ? `${days} ${days == 1 ? 'day' : 'days'} ` : ''}${str}`);
Prints:
2 days 14 h 00 min 00 s
There is no longer (if there ever was) any need to convert duration to utc to solve this issue. This is like converting a base10 "1" to binary and then saying that since output "1" looks like base10 we'll have no issues assuming this is a base10 value for any further operations.
Use moment-duration-format and note that with { trim: false } you can prevent trimming:
moment.duration(1000000, "seconds").format("hh:mm:ss", { trim: false })
> "277:46:40"
moment.duration(0, "seconds").format("hh:mm:ss", { trim: false })
> "00:00:00"
Let's compare this with the not recommended method of using abusing utc:
moment.utc(moment.duration(1000000, "seconds").asMilliseconds()).format('HH:mm:ss')
> "13:46:40"
Just moment.js without any other plugins
moment().startOf('day').seconds(duration).format('HH:mm:ss')
import * as moment from 'moment'
var sleep = require('sleep-promise');
(async function () {
var t1 = new Date().getTime();
await sleep(1000);
var t2 = new Date().getTime();
var dur = moment.duration(t2-t1);
console.log(`${dur.hours()}h:${dur.minutes()}m:${dur.seconds()}s`);
})();
0h:0m:1s
You can use numeral.js to format your duration:
numeral(your_duration.asSeconds()).format('00:00:00') // result: hh:mm:ss
This can be used to get the first two characters as hours and last two as minutes. Same logic may be applied to seconds.
/**
* PT1H30M -> 0130
* #param {ISO String} isoString
* #return {string} absolute 4 digit number HH:mm
*/
const parseIsoToAbsolute = (isoString) => {
const durations = moment.duration(isoString).as('seconds');
const momentInSeconds = moment.duration(durations, 'seconds');
let hours = momentInSeconds.asHours().toString().length < 2
? momentInSeconds.asHours().toString().padStart(2, '0') : momentInSeconds.asHours().toString();
if (!Number.isInteger(Number(hours))) hours = '0'+ Math.floor(hours);
const minutes = momentInSeconds.minutes().toString().length < 2
? momentInSeconds.minutes().toString().padEnd(2, '0') : momentInSeconds.minutes().toString();
const absolute = hours + minutes;
return absolute;
};
console.log(parseIsoToAbsolute('PT1H30M'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment-with-locales.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
If you use Angular >2, I made a Pipe inspired by #hai-alaluf answer.
import {Pipe, PipeTransform} from "#angular/core";
#Pipe({
name: "duration",
})
export class DurationPipe implements PipeTransform {
public transform(value: any, args?: any): any {
// secs to ms
value = value * 1000;
const days = Math.floor(value / 86400000);
value = value % 86400000;
const hours = Math.floor(value / 3600000);
value = value % 3600000;
const minutes = Math.floor(value / 60000);
value = value % 60000;
const seconds = Math.floor(value / 1000);
return (days ? days + " days " : "") +
(hours ? hours + " hours " : "") +
(minutes ? minutes + " minutes " : "") +
(seconds ? seconds + " seconds " : "") +
(!days && !hours && !minutes && !seconds ? 0 : "");
}
}
Related
I have two inputs of time and I want to get the difference/time-interval between these two using dayjs
fromtime = '13:00'
totime = '17:00'
So the output for the above two should be 4:00 hours
I tried
console.log(
dayjs(fromtime).diff(dayjs(totime), "hours")
);
But am not getting the expected output.
I found the solution to this.
const fromtime = '11:20'
const totime = '12:30'
const ft = dayjs(`2000-01-01 ${fromtime}`);
const tt = dayjs(`2000-01-01 ${totime}`);
const mins = tt.diff(ft, "minutes", true);
const totalHours = parseInt(mins / 60);
const totalMins = dayjs().minute(mins).$m
This will give the output as totalHours = 1 and totalMins = 10.
Hope this help someone.
Dayjs expects a Date in a certain format (dayjs parse string) not just a time. However you can set the hour (dayjs set hour) without setting a certain date (dayjs parse now):
var fromtime = dayjs().hour(13)
var totime = dayjs().hour(17)
console.log(totime.diff(fromtime, "hours"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.8.20/dayjs.min.js"></script>
EDIT
What if the input contains fromtime = '10.25' and totime = '11.30'. So my output should be '1.05'. But when I follow your method the output is 1. Is there a way to solve this
You can set The minutes also (dayjs set minute). Unfortunately i do not see any formatting options for time-differences in that library. So we will have to calculate that on our own:
function formatInterval(minutes) {
let interval = [
Math.floor(minutes / 60).toString(), //hours ("1" - "12")
(minutes % 60).toString() //minutes ("1" - "59")
];
return interval[0].padStart(2, '0') + ':' + interval[1].padStart(2, '0')
}
let fromtime = dayjs().hour(10).minute(25);
let totime = dayjs().hour(11).minute(30);
let interval = totime.diff(fromtime, "minute");
console.log(formatInterval(interval));
<script src="https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.8.20/dayjs.min.js"></script>
EDIT2
This will fail if the day switches between the two first lines
OK was assuming the fromtime will always be a smaller number than the totime ... if thats not the case we can just substract negative amount of minutes from the total amount of minutes in a day like so:
function formatInterval(minutes) {
let interval = [Math.floor(minutes / 60).toString(), (minutes % 60).toString()];
return interval[0].padStart(2, '0') + ':' + interval[1].padStart(2, '0')
}
function getInterval(from, to) {
let [hoursA, minutesA] = from.split(':');
let [hoursB, minutesB] = to.split(':');
let timeA = dayjs().hour(hoursA).minute(minutesA);
let timeB = dayjs().hour(hoursB).minute(minutesB);
let interval = timeB.diff(timeA, 'minutes');
if(interval < 0) {
return formatInterval(24 * 60 + timeB.diff(timeA, 'minutes'));
}
return formatInterval(interval);
}
console.log(getInterval('23:00', '1:45'));
console.log(getInterval('10:25', '11:30'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.8.20/dayjs.min.js"></script>
// Addition, Difference between two time zones
import timezone from 'dayjs/plugin/timezone';
dayjs.extend(timezone);
const d1 = dayjs((dayjs().tz('Europe/Kiev').format('YYYY-MM-DDTHH:mm')));
const d2 = dayjs((dayjs().tz('Europe/London').format('YYYY-MM-DDTHH:mm')));
console.log(d1.diff(d2, 'hours', true)); // 2
fromtime = '13:00'
totime = '17:00'
These are currently strings and you need to convert it into integers.
console.log(parseInt(fromtime) - parseInt(totime)) //4
I need to get the duration between two dates in hh:mm:ss format using moment. but i am not able to get the exact difference. Here is my example.
let start = moment("2018-07-27T14:56:33.763Z");
let end = moment("2018-07-28T14:56:33.763Z");
let diff = end.diff(start);
let f = moment.utc(diff).format("HH:mm:ss");
alert(f);
For the above dates i need to get the output as 24:00:00, because it's one day difference. But i am getting 00:00:00 as response.
If i am changing the hrs it should display based on that. how can i achieve this? can someone help me to fix this.
There's a rather lengthy discussion on Moments GitHub Page but this may be what you are after:
let start = moment("2018-07-27T14:56:33.763Z");
let end = moment("2018-07-28T14:56:33.763Z");
let duration = moment.duration(end.diff(start));
let f = Math.floor(duration.asHours()) + moment.utc(duration.asMilliseconds()).format(":mm:ss")
alert(f);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.js"></script>
By the way there is a plugin that someone created for this specific issue, which is posted on Moments Website as well.
try this:
let f = moment.utc(diff).format('D[days] H[ hours]');
Example
If you want to convert that time in only HH:mm:ss maybe you can manually convert it to miliseconds and parse it to hours.
Try the following to achieve the quest.
let start = moment("2018-07-27T14:56:33.763Z");
let end = moment("2018-07-28T14:56:33.763Z");
let diff = end.diff(start);
var d = moment.duration(diff, 'milliseconds');
var hours = Math.floor(d.asHours());
var mins = Math.floor(d.asMinutes()) - hours * 60;
var secs = Math.floor(d.asSeconds()) - mins * 60 - hours * 60*60;;
console.log( hours + ":" + mins + ":" + secs);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.js"></script>
It states
enter code here
H, HH 24 hour time
h, or hh 12 hour time (use in conjunction with a or A)
Thus, stating your time as HH will give you 24h format, and hh will give 12h format.
Since the difference is a day so hours,minutes,seconds return zero so change the condition in this way
let f = moment.utc(diff).format("HH:mm:ss");
if(f=="00:00:00"){
f=moment.utc(diff).format("D[days] H[hours]");
}
What you are doing is trying to format a difference of 2 dates which will result in a date formated string, what you need to do is to get the difference in hours of both dates, to do that, you need the duration method:
let start = moment("2018-07-27T14:56:33.763Z");
let end = moment("2018-07-28T13:56:33.763Z");
let diff = end.diff(start);
let diffData = moment.duration(diff);
alert((diffData.days() * 24) + diffData.hours());
This will help you.
var units = ["year", "month", "day", "hour", "minute", "second", "millisecond"];
var unitmapping = {month:12,day:30,hour:24,minute:60,second:60,millisecond:1000};
function getDiff(start, end)
{
var duration = "", start = moment(start), end = moment(end);
units.forEach(function(unit,index){
var diff = Math.abs(end.diff(start,unit));
if(unitmapping[unit]) diff = (diff%unitmapping[unit]).toFixed(0);
duration += diff + " "
+ unit
+ (diff==1 ? "":"s")
+ (index!=units.length-1 ? " : ":"");
});
return duration;
}
console.log(getDiff("2018-07-27T14:56:33.843Z","2018-07-27T14:56:33.763Z"));
console.log(getDiff("2018-07-26T14:56:33.843Z","2018-07-27T14:56:33.763Z"));
console.log(getDiff("2018-07-27T14:46:33.843Z","2018-07-27T14:56:33.763Z"));
console.log(getDiff("2018-07-27T14:56:33.843Z","2048-07-29T14:56:33.763Z"));
console.log(getDiff("2018-09-27T14:56:33.843Z","2048-07-29T14:56:33.763Z"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
I know I can do anything and some more envolving Dates with momentjs. But embarrassingly, I'm having a hard time trying to do something that seems simple: geting the difference between 2 times.
Example:
var now = "04/09/2013 15:00:00";
var then = "04/09/2013 14:20:30";
//expected result:
"00:39:30"
what I tried:
var now = moment("04/09/2013 15:00:00");
var then = moment("04/09/2013 14:20:30");
console.log(moment(moment.duration(now.diff(then))).format("hh:mm:ss"))
//outputs 10:39:30
I do not understand what is that "10" there. I live in Brazil, so we are utc-0300 if that is relevant.
The result of moment.duration(now.diff(then)) is a duration with the correct internal values:
days: 0
hours: 0
milliseconds: 0
minutes: 39
months: 0
seconds: 30
years: 0
So, I guess my question is: how to convert a momentjs Duration to a time interval? I sure can use
duration.get("hours") +":"+ duration.get("minutes") +:+ duration.get("seconds")
but i feel that there is something more elegant that I am completely missing.
update
looking closer, in the above example now is:
Tue Apr 09 2013 15:00:00 GMT-0300 (E. South America Standard Time)…}
and moment(moment.duration(now.diff(then))) is:
Wed Dec 31 1969 22:39:30 GMT-0200 (E. South America Daylight Time)…}
I am not sure why the second value is in Daylight Time (-0200)... but I am sure that i do not like dates :(
update 2
well, the value is -0200 probably because 31/12/1969 was a date where the daylight time was being used... so thats that.
This approach will work ONLY when the total duration is less than 24 hours:
var now = "04/09/2013 15:00:00";
var then = "04/09/2013 14:20:30";
moment.utc(moment(now,"DD/MM/YYYY HH:mm:ss").diff(moment(then,"DD/MM/YYYY HH:mm:ss"))).format("HH:mm:ss")
// outputs: "00:39:30"
If you have 24 hours or more, the hours will reset to zero with the above approach, so it is not ideal.
If you want to get a valid response for durations of 24 hours or greater, then you'll have to do something like this instead:
var now = "04/09/2013 15:00:00";
var then = "02/09/2013 14:20:30";
var ms = moment(now,"DD/MM/YYYY HH:mm:ss").diff(moment(then,"DD/MM/YYYY HH:mm:ss"));
var d = moment.duration(ms);
var s = Math.floor(d.asHours()) + moment.utc(ms).format(":mm:ss");
// outputs: "48:39:30"
Note that I'm using the utc time as a shortcut. You could pull out d.minutes() and d.seconds() separately, but you would also have to zeropad them.
This is necessary because the ability to format a duration objection is not currently in moment.js. It has been requested here. However, there is a third-party plugin called moment-duration-format that is specifically for this purpose:
var now = "04/09/2013 15:00:00";
var then = "02/09/2013 14:20:30";
var ms = moment(now,"DD/MM/YYYY HH:mm:ss").diff(moment(then,"DD/MM/YYYY HH:mm:ss"));
var d = moment.duration(ms);
var s = d.format("hh:mm:ss");
// outputs: "48:39:30"
Your problem is in passing the result of moment.duration() back into moment() before formatting it; this results in moment() interpreting it as a time relative to the Unix epoch.
It doesn't give you exactly the format you're looking for, but
moment.duration(now.diff(then)).humanize()
would give you a useful format like "40 minutes". If you're really keen on that specific formatting, you'll have to build a new string yourself. A cheap way would be
[diff.asHours(), diff.minutes(), diff.seconds()].join(':')
where var diff = moment.duration(now.diff(then)). This doesn't give you the zero-padding on single digit values. For that, you might want to consider something like underscore.string - although it seems like a long way to go just for a few extra zeroes. :)
var a = moment([2007, 0, 29]);
var b = moment([2007, 0, 28]);
a.diff(b, 'days') //[days, years, months, seconds, ...]
//Result 1
Worked for me
See more in
http://momentjs.com/docs/#/displaying/difference/
If you want difference of two timestamp into total days,hours and minutes only, not in months and years .
var now = "01/08/2016 15:00:00";
var then = "04/02/2016 14:20:30";
var diff = moment.duration(moment(then).diff(moment(now)));
diff contains 2 months,23 days,23 hours and 20 minutes. But we need result only in days,hours and minutes so the simple solution is:
var days = parseInt(diff.asDays()); //84
var hours = parseInt(diff.asHours()); //2039 hours, but it gives total hours in given miliseconds which is not expacted.
hours = hours - days*24; // 23 hours
var minutes = parseInt(diff.asMinutes()); //122360 minutes,but it gives total minutes in given miliseconds which is not expacted.
minutes = minutes - (days*24*60 + hours*60); //20 minutes.
Final result will be : 84 days, 23 hours, 20 minutes.
When you call diff, moment.js calculates the difference in milliseconds.
If the milliseconds is passed to duration, it is used to calculate duration which is correct.
However. when you pass the same milliseconds to the moment(), it calculates the date that is milliseconds from(after) epoch/unix time that is January 1, 1970 (midnight UTC/GMT).
That is why you get 1969 as the year together with wrong hour.
duration.get("hours") +":"+ duration.get("minutes") +":"+ duration.get("seconds")
So, I think this is how you should do it since moment.js does not offer format function for duration. Or you can write a simple wrapper to make it easier/prettier.
This should work fine.
var now = "04/09/2013 15:00:00";
var then = "02/09/2013 14:20:30";
var ms = moment(now,"DD/MM/YYYY HH:mm:ss").diff(moment(then,"DD/MM/YYYY HH:mm:ss"));
var d = moment.duration(ms);
console.log(d.days() + ':' + d.hours() + ':' + d.minutes() + ':' + d.seconds());
If we want only hh:mm:ss, we can use a function like that:
//param: duration in milliseconds
MillisecondsToTime: function(duration) {
var seconds = parseInt((duration/1000)%60)
, minutes = parseInt((duration/(1000*60))%60)
, hours = parseInt((duration/(1000*60*60))%24)
, days = parseInt(duration/(1000*60*60*24));
var hoursDays = parseInt(days*24);
hours += hoursDays;
hours = (hours < 10) ? "0" + hours : hours;
minutes = (minutes < 10) ? "0" + minutes : minutes;
seconds = (seconds < 10) ? "0" + seconds : seconds;
return hours + ":" + minutes + ":" + seconds;
}
Use this:
var duration = moment.duration(endDate.diff(startDate));
var aa = duration.asHours();
Instead of
Math.floor(duration.asHours()) + moment.utc(duration.asMilliseconds()).format(":mm:ss")
It's better to do
moment.utc(total.asMilliseconds()).format("HH:mm:ss");
This will work for any date in the format YYYY-MM-DD HH:mm:ss
const moment=require("moment");
let startDate=moment("2020-09-16 08:39:27");
const endDate=moment();
const duration=moment.duration(endDate.diff(startDate))
console.log(duration.asSeconds());
console.log(duration.asHours());
In ES8 using moment, now and start being moment objects.
const duration = moment.duration(now.diff(start));
const timespan = duration.get("hours").toString().padStart(2, '0') +":"+ duration.get("minutes").toString().padStart(2, '0') +":"+ duration.get("seconds").toString().padStart(2, '0');
Typescript: following should work,
export const getTimeBetweenDates = ({
until,
format
}: {
until: number;
format: 'seconds' | 'minutes' | 'hours' | 'days';
}): number => {
const date = new Date();
const remainingTime = new Date(until * 1000);
const getFrom = moment([date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()]);
const getUntil = moment([remainingTime.getUTCFullYear(), remainingTime.getUTCMonth(), remainingTime.getUTCDate()]);
const diff = getUntil.diff(getFrom, format);
return !isNaN(diff) ? diff : null;
};
DATE TIME BASED INPUT
var dt1 = new Date("2019-1-8 11:19:16");
var dt2 = new Date("2019-1-8 11:24:16");
var diff =(dt2.getTime() - dt1.getTime()) ;
var hours = Math.floor(diff / (1000 * 60 * 60));
diff -= hours * (1000 * 60 * 60);
var mins = Math.floor(diff / (1000 * 60));
diff -= mins * (1000 * 60);
var response = {
status : 200,
Hour : hours,
Mins : mins
}
OUTPUT
{
"status": 200,
"Hour": 0,
"Mins": 5
}
The following approach is valid for all cases (difference between dates less than 24 hours and difference greater than 24 hours):
// Defining start and end variables
let start = moment('04/09/2013 15:00:00', 'DD/MM/YYYY hh:mm:ss');
let end = moment('04/09/2013 14:20:30', 'DD/MM/YYYY hh:mm:ss');
// Getting the difference: hours (h), minutes (m) and seconds (s)
let h = end.diff(start, 'hours');
let m = end.diff(start, 'minutes') - (60 * h);
let s = end.diff(start, 'seconds') - (60 * 60 * h) - (60 * m);
// Formating in hh:mm:ss (appends a left zero when num < 10)
let hh = ('0' + h).slice(-2);
let mm = ('0' + m).slice(-2);
let ss = ('0' + s).slice(-2);
console.log(`${hh}:${mm}:${ss}`); // 00:39:30
This will return biggest time period diff like (4 seconds, 2 minutes, 1 hours, 2 days, 3 weeks, 4 months, 5 years).
I use this for notification recent time.
function dateDiff(startDate, endDate) {
let arrDate = ["seconds", "minutes", "hours", "days", "weeks", "months", "years"];
let dateMap = arrDate.map(e => moment(endDate).diff(startDate, e));
let index = 6 - dateMap.filter(e => e == 0).length;
return {
type: arrDate[index] ?? "seconds",
value: dateMap[index] ?? 0
};
}
Example:
dateDiff("2021-06-09 01:00:00", "2021-06-09 04:01:01")
{type: "hours", value: 3}
dateDiff("2021-06-09 01:00:00", "2021-06-12 04:01:01")
{type: "days", value: 3}
dateDiff("2021-06-09 01:00:00", "2021-06-09 01:00:10")
{type: "seconds", value: 10}
I create a simple function with typescript
const diffDuration: moment.Duration = moment.duration(moment('2017-09-04 12:55').diff(moment('2017-09-02 13:26')));
setDiffTimeString(diffDuration);
function setDiffTimeString(diffDuration: moment.Duration) {
const str = [];
diffDuration.years() > 0 ? str.push(`${diffDuration.years()} year(s)`) : null;
diffDuration.months() > 0 ? str.push(`${diffDuration.months()} month(s)`) : null;
diffDuration.days() > 0 ? str.push(`${diffDuration.days()} day(s)`) : null;
diffDuration.hours() > 0 ? str.push(`${diffDuration.hours()} hour(s)`) : null;
diffDuration.minutes() > 0 ? str.push(`${diffDuration.minutes()} minute(s)`) : null;
console.log(str.join(', '));
}
// output: 1 day(s), 23 hour(s), 29 minute(s)
for generate javascript https://www.typescriptlang.org/play/index.html
InTime=06:38,Outtime=15:40
calTimeDifference(){
this.start = dailyattendance.InTime.split(":");
this.end = dailyattendance.OutTime.split(":");
var time1 = ((parseInt(this.start[0]) * 60) + parseInt(this.start[1]))
var time2 = ((parseInt(this.end[0]) * 60) + parseInt(this.end[1]));
var time3 = ((time2 - time1) / 60);
var timeHr = parseInt(""+time3);
var timeMin = ((time2 - time1) % 60);
}
EPOCH TIME DIFFERENCE USING MOMENTJS:
To Get Difference between two epoch times:
Syntax:
moment.duration(moment(moment(date1).diff(moment(date2)))).asHours()
Difference in Hours:
moment.duration(moment(moment(1590597744551).diff(moment(1590597909877)))).asHours()
Difference in minutes:
moment.duration(moment(moment(1590597744551).diff(moment(1590597909877)))).asMinutes().toFixed()
Note: You could remove .toFixed() if you need precise values.
Code:
const moment = require('moment')
console.log('Date 1',moment(1590597909877).toISOString())
console.log('Date 2',moment(1590597744551).toISOString())
console.log('Date1 - Date 2 time diffrence is : ',moment.duration(moment(moment(1590597909877).diff(moment(1590597744551)))).asMinutes().toFixed()+' minutes')
Refer working example here:
https://repl.it/repls/MoccasinDearDimension
To get the difference between two-moment format dates or javascript Date format indifference of minutes the most optimum solution is
const timeDiff = moment.duration((moment(apptDetails.end_date_time).diff(moment(apptDetails.date_time)))).asMinutes()
you can change the difference format as you need by just replacing the asMinutes() function
If you want a localized number of days between two dates (startDate, endDate):
var currentLocaleData = moment.localeData("en");
var duration = moment.duration(endDate.diff(startDate));
var nbDays = Math.floor(duration.asDays()); // complete days
var nbDaysStr = currentLocaleData.relativeTime(returnVal.days, false, "dd", false);
nbDaysStr will contain something like '3 days';
See https://momentjs.com/docs/#/i18n/changing-locale/ for information on how to display the amount of hours or month, for example.
It is very simple with moment
below code will return diffrence in hour from current time:
moment().diff('2021-02-17T14:03:55.811000Z', "h")
const getRemainingTime = (t2) => {
const t1 = new Date().getTime();
let ts = (t1-t2.getTime()) / 1000;
var d = Math.floor(ts / (3600*24));
var h = Math.floor(ts % (3600*24) / 3600);
var m = Math.floor(ts % 3600 / 60);
var s = Math.floor(ts % 60);
console.log(d, h, m, s)
}
This is an easy thing to do in PHP with code like this;
if (strtotime($given_time) >= time()+300) echo "You are online";
But can't find anything on SO to do exactly this in javascript.
I want to check if the difference between a given time and the current time is less than 45mins
For instance
$scope.given_time = "14:10:00"
$scope.current_time = new Date();
I'm only concerned with the time part. I need to extract time part from new Date(); and then compare.
Then this should be true
How can I achieve this with Javascript:
if ($scope.given_time - $scope.current_time < 45 minutes) {
// do something
}
Javascript uses unix timestamps in milliseconds, so it is similar to the output of strtotime (which uses seconds).
var date = new Date();
Then you'll need to do the calculation from milliseconds. (Minutes * 60 * 1000)
You can also use date.parse() to parse a string to milliseconds, just like strtotime() in PHP does to seconds.
In full:
var date = new Date();
var last = new Date('Previous Date'); // or a previous millisecond timestamp
if ( ( date - last ) > ( 45 * 60 * 1000 ) ) {
// do something
}
You could use a static date to compare just time, this is exactly what strtotime does if you exclude the date:
var last = new Date('1/1/70 14:10:00');
var date = new Date('1/1/70 14:30:00');
However, this approach will fail if you're trying to compare time that cross over day boundaries.
Try this:
function checkTime(time) {
var date = new Date();
var date1 = new Date((date.getMonth() + 1) + "/" + date.getDate() + "/" + date.getFullYear() + " " + time);
var minutes = (date1.getTime() - date.getTime()) / (60 * 1000);
if (minutes > 45 || (minutes < 0 && minutes > -1395)) {
// greater than 45 is todays time is above 45 minutes
// less than 0 means the next available time will be tomorrow and the greater than -1395 means it will be more than 45 minutes from now into tomorrow
document.write(time + ': true<br />');
} else {
document.write(time + ': false<br />');
}
}
checkTime("14:10:00");
checkTime("16:30:00");
checkTime("17:10:00");
There's a JavaScript method called getMinutes(); you can use to get only the minutes and compare.
Your code should look something like:
var received_time = "14:10:00".split(':');
var minute = '';
if(received_time.length === 3) {
minute = parseInt(received_time[1], 10);
}
$scope.given_time = minute;
var the_time = new Date();
$scope.current_time = the_time.getMinutes();
And you now can do your thing:
if ($scope.given_time - $scope.current_time < 45 minutes) {
// do something
}
Using a library like moment.js you can simply diff the two times.
var $log = $("#log");
/* Difference between just times */
$log.append("Difference between times\n");
var givenTime = moment("14:10:00", "HH:mm:ss");
var minutesPassed = moment("14:30:00", "HH:mm:ss").diff(givenTime, "minutes");
$log.append("Minutes passed: " + minutesPassed + "\n");
if (minutesPassed < 45) {
$log.append(minutesPassed + " minutes have elapsed. Event Triggered." + "\n");
}
/* Better: Difference between times that have dates attached to them and cross a day boundary. */
$log.append("\n\nDifference between dates with times\n");
givenTime = moment("2015-12-03 23:33:00");
minutesPassed = moment("2015-12-04 00:14:00").diff(givenTime, "minutes");
$log.append("Minutes passed: " + minutesPassed + "\n");
if (minutesPassed < 45) {
$log.append(minutesPassed + " minutes have elapsed. Event Triggered." + "\n");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://momentjs.com/downloads/moment.js"></script>
<p>Results:</p>
<hr>
<pre id="log"></pre>
<hr>
Caveat: If the given time is yesterday such as 11:30pm and the current time is 12:10am then you will get the wrong result. You'd want to use a date with the time if this type of thing is an issue for your use case.
The moment.js documentation
http://momentjs.com/docs/
Angular directive for moment documentation
https://github.com/urish/angular-moment/blob/master/README.md
I am new to Momentjs. I am trying to use it to convert milliseconds to hours and minutes. Below, x is milliseconds
x = 433276000
var y = moment.duration(x, 'milliseconds').asHours;
Can anyone help?
I ended up doing this...
var x = 433276000
var tempTime = moment.duration(x);
var y = tempTime.hours() + tempTime.minutes();
Try this:
var x = 433276000
var d = moment.duration(x, 'milliseconds');
var hours = Math.floor(d.asHours());
var mins = Math.floor(d.asMinutes()) - hours * 60;
console.log("hours:" + hours + " mins:" + mins);
You can create a Moment.js date from milliseconds using moment.utc().
var milliseconds = 1000;
moment.utc(milliseconds).format('HH:mm');
Using the moment-duration-format plugin:
moment.duration(ms).format("h:mm")
There is an easier way to achieve what you want.
This
moment('2000-01-01 00:00:00').add(moment.duration(1000)).format('HH:mm:ss');
Will output this
00:00:01
Not the fanciest, I know, but it is 100% pure moment js.
edit: Doesn't work for periods longer than 24h
This seems unsupported per this SO. Following this github issue, there's a moment-to-countdown plugin that you may be able to use.
But it seems you may want Countdown.js for this in the first place.
countdown(0, 433276000, countdown.HOURS | countdown.MINUTES).toString();
Note this does not take into account leap seconds, or leap anything for that matter, as it fixes to the Unix epoch (so it's not a pure time interval).
There really is no need to use Moment for this operation.
It can be written in a single line:
var hours = Math.round((450616708 / 1000 / 60 / 60) * 100) / 100;
or as function:
function millisecondsToHours(ms){
return Math.round((ms / 1000 / 60 / 60) * 100) / 100;
}
In Moment.js duration you can just use Math.trunc for hours if you are expecting it to be over 24hrs. hh:mm:ss format.
var seconds = moment.duration(value).seconds();
var minutes = moment.duration(value).minutes();
var hours = Math.trunc(moment.duration(value).asHours());
see it here: https://codepen.io/brickgale/pen/mWqKJv?editors=1011
Here is a function that formats it for you into a string.
function ms_to_str(val) {
let tempTime = moment.duration(val),
timeObj = {
years: tempTime.years(),
months: tempTime.months(),
days: tempTime.days(),
hrs: tempTime.hours(),
mins: tempTime.minutes(),
secs: tempTime.seconds(),
ms: tempTime.milliseconds()
},
timeArr = [];
for (let k in timeObj) {
if (Number(timeObj[k]) > 0) {
timeArr.push(`${timeObj[k]} ${k}`)
}
}
return timeArr.join(', ');
}
Then simply call ms_to_str(2443253) which returns 40 mins, 43 secs, 253 ms.
If you do not need to show milliseconds, simply comment off the ms: tempTime.milliseconds().toString().padStart(3, '0') line.
Momentjs itself doesn't support duration, in order to do so, we need a plugin moment-duration-format
To use this plugin follow these steps (for React-js)
import moment from 'moment';
import momentDurationFormatSetup from "moment-duration-format";
var time = moment.duration(value,unit).format('hh:mm:ss',{trim:false})
Note: I have used {trim: false} as extra parameter so that it doesn't trim out extra 0's in the beginning. You can omit it if you want "11:30" instead of "00:11:30".
function durationAsString(ms, maxPrecission = 3) {
const duration = moment.duration(ms)
const items = []
items.push({ timeUnit: 'd', value: Math.floor(duration.asDays()) })
items.push({ timeUnit: 'h', value: duration.hours() })
items.push({ timeUnit: 'm', value: duration.minutes() })
items.push({ timeUnit: 's', value: duration.seconds() })
const formattedItems = items.reduce((accumulator, { value, timeUnit }) => {
if (accumulator.length >= maxPrecission || (accumulator.length === 0 && value === 0)) {
return accumulator
}
accumulator.push(`${value}${timeUnit}`)
return accumulator
}, [])
return formattedItems.length !== 0 ? formattedItems.join(' ') : '-'
}
Lets you set max-precision and will not show insignificant values.
Examples:
durationAsString(0) will return -
durationAsString(10000) will return 10s
durationAsString(100000) will return 1m 40s
durationAsString(10000000) will return 2h 46m 40s
durationAsString(100000000) will return 1d 3h 46m
durationAsString(100000000, 4) will return 1d 3h 46m 40s
moment('2000-01-01 00:00:00').millisecond(XXXXXX).format("HH:mm:ss")