Moment: طلب الميزة: أكثر دقة

تم إنشاؤها على ٢٤ يونيو ٢٠١٢  ·  112تعليقات  ·  مصدر: moment/moment

.humanize ليست دقيقة حقًا عندما يتعلق الأمر بالثواني.

moment.duration(40, 's').humanize() === "a few seconds" // expected "40 seconds"
moment.duration(45, 's').humanize() === "a minute" // expected "45 seconds"

أفهم أننا لا نريد غالبًا هذا المستوى من الدقة ولكن في بعض الأحيان نريد القيمة الدقيقة بطريقة يمكن للبشر قراءتها.

أقترح تغيير واجهة برمجة التطبيقات (التي تبدو متوافقة مع الإصدارات السابقة مما أراه بالفعل) لدعم هذه الميزة:

moment.duration(40, 's').humanize() === "a few seconds"
moment.duration(40, 's').humanize(true) === "in a few seconds"

moment.duration(40, 's').humanize({precise:true}) === "40 seconds"

moment.duration(40, 's').humanize({suffix:true, precise:true}) === "in 40 seconds"
moment.duration(40, 's').humanize({precise:false, suffix:true}) === "in a few seconds"

ما رأيك ؟

Enhancement New Feature

التعليق الأكثر فائدة

moment.duration(183, "minutes").humanize() // 3 hours

سيكون من الجيد الحصول على إخراج دقيق مثل: 3 ساعات و 3 ثوان.

ال 112 كومينتر

FGRibreau ، ظهرت هذه المشكلة في # 232 ، ويبدو أن OP هناك لا بأس به ولا تضيف ذلك إلى النواة.

يمكنك كتابة تعريف لغة يسمى precise-english أو شيء ما عندما تريد أوقاتًا نسبية أكثر دقة. مع ظهور ميزة مثيل lang الجديدة في 1.7.0 ، قد تكون مفيدة جدًا. في الوقت الحالي ، سيرث أي تعريف للغة جميع القيم غير المحددة من اللغة الإنجليزية ، لذلك عليك فقط تغيير قاموس النسبي تايم. لسوء الحظ ، لا يتم توريث الميراث داخل القواميس ، لذلك عليك تحديد القاموس بالكامل.

يرجى ملاحظة: الطريقة الموضحة في # 232 لن تعمل بعد الآن في 1.7.0 ، بسبب التغييرات في # 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();

الشيء الوحيد الذي من شأنه أن يجعل هذا أسهل هو أن تعمل الوراثة بحيث يتعين عليك فقط تحديد قيمة واحدة فقط داخل الكائن relativeTime . timrwood ، هل تعتقد أننا بحاجة _smarter_ الميراث؟

إذا أضفنا ميراثًا أكثر ذكاءً ، فقد أرغب في القيام بشيء مثل CLDR وأن ترث كل لغة فرعية من اللغة الرئيسية. لذا فإن fr_CA سيرث من fr و en_GB سيرث من en .

لا أعتقد أننا بحاجة إلى القيام بتوسيع عميق لتغيير "الوقت النسبي" فقط.

هل فعل FGRibreau شيئًا على غرار تعريف اللغة precise-en مناسبًا لك؟

إغلاق هذا كحل rockymeza هو الطريقة المفضلة للتعامل مع هذا.

هذا ينطبق على أكثر من مجرد ثوان. الأمر نفسه ينطبق على الساعات والسنوات وما إلى ذلك ...

نعم ، ويفضل الحل المفضل فقط للسمعيات الناطقة باللغة الإنجليزية. في اللغات الأخرى ، عليك أن تزعج نفسك بتصريفات الأسماء (الانحرافات).

أنا أضيف وزنا لهذه القضية. عند تصميم العد التنازلي ، فإن الدقة مطلوبة.

لذلك من الجيد أن يكون لديك "قبل 10 ساعات" عند النظر إلى الأشياء الماضية ، ولكن إذا كنت أنتظر حدثًا بفارغ الصبر ، فأنا أريد "خلال 10 ساعات و 3 دقائق و 8 ثوانٍ"

لا تقل لي أنه يجب علي كتابة لغة مخصصة للحصول على ذلك؟

moment.duration(183, "minutes").humanize() // 3 hours

سيكون من الجيد الحصول على إخراج دقيق مثل: 3 ساعات و 3 ثوان.

اريد هذه الميزة ايضا.

أنا أيضا بحاجة إلى نسخة دقيقة أنسنة!

أعتقد أيضًا أنه سيكون من الجيد أن تكون لحظة إنسانية (اختياريًا) أكثر دقة ، لكن بالنسبة لأي شخص أتى إلى هنا يبحث عن حل الآن ، وجدت أن HumanizeDuration.js يعمل بشكل جيد:

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'

أرغب في رؤية خيار "إضفاء الطابع الإنساني الدقيق" ، فإن الاضطرار إلى استخدام مكتبة إضافية في آخر لحظة أمر صعب بعض الشيء ..

+1 لإضفاء طابع إنساني دقيق!

محبط حقًا لرؤية أنه لا يوجد خيار للحصول على المدة التي تناسب البشر بدقة. : |

هناك بعض المكونات الإضافية تسمى Precise Range المشار إليها في المستندات. هل جربها أحد؟

يعمل النطاق الدقيق تقنيًا ، ولكن يبدو أنه يُرجع سلسلة بدلاً من كائن لحظة ، لذلك لا يمكنني تحديد أجزاء التاريخ التي قد أحبها على وجه التحديد.

اللغة (imo) متوقفة قليلاً أيضًا ، وكانت إحدى النتائج - "ساعة و 19 دقيقة بضع ثوانٍ". أفضل أن أرى ساعة و 19 دقيقة وبضع ثوان. لطالما كان الخلط بين الكلمات والأرقام أمرًا نحويًا نوعا ما (على حد علمي).

+1 للحظة الدقيقة إضفاء الطابع الإنساني

Envek Precise Range يبدو لطيفًا ، لا يدعم أي i18n / l10n على الرغم من ...

سيكون الدعم الرسمي باللحظة. js رائعًا لأنني كنت بحاجة إلى هذا في اثنين أو ثلاثة من مشاريعي على الأقل.

topaxi +1

+1

doingweb أؤكد أن وحدة HumanizeDuration.js تعمل بشكل جيد!

+1 للحظة الدقيقة إضفاء الطابع الإنساني

+1 للحصول على لحظة أكثر دقة وإضفاء الطابع الإنساني

+1

+1

+1

+1

+1

+1

+1

لماذا يتم إغلاق هذا طوال الوقت؟ هذه هي الميزة الأكثر وضوحًا التي يجب تنفيذها في الوقت الحالي. js. لقد صدمت بالفعل لأنه ليس موجودًا بالفعل. من الواضح أن الإنسانية عديمة الفائدة في أي مكان آخر غير عرض الوقت الغامض كما هو الحال في المشاركات في المنتديات بدونها.

+1

+1

+1

-1. أنا أحب أن أنسنة كيف يعمل الآن. من المفترض أن تعطي نسخة من المدة "صديقة للإنسان".

"مرحبًا فرانك ، متى أرسلت هذا البريد الإلكتروني؟"
"منذ دقيقة واحدة."

ضد

"مرحبًا فرانك ، متى أرسلت هذا البريد الإلكتروني؟"
"قبل ثلاث وأربعين ثانية."

أيهما يبدو أكثر "إنسانية"؟

لم يكن من المفترض أن تحل النسخة الأكثر دقة محل النسخة الحالية. إنه طلب ميزة جديدة.

+1 ، mattgrande بينما ما لدينا الآن رائع لوصف مدة شيء ما في الماضي ، فإنه ليس مناسبًا لوصف ، على سبيل المثال ، طول الموعد ، على سبيل المثال "1 ساعة ، 30 دقيقة".

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1 لهذا مني. إن عمل تعريف جديد للغة ، أو تعديل تعريف موجود ، لا ينجح حقًا. يبدو أن هناك 108 لغة مدعومة حاليًا بواسطة Moment ، لذلك يتعين علينا إما تعديل 108 تعريفًا يدويًا (ونأمل أن نحصل عليها جميعًا بشكل صحيح نحويًا) ، أو ننسى أي مستخدم لا يتحدث الإنجليزية؟ لا يبدو أي من هذين الحلين جيدًا ...

أنا أستخدم هذا:

جافا سكريبت
var humanizeDuration = function (eventDuration) {
eventMDuration = moment.duration (eventDuration، 'seconds') ؛
eventDurationString = ""
إذا (eventMDuration.days ()> 0)
eventDurationString + = "" + moment.duration (eventMDuration.days ()، 'days'). humanize ()
إذا (eventMDuration.hours ()> 0)
eventDurationString + = "" + moment.duration (eventMDuration.hours ()، 'Hours'). humanize ()
إذا (eventMDuration.minutes ()> 0)
eventDurationString + = "" + moment.duration (eventMDuration.minutes ()، 'minutes'). humanize ()

إرجاع eventDurationString.trim ()
}
""

+1

+1 بدون هذه الميزة ، لا يمكن تتبع الوقت.

لماذا تم إغلاق الإصدار؟

+1

+1

+1

القدرة على إضافة خيار أكثر دقة ، بينما لا يزال خيار "بشري" سيكون ذا قيمة فائقة.

+1

+1

+1

+1

+1. العمل على تطبيق محاسبة يتطلب عرض المدة بشكل دقيق ولكن بشكل بشري. "1 عام ، شهرين ، 3 أيام" أفضل من "398 يومًا" ، ولكن "عام واحد" غير مقبول حقًا.

التنفيذ الحالي إنساني للغاية بحيث يصبح عديم الفائدة بشكل أساسي.

+1

duration.humanize له عتبات تحدد متى يتم اعتبار الوحدة دقيقة وساعة وما إلى ذلك. على سبيل المثال ، بشكل افتراضي أكثر من 45 ثانية تعتبر دقيقة ، وأكثر من 22 ساعة تعتبر في اليوم وهكذا. لتغيير هذه القطع ، استخدم moment.relativeTimeThreshold(unit, limit) حيث تكون الوحدة واحدة من ss ، s ، m ، h ، d ، M .

https://momentjs.com/docs/#/customization/relative -time-threshold /

+1

+1

+1 ، يرجى إعادة النظر في فتح هذه المشكلة 😍

+1

+1

+1

+1

+1

+1

أستخدم شيئًا مثل هذا:

function stringifyDuration(duration) {
    // Return a human readable string representing the given moment duration

    // Split the duration into parts, and drop the most significant parts with a value of 0
    const durationParts = _.dropWhile([
        { value: duration.years(), unit: 'year' },
        { value: duration.months(), unit: 'month' },
        { value: duration.days(), unit: 'day' },
        { value: duration.hours(), unit: 'hour' },
        { value: duration.minutes(), unit: 'minute' },
        { value: duration.seconds(), unit: 'second' },
        { value: duration.milliseconds(), unit: 'millisecond' },
    ], (part) => part.value === 0);

    // Display up to two of the most significant remaining parts
    return _.take(durationParts, 2).map((part) => (
        `${part.value} ${pluralize(part.unit, part.value)}`
    )).join(', ');
}
> stringifyDuration(moment.duration(26, 'hours'))
"1 day, 2 hours"

يستخدم لوداش والجمع .

timrwood حالة لتنفيذ هذا:

  1. يعني حل rockymeza https://github.com/moment/moment/issues/348#issuecomment -6535794 أنه يتعين علينا (كل مطور واحد موجود) إعادة تنفيذ هذا في كل لغة يدعمونها ، على الرغم من أنك لقد قام المساهمون بالفعل بعمل رائع يتمثل في الترجمة إلى العديد من اللغات
  2. mattgrande https://github.com/moment/moment/issues/348#issuecomment -237830415 إن الجدل القائل بأنه بالفعل بشري بما فيه الكفاية ، هو مجرد استدعاء الجزء الذي يعمل بشكل جيد. ضع في اعتبارك هذه المحادثة:

مرحبًا فرانك ، أنا ذاهب لتناول الغداء ، كم من الوقت لدي حتى الاجتماع التالي؟
ساعة

Now, let's see what that "hour" can mean in `moment`:

```js
moment.duration({hours: 0, minutes: 45}).humanize() === "an hour"
moment.duration({hours: 1, minutes: 29}).humanize() === "an hour"
```
This means that if we understand things differently I could be ~45 minutes early or late for that meeting.
  1. بفضل sproot لاستدعاء RTFM

    moment.relativeTimeThreshold('m', 60);
    moment.duration({hours: 0, minutes: 45}).humanize() === "45 minutes"
    moment.duration({hours: 0, minutes: 59}).humanize() === "59 minutes"
    moment.duration({hours: 0, minutes: 60}).humanize() === "an hour"
    moment.duration({hours: 1, minutes: 29}).humanize() === "an hour"
    

    إنه أفضل قليلاً ، لكنه لا يزال يمثل مشكلة عندما تكون مدة الاستراحة أطول من 60 دقيقة. يمكن أن يعني هذا الاختلاف الذي يبلغ 30 دقيقة أنه يمكنني العودة إلى المنزل وتناول الطعام والعودة ، أو يجب أن أحضر شيئًا في مكان قريب.

  2. حلولNerian https://github.com/moment/moment/issues/348#issuecomment -279819773 و cogwirrel https://github.com/moment/moment/issues/348#issuecomment -346233713 جنبًا إلى جنب مع sproot ' يحصل تلميح s على تنفيذ "جيد بما فيه الكفاية" دون الحاجة إلى مكتبة إضافية (_ يمكن تنفيذ الأجزاء باستخدام JS عادي) ، ولكنه اختراق لشيء يمكن دعمه مباشرة:

    var el = document.createElement('script');
    el.src = "https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js";
    document.head.appendChild(el)
    moment.relativeTimeThreshold('s', 60);
    moment.relativeTimeThreshold('ss', 0); // must be after 's', disables "few seconds"
    moment.relativeTimeThreshold('m', 60);
    moment.relativeTimeThreshold('h', 24);
    moment.relativeTimeThreshold('d', 31);
    moment.relativeTimeThreshold('M', 12);
    /**
     * Return a precize human readable string representing the given moment duration.
     *
     * <strong i="34">@param</strong> {Moment.Duration} duration
     * <strong i="35">@param</strong> {{mostPreciseUnit: string, numberOfSignificantParts: integer}} options
     */
    moment.duration.fn.humanizePrecisely = function(options = {}) {
        // Split the duration into parts to be able to filter out unwanted ones
        const allParts = [
            { value: this.years(), unit: 'years' },
            { value: this.months(), unit: 'months' },
            { value: this.days(), unit: 'days' },
            { value: this.hours(), unit: 'hours' },
            { value: this.minutes(), unit: 'minutes' },
            { value: this.seconds(), unit: 'seconds' },
            // cannot format with moment.humanize()
            //{ value: duration.milliseconds(), unit: 'milliseconds' },
        ];
    
        return _(allParts)
            // only use the first parts until the most precise unit wanted
            .take(_.findIndex(allParts, {unit: options.mostPreciseUnit || 'seconds'}) + 1)
            // drop the most significant parts with a value of 0
            .dropWhile((part) => part.value === 0)
            // skip other zeroes in the middle (moment.humanize() can't format them)
            .reject((part) => part.value === 0)
            // use only the significant parts requested
            .take(options.numberOfSignificantParts || allParts.length)
            // format each part
            .map((part) => moment.duration(part.value, part.unit).locale(this.locale()).humanize())
            .join(' ');
    }
    moment.duration({hours: 2, minutes: 3, seconds: 4}).locale('de').humanizePrecisely()
        // === "2 Stunden 3 Minuten 4 seconds"
    

    (ملاحظة: هناك خطأ ما في تنسيق الثواني واللغات ، والتي سيتم إصلاحها بواسطة # 3981 في # 4183.)

لما يستحق ، لقد وجدت هذا للتو من الوثائق الرسمية:

https://momentjs.com/docs/#/plugins/preciserange/

يبدو الرمز الخاص بي على هذا النحو - وهو يعمل بشكل مثالي:

    var d1 = new Date()
    var d2 = new Date(durationInMinutes * 60 * 1000)
    return moment.preciseDiff(d1 - d2)

أعتقد أن هذا يغلق هذه المشكلة بشكل فعال ...؟

mercmobily for AU، US (CA)، UK: نعم ، ROW: ليس حقًا ؛ ربما عند إصلاح https://github.com/codebox/moment-precise-range/issues/6 .

(ملاحظة جانبية: استخدام moment و *60*1000 يبدو غريبًا بعض الشيء بالنسبة لي ، هل فكرت في moment().add(durationInMinutes, 'minutes') ؟)

آه ، أنا لست على دراية جيدة باللحظة! ما الذي يضيفه moment().add(durationInMinutes, 'minutes') ؟
أعتقد أنه بمجرد إغلاق هذه المشكلة ، يكون هذا هو "الحل" لهذه المشكلة ...

moment() "الآن" (على غرار new Date() ) ، و add يزيد ذلك بمقدار n دقيقة. يمكن استخدام أي كائن لحظة ، على الرغم من ذلك ، لا يقتصر على "الآن". (من أجل الحفاظ على تركيز هذه المناقشة الطويلة بالفعل ، دع هذا يكون التعليق الأخير المتعلق بهذا العرض الجانبي ؛)

+1

+2

+1

+1

+1

يرجى إعادة فتح هذا. يرغب برنامجي في عرض أي نوع من الفاصل الزمني بشكل صحيح ، ولا يُقبل تغيير "كل 12 ثانية" إلى "كل بضع ثوان" أو تغيير "كل 54 ثانية" إلى "كل دقيقة".

+1

+1

انا افعل:

moment.duration('PT5S').humanize();

وأود أن أقول: "5 ثوانٍ" ولكن بدلاً من ذلك تقول "بضع ثوانٍ". متى يمكننا إضافة هذا الدعم؟

+1

+1

ها هي وظيفة صغيرة تعتمد على cogwirrel ولا تستخدم اللوداش

import { pluralize } from '...'

export function humanize (duration) {
  const durationComponents = [
    { value: duration.years(), unit: 'year' },
    { value: duration.months(), unit: 'month' },
    { value: duration.days(), unit: 'day' },
    { value: duration.hours(), unit: 'hour' },
    { value: duration.minutes(), unit: 'minute' },
    { value: duration.seconds(), unit: 'second' },
    { value: duration.milliseconds(), unit: 'millisecond' }
  ]
  return durationComponents
    .filter(({ value }) => value !== 0)
    .slice(0, 3)
    .map(({ unit, value }) => pluralize(value, unit))
    .join(', ')
}

+1

(أود أن أزعم أنه إذا كان لديك طريقة إنسانية () ، فإن تحويل "1.51 ساعة" إلى "ساعتان" لا يعد أمرًا خاصًا بشريًا).

+1
لا تدعم المكتبات الأخرى مثل هذه المجموعة الكبيرة من اللغات مثل Moment.js. يرجى إعادة النظر!

+1

+1

+1

+1

PS لا يصدق لم يتم تنفيذه بعد ؛ (

+1 حقًا ، ما زال هذا غير موجود ؟!

لقد ألغيت الاشتراك أخيرًا (لقد مر ما يقرب من 7 سنوات بالفعل ، لكنني أعتقد أنني حصلت عليها أخيرًا مع كل إجراءات +1 هذه)

لقد وجدت حزمة تحل مشاكلي 🎉
https://github.com/EvanHahn/HumanizeDuration.js

ربما يكون مفيدًا لأي شخص آخر أيضًا.

+1

+1

+1

+1

رأيي في هذه المشكلة:

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(', ');
}

هذا منطقي للغاية ، أحب أن أرى تنسيقًا دقيقًا للمدة.

أحب خيار أنسنة دون التقريب
+1

+1 على هذا

+1

+1

+1

+1

فقط في حالة وصول أي شخص إلى هنا بعد البحث في googling ، كان هذا config / workaround كافيًا في حالتي:

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"

لأن الدقة في حالة الاستخدام الخاصة بي أهم بكثير من النص الجميل المظهر.

هذه مقارنة قبل وبعد تكوين / استدعاء طرق moment.relative*() :

| المدة | قبل | بعد |
| --------- | --------------- | -------------- |
| 3s | a few seconds | 3 seconds |
| 44s | a few seconds | 44 seconds |
| 45s | a minute | 45 seconds |
| 1m 29s | a minute | 1.48 minutes |
| 1m 30s | 2 minutes | 1.5 minutes |
| 1m 59s | 2 minutes | 1.98 minutes |
| 44m | 44 minutes | 44 minutes |
| 45m | an hour | 45 minutes |
| 1h 29m | an hour | 1.48 hours |
| 1h 30m | 2 hours | 1.5 hours |
| 21h | 21 hours | 21 hours |
| 22h | a day | 22 hours |
| 35h | a day | 35 hours |
| 35h 30m | a day | 35.5 hours |
| 36h | 2 days | 36 hours |

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات