【问题标题】:How to set Z as timezone in SimpleDateFormat如何在 SimpleDateFormat 中将 Z 设置为时区
【发布时间】:2018-04-06 12:08:59
【问题描述】:

代码示例:

SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
System.out.println(dateFormat.getTimeZone());
System.out.println(dateFormat.parse(time));
//  dateFormat.setTimeZone(TimeZone.getTimeZone("Asia/Kolkata"));

我不想使用评论区。

应根据我在输入字符串中给出的IST 设置区域:

String time ="2018-04-06 16:13:00 IST";

当前机器区是:America/New_York。我应该如何根据 z 获得对 IST 的区域更改?

SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
String time ="2018-04-06 18:40:00 IST";
dateFormat.setTimeZone(TimeZone.getTimeZone("Asia/Kolkata"));

以上运行正常,但我不想明确设置区域。应该根据我在输入时间字符串中给出的 IST 来选择它。

【问题讨论】:

  • 我建议你避免使用SimpleDateFormat 类。它不仅过时了,而且出了名的麻烦。今天我们在java.time, the modern Java date and time API 中做得更好。
  • 你能提供样品吗
  • IST 不明确,可能是爱尔兰夏令时间、以色列标准时间或印度标准时间。正是出于这个原因,建议避免使用三个和四个字母的时区缩写。如果您在自己的计算机上获得其中一个区域,那么您在另一台计算机上运行代码的那一天就有可能获得不同的区域。您是否有可能在没有这种歧义的情况下获得日期时间字符串?例如,使用 region/city 格式的 UTC 偏移量和/或时区,例如 Asia/Tel_Aviv?
  • @AnkushNakaskar,“我应该如何将区域更改为 IST”是什么意思?这不是我可以回答的问题。请阅读help/asking 并将您的问题发送到minimal reproducible example

标签: java date timezone simpledateformat datetime-parsing


【解决方案1】:

“我不想明确设置区域”

很抱歉让您失望了,但 SimpleDateFormat 不可能做到这一点。 Timezone abbreviations like IST are ambiguous - 正如 cmets 中已经说过的,ISTused in many places(AFAIK,在印度、爱尔兰和以色列)。

其中一些缩写可能在特定情况下有时会起作用,但通常以任意且未记录的方式起作用,您不能真正依赖它。 Quoting the javadoc:

为了与 JDK 1.1.x 兼容,还支持一些其他的三字母时区 ID(例如“PST”、“CTT”、“AST”)。但是,已弃用,因为相同的缩写通常用于多个时区(例如,“CST”可能是美国“中部标准时间”和“中国标准时间”),而 Java然后平台只能识别其中之一。

由于时区缩写的模棱两可和不标准的特点,用SimpleDateFormat解决它的唯一方法是在上面设置一个特定的时区。

"应该根据Z设置"

我不太确定这意味着什么,但无论如何......

ZUTC designator。但是如果输入包含一个时区短名称,例如 IST,那么这意味着它在 UTC 中 不是,所以你不能像在世界标准时间。

如果你想用Z 输出日期,那么你需要另一个格式化程序设置为UTC:

SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
String time = "2018-04-06 18:40:00 IST";
dateFormat.setTimeZone(TimeZone.getTimeZone("Asia/Kolkata"));
// parse the input
Date date = dateFormat.parse(time);

// output format, use UTC
SimpleDateFormat outputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssX");
outputFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(outputFormat.format(date)); // 2018-04-06 13:10:00Z

也许如果您准确指定要获得的输出(带有实际,一些输出示例)以及预期输出是什么,我们可以为您提供更多帮助。

【讨论】:

  • 我想使用日期对象从rest api转换日期,我也可以在requestBody中提供时区
【解决方案2】:
    DateTimeFormatter formatter 
            = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss z", Locale.ENGLISH);
    String time ="2018-04-06 16:13:00 IST";
    ZonedDateTime dateTime = ZonedDateTime.parse(time, formatter);
    System.out.println(dateTime.getZone());

在我的 Java 8 上打印

亚洲/耶路撒冷

显然 IST 被解释为以色列标准时间。在其他具有其他设置的计算机上,您将获得爱尔兰夏令时间的欧洲/都柏林或印度标准时间的亚洲/加尔各答。无论如何,时区来自与格式模式字符串中的模式字母(小写)z 匹配的缩写,我想这就是你的意思(?)

如果你想在经常出现的歧义情况下控制时区的选择,你可以用这种方式构建你的格式化程序(这个想法来自this answer):

    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .appendPattern("uuuu-MM-dd HH:mm:ss ")
            .appendZoneText(TextStyle.SHORT,
                    Collections.singleton(ZoneId.of("Asia/Kolkata")))
            .toFormatter(Locale.ENGLISH);

现在输出是

亚洲/加尔各答

我正在使用并推荐java.time,而不是长期过时且臭名昭著的SimpleDateFormat 课程。

链接: Oracle tutorial: Date Time 解释如何使用java.time

【讨论】:

    猜你喜欢
    • 2019-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-13
    • 1970-01-01
    • 1970-01-01
    • 2020-05-10
    • 1970-01-01
    相关资源
    最近更新 更多