我正面临与GregorianCalendar相关的问题。
Prerequisit: 系统timeZone是:“亚洲/新加坡” 系统时间是:2014年1月30日
执行代码:
Calendar cal = new GregorianCalendar();
TimeZone tz = TimeZone.getTimeZone("Asia/Singapore");
cal.setTimeZone(tz);
cal.set(Calendar.MONTH, 1);//1 is equivalent to Feb
cal.get(Calendar.YEAR);
cal.set(Calendar.YEAR, 2014);
cal.get(Calendar.DAY_OF_MONTH);
cal.set(Calendar.DAY_OF_MONTH, 5);
Date dte=cal.getTime();
实际结果: 2014年3月5日
预期成果: 2014年2月5日
但是如果我按顺序改变执行相同的代码,则会产生正确的值:
Calendar cal = new GregorianCalendar();
TimeZone tz = TimeZone.getTimeZone("Asia/Singapore");
cal.setTimeZone(tz);
cal.get(Calendar.DAY_OF_MONTH);
cal.set(Calendar.DAY_OF_MONTH, 5);
cal.set(Calendar.MONTH, 1);//1 is equivalent to Feb
cal.get(Calendar.YEAR);
cal.set(Calendar.YEAR, 2014);
它给出了正确的结果
有人可以帮助我知道这个的根本原因吗?
答案 0 :(得分:1)
在1月30日运行代码时,这将是您日历的初始状态。然后cal.set(Calendar.MONTH, 1);
将日历设置为2月30日。
致电cal.get(DAY_OF_MONTH)
时,将重新计算日历的内部状态以获得正确的日期。因此cal.isLenient()
为真,所以2月30日将被转换为3月2日。
然后将日期设置为30将导致3月30日。
尝试在创建日历后添加cal.setLenient(false)
,然后查看代码的第一个版本是如何失败的......
要修复代码,请在日历处于中间状态时删除get cal.get()
- 语句,以避免过早重新计算。
编辑:添加了关于cal.get()