Java中的Date.getTime()在不同的服务器中返回不同的时间

Java中的Date.getTime()在不同的服务器中返回不同的时间,java,timezone,simpledateformat,milliseconds,java.util.date,Java,Timezone,Simpledateformat,Milliseconds,Java.util.date,我需要计算一个基于日期的值。因此,我首先使用date format类解析日期,然后使用getTime()获取毫秒。用这些毫秒,我将计算一些值。但是getTime()在不同的服务器中返回不同的值。我们在印度开发,在那里我得到了正确的价值,但在美国我得到了不同的价值 情景: public class Test { public static void main(String[] args) throws ParseException { SimpleDateFormat

我需要计算一个基于日期的值。因此,我首先使用date format类解析日期,然后使用
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”为“2018年11月3日星期六00:00:00”。, 但在美国服务器上,我得到的“1541217600000”等于日期“2018年11月3日星期六09:30:00”。 所以当我使用这个值时,我会遇到小数点格式的问题。 如何解决这个问题


提前谢谢

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

这与浮点无关,而是与时区有关


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

您会得到这些不同的值,因为您在美国的服务器与在印度的服务器之间的时差为9h 30

这与浮点无关,而是与时区有关


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

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

public class Test {

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

}

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

public class Test {

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

}
java.time
我建议您为此使用
java.time
,也称为JSR-310。您使用的类,
Date
SimpleDateFormat
早已过时,
SimpleDateFormat
尤其以产生令人惊讶的结果而闻名,可以说在您的案例中也发生了这种情况。现代API通常更易于使用

正如我认为您已经怀疑的那样,您的问题来自这样一个事实,即您的服务器运行不同的时区,并且由于历元始终是同一时间点(1970年1月1日UTC午夜),因此将日期转换为毫秒是一种依赖于时区的操作。由于我正在使用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位于这两个时区之间。如果您认为使用亚洲/加尔各答时间更为正确,只要在代码中替换<代码> ZONID.[(亚洲/加尔各答)< /COD>而不是<代码> ZONOffOff.UTC/<代码>,您应该得到与您在印度服务器上运行代码时所获得的相同输出(请记住重命名变量)。 我的代码比你的长一点。在这种情况下,我认为这是一个优势。是的,的确如此。使用
java.time
的代码明确表示,我们使用的是一天开始时的时间(午夜0:00),我们使用的是时区或偏移量进行转换。这迫使作为编码者的您考虑这些问题,并且您将不太可能编写代码,从而产生跨时区的意外结果,也就是说,您的问题永远不会出现。同时,它明确地告诉读者操作取决于时区,并且您已经有意识地选择了使用哪个时区。这些优点值得再多写几行代码。

java.time
我建议您为此使用
java.time
,也称为JSR-310。您使用的类,
Date
SimpleDateFormat
早已过时,
SimpleDateFormat
尤其以产生令人惊讶的结果而闻名,可以说在您的案例中也发生了这种情况。现代API通常更易于使用

正如我认为您已经怀疑的那样,您的问题来自这样一个事实,即您的服务器运行不同的时区,并且由于历元始终是同一时间点(1970年1月1日UTC午夜),因此将日期转换为毫秒是一种依赖于时区的操作。由于我正在使用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位于这两个时区之间。如果您认为使用亚洲/加尔各答时间更为正确,只要在代码中替换<代码> ZONID.[(亚洲/加尔各答)< /COD>而不是<代码> ZONOffOff.UTC/<代码>,您应该得到与您在印度服务器上运行代码时所获得的相同输出(请记住重命名变量)。
我的代码比你的长一点。在这种情况下,我认为这是一个优势。是的,的确如此。使用
java.time
的代码明确表示,我们使用的是一天开始时的时间(午夜0:00),我们使用的是时区或偏移量进行转换。这迫使作为编码者的您考虑这些问题,并且您将不太可能编写代码,从而产生跨时区的意外结果,也就是说,您的问题永远不会出现。同时,它明确地告诉读者操作取决于时区,并且您已经有意识地选择了使用哪个时区。这些优点值得再多写几行代码。

此代码片段可能适合您

public static String getGmtTime(String timezone) {
    return ZonedDateTime
            .now()
            .withZoneSameInstant(ZoneId.of(timezone))
            .toLocalDateTime()
            .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
}
时区
作为
美国/洛杉矶
传递,以获得具有适当时区的时间,
时区可以找到

此代码片段可能适合您

public static String getGmtTime(String timezone) {
    return ZonedDateTime
            .now()
            .withZoneSameInstant(ZoneId.of(timezone))
            .toLocalDateTime()
            .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
}
通过
时区
作为
美国/洛杉矶
获取时间