Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8077673

GregorianCalendar: Julian dates before 1899-12-21 are wrong

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: P4 P4
    • None
    • 8u40
    • core-libs

      FULL PRODUCT VERSION :
      java version "1.8.0_40"
      Java(TM) SE Runtime Environment (build 1.8.0_40-b26)
      Java HotSpot(TM) 64-Bit Server VM (build 25.40-b25, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows [Version 6.3.9600]

      A DESCRIPTION OF THE PROBLEM :
      As the Javadoc says: "GregorianCalendar is a hybrid calendar that supports both the Julian and Gregorian calendar systems"

      So I wrote a method to convert dates from the Julian calendar system to the Gregorian calendar system by using GregorianCalendar. This method works correctly for all dates, starting from 1899-12-21. However, dates before 1899-12-21 are off by one day.


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Run the test case. In the actual result, you can see that there is a gap: there is no date in the Julian calendar system that maps to 1900-01-01. This causes all dates before the Julian date 1899-12-21 to be off by one day. Another illustration of this, is the fact that 0200-03-01 is mapped to 0200-02-28, though it should be mapped to 0200-03-01.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      0200-03-01 maps to 0200-03-01
      1899-12-20 maps to 1900-01-01
      1899-12-21 maps to 1900-01-02
      ACTUAL -
      0200-03-01 maps to 0200-02-28
      1899-12-20 maps to 1899-12-31
      1899-12-21 maps to 1900-01-02

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------

      import java.time.LocalDate;
      import java.time.Month;
      import java.util.Calendar;
      import java.util.Date;
      import java.util.GregorianCalendar;

      public class JulianBug {

      public static void main(String[] args) {
      System.out.println(ofJulian(200, Month.MARCH, 1) + " must be 0200-03-01");
      System.out.println(ofJulian(1899, Month.DECEMBER, 20) + " must be 1900-01-01");
      System.out.println(ofJulian(1899, Month.DECEMBER, 21) + " must be 1900-01-02");
      }

      public static LocalDate ofJulian(int year, Month month, int dayOfMonth) {
      GregorianCalendar julianCalendar = new GregorianCalendar();
      julianCalendar.setGregorianChange(new Date(Long.MAX_VALUE));
      julianCalendar.clear();
      julianCalendar.set(Calendar.ERA, GregorianCalendar.AD);
      julianCalendar.set(year, month.getValue() - 1, dayOfMonth);
      return julianCalendar.toZonedDateTime().toLocalDate();
      }

      }

      ---------- END SOURCE ----------

            okutsu Masayoshi Okutsu
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: