I have been using this excellent function for HH:MM:SS, but how could I modify it to return only HH:MM with either the seconds truncated or rounded.
function formatSeconds(seconds)
{
var date = new Date(1970,0,1);
date.setSeconds(seconds);
return date.toTimeString().replace(/.*(\d{2}:\d{2}:\d{2}).*/, "$1");
}
function formatSeconds(seconds)
{
var date = new Date(1970,0,1);
date.setSeconds(seconds);
return date.toTimeString().replace(/.*?(\d{2}:\d{2}).*/, "$1");
}
remove the last \d{2} and add ? after the first *
The problem with using a Date to format seconds is that it can't handle times longer than 24 hours and the vagaries of Dates. Simply reformat the value as required:
function formatSeconds(seconds) {
function z(n) {return (n < 10 ? '0' : '') + n;}
return z(seconds / 3600 | 0) + ':' + z((seconds % 3600) / 60 | 0)
}
// Some examples
[0,1,61,3600,3660,765467].forEach(function (seconds) {
console.log(seconds + ' -> ' + formatSeconds(seconds))
});
No Date, no regular expression, no library, no dependencies and works in every host that ever supported ECMAScript.
Though ideal way would be to use moment.js but if you wish to use custom function, you can try something like this:
function formatSeconds(milliseconds, format) {
var dateObj = new Date(milliseconds);
function getDoubleDigits(value){
return ("0" + value).slice(-2)
}
var o = {
DD: getDoubleDigits(dateObj.getDate()),
MM: getDoubleDigits(dateObj.getMonth() + 1),
YY: dateObj.getYear(),
YYYY: dateObj.getFullYear(),
hh: getDoubleDigits(dateObj.getHours()),
mm: getDoubleDigits(dateObj.getMinutes()),
ss: getDoubleDigits(dateObj.getSeconds())
}
var dilimeter = format.match(/[^\w]/)[0];
return format.split(dilimeter).map(function(f){
return o[f];
}).join(dilimeter);
}
var today = new Date();
console.log(formatSeconds(+today, "DD-MM-YYYY"))
console.log(formatSeconds(+today, "hh:mm"))
Related
how do I format a javascript date like ISO format, but in local time?
with myDate.toISOString() I am getting the time as: "2012-09-13T19:12:23.826Z"
but here, it is 22:13, so how do I include the timezone in above format?
I ended up doing...
pad=function(e,t,n){n=n||"0",t=t||2;while((""+e).length<t)e=n+e;return e}
c = new Date()
c.getFullYear()+"-"+pad(c.getMonth()+1)+"-"+pad(c.getDate()-5)+"T"+c.toLocaleTimeString().replace(/\D/g,':')+"."+pad(c.getMilliseconds(),3)
No library required! For some Date object, e.g. t = new Date()
convert the local time zone offset from minutes to milliseconds
z = t.getTimezoneOffset() * 60 * 1000
subtract the offset from t
tLocal = t-z
create shifted Date object
tLocal = new Date(tLocal)
convert to ISO format string
iso = tLocal.toISOString()
drop the milliseconds and zone
iso = iso.split(".")[0]
replace the ugly 'T' with a space
iso = iso.replace('T', ' ')
Result is a nice ISO-ish format date-time string like "2018-08-01 22:45:50" in the local time zone.
A bit of a hack but can be done in one line by taking advantage of the fact that Sweden uses a format very close to ISO:
// Returns a string like 2021-01-17T01:59:57
function dateToISOButLocal(date) {
return date.toLocaleString('sv').replace(' ', 'T');
}
To support milliseconds:
return date.toLocaleString('sv', {year:'numeric', month:'numeric', day:'numeric', hour:'numeric', minute:'numeric', second:'numeric', fractionalSecondDigits: 3}).replace(',', '.').replace(' ', 'T');
I went with what Denis Howe said, below as a ready made function for convenience.
Also one fix: in the original answer t-z does not work because t is a Date, not milliseconds.
function dateToISOLikeButLocal(date) {
const offsetMs = date.getTimezoneOffset() * 60 * 1000;
const msLocal = date.getTime() - offsetMs;
const dateLocal = new Date(msLocal);
const iso = dateLocal.toISOString();
const isoLocal = iso.slice(0, 19);
return isoLocal;
}
With this I get the kind of string that needed as a URL parameter:
"2018-11-16T12:23:50"
AFAIK you can't format dates in javascript (without using external libraries). The best you could do is "format it yourself". I mean:
var date = new Date();
var year = date.getFullYear();
var month = date......
var ISOdate = year + "-" + month + "-" + .... ;
But there are some good libraries that will let you format dates! (read "format" as in library.getDate("YYYY-MM-DD.........");)
EDIT:
Moment.js seems the thing you're looking for: http://momentjs.com/
Although answers here might work, there's nothing like a simple one-liner:
new Date(new Date().getTime() - new Date().getTimezoneOffset() * 60 * 1000).toISOString()
Explanation for those who are interested:
We create a new instance of Date (the outer one).
We give it another instance of Date (in milliseconds) from which we subtract the timezone offset (in milliseconds too, either positive or negative). All of this we format into ISO
I don't quite understand which date did you need
but I think you need
const ISOLocaleString = d => {
const pad = n => n < 10 ? '0'+n : n;
return d.getFullYear()+'-'
+ pad(d.getMonth()+1)+'-'
+ pad(d.getDate())+'T'
+ pad(d.getHours())+':'
+ pad(d.getMinutes())+':'
+ pad(d.getSeconds())+'Z'
}
or
const ISOUTCLocaleString = d => {
const pad = n => n<10 ? '0'+n : n;
return d.getUTCFullYear()+'-'
+ pad(d.getUTCMonth()+1)+'-'
+ pad(d.getUTCDate())+'T'
+ pad(d.getUTCHours())+':'
+ pad(d.getUTCMinutes())+':'
+ pad(d.getUTCSeconds())+'Z'
}
In the original post, the current ISO date is "2012-09-13T19:12:23.826Z"
If what is wanted is a date that respects ISO norm but reflects the local offset from UTC time, the target answer should be "2012-09-13T22:12:23.826+03:00".
Best answer in the post bellow, with code snippet that respects the ISO 8601 format / RFC 3339
https://stackoverflow.com/a/17415677/1563072
Another method is to define a prototype on the Date object that leverages the built-in toISOString method (a separate function is also provided):
// Extend Date.prototype
Date.prototype.toLocalISOString = function() {
// Get the local offset for the date in minutes
let offsetMins = this.getTimezoneOffset();
// Get a time value adjusted for the offset
let localTimeMs = this - offsetMins * 6e4;
// Make a new Date so don't affect this
let date = new Date(localTimeMs);
// Get the local offset sign (ECMAScript sign is opposite to usual)
let utcOffsetSign = offsetMins > 0? '-' : '+';
// Remove sign from offsetMins
offsetMins = Math.abs(offsetMins);
// Get offset hours and minutes, padd to 2 digits
let utcOffsetHr = String(offsetMins / 60 | 0).padStart(2,'0');
let utcOffsetMin = String(offsetMins % 60).padStart(2,'0');
// Build offset string
let utcOffsetString = `${utcOffsetSign}${utcOffsetHr}:${utcOffsetMin}`;
// Return as adjusted ISO 8601 format string with adjusted offset
return date.toISOString().replace('Z', utcOffsetString);
};
// E.g.
let date = new Date();
// Like 2020-08-04T14:52:38.613-07:00
console.log(`UTC : ${date.toISOString()}\n` +
`Local: ${date.toLocalISOString()}`);
// Stand alone function
function toISOLocal(date) {
let offsetMins = date.getTimezoneOffset();
let d = new Date(date - offsetMins*6e4);
let offsetSign = offsetMins > 0? '-' : '+';
offsetMins = Math.abs(offsetMins);
let offsetHr = String(offsetMins / 60 | 0).padStart(2,'0');
let offsetMin = String(offsetMins % 60).padStart(2,'0');
return d.toISOString().replace('Z', `${offsetSign}${offsetHr}:${offsetMin}`);
}
// Like 2020-08-04T14:52:38.613-07:00
console.log(`fn : ${toISOLocal(date)}`);
ISO 8601 is simply a way of formatting dates and can as such can be applied to any time zone.
Have you tried the timeZone option to the Date object's toLocaleString method?
This question has answers with examples.
This is the method I use. It takes care to add zeros if date/month/hour etc is single digit number (for example turns '6' to '06')
function formatLikeISO (d: Date): string {
let lengthChecker = (str) => {
if (str.length == 1) { return '0' + str; }
return str;
}
let theDate = lengthChecker(String(d.getDate()));
let month = lengthChecker(String(d.getMonth() + 1));
let mins = lengthChecker(String(d.getMinutes()));
let hours = lengthChecker(String(d.getHours()));
let secs = lengthChecker(String(d.getSeconds()));
let formatted =
d.getFullYear() + '-' +
month + '-' +
theDate + ' ' +
hours + ':' +
mins + ':' +
secs;
return formatted;
}
This will output this kind of format:
"2021-06-30 11:31:34"
There's no direct way to do this. However, you can use toLocaleString to create a string that you can easily parse to make it an ISO string.
This works on node:
function getLocalIsoTime(time, timezone) {
const local = time.toLocaleString("en-US", {timeZone: timezone, hour12: false, year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});
return `${local.substr(6, 4)}-${local.substr(0, 2)}-${local.substr(3, 2)}T${local.substr(12, 8)}`;
}
console.log(getLocalIsoTime(new Date(), 'Asia/Kolkata'));
A simpler version works on node 15+ and on most modern browsers:
function getLocalIsoTime(time, timezone) {
return time.toLocaleString("en-CA", {timeZone: timezone, hour12: false}).replace(/, /, "T");
}
console.log(getLocalIsoTime(new Date(), 'Asia/Kolkata'));
Based on https://stackoverflow.com/a/68191554/833960, but I wanted the ms to be present and consistent width output of 3 digits for ms.
function formatLikeISO(d: Date): string {
let lengthChecker = (str: string, targetLen = 2) => {
if (str.length < targetLen) {
return str.padStart(targetLen, '0')
}
return str
}
let day = lengthChecker(String(d.getDate()))
let month = lengthChecker(String(d.getMonth() + 1))
let mins = lengthChecker(String(d.getMinutes()))
let hours = lengthChecker(String(d.getHours()))
let secs = lengthChecker(String(d.getSeconds()))
let ms = lengthChecker(String(d.getMilliseconds()), 3)
let formatted =
d.getFullYear() +
'-' +
month +
'-' +
day +
' ' +
hours +
':' +
mins +
':' +
secs +
'.' +
ms
return formatted
}
Output:
2023-02-13 10:23:59.025
2023-02-13 10:23:59.026
2023-02-13 10:23:59.026
2023-02-13 10:23:59.030
2023-02-13 10:23:59.438
2023-02-13 10:23:59.438
I am using the HTML5 element datetime-local. I need to have two formats of the date. One as a date object the other as a string. I am going to store the date object in the database and I am going to use the string to set the datetime-local form input.
I need to convert this string to a date object:
"2014-06-22T16:01"
I can't seem to get the correct time. This is what I am getting. The time not correct.
Sun Jun 22 2014 09:01:00 GMT-0700 (PDT)
This is the how I am formating the date:
function formatTime(_date) {
var _this = this,
date = (_date) ? _date : new Date(),
day = date.getDate(),
month = date.getMonth() + 1,
year = date.getFullYear(),
hour = date.getHours(),
minute = date.getMinutes(),
seconds = date.getSeconds(),
function addZero(num) {
return num > 9 ? num : '0' + num;
}
minute = addZero(minute);
seconds = addZero(seconds);
hour = addZero(hour);
day = addZero(day);
month = addZero(month);
return year + '-' + month + '-' + day + 'T' + hour + ':' + minute;
};
Example:
http://codepen.io/zerostyle/pen/gwpuK/
If you are trying to get an ISO 8601 date string, you can try Date.prototype.toISOString. However, it always uses UTC. If you want to include the local timezone, use something like the following:
/* Return a string in ISO 8601 format with current timezone offset
** e.g. 2014-10-02T23:31:03+0800
** d is a Date object, or defaults to current Date if not supplied.
*/
function toLocalISOString(d) {
// Default to now if no date provided
d = d || new Date();
// Pad to two digits with leading zeros
function pad(n){
return (n<10?'0':'') + n;
}
// Pad to three digits with leading zeros
function padd(n){
return (n<100? '0' : '') + pad(n);
}
// Convert offset in mintues to +/-HHMM
// Note change of sign
// e.g. -600 => +1000, +330 => -0530
function minsToHHMM(n){
var sign = n<0? '-' : '+';
n = Math.abs(n);
var hh = pad(n/60 |0);
var mm = pad(n%60);
return sign + hh + mm;
}
var offset = minsToHHMM(d.getTimezoneOffset() * -1);
return d.getFullYear() + '-' + pad(d.getMonth() + 1) + '-' + pad(d.getDate()) +
'T' + pad(d.getHours()) + ':' + pad(d.getMinutes()) + ':' + pad(d.getSeconds()) +
'.' + padd(d.getMilliseconds()) + offset;
}
console.log(toLocalISOString(new Date())); // 2014-06-23T07:58:04.773+0800
Edit
The above probably misses your question, which seems to be;
I need to convert this string to a date object: "2014-06-22T16:01"
Presumaly you want to treat it as a local time string. ECMA-262 says that ISO–like strings without a timezone are to be treated as UTC, and that is what your host seems to be doing. So you need a function to create a local Date object from the string:
function parseYMDHM(s) {
var b = s.split(/\D+/);
return new Date(b[0], --b[1], b[2], b[3], b[4], b[5]||0, b[6]||0);
}
console.log(parseYMDHM('2014-06-22T16:01')); // Sun Jun 22 16:01:00 UTC+0800 2014
i have an epoch time: x = 1383483902000
I am trying to get a date like: dd-mm-yyyy and want to do this without additional library.
I have tried several ways and my last method end up like :
var date = new Date(Math.round(Number(x)));
but i get an ugly thing like: sun nov 03 2013 14:05:02 GMT+01:00
Use your date object to extract/format the parts you want:
var formattedDate = date.getUTCDate() + '-' + (date.getUTCMonth() + 1)+ '-' + date.getUTCFullYear()
The example below uses the UTC methods of the date object as you are dealing with epoch time (which is milliseconds since epoch in UTC):
var formatDate = function formatDate(date) { // function for reusability
var d = date.getUTCDate().toString(), // getUTCDate() returns 1 - 31
m = (date.getUTCMonth() + 1).toString(), // getUTCMonth() returns 0 - 11
y = date.getUTCFullYear().toString(), // getUTCFullYear() returns a 4-digit year
formatted = '';
if (d.length === 1) { // pad to two digits if needed
d = '0' + d;
}
if (m.length === 1) { // pad to two digits if needed
m = '0' + m;
}
formatted = d + '-' + m + '-' + y; // concatenate for output
return formatted;
},
x = 1383483902000, // sample time in ms since epoch
d = new Date(x), // convert to date object
f = formatDate(d); // pass to formatDate function to get dd-mm-yyyy
console.log(f); // log output to console for testing
You can run this in the browser console as-is.
function formatDate(value: any): any{
let date = new Date(Math.round(Number(value)));
let day = ("0" + date.getDate()).slice(-2);
let month = ("0" + (date.getMonth() + 1)).slice(-2);
let formatDate = date.getFullYear()+"-"+(month)+"-"+(day) ;
return formatDate;
}
I get a variable string like so:
8:45 am
And want, if it is pm, to convert it to 24 hour time. So that I can then drop the am/pm and use it with something else.
I can drop the am/pm quite easily like this:
function replaceEnds(string) {
string = string.replace("am", "");
string = string.replace("pm", "");
return string;
}
But of course if I do that, I don't know if the string is am or pm, so I don't know to add 12 hours on to the string to make it 24 hour.
Anyone know how I could resolve this? I absolutely cannot change the input that I get of the variable, it'll always be the hour (in 12 hour time), minutes, and am or pm.
Using moment.js:
moment(string, 'h:mm a').format('H:mm');
If you want to do it manually, this would be my solution:
function to24Hour(str) {
var tokens = /([10]?\d):([0-5]\d) ([ap]m)/i.exec(str);
if (tokens == null) { return null; }
if (tokens[3].toLowerCase() === 'pm' && tokens[1] !== '12') {
tokens[1] = '' + (12 + (+tokens[1]));
} else if (tokens[3].toLowerCase() === 'am' && tokens[1] === '12') {
tokens[1] = '00';
}
return tokens[1] + ':' + tokens[2];
}
The manual solution is harder to understand, is less flexible, is missing some error checking and needs unit tests. In general, you should usually prefer a well-tested popular library's solution, rather than your own (if a well-tested library is available).
Without using any additional JavaScript libraries:
/**
* #var amPmString - Time component (e.g. "8:45 PM")
* #returns - 24 hour time string
*/
function getTwentyFourHourTime(amPmString) {
var d = new Date("1/1/2013 " + amPmString);
return d.getHours() + ':' + d.getMinutes();
}
So for example:
getTwentyFourHourTime("8:45 PM"); // "20:45"
getTwentyFourHourTime("8:45 AM"); // "8:45"
In case you're looking for a solution that converts ANY FORMAT to 24 hours HH:MM correctly.
function get24hTime(str){
str = String(str).toLowerCase().replace(/\s/g, '');
var has_am = str.indexOf('am') >= 0;
var has_pm = str.indexOf('pm') >= 0;
// first strip off the am/pm, leave it either hour or hour:minute
str = str.replace('am', '').replace('pm', '');
// if hour, convert to hour:00
if (str.indexOf(':') < 0) str = str + ':00';
// now it's hour:minute
// we add am/pm back if striped out before
if (has_am) str += ' am';
if (has_pm) str += ' pm';
// now its either hour:minute, or hour:minute am/pm
// put it in a date object, it will convert to 24 hours format for us
var d = new Date("1/1/2011 " + str);
// make hours and minutes double digits
var doubleDigits = function(n){
return (parseInt(n) < 10) ? "0" + n : String(n);
};
return doubleDigits(d.getHours()) + ':' + doubleDigits(d.getMinutes());
}
console.log(get24hTime('6')); // 06:00
console.log(get24hTime('6am')); // 06:00
console.log(get24hTime('6pm')); // 18:00
console.log(get24hTime('6:11pm')); // 18:11
console.log(get24hTime('6:11')); // 06:11
console.log(get24hTime('18')); // 18:00
console.log(get24hTime('18:11')); // 18:11
I've use something similar to this
//time is an array of [hh] & [mm am/pm] (you can get this by time = time.split(":");
function MilitaryTime(time){
if(time[1].indexOf("AM")!=-1){
//its in the morning, so leave as is
return time;
}else if(time[0]!="12"){
//If it is beyond 12 o clock in the after noon, add twelve for military time.
time[0]=String(parseInt(time[0])+12);
return time;
}
else{
return time;
}
}
Once you get your time returned, you can alter the text in any way you want.
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 : "");
}
}