Java中的Date.getTime()在不同的服务器

时间:2017-11-16 05:48:44

标签: java timezone simpledateformat milliseconds java.util.date

我需要计算一个基于日期的值。所以我首先使用日期格式类解析日期,然后我使用getTime()来获取毫秒。用那几毫秒我会算出一些价值。但是getTime()在不同的服务器中返回不同的值。我们在印度开发,在那里我得到了正确的价值但在美国服务器上我的价值不同。

情景:

public class Test {

    public static void main(String[] args) throws ParseException {

        SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");

        String now = "11/03/2018";

        Date UsualDateformat = sdf.parse(now);

        System.out.println(UsualDateformat.getTime());
    }
}

上面是示例代码,但我的实际代码是drl文件中的规则(drools)。 该程序返回 我转换为日期的“1541183400000”是“星期六3月2018 00:00:00”。, 但在美国服务器我得到“1541217600000”等于日期“星期六3月2018年09:30 09:30”。 因此,当我使用此值时,我会得到边缘小数点格式问题。 如何解决这个问题?

提前致谢!

4 个答案:

答案 0 :(得分:3)

您需要将SimpleDateFormat上的时区设置为在不同区域的服务器之间保持一致。例如:

public class Test {

    public static void main(String[] args) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
        sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
        ....
    }

}

答案 1 :(得分:2)

您可以获得这些不同的值,因为您在美国的服务器与印度的服务器之间的时差为9小时30分。

这与浮点无关,但与时区无关。

解决此问题的一种方法是始终在同一时区内工作(例如印度)

答案 2 :(得分:2)

此代码段可能适合您,

public static String getGmtTime(String timezone) {
    return ZonedDateTime
            .now()
            .withZoneSameInstant(ZoneId.of(timezone))
            .toLocalDateTime()
            .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
}

timezone传递给America/Los_Angeles以获得适当时区的时间, 可以找到时区here

答案 3 :(得分:1)

java.time

我建议您使用java.time,也称为JSR-310。您使用的课​​程DateSimpleDateFormat已经过时,特别是SimpleDateFormat因产生令人惊讶的结果而闻名,人们可能会说这种情况也会发生在您的案例中。现代API通常可以更好地使用。

正如我认为您已经怀疑的那样,您的问题来自于您的服务器运行不同时区的事实,并且自纪元以来将日期转换为millis是时区相关操作,因为纪元总是相同的时间点(1970年1月1日午夜 UTC )。作为mweiss我使用UTC进行转换,以确保无论服务器的时区如何都能得到相同的结果:

    DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MM/dd/yyyy");
    String now = "11/03/2018";
    LocalDate date = LocalDate.parse(now, dtf);
    long millisInUtc = date.atStartOfDay(ZoneOffset.UTC)
            .toInstant()
            .toEpochMilli();
    System.out.println(millisInUtc);

正如我的代码所示,它会打印

1541203200000

这是您在印度和美国获得的值之间的比较,因为UTC介于这两个时区之间。如果您认为使用例如亚洲/加尔各答时间更正确,只需在代码中替换ZoneId.of("Asia/Kolkata")而不是ZoneOffset.UTC,您应该获得与运行代码时相同的输出你在印度的服务器(请记得重命名变量)。

我的代码比你的有点长。在这种情况下,我认为这是一个优势。确实是的。使用java.time的代码明确表示我们正在使用当天开始的时间(午夜0:00)并且我们正在使用时区或偏移进行转换。这迫使您作为编码人员考虑这些问题,并且您不太可能编写产生跨时区意外差异的结果的代码,也就是说,您的问题永远不会出现。同时,它向读者明确说明操作取决于时区,并且您已经有意识地选择使用哪个区域。这些优点是以及值得多一些代码行。