我正在解决将GregorianCalendar转换为java.util.Date对象的问题,该GregorianCalendar仅代表当前日期(即,// 2013-03-10 00:00:00)。该测试背后的想法是获取两个日期-一个仅包含当前日期的日期,以及一个仅包含当前时间的日期(即1970-01-01 12:30:45),并将它们合并为一个表示日期的日期和时间(2013-03-10 12:30:45)。

在DST切换发生的那天,测试失败-因为将GregorianCalendar转换为日期对象(Date date = dateCal.getTime();在下面的代码中)损失了一个小时,因此回滚到(2013-03-09 23:00:00)。我该如何避免这种情况发生?

public static Date addTimeToDate(Date date, Date time) {
    if (date == null) {
        throw new IllegalArgumentException("date cannot be null");
    } else if (time == null) {
        throw new IllegalArgumentException("time cannot be null");
    } else {
        Calendar timeCal = GregorianCalendar.getInstance();
        timeCal.setTime(time);

        long timeMs = timeCal.getTimeInMillis() + timeCal.get(Calendar.ZONE_OFFSET) + timeCal.get(Calendar.DST_OFFSET);
        return addMillisecondsToDate(date, timeMs);
    }
}


@Test
public void testAddTimeToDate() {
    Calendar expectedCal = Calendar.getInstance();
    Calendar dateCal = Calendar.getInstance();
    dateCal.clear();
    dateCal.set(expectedCal.get(Calendar.YEAR), expectedCal.get(Calendar.MONTH), expectedCal.get(Calendar.DAY_OF_MONTH));

    Calendar timeCal = Calendar.getInstance();
    timeCal.clear();
    timeCal.set(Calendar.HOUR_OF_DAY, expectedCal.get(Calendar.HOUR_OF_DAY));
    timeCal.set(Calendar.MINUTE, expectedCal.get(Calendar.MINUTE));
    timeCal.set(Calendar.SECOND, expectedCal.get(Calendar.SECOND));
    timeCal.set(Calendar.MILLISECOND, expectedCal.get(Calendar.MILLISECOND));

    Date expectedDate = expectedCal.getTime();
    Date date = dateCal.getTime();
    Date time = timeCal.getTime();

    Date actualDate = DateUtil.addTimeToDate(date, time);

    assertEquals(expectedDate, actualDate);
}

最佳答案

为什么在计算中包括时区偏移量?当您在Java中使用毫秒时,它们始终以UTC为单位。您无需进行任何其他转换。

您最大的问题可能是尝试手动进行这些日期/时间计算。您应该使用Calendar类本身来处理计算。

10-07 19:18
查看更多