Java:将时区添加到 DateTimeFormatter

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/49458878/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 10:21:58  来源:igfitidea点击:

Java: Adding TimeZone to DateTimeFormatter

javadatetime

提问by Herr.Roehrig

The LocalDateTime API gives the possibility to add the TimeZone Name by using the key "z" in the formatter. I get an exception adding this key and don't understand why. I'm looking for something like this example '11:59:22 PM GMT' and not '**... UMT+2**'.

LocalDateTime API 提供了通过在格式化程序中使用键“z”来添加时区名称的可能性。我在添加此密钥时遇到异常,但不明白为什么。我正在寻找类似这个例子的东西“ 11:59:22 PM GMT”而不是“ **... UMT+2**”。

My Code:

我的代码:

public class TimeZone
{
    public static void main(String[] args)
    {
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("hh:mm:ss a z");
        System.out.println(now.format(formatter));
    }
}

The Exception:

例外:

Exception in thread "main" java.time.DateTimeException: Unable to extract value: class java.time.LocalDateTime
at java.time.format.DateTimePrintContext.getValue(Unknown Source)
at java.time.format.DateTimeFormatterBuilder$ZoneTextPrinterParser.format(Unknown Source)
at java.time.format.DateTimeFormatterBuilder$CompositePrinterParser.format(Unknown Source)
at java.time.format.DateTimeFormatter.formatTo(Unknown Source)
at java.time.format.DateTimeFormatter.format(Unknown Source)
at java.time.LocalDateTime.format(Unknown Source)
at tz.TimeZone.main(TimeZone.java:12)

Here is the DateTimeFormatter API part:

这是 DateTimeFormatter API 部分:

All letters 'A' to 'Z' and 'a' to 'z' are reserved as pattern letters. The following pattern letters are defined: 
  Symbol  Meaning                     Presentation      Examples
  ------  -------                     ------------      -------
   G       era                         text              AD; Anno Domini; A
   u       year                        year              2004; 04
   y       year-of-era                 year              2004; 04
   D       day-of-year                 number            189
   M/L     month-of-year               number/text       7; 07; Jul; July; J
   d       day-of-month                number            10

   Q/q     quarter-of-year             number/text       3; 03; Q3; 3rd quarter
   Y       week-based-year             year              1996; 96
   w       week-of-week-based-year     number            27
   W       week-of-month               number            4
   E       day-of-week                 text              Tue; Tuesday; T
   e/c     localized day-of-week       number/text       2; 02; Tue; Tuesday; T
   F       week-of-month               number            3

   a       am-pm-of-day                text              PM
   h       clock-hour-of-am-pm (1-12)  number            12
   K       hour-of-am-pm (0-11)        number            0
   k       clock-hour-of-am-pm (1-24)  number            0

   H       hour-of-day (0-23)          number            0
   m       minute-of-hour              number            30
   s       second-of-minute            number            55
   S       fraction-of-second          fraction          978
   A       milli-of-day                number            1234
   n       nano-of-second              number            987654321
   N       nano-of-day                 number            1234000000

   V       time-zone ID                zone-id           America/Los_Angeles; Z; -08:30
   z       time-zone name              zone-name         Pacific Standard Time; PST
   O       localized zone-offset       offset-O          GMT+8; GMT+08:00; UTC-08:00;
   X       zone-offset 'Z' for zero    offset-X          Z; -08; -0830; -08:30; -083015; -08:30:15;
   x       zone-offset                 offset-x          +0000; -08; -0830; -08:30; -083015; -08:30:15;
   Z       zone-offset                 offset-Z          +0000; -0800; -08:00;

Can anyone see what the problem is?

任何人都可以看到问题是什么?

回答by Andreas

LocalDateTimehas two fields of type LocalDateand LocalTime.
LocalDatehas fields day, month, and year.
LocalTimehas fields hour, minute, second, and nano.

LocalDateTime有两个类型为LocalDate和 的字段LocalTime
LocalDate有田daymonthyear
LocalTime有田hourminutesecond,和nano

Nowhere in that is a time zone given. Which is by nature, since the javadoc of LocalDateTimesays:

没有任何地方给出时区。这是本质上的,因为 javadocLocalDateTime说:

A date-time without a time-zone

没有时区的日期时间

So, if the "local" date/time value is already representing a time in UTC, and you want it formatted saying so, you have multiple options:

因此,如果“本地”日期/时间值已经表示 UTC 时间,并且您希望它的格式如此设置,则您有多种选择:

  • Change the LocalDateTimeto a ZonedDateTimeby calling atZone():

    System.out.println(time.atZone(ZoneOffset.UTC)
                           .format(DateTimeFormatter.ofPattern("hh:mm:ss a z")));
    
  • Specify an override time zone in the formatter by calling withZone():

    System.out.println(time.format(DateTimeFormatter.ofPattern("hh:mm:ss a z")
                                                    .withZone(ZoneOffset.UTC)));
    
  • Format with a literal Zcharacter:

    System.out.println(time.format(DateTimeFormatter.ofPattern("hh:mm:ss a 'Z'")));
    
  • 通过调用将更改LocalDateTime为 a :ZonedDateTimeatZone()

    System.out.println(time.atZone(ZoneOffset.UTC)
                           .format(DateTimeFormatter.ofPattern("hh:mm:ss a z")));
    
  • 通过调用在格式化程序中指定覆盖时区withZone()

    System.out.println(time.format(DateTimeFormatter.ofPattern("hh:mm:ss a z")
                                                    .withZone(ZoneOffset.UTC)));
    
  • 带有文字Z字符的格式:

    System.out.println(time.format(DateTimeFormatter.ofPattern("hh:mm:ss a 'Z'")));
    

All three of the above outputs:

以上三个输出:

11:59:22 PM Z

11:59:22 PM Z



Now, if the "local" date/time is really in a different time zone, you can use either of the first two, and just specify the actual zone.

现在,如果“本地”日期/时间确实在不同的时区,您可以使用前两个中的任何一个,只需指定实际时区。

E.g. if time zone is -04:00, use ZoneOffset.ofHours(-4), and you'll get:

例如,如果时区是-04:00,使用ZoneOffset.ofHours(-4),你会得到:

11:59:22 PM -04:00

11:59:22 PM -04:00

Or if you are in New York, use ZoneId.of("America/New_York"), and you'll get:

或者,如果您在纽约,请使用ZoneId.of("America/New_York"),您将获得:

11:59:22 PM EDT

11:59:22 PM EDT

If the "local" date/time is for New York, but you want formatted text to be UTC, use both at the same time, i.e.

如果“本地”日期/时间适用于纽约,但您希望格式化文本为 UTC,请同时使用两者,即

System.out.println(time.atZone(ZoneId.of("America/New_York"))
                       .format(DateTimeFormatter.ofPattern("hh:mm:ss a z")
                                                .withZone(ZoneOffset.UTC)));

With that, you get the time converted to:

这样,您将时间转换为:

03:59:22 AM Z

03:59:22 AM Z

回答by Jacob G.

The LocalDateTimeclass does not support time zones; you can use ZonedDateTimeinstead.

LocalDateTime类不支持时区; 你可以用ZonedDateTime

ZonedDateTime now = ZonedDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("hh:mm:ss a z");
System.out.println(now.format(formatter));

This no longer throws an exception and prints 06:08:20 PM EDTfor me, but the timezone will differ depending on your location.

这不再抛出异常并06:08:20 PM EDT为我打印,但时区会因您的位置而异。