-
Notifications
You must be signed in to change notification settings - Fork 7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature request: Formatting duration in multiple time units #4344
Comments
This is pretty cool! |
@rokoroku how would you handle unit "holes", like |
Lines 29 to 44 in 2e2a5b3
Since moment already has locale strings for each time units, we can compose the duration with existing unit strings by mathematical modulus(remainder) and floor operation. |
@ichernev I'm very interested in this proposal! I also read the source code, but as you said, there are "vulnerabilities" in the processing unit. I checked issue #2928, The same is true here. Can we use the idea of Fake code let ms = this.$ms;
this.$d.years = Math.floor(ms / MILLISECONDS_A_YEAR)
ms %= MILLISECONDS_A_YEAR
this.$d.months = Math.floor(ms / MILLISECONDS_A_MONTH)
ms %= MILLISECONDS_A_MONTH
this.$d.days = Math.floor(ms / MILLISECONDS_A_DAY)
ms %= MILLISECONDS_A_DAY
this.$d.hours = Math.floor(ms / MILLISECONDS_A_HOUR)
ms %= MILLISECONDS_A_HOUR
this.$d.minutes = Math.floor(ms / MILLISECONDS_A_MINUTE)
ms %= MILLISECONDS_A_MINUTE
this.$d.seconds = Math.floor(ms / MILLISECONDS_A_SECOND)
ms %= MILLISECONDS_A_SECOND
this.$d.milliseconds = ms |
I was actually looking for something like this recently. I ended up just writing my own helper function to do this. Maybe this code would help someone implement this in the future. @ichernev Could you explain what you mean by unit "holes"? import _ from "lodash";
import moment from "moment";
/**
* @function formatDuration
* @description Formats a number representing a duration to a humanized version
* of said duration.
*
* @example duration = 90
* durationUnit = "minutes"
* result = 1 Hour 30 Minutes
*
* @param {Number} duration
* @param {Object} options
* @property {String} [durationUnit = "minutes"]
* @property {Boolean} withWeeks - return the number of weeks in the duration.
* @example: 1 Month 3 Weeks 2 Days vs 1 Month 23 Days
* @property {Boolean} useAnd - formats the last unit to be preceded by the word "and"
* @property {Boolean} [capitalize = true] - capitalize the duration unit string
*
* @returns {String} Formatted duration
*/
export const formatDuration = (
duration,
{ durationUnit = "minutes", withWeeks, useAnd, capitalize = true } = {}
) => {
const units = [
"year",
"month",
"week",
"day",
"hour",
"minute",
"second",
"millisecond",
];
const d = moment.duration(duration, durationUnit);
const segments = units
.map(unit => {
let value = d.get(unit);
if (withWeeks && unit === "day") {
value = value % 7;
}
if (value > 0) {
if ((unit === "week" && withWeeks) || unit !== "week") {
let unitString = capitalize ? _.capitalize(unit) : unit;
if (value > 1) {
unitString = `${unitString}s`;
}
return `${value} ${unitString}`;
}
}
})
.filter(Boolean);
if (useAnd) {
const head = _.initial(segments);
const tail = _.last(segments);
return `${head.join(" ")} and ${tail}`;
}
return segments.join(" ");
}; |
Unfortunately we will not take any new features. |
Description of the Issue and Steps to Reproduce:
It's a subsequent feature request for #4295
momentjs
' existing relative formatting behavior..humanize()
could be also achieved with multiple time units. e.g.The text was updated successfully, but these errors were encountered: