繁体   English   中英

ZonedDateTime 不显示通过 DateTimeFormatter 预期的时区

[英]ZonedDateTime not displaying Time Zone expected via DateTimeFormatter

我有一个时区为EST的日期输入。

我将它解析为ZonedDateTime ,但是在格式化时,它显示为GMT-04:00 ,而不是我期望的EST

为什么会发生这种情况 - 我可以让它显示我期望的时区吗?

例子

final String dateString = "16/07/2017 19:28:33 EST";
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss z");

System.out.println(MessageFormat.format("Input - {0}", dateString));
System.out.println(MessageFormat.format("Parsed - {0}", formatter.format(ZonedDateTime.parse(dateString, formatter))));

Output:

Input - 16/07/2017 19:28:33 EST
Parsed - 16/07/2017 19:28:33 GMT-04:00

我的时区是格林威治标准时间。 采用OpenJDK 14.0.2.12,en_GB 语言环境。

对于上下文,我试图在最近版本的 Amazon Corretto 11 中更好地理解这个问题 - https://github.com/corretto/corretto-11/issues/147

tl;博士

你说:

它显示为 GMT-04:00,而不是我期望的 EST。

此类详细信息取决于Locale.UK是否生效。

  • 16/07/2017 19:28:33 GMT-04:00Locale.UK
  • 16/07/2017 19:28:33 EDTLocale.US
  • 16/07/2017 19:28:33 HAELocale.CANADA_FRENCH

➥ 对于文本日期时间数据交换,(a) 坚持使用ISO 8601标准格式,(b) 尽可能使用零偏移量。 这样做会使问题 #147变得毫无意义。

细节

顺便说一句,尽量避免使用 2-4 个字母的伪区域(如ESTEDTISTCST )来解析日期时间文本。 这些是非标准的、非唯一的(,)、弱尝试给出时区和夏令时 (DST)是否有效的提示。

仅使用实时时区,格式为Continent/Region ,例如Europe/London


你说:

而不是我所期望的 EST

夏令时 (DST) 在America/New_York时区的该日期时间生效,而不是Standard Time 所以你应该期待EDT而不是EST


我建议您不要通过在您的println语句中嵌入调用来使事情复杂化。

您应该指定Locale ,而不是隐式依赖 JVM 的当前默认语言环境,该语言环境可以在运行时随时更改。 所以请注意我是如何将.withLocale( locale )附加到DateTimeFormatter object 的形成中的。 我指定了Locale.UK ,因为您在评论中提到了en_GB

因此,让我们将您的代码修改为:

final Locale locale = Locale.US ;  // Locale.UK versus Locale.US yield different outputs.
final String input = "16/07/2017 19:28:33 EST";
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "dd/MM/yyyy HH:mm:ss z" ).withLocale( locale ) ;
final ZonedDateTime zdt = ZonedDateTime.parse( input , formatter ) ;
final String zdtToString = zdt.toString() ;
final String zdtFormatted = zdt.format( formatter ) ;

… 和:

// Dump to console.
System.out.println( "input: " + input ) ;
System.out.println( "zdt: " + zdt ) ;
System.out.println( "zdtToString: " + zdtToString ) ;
System.out.println( "zdtFormatted: " + zdtFormatted ) ;

请参阅在 Java 12 上的 IdeOne.com 上实时运行的代码

input: 16/07/2017 19:28:33 EST
zdt: 2017-07-16T19:28:33-04:00[America/New_York]
zdtToString: 2017-07-16T19:28:33-04:00[America/New_York]
zdtFormatted: 16/07/2017 19:28:33 GMT-04:00

如果我们将该语言环境从Locale.UK更改为Locale.US ,我们会得到不同的结果。

zdtFormatted: 16/07/2017 19:28:33 EDT

tl;博士

永远不要使用没有Locale的日期时间解析器/格式化程序类型(类)。

import java.text.MessageFormat;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

class Main {
    public static void main(String[] args) {
        final String dateString = "16/07/2017 19:28:33 EST";
        final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss z", Locale.ENGLISH);

        System.out.println(MessageFormat.format("Input - {0}", dateString));
        System.out.println(
                MessageFormat.format("Parsed - {0}", formatter.format(ZonedDateTime.parse(dateString, formatter))));
    }
}

Output:

Input - 16/07/2017 19:28:33 EST
Parsed - 16/07/2017 19:28:33 EDT

在线演示

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM