Why does a new SimpleDateFormat object contain calendar with the wrong year?

后端 未结 5 545
暖寄归人
暖寄归人 2020-12-20 15:54

I came upon a strange behavior that has left me curious and without a satisfactory explanation as yet.

For simplicity, I\'ve reduced the symptoms I\'ve noticed to th

5条回答
  •  囚心锁ツ
    2020-12-20 16:09

    I'm not sure why Tom says "it's something to do with serialization", but he has the right line:

    private void initializeDefaultCentury() {
        calendar.setTime( new Date() );
        calendar.add( Calendar.YEAR, -80 );
        parseAmbiguousDatesAsAfter(calendar.getTime());
    }
    

    It's line 813 in SimpleDateFormat.java, which is very late in the process. Up to that point, the year is correct (as is the rest of the date part), then it's decremented by 80.

    Aha!

    The call to parseAmbiguousDatesAsAfter() is the same private function that set2DigitYearStart() calls:

    /* Define one-century window into which to disambiguate dates using
     * two-digit years.
     */
    private void parseAmbiguousDatesAsAfter(Date startDate) {
        defaultCenturyStart = startDate;
        calendar.setTime(startDate);
        defaultCenturyStartYear = calendar.get(Calendar.YEAR);
    }
    
    /**
     * Sets the 100-year period 2-digit years will be interpreted as being in
     * to begin on the date the user specifies.
     *
     * @param startDate During parsing, two digit years will be placed in the range
     * startDate to startDate + 100 years.
     * @see #get2DigitYearStart
     * @since 1.2
     */
    public void set2DigitYearStart(Date startDate) {
        parseAmbiguousDatesAsAfter(startDate);
    }
    

    Now I see what's going on. Peter, in his comment about "apples and oranges", was right! The year in SimpleDateFormat is the first year of the "default century", the range into which a two-digit year string (e.g, "1/12/14") is interpreted to be. See http://java.sun.com/j2se/1.4.2/docs/api/java/text/SimpleDateFormat.html#get2DigitYearStart%28%29 :

    So in a triumph of "efficiency" over clarity, the year in the SimpleDateFormat is used to store "the start of the 100-year period into which two digit years are parsed", not the current year!

    Thanks, this was fun -- and finally got me to install the jdk source (I only have 4GB total space on my / partition.)

提交回复
热议问题