jsmreese / moment-duration-format

Format function plugin for the Moment Duration object.
MIT License
968 stars 120 forks source link

Allow coordinated trimming of multiple durations with the same settings #49

Closed miketamis closed 6 years ago

miketamis commented 8 years ago

Would love to be able to trim on a different moment, the reason for this is i want to show a progress ie 0:10/2:30 however due to trimming its displayed as 10/2:30 I could turn trimming off completely but then it would be 00:00:10/00:02:30 because I still want the hours for those durations that are this long.

GendelfLugansk commented 7 years ago

I faced the same issue (want to always show minutes, but show hours only if duration has hours) and solved it by using function instead of template:

moment.duration(duration, 'seconds').format(function () {
    return duration >= 60*60 ? 'h:mm:ss' : 'mm:ss';
}, {trim: false});

So, I just use different template if duration is more that an hour. But could become complicated if someone will need also to support days for example. So option to trim only durations that are greater than some value would be great.

jsmreese commented 6 years ago

This is an interesting use case. I'm not sure how this could work in code, but I'll give it some thought in the next few days before finalizing the 2.0.0 version.

jsmreese commented 6 years ago

@miketamis here's what I'm thinking: Create a static format function on the moment.duration object itself (not the prototype) that can accept an array of durations, an optional template string, optional precision, and an optional settings object (to keep the rest of the interface the same).

moment.duration.format(durations [, template] [, precision] [, settings]);

The durations would be formatted based on the union of all of the moment types present in the formatted output for all of the durations in the array, with some special handling around largest.

Return value is an array containing the formatted output for each of the input durations.

moment.duration.format([
    moment.duration(1, "second"),
    moment.duration(1, "minute"),
    moment.duration(1, "hour")],
    "d [days] hh:mm:ss"
);
// ["00:00:01", "00:01:00", "01:00:00"]
moment.duration.format([
    moment.duration(1, "second"),
    moment.duration(1, "minute")],
    "d [days] hh:mm:ss"
);
// ["00:01", "01:00"]
moment.duration.format([
    moment.duration(1, "second"),
    moment.duration(1, "minute"),
    moment.duration(1, "day")],
    "d [days] hh:mm:ss"
);
// ["0 days 00:00:01", "0 days 00:01:00", "1 day 00:00:00"]
moment.duration.format([
    moment.duration(1, "minute"),
    moment.duration(1, "day")],
    "y [years], d [days], h [hours], m [minutes], s [seconds]",
    { trim: "both" }
);
// ["0 days, 0 hours, 1 minute", "1 day, 0 hours, 0 minutes"]
jsmreese commented 6 years ago

@GendelfLugansk does my above comment look like it would satisfy your requirements? I think it's doable if I can modularize some of the formatting logic...

GendelfLugansk commented 6 years ago

@jsmreese yes, I think it would solve this issue.

jsmreese commented 6 years ago

@miketamis and @GendelfLugansk, there's a working version pushed to the format-durations branch if you want to check it out.

Still adding tests and docs, it doesn't work with minValue yet, and haven't tested useSignificantDigits at all. But most formatting options work properly.

jsmreese commented 6 years ago

@miketamis and @GendelfLugansk the updated version is published. Happy formatting, and please let me know if you see any issues with the new function!

https://github.com/jsmreese/moment-duration-format/releases