【问题标题】:BST Time is wrongBST 时间错误
【发布时间】:2018-09-04 09:05:43
【问题描述】:

使用下面的代码,除了BST之外,每个时区都可以正确打印值

​import java.text.*;

def format = "yyyy-MM-dd HH:mm:ssXXX"
def dt = new Date();
println dt;

SimpleDateFormat utcFormat = new SimpleDateFormat(format)
utcFormat.setTimeZone(TimeZone.getTimeZone("UTC"))
println utcFormat.format(dt)

SimpleDateFormat istFormat = new SimpleDateFormat(format)
istFormat .setTimeZone(TimeZone.getTimeZone("IST"))
println istFormat.format(dt)

SimpleDateFormat cetFormat = new SimpleDateFormat(format)
cetFormat.setTimeZone(TimeZone.getTimeZone("CET"))
println cetFormat.format(dt)

SimpleDateFormat bstFormat = new SimpleDateFormat(format)
bstFormat.setTimeZone(TimeZone.getTimeZone("BST"))
println bstFormat.format(dt)

输出:

2018 年 3 月 26 日星期一 09:04:14 UTC

2018-03-26 09:04:14Z

2018-03-26 14:34:14+05:30

2018-03-26 11:04:14+02:00

2018-03-26 15:04:14+06:00

这里BST 时间不对。有什么问题?

【问题讨论】:

  • 你的时区数据库是新的吗?
  • 对不起,我没有得到你的要求

标签: java groovy timezone java-time timezone-offset


【解决方案1】:

您似乎希望 BST 是英国夏令时,但在这种情况下,它代表 Bangladesh Standard Time。 另见What does Java's BST ZoneId represent?

来自答案:

以下代码有效

SimpleDateFormat bstFormat = new SimpleDateFormat(format)
bstFormat.setTimeZone(TimeZone.getTimeZone("Europe/London"))
println bstFormat.format(dt)

【讨论】:

    【解决方案2】:

    我运行了您的代码,发现 BST 的时间恰到好处。将 6 小时的偏移量添加到 UTC 时间 09:04:14 会得到 15:04:14。我认为您对时区的首字母缩写词感到困惑。

    如果您在JVM中的时区数据库不正确,您可以通过TimeZone.getTimeZone("Europe/London");获取英国夏令时区

    【讨论】:

      【解决方案3】:

      您应该避免使用缩写的时区名称。请查看TimeZone documentation 中的以下注释:

      三个字母的时区 ID

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

      在您的情况下,系统可能已将 BST 映射到 比什凯克标准时间,其时区偏移量为 +06:00 小时。标准命名约定是 Region/City 例如Europe/London、Europe/Paris、Asia/Kolkata 等,其中City 通常是指该地区一个国家的最大城市。如有疑问,请执行以下语句以获取所有时区 ID:

      System.out.println(ZoneId.getAvailableZoneIds());
      

      java.time

      java.util 日期时间 API 及其格式化 API SimpleDateFormat 已过时且容易出错。建议完全停止使用,改用modern Date-Time API*

      使用现代日期时间 API java.time 的解决方案:

      import java.time.Instant;
      import java.time.ZoneId;
      import java.time.ZoneOffset;
      import java.time.format.DateTimeFormatter;
      import java.util.Locale;
      
      public class Main {
          public static void main(String args[]) {
              DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ssXXX", Locale.ENGLISH);
              
              Instant now = Instant.now();
              
              System.out.println(now.atZone(ZoneOffset.UTC).format(dtf));
              System.out.println(now.atZone(ZoneId.of("Asia/Kolkata")).format(dtf));
              System.out.println(now.atZone(ZoneId.of("Europe/Paris")).format(dtf));
              System.out.println(now.atZone(ZoneId.of("Europe/London")).format(dtf));
          }
      }
      

      输出 来自示例运行:

      2021-10-12 12:24:03Z
      2021-10-12 17:54:03+05:30
      2021-10-12 14:24:03+02:00
      2021-10-12 13:24:03+01:00
      

      ONLINE DEMO

      Trail: Date Time 了解有关现代日期时间 API 的更多信息。


      * 如果您正在为一个 Android 项目工作,并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaring。请注意,Android 8.0 Oreo 已经提供了support for java.time

      【讨论】:

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