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
Java: Adding TimeZone to DateTimeFormatter
提问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
LocalDateTime
has two fields of type LocalDate
and LocalTime
.LocalDate
has fields day
, month
, and year
.LocalTime
has fields hour
, minute
, second
, and nano
.
LocalDateTime
有两个类型为LocalDate
和 的字段LocalTime
。LocalDate
有田day
,month
和year
。LocalTime
有田hour
,minute
,second
,和nano
。
Nowhere in that is a time zone given. Which is by nature, since the javadoc of LocalDateTime
says:
没有任何地方给出时区。这是本质上的,因为 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
LocalDateTime
to aZonedDateTime
by callingatZone()
: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
Z
character:System.out.println(time.format(DateTimeFormatter.ofPattern("hh:mm:ss a 'Z'")));
通过调用将更改
LocalDateTime
为 a :ZonedDateTime
atZone()
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 LocalDateTime
class does not support time zones; you can use ZonedDateTime
instead.
本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 EDT
for me, but the timezone will differ depending on your location.
这不再抛出异常并06:08:20 PM EDT
为我打印,但时区会因您的位置而异。