如何使用时区作为输入在Java中获取没有服务器时间的正确日期和时间

时间:2018-11-07 18:32:26

标签: java timezone

我的应用托管在伦敦服务器中。我在美国Minasota。所以时区是不同的小时。

如何获取带有时区的当前日期/时间。棘手的部分是我不想基于服务器日期和时间获取当前日期和时间。有没有一种方法可以根据时区获取实际的当前日期和时间。

以下代码返回信息,但如果服务器日期无效,则响应也将为无效日期。但是我想要真实的当前日期和时间。  我的输入将是时区。任何帮助表示赞赏。

    Date date = new Date();
    DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

 // Use Minasota's time zone to format the date in
    df.setTimeZone(TimeZone.getTimeZone("America/Minasota"));
    System.out.println("Date and time in Minasota: " + df.format(date));

2 个答案:

答案 0 :(得分:2)

重要的是要知道在Java 8中不赞成使用三个字母的时区缩写。因此,不要指望它们永远得到支持。这是使用Java 8 time api实现此目的的两个等效示例:

System.out.println(Instant.now().atZone(ZoneId.of("CST",ZoneId.SHORT_IDS)));
System.out.println(Instant.now().atZone(ZoneId.of("America/Chicago")));

此问题可能是this

的重复项

答案 1 :(得分:1)

tl; dr

  

有没有一种方法可以根据时区获取实际的当前日期和时间。

是的。使用现代的 java.time 而不是可怕的旧类。

ZonedDateTime.now(                    // Represent a moment as seen through the wall-clock time used by the people of a particular region (a time zone). 
    ZoneId.of( "America/Chicago" )    // Specify time zone by proper `Continent/Region` name, *never* 2-4 letter pseudo-zones such as “CST”. 
)                                     // Returns a `ZonedDateTime` object.
.toString()                           // Generate text in standard ISO 8601 format wisely extended to append the name of the time zone in square brackets. 
  

2018-11-07T14:38:24.723394-06:00 [美国/芝加哥]

详细信息

  

我的应用托管在伦敦服务器中。我在美国Minasota。

这应该与您的应用无关。

  • 服务器应默认为UTC时区(通常)。
  • 应要求客户确认其期望/预期时区(关键时)。
  • 始终通过传递可选参数来明确指定所需/期望的时区,而不是隐式依赖JVM当前的默认时间,该时间可以在 runtime(!)期间随时更改。
  

如何获取带有时区的当前日期/时间。

首先,您的大多数业务逻辑,存储和日期时间值的交换都应在UTC中完成。

Instant instant = Instant.now() ;  // Current moment in UTC.

您可以通过特定区域的人(一个时区)的墙上时钟看到同一时刻。

time zone for MinnesotaAmerica/Chicago

continent/region的格式指定proper time zone name,例如America/MontrealAfrica/CasablancaPacific/Auckland。切勿使用2-4个字母的缩写,例如CSTESTIST,因为它们不是真正的时区,不是标准化的,甚至不是唯一的( !)。

ZoneId z = ZoneId.of( "America/Chicago" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;

作为快捷方式,您可以跳过Instant

ZonedDateTime zdt = ZonedDateTime.now( z ) ;
  

但是我想要真实的当前日期和时间

➥这是掌握日期和时间工作的核心概念Instant(UTC)和ZonedDateTime(某些时区) >代表同一时刻。这两个对象表示时间轴上的同一点。它们都是“真正的日期和时间”。他们使用两个不同的挂钟时间来显示同一时刻。

如果冰岛的一个人和明尼阿波利斯的一个人通电话,并且他们俩都在墙上抬起各自的时钟和日历,大声说出了当前的日期和时间,那么哪个是正确的?两者都是正确的,有两种表达同一瞬间的方式。

实际上,您最好将UTC视为一个真实时间™,而所有分区时间都只是变化而已。专注于您自己的狭区时区,然后来回转换,将使您精疲力尽。专注于UTC,仅在用户期望或业务逻辑需要时才调整时区。

在Stack Overflow上已经对此进行了很多讨论。因此,搜索更多信息和示例。并学会在发布前搜索Stack Overflow。

要生成字符串,请为标准ISO 8601格式的文本调用toString,或使用DateTimeFormatter.ofLocalized…自动进行本地化,或使用DateTimeFormatter.ofPattern指定自定义格式。堆栈溢出已对此进行了多次讨论,因此请搜索更多信息。


关于 java.time

java.time框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendarSimpleDateFormat

目前位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解更多信息,请参见Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310

您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*类。

在哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore