无法创建代表2019年12月29日的Date对象

时间:2019-12-17 16:03:44

标签: java.util.date java.util.calendar

我希望这不是JDK的错误,或者我很想兑现我所有的银行帐户并将其放入床垫中... 这是代码。请注意,将日期设置为12月29日会立即将年份推迟到2020年。此外,toString()输出还显示Calendar似乎认为星期数是“ 1”。

import java.util.*; // headers MUST be above the first class
import java.text.*;

public class JDKCalendarBug {

    public static void main(String[] args) {
        SimpleDateFormat sdf = new SimpleDateFormat("MM-dd-YYYY kk:mm");
        Calendar cal = java.util.Calendar.getInstance(TimeZone
                .getTimeZone("EST"));
        cal.clear();
        cal.set(Calendar.YEAR, 2019);
        cal.set(Calendar.MONTH, Calendar.DECEMBER);

        cal.set(Calendar.DAY_OF_MONTH, 26);
        Date t = cal.getTime();
        System.out.print("\n"+sdf.format(t));
        System.out.print("\n"+cal.toString());

        cal.set(Calendar.DAY_OF_MONTH, 27);
        t = cal.getTime();
        System.out.print("\n"+sdf.format(t));
        System.out.print("\n"+cal.toString());

        cal.set(Calendar.DAY_OF_MONTH, 28);
        t = cal.getTime();
        System.out.print("\n"+sdf.format(t));
        System.out.print("\n"+cal.toString());

        cal.set(Calendar.DAY_OF_MONTH, 29);
        t = cal.getTime();
        System.out.print("\n"+sdf.format(t));
        System.out.print("\n"+cal.toString());

    }

}

输出:

  

12-26-2019 24:00   java.util.GregorianCalendar [time = 1577336400000,areFieldsSet = true,areAllFieldsSet = false,lenient = true,zone = sun.util.calendar.ZoneInfo [id =“ EST”,offset = -18000000,dstSavings = 0,useDaylight = false ,transitions = 0,lastRule = null],firstDayOfWeek = 1,minimalDaysInFirstWeek = 1,ERA = ?, YEAR = 2019,MONTH = 11,WEEK_OF_YEAR = ?, WEEK_OF_MONTH = ?, DAY_OF_MONTH = 26,DAY_OF_YEAR = ?, DAY_OF_WEEK = ?, DAY_OF_WEEK_IN_MONTH = ?, AM_PM = ?, HOUR = ?, HOUR_OF_DAY = ?, MINUTE = ?, SECOND = ?, MILLISECOND = ?, ZONE_OFFSET = ?, DST_OFFSET =?]

     

12-27-2019 24:00   java.util.GregorianCalendar [time = 1577422800000,areFieldsSet = true,areAllFieldsSet = false,lenient = true,zone = sun.util.calendar.ZoneInfo [id =“ EST”,offset = -18000000,dstSavings = 0,useDaylight = false ,transitions = 0,lastRule = null],firstDayOfWeek = 1,minimalDaysInFirstWeek = 1,ERA = 1,YEAR = 2019,MONTH = 11,WEEK_OF_YEAR = 52,WEEK_OF_MONTH = 4,DAY_OF_MONTH = 27,DAY_OF_YEAR = 361,DAY_OF_WEEK = 6, DAY_OF_WEEK_IN_MONTH = 4,AM_PM = 0,HOUR = 0,HOUR_OF_DAY = 0,MINUTE = 0,SECOND = 0,MILLISECOND = 0,ZONE_OFFSET = -18000000,DST_OFFSET = 0] 12-28-2019 24:00   java.util.GregorianCalendar [time = 1577509200000,areFieldsSet = true,areAllFieldsSet = false,lenient = true,zone = sun.util.calendar.ZoneInfo [id =“ EST”,offset = -18000000,dstSavings = 0,useDaylight = false ,transitions = 0,lastRule = null],firstDayOfWeek = 1,minimumDaysInFirstWeek = 1,ERA = 1,YEAR = 2019,MONTH = 11,WEEK_OF_YEAR = 52,WEEK_OF_MONTH = 4,DAY_OF_MONTH = 28,DAY_OF_YEAR = 362,DAY_OF_WEEK = 7, DAY_OF_WEEK_IN_MONTH = 4,AM_PM = 0,HOUR = 0,HOUR_OF_DAY = 0,MINUTE = 0,SECOND = 0,MILLISECOND = 0,ZONE_OFFSET = -18000000,DST_OFFSET = 0]

     

12-29-2020 24:00   java.util.GregorianCalendar [time = 1577595600000,areFieldsSet = true,areAllFieldsSet = false,lenient = true,zone = sun.util.calendar.ZoneInfo [id =“ EST”,offset = -18000000,dstSavings = 0,useDaylight = false ,transitions = 0,lastRule = null],firstDayOfWeek = 1,minimalDaysInFirstWeek = 1,ERA = 1,YEAR = 2019,MONTH = 11,WEEK_OF_YEAR = 1,WEEK_OF_MONTH = 5,DAY_OF_MONTH = 29,DAY_OF_YEAR = 363,DAY_OF_WEEK = 1, DAY_OF_WEEK_IN_MONTH = 5,AM_PM = 0,HOUR = 0,HOUR_OF_DAY = 0,MINUTE = 0,SECOND = 0,MILLISECOND = 0,ZONE_OFFSET = -18000000,DST_OFFSET = 0]

1 个答案:

答案 0 :(得分:0)

问题出在SimpleDateFormat上。如果将格式字符串更改为小写y,则日期格式正确为12-29-2019 24:00

new SimpleDateFormat("MM-dd-yyyy kk:mm")

Y对应于“周年”,与“年”不同,并非所有日历都支持。根据{{​​3}}:

  

如果指定周年“ Y”且日历不支持   周年,则改用日历年('y')。的支持   可以通过致电来测试周年   getCalendar()。isWeekDateSupported()。

在这种情况下,由于基本的Calendar实现是GregorianCalendar,因此支持“星期”。根据其JavaDocs

  

一周的一年与WEEK_OF_YEAR周期保持同步。之间的所有星期   前一周和后一周(含)具有相同的周年值。   因此,一周的第一天和最后一天可能会有所不同   日历年的值。