比较时间偏移使用两个Date对象

时间:2017-04-13 21:02:33

标签: java date time

我有两个日期对象,Date1和Date2。 Date1有一个时间,Date2有一个时间,与UTC的偏移量(仅在时间内,而不是实际日期本身):

Date1: Thu Apr 13 20:41:46 CDT 2017

Date2: Thu Apr 13 15:41:46 CDT 2017

我想提取这两个日期,提取时间,比较它们,然后确保它们与我的系统时间和UTC正确偏移(此比较还需要考虑夏令时)。

请注意,我无法使用java.time作为输入。我理解它会更容易但是使用我们的配置我使用java.util.Date作为输入日期< /强>)

这是我生成这些日期值的代码,我只需要一种方法来验证两者之间的差异实际上是正确的偏移量(没有硬编码偏移量并且必须在每次夏令时更改时更改它):< / p>

public static final String TIMESTAMP_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS";
public static final int MILLI_TO_HOUR = 1000 * 60 * 60;

public static void main(String args[]) throws java.text.ParseException {
    Date date1 = nowInUTC();
    Date date2 = Date.from(Instant.now());
    System.out.println("date1: " + date1);
    System.out.println("date2: " + date2);

     /* Needs to be modified to contain the logic
      * I need to verify that the time given in date2 is the offset from date1
      * in respect to its timezone. You can ignore the CDT in date1*/
    if(true){
        System.out.println("You have the correct offset!");
    }
    else
    {
        System.out.println("you do not have the correct offset!");
    }
}

private static long toHours(long millis){
    return millis / MILLI_TO_HOUR;
}

private static Date nowInUTC() {
    try {
        Date date = new Date(new SimpleDateFormat(TIMESTAMP_FORMAT).parse(
                nowInUTCAsString()).getTime());
        return date;
    }
    catch(ParseException pe){
        pe.printStackTrace();
        return null;
    }
}

private static String nowInUTCAsString() {
    SimpleDateFormat sdf = new SimpleDateFormat(TIMESTAMP_FORMAT);
    sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
    return sdf.format(new Date());
}

1 个答案:

答案 0 :(得分:1)

感谢您的评论澄清您的有趣挑战。我知道您确实需要提前5小时制作一个日期,以补偿数据库占用CDT时间并将其理解为UTC。实际偏移量取决于计算机的时区设置。我假设您的数据库在本地运行,或者至少保证与JVM具有相同的时区设置 - 您应该检查这个假设。

您的代码在生成两个日期时基本上是正确的,这两个日期的差异等于您的计算机与UTC的偏移量,因此您不应该真正需要验证该事实。我将在下面的陈述中添加一两个细微差别。

首先,您如何验证?听从你想要的话。这是我的建议:

    LocalDateTime date1AsLdt = date1.toInstant()
            .atZone(ZoneId.systemDefault())
            .toLocalDateTime();
    LocalDateTime utc = OffsetDateTime.now(ZoneOffset.UTC).toLocalDateTime();
    if (date1AsLdt.isEqual(utc)){
        System.out.println("You have the correct offset!");
    }
    else
    {
        System.out.println("you do not have the correct offset!");
    }

即使我声称这是一种正确的检查方式,正如您生成date1的方式一样正确,但在我的旧计算机上打印you do not have the correct offset!这是因为两次相差最多为几百毫秒。这不是错误,代码中的不准确。它来自您的代码读取系统时钟两次,并且根据两次读数之间的时间流逝,它们可能会也可能不会达成一致。您先创建new Date(),然后再按Instant.now()再次阅读时钟。我建议您只读一次时钟,并在两个日期使用相同的读数。

由于您在代码中使用了java.time.Instant,因此我假设您可以在内部使用java.time,只要您最终生成java.util.Date。我上面代码中的LocalDateTime也位于java.time

如果没问题,在你的代码中就不需要转换为字符串和返回的复杂性。我建议:

private static Date nowInUTC() {
    LocalDateTime utc = OffsetDateTime.now(ZoneOffset.UTC).toLocalDateTime();
    return Date.from(utc.atZone(ZoneId.systemDefault()).toInstant());
}

正如我所说,上面有很多假设。如果我在某处错了,请回复,我很乐意再看看。

最后的警告。每个秋天,从DST到标准时间的变化都有几个小时,时钟时间不明确。即使您的程序正确生成UTC时间(从不模糊的UTC),您的数据库也需要选择传递给它的时间的解释,我看不出它能找到正确的方法。< / p>