تاريخ التحليل/التنسيق مع المنطقة الزمنية و simpledateformat يعطي نتائج مختلفة حول مفتاح DST

StackOverflow https://stackoverflow.com/questions/2356672

  •  23-09-2019
  •  | 
  •  

سؤال

لقد ذهبت إلى مشاركات متعددة حول TimeZone و SimpleDateFormat على Google و Stack Overflow ، لكن ما زلت لا أحصل على ما أفعله خطأ. أنا أعمل على بعض التعليمات البرمجية القديمة ، وهناك طريقة parsedate ، والتي تعطي نتائج خاطئة.

لقد أرفقت عينة Junit التي أحاول استخدامها ، لا تحقق مشكلة.

الطريقة الأولى (TestParsestrangedate_ibm_ibm) يستخدم تطبيق IBM لتنسيق إخراج تحليل طريقة. التنسيقات الثانية الناتج مع تنفيذ Sun.

يمنحنا استخدام SUNPEDATEFORMAT وقتًا مختلفًا لمدة ساعة (والذي قد يكون مرتبطًا بتوفير الضوء النهاري). تعيين المنطقة الزمنية الافتراضية لإصلاحات تنفيذ IBM تحليل الطريقة (ببساطة Uncomment 3 خطوط في طريقة setupDefaulttz).

أنا متأكد من أنها ليست خطأ ، لكنني أفعل شيئًا خاطئًا.

@Test
public void testParseStrangeDate_IBM_IBM() {
    setupDefaultTZ();

    Calendar date = parseDate("2010-03-14T02:25:00");
    com.ibm.icu.text.SimpleDateFormat dateFormat = new com.ibm.icu.text.SimpleDateFormat(
            "yyyy-MM-dd HH:mm:ss");

    // PASSES:
    assertEquals("2010-03-14 02:25:00", dateFormat.format(date.getTime()));
}

@Test
public void testParseStrangeDate_SUN_SUN() {
    setupDefaultTZ();

    Calendar date = parseDate("2010-03-14T02:25:00");
    java.text.SimpleDateFormat dateFormat = new java.text.SimpleDateFormat(
            "yyyy-MM-dd HH:mm:ss");

    // FAILS:
    assertEquals("2010-03-14 02:25:00", dateFormat.format(date.getTime()));
}

public static Calendar parseDate(String varDate) {
    Calendar cal = null;
    try {
        // DOES NOT MAKE ANY DIFFERENCE:
        // com.ibm.icu.text.SimpleDateFormat simpleDateFormat = new
        // com.ibm.icu.text.SimpleDateFormat(
        // "yyyy-MM-dd'T'HH:mm:ss");
        java.text.SimpleDateFormat simpleDateFormat = new java.text.SimpleDateFormat(
                "yyyy-MM-dd'T'HH:mm:ss", Locale.US);
        Date date = simpleDateFormat.parse(varDate);
        cal = GregorianCalendar.getInstance();
        cal.setTimeInMillis(date.getTime());
        System.out.println("CAL: [" + cal + "]");
    } catch (ParseException pe) {
        pe.printStackTrace();
    }
    return cal;
}

private void setupDefaultTZ() {
    java.util.TimeZone timeZoneSun = java.util.TimeZone.getTimeZone("America/Chicago");
    java.util.TimeZone.setDefault(timeZoneSun);

    // UNCOMMENTING THIS ONE FIXES SUN PARSING ??
    // com.ibm.icu.util.TimeZone timeZoneIbm = com.ibm.icu.util.TimeZone
    // .getTimeZone("America/Chicago");
    // com.ibm.icu.util.TimeZone.setDefault(timeZoneIbm);

    Locale.setDefault(Locale.US);
}
هل كانت مفيدة؟

المحلول

المشكلة هي أنك حددت وقتًا غير موجود. تسير الساعات إلى الأمام بحيث تصبح الساعة 2 صباحًا من الساعة 3 صباحًا إلى 2:25 صباحًا.

الآن ، هناك خيارات مختلفة لما يمكن أن يحدث هنا. في وقت نودا أعتقد أننا سنرمي استثناء (هذه هي الخطة على أي حال) ؛ أعتقد وقت جودا (واجهة برمجة تطبيقات Java أفضل بكثير من التاريخ/التقويم/SimpledateFormat - يجب أن تفكر في الترحيل إليها إذا كان بإمكانك) أن تمنحك 3:25 صباحًا ، أي بعد 25 دقيقة من الانتقال.

ماذا كنت تريد أن يحدث عندما تحصل على مزيج من التاريخ/الوقت وهو أمر مستحيل بسبب انتقال DST؟ في هذه الحالة ، من الصعب معرفة ما تعنيه بالنتائج "الخاطئة". أود أن أقول إن اختبار الوحدة الخاص بك معيب إلى حد ما - لا يوجد وقت ممكن ينبغي تكون منسقة في ذلك الوقت.

أظن عن سبب "عمل" المنطقة الزمنية IBM هو أنها قد تستخدم بيانات المنطقة الزمنية القديمة ، من قبل أن تغير الولايات المتحدة انتقالات DST. حاول استخدام 28 مارس ، وهو عندما أعتقد ذلك سيكون على خلاف ذلك - ستجد على الأرجح أن الاختبارات تفشل بنفس الطريقة مع منطقة IBM ، ولكن ليس مع Sun One :) (لأن منطقة الشمس لن تعتبرها انتقالًا ديست.)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top