Moment: يعطي isSameOrAfter إخراجًا عشوائيًا عند مقارنة اللحظة () باللحظة ()

تم إنشاؤها على ٢١ فبراير ٢٠١٧  ·  4تعليقات  ·  مصدر: moment/moment

وصف
لذلك ، عثرت أنا وزميلي على خطأ في الكود الخاص بنا والذي اتضح أنه نتج عن استخدامنا لمتغير غير محدد (أساسًا moment(undefined) ثم حاول مقارنة ذلك بمثيل لحظة جديدة ( moment() ) بالطريقة isSameOrAfter .

إذن ما استخدمناه بشكل أساسي هو:

let isSame = moment(undefined).isSameOrAfter(moment());

سيؤدي تشغيل هذا الرمز مرة أو مرتين إلى إرجاع true ، ولكن ليس دائمًا. من حين لآخر ، تُرجع false ، أعتقد أن ذلك لأن إنشاء حالتين من اللحظة ، بعد بعضهما البعض ، بدون تحديد وقت قد يؤدي إلى إنشاءهما بفارق بضع ميكروثانية.

هذا اختبار أجريته في كل من Node v7.1.0 على Windows 10 و Chrome / 56.0.2924.87 مع Moment.js 2.17.1.

const moment = require('moment');

function isSameOrAfter() {
    console.log('isSameOrAfter')
    for (let i = 0; i < 1000; i++) {
        let output = moment().isSameOrAfter(moment());
        if (!output) {
            console.log(output, i);
        }
    }
}

function isSame() {
    console.log('isSame')
    for (let i = 0; i < 1000; i++) {
        let output = moment().isSame(moment());
        if (!output) {
            console.log(output, i);
        }
    }
}

function sameExactVariable() {
    console.log('Another test comparing the same exact variable')
    for (let i = 0; i < 1000; i++) {
        const now = moment();
        let output = now.isSame(now);
        if (!output) {
            console.log(output, i);
        }
    }
}

isSameOrAfter();
isSame();
sameExactVariable();

ستقوم أول وظيفتين بتسجيل false بضع مرات من أصل 1000 ، ولن يتم تسجيل الوظيفة الثالثة. يتم تسجيله فقط عندما يأتي عند استثناء.

بيئة:
الثلاثاء 21 فبراير 2017 14:36:06 GMT + 0100 (توقيت غرب أوروبا القياسي)
2017-02-21 14:36:06
-60
Mozilla / 5.0 (Windows NT 10.0 ؛ Win64 ؛ x64) AppleWebKit / 537.36 (KHTML ، مثل Gecko) Chrome / 56.0.2924.87 Safari / 537.36
2.17.1

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

imrvshah أولا لاحظ ذلك

...isSameOrAfter(moment().format('MM-DD-YYYY'))

ينشئ لحظة جديدة مع الوقت الحالي ، وينسقها كسلسلة ، ويمرر هذه السلسلة إلى isSameOrAfter() ، والتي تحللها مرة أخرى. كان يجب أن تقول للتو:

...isSameOrAfter(moment())

وحفظها لحظة -> خيط -> لحظة عمل. هذا رمز أفضل بكثير ، لكنني أراهن أيضًا أنه يصلح الخطأ. هل لاحظت تحذيرات من الإهمال تقول "مرحبًا ، ليس من المفترض أن تمرر الخيوط إلى لحظة كهذه"؟ يعرف Moment كيفية تحليل سلاسل ISO 8601 مثل moment("1982-05-25") . يعرف أيضًا كيفية تحليل السلاسل حيث يتم تحديد التنسيق ، مثل moment("05-25-1982", "MM-DD-YYYY") . ولكن ليس لديه فكرة أن سلسلة مثل "05-25-1982" من المفترض أن تكون "MM-DD-YYYY" دون أن تخبرها بذلك. لذلك يتيح للمتصفح التخمين بمجرد تسليم هذه السلسلة إلى المُنشئ Date . بمعنى آخر ، يتم فك الشفرة الخاصة بك مثل هذا:

m.isSameOrAfter("05-25-1982");
m.isSameOrAfter(moment("05-25-1982"))
m.isSameOrAfter(moment(new Date("05-25-1982")))

هناك سبب لإهمالنا: أنه يعطي نتائج غير متسقة بناءً على المتصفح الذي يقوم بتشغيله. إذن ما تواجهه هو أن iOS لا يدعم هذا التنسيق محليًا. في وحدة تحكم تطوير Safari الخاصة بي:

> new Date("05-25-1982")
Invalid Date

أعطاك ذلك مقارنات سيئة تركتك بمصفوفة فارغة.

ال 4 كومينتر

ربما لدي نفس النوع من المشكلة. إنه يعمل كما هو متوقع على جهاز Chrome و Android ولكن ليس في iOS.

let arrDates: Array<String> = []; _.each(Dates, (date) => { if (moment(date).isSameOrAfter(moment().format('MM-DD-YYYY'))) { arrDates.push(date); } });

في نظام التشغيل iOS ، أحصل على صفيف فارغ أثناء عمله على Chrome و Android.

بيئة:

كوردوفا CLI: 6.4.0
إصدار الإطار الأيوني: 2.0.0
إصدار أيوني CLI: 2.1.18.1
إصدار ليب التطبيق الأيوني: 2.1.9
إصدار البرامج النصية للتطبيق الأيوني: 1.0.0
إصدار iOS: 1.9.0
إصدار ios-sim: 5.0.13
نظام التشغيل: macOS Sierra
إصدار العقدة: v6.9.2
إصدار Xcode: Xcode 8.2.1 Build version 8C1002

تضمين التغريدة

أعتقد أن السبب في ذلك هو أن إنشاء حالتين من اللحظة ، بعد بعضهما البعض ، بدون تحديد وقت قد يخلقهما بفارق بضعة ميكروثانية.

نعم ، يعني moment() أو moment(undefined) وهما متطابقان - الآن . تحتوي تواريخ JS على دقة بالمللي ثانية ، لذلك إذا كانت الآن ملي ثانية مختلفة ، وهو ما سيحدث أحيانًا ، تكون المرة تلو الأخرى. لا تحدد AFAIK ، JS الطلب الذي يقوم فيه moment().isSameOrAfter(moment()) بتقييم هاتين المكالمتين moment() ،. ولكن نظرًا لأنه من الواضح أنه يتعين عليه إجراء المكالمة الثانية قبل تنفيذ isSameOrAfter() أي حال ، فلن أتفاجأ إذا كانت المكالمة الثانية من الناحية العملية تأتي دائمًا أولاً. هذا يعني أنه إذا كان هناك فارق زمني ، فسوف يفشل أيضًا في جزء "أو بعد" من الاختبار. يمكنك تأكيد ذلك باستخدام مصحح أخطاء.

لا اعرف ماذا اقول لك. هذه هي الطريقة التي يجب أن تعمل بها التواريخ ذات الدقة المحدودة ؛ "الآن" تعني وقتًا مختلفًا بناءً على الوقت الذي تقوله فيه.

imrvshah أولا لاحظ ذلك

...isSameOrAfter(moment().format('MM-DD-YYYY'))

ينشئ لحظة جديدة مع الوقت الحالي ، وينسقها كسلسلة ، ويمرر هذه السلسلة إلى isSameOrAfter() ، والتي تحللها مرة أخرى. كان يجب أن تقول للتو:

...isSameOrAfter(moment())

وحفظها لحظة -> خيط -> لحظة عمل. هذا رمز أفضل بكثير ، لكنني أراهن أيضًا أنه يصلح الخطأ. هل لاحظت تحذيرات من الإهمال تقول "مرحبًا ، ليس من المفترض أن تمرر الخيوط إلى لحظة كهذه"؟ يعرف Moment كيفية تحليل سلاسل ISO 8601 مثل moment("1982-05-25") . يعرف أيضًا كيفية تحليل السلاسل حيث يتم تحديد التنسيق ، مثل moment("05-25-1982", "MM-DD-YYYY") . ولكن ليس لديه فكرة أن سلسلة مثل "05-25-1982" من المفترض أن تكون "MM-DD-YYYY" دون أن تخبرها بذلك. لذلك يتيح للمتصفح التخمين بمجرد تسليم هذه السلسلة إلى المُنشئ Date . بمعنى آخر ، يتم فك الشفرة الخاصة بك مثل هذا:

m.isSameOrAfter("05-25-1982");
m.isSameOrAfter(moment("05-25-1982"))
m.isSameOrAfter(moment(new Date("05-25-1982")))

هناك سبب لإهمالنا: أنه يعطي نتائج غير متسقة بناءً على المتصفح الذي يقوم بتشغيله. إذن ما تواجهه هو أن iOS لا يدعم هذا التنسيق محليًا. في وحدة تحكم تطوير Safari الخاصة بي:

> new Date("05-25-1982")
Invalid Date

أعطاك ذلك مقارنات سيئة تركتك بمصفوفة فارغة.

تضمين التغريدة

أنا أتفق معك واكتشف الحالة في وحدة التحكم ، فقد كان تحذيرًا من الإيقاف بسبب تنسيق التاريخ.

نشكرك على تعليقك حول عدم تغليفه عدة مرات واستخدامه فقط. ...isSameOrAfter(moment())

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