奇怪的Java日历不一致

时间:2018-05-31 09:31:13

标签: java calendar

为什么会出现这种不一致的情况?

public static void main(String[] args) {
    final Calendar calendar = Calendar.getInstance();

    calendar.set(Calendar.MONTH, 1);
    System.out.println("KO current month: " + calendar.get(Calendar.MONTH));

    calendar.set(Calendar.MONTH, 1);
    System.out.println("OK current month: " + calendar.get(Calendar.MONTH));
}

输出:

KO current month: 2
OK current month: 1

2 个答案:

答案 0 :(得分:11)

今天是5月31日。 Calendar对象默认为lenient,因此在第一个set()日期切换到2月31日之后不存在。 Calendar通过搬到3月3日来宽大地修复它。月2表示三月。

第二个set()操作适用于3月3日,因此可以按照预期切换到2月3日。月1表示二月。

您可以通过格式化完整日期来看到这一点:

SimpleDateFormat sdf = new SimpleDateFormat();
Calendar calendar = Calendar.getInstance();

calendar.set(Calendar.MONTH, 1);
System.out.println(sdf.format(calendar.getTime()));

calendar.set(Calendar.MONTH, 1);
System.out.println(sdf.format(calendar.getTime()));

返回

03/03/18 10:40
03/02/18 10:40

如果您想阻止您需要调用setLenient()方法

的行为
Calendar calendar = Calendar.getInstance();
calendar.setLenient(false);
calendar.set(Calendar.MONTH, 1);

将导致以下IllegalArgumentException例外:

  

线程“main”中的异常java.lang.IllegalArgumentException:MONTH:1 - > 2       at java.util.GregorianCalendar.computeTime(GregorianCalendar.java:2829)       at java.util.Calendar.updateTime(Calendar.java:3393)       ...

答案 1 :(得分:3)

Karol Dowbecki’s answer是正确的并且得到了很好的解释(我应该说得很好)。我想提供良好和现代的解决方案。

FEBRUARY
2018-02-28

输出:

Calendar

LocalDate类令人困惑且设计不佳,因此我使用java.time中的LocalDate,即现代Java日期和时间API。这个API非常适合使用。幸运的是, LocalDate date = LocalDate.now(ZoneId.of("Europe/Paris"))` 不会在2月31日给你,因为这个日期不存在。它为您提供了2月的最后一天,也就是您预期的月份。

PS以下初始化将模仿您的代码:

java.time

但是,我倾向于提供一些代码,这些代码也可以证明某人在将来的某一天尝试运行该代码。

链接: Oracle tutorial: Date Time解释如何使用@Component public class BulkActionRoutes extends RouteBuilder { @Override public void configure() throws Exception { CsvDataFormat csv = new CsvDataFormat(","); csv.setUseMaps(true); ArrayList<String> list = new ArrayList<String>(); list.add("DeviceName"); list.add("Brand"); list.add("status"); list.add("type"); list.add("features_c"); list.add("battery_c"); list.add("colors"); csv.setHeader(list); from("direct:bulkImport") .convertBodyTo(String.class) .unmarshal(csv) .split(body()).streaming() .process(new Processor() { @Override public void process(Exchange exchange) throws Exception { GenericObjectModel model = null; HashMap<String, String> csvRecord = (HashMap<String, String>)exchange.getIn().getBody(); } }); } }