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: A more accurate .humanize #348
Comments
@FGRibreau, this issue came up in #232, and the OP over there seemed to be OK not adding that to core. You could write a language definition called Please note: the method described in #232 will not work anymore in 1.7.0, because of the changes in #332. moment.lang('precise-en', {
relativeTime : {
future : "in %s",
past : "%s ago",
s : "%d seconds", //see https://github.com/timrwood/moment/pull/232#issuecomment-4699806
m : "a minute",
mm : "%d minutes",
h : "an hour",
hh : "%d hours",
d : "a day",
dd : "%d days",
M : "a month",
MM : "%d months",
y : "a year",
yy : "%d years"
}
});
// one way
moment.lang('precise-en');
moment.duration({s: 40}).humanize();
// other way
moment.duration({s: 40}).lang('precise-en').humanize(); One thing that would make this easier would be for the inheritance to work so that you only have to specify just one value inside of the |
If we add in smarter inheritance, I would want to possibly do something like CLDR does and have each sub-language inherit from the master language. So I don't think we need to do deep extending to change out only 'relativeTime.s' though. |
@FGRibreau did something along the lines of a |
Closing this as @rockymeza's solution is the preferred way of handling this. |
This applies to more than just seconds. The same applies to hours, years, etc... |
Yeap, and the preferred solution is preferred only for english-speaking auditory. In other langs you have to bother yourself with noun inflections (declensions). |
I add weight for this issue. When devising a countdown, the precision is needed. So it's OK to have "10 hours ago" when looking at past things, but if eagerly waiting for an event, I want "in 10 hours 3 minutes 8 seconds" Don't tell me that I have to write a custom language to obtain that ? |
moment.duration(183, "minutes").humanize() // 3 hours Would be nice to have de precise output like: 3 hours and 3 seconds. |
I want this feature too. |
I also need a precise humanize version! |
I also think it would be nice for Moment's humanize to be (optionally) more precise, but for anyone who came here looking for a solution right now, I've found that HumanizeDuration.js works pretty well: var
moment = require('moment'),
humanizeDuration = require('humanize-duration');
console.log(humanizeDuration(moment.duration('PT1H15M').asMilliseconds())); // '1 hour, 15 minutes'
// whereas:
console.log(moment.duration('PT1H15M').humanize()); // 'an hour' |
Would love to see an "accurate humanize" option, having to use an additional library on top of moment is a little clunky.. |
+1 for precise humanize! |
Really disappointed to see that there is no option to get the precise humanized duration. :| |
There is some plugin called Precise Range referenced in the docs. Have anyone tried it? |
Precise Range technically works, but it seems to return a string instead of a moment object, so I can't pick out specifically what date parts I might like. The language (imo) is a bit off too, one result was - 'an hour 19 minutes a few seconds' . I'd prefer to see something like 1 hour 19 minutes and a few seconds. Mixing words and numbers has always been a bit of a grammatical no-no (as far as I know). +1 for precise moment humanize |
@Envek Precise Range seems nice, doesn't support any i18n/l10n though... Official support by moment.js would be nice as I needed this in at least two or three of my projects. |
@topaxi +1 |
+1 |
@doingweb I confirm that the HumanizeDuration.js module works pretty well ! |
+1 for precise moment humanize |
+1 for more precise moment humanize |
+1 |
2 similar comments
+1 |
+1 |
+1 😞 |
+1 |
2 similar comments
+1 |
+1 |
+1 P.S. unbelievable it's not yet implemented ;( |
+1 really, this still isn't here?! |
I'm finally unsubscribing (it's been roughly 7 years already, but I think I finally had it with all those +1s) |
I found a package which solves my problems 🎉 Maybe it is useful for anyone else as well. |
+1 |
3 similar comments
+1 |
+1 |
+1 |
My take on that problem: const units: Array<{unit: moment.unitOfTime.Base, key: moment.RelativeTimeKey}> = [
{unit: 'y', key: 'yy'},
{unit: 'M', key: 'MM'},
{unit: 'd', key: 'dd'},
{unit: 'h', key: 'hh'},
{unit: 'm', key: 'mm'},
{unit: 's', key: 'ss'},
];
function accurateHumanize(duration: moment.Duration, accuracy: number = 2): string {
let beginFilter = false;
let componentCount = 0;
return units
.map(({unit, key}) => ({value: duration.get(unit), key}))
.filter(({value, key}) => {
if (beginFilter === false) {
if (value === 0) {
return false;
}
beginFilter = true;
}
componentCount++;
return value !== 0 && componentCount <= accuracy;
})
.map(({value, key}) => ({value: value, key: value === 1 ? key[0] as moment.RelativeTimeKey : key}))
.map(({value, key}) => moment.localeData().relativeTime(value, true, key, true))
.join(', ');
} |
This makes a lot of sense, would love to see a precise formatting of a duration. |
Would love the option to humanize without rounding |
+1 on this |
+1 |
3 similar comments
+1 |
+1 |
+1 |
Just in case anyone lands here after googling, this config/workaround was sufficient in my case: moment.relativeTimeRounding((t) => {
const DIGITS = 2; // like: 2.56 minutes
return Math.round(t * Math.pow(10, DIGITS)) / Math.pow(10, DIGITS);
});
moment.relativeTimeThreshold('y', 365);
moment.relativeTimeThreshold('M', 12);
moment.relativeTimeThreshold('w', 4);
moment.relativeTimeThreshold('d', 31);
moment.relativeTimeThreshold('h', 24);
moment.relativeTimeThreshold('m', 60);
moment.relativeTimeThreshold('s', 60);
moment.relativeTimeThreshold('ss', 0);
console.log(moment.duration(89, 's'));
// Output: "1.48 minutes"
// … without configuring the moment.relative*(), output was: "a minute" because accuracy in my particular use case is much more important than a nice looking text. And this is a comparison before and after configuring/invoking
|
momentjs's `.humanize` sadly does not allow for specifying the precision you want (see moment/moment#348), so all the 4.5 hour hackathons were displaying as 4. The humanize-duration library allows us to specify the precision and our durations are now more readable.
Holy cow... That's still not fixed!? ._. |
@Gredys - and it won't be! As per the README for "moment":
I now use dayjs + https://www.npmjs.com/package/humanize-duration which works well for me |
@digitaltoast thats the reasion why I am not going to use anymore in my projects. (yeah, using same bundles as u) |
This should be included in the moment library instead of giving it as a separate plugin |
Let our grandsons do the implement this feature |
.humanize isn't really accurate when it comes to seconds.
I understand that we don't often want this level of accuracy but sometimes we do want the exact value in a human readable way.
I suggest a change to the API (which seems backwards compatible from what I actually see) to support this feature:
What do you think ?
The text was updated successfully, but these errors were encountered: