Moment: فشل endOf ("day") في الأيام التي لا تبدأ في منتصف الليل

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

انصح:

moment("2016-10-16").endOf('day').format("YYYY-MM-DD HH:mm:ss")

في معظم المناطق الزمنية ، سيؤدي هذا إلى إرجاع "2016-10-16 23:59:59" . ومع ذلك ، في البرازيل ، سيؤدي هذا إلى إرجاع "2016-10-17 00:59:59" . هذا غير صحيح ، لأن الساعة فقط من 00:00 إلى 00:59 يوم 2016-10-16 مفقودة. لا تزال نهاية 2016/10/16 الساعة 23:59:59 في نفس التاريخ.

هذا أيضًا قابل للتكرار مع المنطقة الزمنية اللحظية:

moment.tz("2016-10-16","America/Sao_Paulo").endOf('day').format("YYYY-MM-DD HH:mm:ss")

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

Bug DST

ال 15 كومينتر

تم الإبلاغ عن هذا في الأصل على أنه لحظة / منطقة زمنية # 327.

2749 مرتبط ، لكنه مختلف قليلاً.

على عكس حساب الطول المحدد لوقت اليوم ، لا يمكنك القيام بما يلي:

moment('2016-10-16').startOf('day').add(1, 'day').startOf('day').subtract(1, 'millisecond').format()
"2016-10-16T23:59:59-02:00"

يعمل بشكل جيد في الخامس عشر عند دفعه إلى السادس عشر أيضًا:

moment('2016-10-15').startOf('day').add(1, 'day').startOf('day').subtract(1, 'millisecond').format()
"2016-10-15T23:59:59-03:00"

هل هناك حالة مميزة لا أفكر فيها؟

أفترض أنه قد يكون هناك فائدة في الأداء للقيام بذلك بشكل مختلف ، ولكن يمكنك قراءته!

هممم ، شيء آخر حلل هنا:

moment.tz("2016-10-16","America/Sao_Paulo").startOf('day').add(1,'day').startOf('day').subtract(1,'ms').format()
// "2016-10-16T23:59:59-02:00"  (ok)

moment.tz("2016-10-15","America/Sao_Paulo").startOf('day').add(1,'day').startOf('day').subtract(1,'ms').format()
// "2016-10-14T23:59:59-03:00"  (wrong date)

moment.tz("2016-10-15","America/Sao_Paulo").startOf('day').add(1,'day').format()
// "2016-10-15T23:00:00-03:00"  should have skipped forward to "2016-10-16T01:00:00-02:00"

هل نتعامل فقط مع سلوك المتصفح الغامض بالكامل هنا؟ أم أن هناك ما هو أكثر من ذلك؟

بالكروم مع النوافذ الزمنية في البرازيل:

moment("2016-10-15").startOf('day').format()
"2016-10-15T00:00:00-03:00"
moment("2016-10-15").startOf('day').add(1, 'day').format()
"2016-10-16T01:00:00-02:00"

في Chrome مع المنطقة الزمنية الخاصة بي باستخدام Moment Timezone:

moment.tz("2016-10-15","America/Sao_Paulo").startOf('day').format()
"2016-10-15T00:00:00-03:00"
moment.tz("2016-10-15","America/Sao_Paulo").startOf('day').add(1, 'day').format()
"2016-10-15T23:00:00-03:00"

بارد!

شيء ما مع المنطقة الزمنية لحظة؟ لا أعرف حقًا هذا الرمز لذا من الصعب تحديده. لا يبدو مثل المتصفح إذا كان الأول يعمل على الرغم من ذلك.

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

//setting moves forward
moment.tz("2016-10-16T00:00:00","America/Sao_Paulo").format()
"2016-10-16T01:00:00-02:00"
//adding moves backward
moment.tz("2016-10-15T00:00:00","America/Sao_Paulo").add(1, 'day').format()
"2016-10-15T23:00:00-03:00"

//setting moves forward
moment.tz("2016-03-13T02:00:00","America/Chicago").format()
"2016-03-13T03:00:00-05:00"
//adding moves backward
moment.tz("2016-03-12T02:00:00","America/Chicago").add(1, 'day').format()
"2016-03-13T01:00:00-06:00"

//one more time for funzies
moment.tz("2016-03-27T01:00:00","Europe/London").format()
"2016-03-27T02:00:00+01:00"

moment.tz("2016-03-26T01:00:00","Europe/London").add(1, 'day').format()
"2016-03-27T00:00:00Z"

أعتقد أن هذا له علاقة بمحاولة استخدام إعداد keepTime عندما لا يمكنك الحفاظ على الوقت. لا أعرف هذا الرمز جيدًا بما يكفي لإخبارك عن سبب ظهور الكود على ما هو عليه ، لكنني أعلم على وجه اليقين أنه إذا كانت مكالمة keepTime في هذا الرمز 0 بدلاً من 1 ، فسيتم المضي قدمًا كما هو متوقع. لأن الحفاظ على الوقت قد تم دفعه للخلف. ويجب أن يستمر الوقت ، إنه أمر غير تقليدي مع هذه الحقيبة المتطورة.

    moment.updateOffset = function (mom, keepTime) {
        var zone = moment.defaultZone,
            offset;

        if (mom._z === undefined) {
            if (zone && needsOffset(mom) && !mom._isUTC) {
                mom._d = moment.utc(mom._a)._d;
                mom.utc().add(zone.parse(mom), 'minutes');
            }
            mom._z = zone;
        }
        if (mom._z) {
            offset = mom._z.offset(mom);
            if (Math.abs(offset) < 16) {
                offset = offset / 60;
            }
            if (mom.utcOffset !== undefined) {
                mom.utcOffset(-offset, keepTime);
            } else {
                mom.zone(offset, keepTime);
            }
        }
    };

لا أعرف ما يكفي عن المنطقة الزمنية اللحظية لأكون مفيدًا هنا ، ولكن ربما تكون التذكرة التي توضح سبب استخدام keepTime مفيدة لأي شخص يحقق: https://github.com/moment/moment-timezone/ القضايا / 28

https://github.com/moment/moment/pull/1564

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

maggiepint هل يمكن أن تشرح قليلاً

سيدفع دائمًا التاريخ غير الصحيح للخلف

جزء. أعني - هل لدينا مثال يكشف مشكلة في المنطقة الزمنية اللحظية ، أم أننا نحتاج فقط إلى بعض الرموز الذكية في الوقت الحالي لاكتشاف التوقيت الصيفي في بداية / نهاية اليوم والتعامل معه بشكل مناسب. والثاني متوسط ​​إلى سهل. إذا كان علينا إعادة تشكيل المنطقة التي تمر بين اللحظة - tz واللحظة ، فعندئذٍ الجحيم - أفضل الانتظار 3.0 وآمل ألا تواجه الواجهة الجديدة هذه المشكلة.

ichernev بالطريقة التي يقف عليها الرمز اليوم ، لدينا أثارها @ mj1856 في الأصل ، وهي أن الأيام التي لا تبدأ في منتصف الليل تنتهي بقيمة غير تقليدية في نهاية اليوم. هذه قضية لحظة.

والآخر هو أن المنطقة الزمنية للحظة ، عند تقديمها مع تاريخ غير صالح ، تتقدم إذا تم استخدام هذا التاريخ غير الصحيح في المُنشئ ، ولكنه يتراجع إذا تم "إضافته" إلى ذلك التاريخ. هذه ، كما هي ، مشكلة تتعلق بالمنطقة الزمنية اللحظية وليست مشكلة اللحظة. لست متأكدًا من كيفية تغيير واجهة المنطقة الزمنية - سأفكر في الأمر قليلاً.

maggiepint أشكركم على الشرح الواضح.

لذا لإصلاح مشكلة اللحظة: endOf('day') غير دقيق - فقط "هدف" لنهاية اليوم ، اذهب إلى هناك ، إذا كان 00:00 ، أكمل ، أو صوِّب مرة أخرى ، إذا وصل الهدف الثاني إلى 00: 00 انتهينا وإلا استخدم اللقطة الأولى. الهدف الثاني سيساعدنا إذا قفزنا عبر التوقيت الصيفي و "تشوهنا" بساعة. إذا كانت نهاية اليوم وقتًا غير صالح بسبب التوقيت الصيفي ، فلن يضر الهدف الثاني.

يجب أن نستخدم هذه الخوارزمية لكل endOf ، ربما حتى startOf ، لكن من الصعب تفسير ذلك مع الضبط إلى الصفر الذي نقوم به حاليًا.

مرحبًا يا شباب ، لقد تأثرت أيضًا بهذه المشكلة في الإصدار الحالي من اللحظة (2.14.1).

لقد تم إرسال # 3716 لإصلاح ذلك ، ولكني أرى حاليًا مشكلات في Travis CI لأسباب تتعلق بالترجمة. سوف ننظر في الأمر أكثر قريبا.

هذا أيضًا مرتبط (اللغة البرازيلية الافتراضية).

نتائج العملية في نفس التاريخ:

لحظة ("2017-10-16T00: 59: 59.999"). طرح (1، "يوم"). endOf ("يوم")
=> "2017-10-16T00: 59: 59.999"

مرحبًا - لقد قدمت للتو # 4164 الذي يعمل على إصلاح هذا لـ startOf وكذلك endOf. أود الحصول على تعليقات هناك حتى نتمكّن أخيرًا من المضي قدمًا.

@ mj1856 ، لقد أغلقت العلاقات العامة الخاصة بي لأنه يبدو أن مشكلة endOf في DST edge قد تم إصلاحها. هل يمكن إصلاح هذا أيضًا؟

لقد اختبرت # 4164 ويبدو أن هذا ثابت عليه. في انتظار الدمج.

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