1

I have a GregorianCalendar that I am am trying to set the time on. I am getting the date from one calendar and the time from another calendar. It mostly works, except for the 2AM hour of the DST switch day.

For example, with a date of 3/10/2013, a time of 2:40AM and a target output of 3/10/2013 2:40AM, I get 3/10/2013 3:40AM:

GregorianCalendar reportingDate = //some instance with a relevant date (in this case 3/10/2013)
GregorianCalendar targetTime = //some instance with a relevant time (in this case 2:40AM)
Calendar combination = Calendar.getInstance();
combination.set(Calendar.YEAR, reportingDate.get(Calendar.YEAR));
combination.set(Calendar.MONTH, reportingDate.get(Calendar.MONTH));
combination.set(Calendar.DAY_OF_YEAR, reportingDate.get(Calendar.DAY_OF_YEAR));
combination.set(Calendar.HOUR, targetTime.get(Calendar.HOUR));
combination.set(Calendar.AM_PM, targetTime.get(Calendar.AM_PM));
combination.set(Calendar.MINUTE, targetTime.get(Calendar.MINUTE));
combination.set(Calendar.SECOND, targetTime.get(Calendar.SECOND));

As soon as the code sets the AM_PM on the combination Calendar the time switches to 3:40AM. I would like it to not switch. I think this has to do with the target time Calendar being created as a time on the epoch date, but I would like the target time's specific date to not really matter...

4

3 回答 3

1

基于此输出...我认为这就是 Java 处理 DST 的方式?似乎凌晨 2-3 点会被遗忘

看我下面的评论

final Calendar reportingDate = Calendar.getInstance();
reportingDate.set(Calendar.YEAR, 2013);
reportingDate.set(Calendar.MONTH, Calendar.MARCH);
reportingDate.set(Calendar.DAY_OF_MONTH, 10);

final Calendar targetTime = Calendar.getInstance();
targetTime.set(Calendar.AM_PM, Calendar.AM);
targetTime.set(Calendar.HOUR_OF_DAY, 3);
targetTime.set(Calendar.MINUTE, 0);
targetTime.set(Calendar.SECOND, 0);
targetTime.set(Calendar.MILLISECOND, 0);

final Calendar combination = Calendar.getInstance();
combination.set(Calendar.YEAR, reportingDate.get(Calendar.YEAR));
combination.set(Calendar.MONTH, reportingDate.get(Calendar.MONTH));
combination.set(Calendar.DAY_OF_YEAR, reportingDate.get(Calendar.DAY_OF_YEAR));
combination.set(Calendar.HOUR, targetTime.get(Calendar.HOUR));
combination.set(Calendar.AM_PM, targetTime.get(Calendar.AM_PM));
combination.set(Calendar.MINUTE, targetTime.get(Calendar.MINUTE));
combination.set(Calendar.SECOND, targetTime.get(Calendar.SECOND));
combination.set(Calendar.MILLISECOND, targetTime.get(Calendar.MILLISECOND));

final long timeAtCombined = combination.getTimeInMillis();

final SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss.SSSZ");
sdf.setTimeZone(TimeZone.getTimeZone("US/Eastern"));

// subtract one minute
System.out.println(sdf.format(combination.getTime()));
combination.add(Calendar.MILLISECOND, -1);
System.out.println(sdf.format(combination.getTime()));

// millis @ 3
System.out.println(sdf.format(new Date(timeAtCombined)));
// millis @ 3 - 1ms
System.out.println(sdf.format(new Date(timeAtCombined - 1)));

输出

03/10/2013 03:00:00.000-0400
03/10/2013 01:59:59.999-0500
03/10/2013 03:00:00.000-0400
03/10/2013 01:59:59.999-0500
于 2013-05-18T00:27:02.367 回答
0

您正在设置所有内容,但时区(包含 DST)除外。也设置它,你应该没问题。

于 2013-05-17T23:53:55.290 回答
0

这并不是直接回答您的问题,但您可以通过使用Joda Time来避免所有这些疯狂

他们确实确定了日期/时间/日历。

于 2013-05-17T23:55:58.560 回答