【问题标题】:Java set timezone does not default to gmt+0Java 设置时区不默认为 gmt+0
【发布时间】:2018-05-23 13:56:42
【问题描述】:

我有以下代码。 java日期时间的字符串形式为gmt+0。因此我需要稍后根据不同的本地时区对其进行转换,但是当我尝试设置默认时区时,它会再返回 8 小时,因为我的机器在 gmt+8 上。输出显示我 2017-12-09 09:00 :00 但我想保持为 2017-12-09 17:00:00 因为这是 gmt+0。

    String existingTime = "2017-12-09 17:00:00";
    String newTime = "2017-12-09 14:00:00";

    Date existingDateTime = null;
    Date newDateTime = null;
    Date localexistingDateTime = null;
    Date localnewDateTime = null;
    DateFormat dateTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    TimeZone tz = TimeZone.getDefault();
    sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
    // sdf.setTimeZone(TimeZone.getTimeZone("GMT+8:30"));

    try {
        existingDateTime = dateTimeFormat.parse(existingTime);
        newDateTime = dateTimeFormat.parse(newTime);

        System.out.println("GMT existingDateTime" + sdf.format(existingDateTime));
        System.out.println("GMT newDateTime" + sdf.format(newDateTime));
    } catch (ParseException ex) {
        System.out.println("MyError:Parse Error has been caught for date parse close");
        ex.printStackTrace(System.out);
    }

【问题讨论】:

  • 我不能更强烈地建议不要使用旧版java.util.Date,这是原因之一。相反,您应该在适合您的用例的 java.time 包中查找适当的类。
  • 我的建议是停止使用java.util.Date 并改用java.time 包中的类。
  • 我把你推荐给this question
  • 已经有很多关于时区转换的问答。你看了吗?我建议这样做。我也同意 Joe C 的观点,所以特别是使用 java.time 寻找答案,有一些。
  • @OleV.V.好的,如果没有,我会得到一些答案,我会提出一个新问题,谢谢。

标签: java datetime time


【解决方案1】:

这个 sn-p 可以帮助您开始使用现代 Java 日期和时间 API java.time。在最先描述它的Java Specification Request之后,它也被称为JSR-310。

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
    String existingTime = "2017-12-09 17:00:00";
    OffsetDateTime existingDateTime = LocalDateTime.parse(existingTime, formatter)
            .atOffset(ZoneOffset.UTC);
    System.out.println("UTC existingDateTime: " + existingDateTime.format(formatter));
    System.out.println("Pyongyang existingDateTime: " 
            + existingDateTime.atZoneSameInstant(ZoneId.of("Asia/Pyongyang"))
                    .format(formatter));
    System.out.println("Singapore existingDateTime: " 
            + existingDateTime.atZoneSameInstant(ZoneId.of("Asia/Singapore"))
                    .format(formatter));

运行 sn-p 的输出是:

UTC existingDateTime: 2017-12-09 17:00:00
Pyongyang existingDateTime: 2017-12-10 01:30:00
Singapore existingDateTime: 2017-12-10 01:00:00

这是我在我的计算机上得到的输出(在欧洲/柏林时区),但是让现代类独立于 JVM 的时区更容易,所以你应该在你的计算机上得到相同的输出。

编辑:您在评论中询问是否可以使用 GMT+09:00 的偏移量而不是时区。我不确定您为什么要这样做,因为真实的人生活在时区而不是偏移中,但是当您知道如何操作时,这很容易:

    System.out.println("GMT+09:00 existingDateTime: "
            + existingDateTime.withOffsetSameInstant(ZoneOffset.ofHours(9))
                    .format(formatter));

输出:

GMT+09:00 existingDateTime: 2017-12-10 02:00:00

LocalDateTime 是没有时区或偏移信息的日期和时间。由于您的字符串不包含偏移量或区域,因此我使用它进行解析。既然你告诉我你的日期时间是 GMT+0,我首先将其转换为 OffsetDateTime,偏移 UTC。从那里可以直接将其转换为不同的本地时区。因此,我演示了几个时区,每次都使用我用于解析的相同格式化程序格式化日期时间,因为我猜你倾向于喜欢yyyy-MM-dd HH:mm:ss 格式。

我总是以 region/city 格式给出时区。这是明确的(与三个字母的缩写相反;例如,PYT 可能表示巴拉圭时间或平壤时间)。如果时区使用夏令时(DST),它将自动处理。甚至区域偏移的历史变化也是内置的。

要学习使用 java.time,请参阅 Oracle Tutorial on Date Time 并在 Stack Overflow 上搜索相关问题,始终寻找 java.time 的答案(使用过时的类有很多旧答案,跳过这些)。网络上更多的地方拥有宝贵的资源。您的搜索引擎和区分好坏的能力是您的朋友。

【讨论】:

  • v.v 感谢您的 sn-p。我如何使用例如可以用 gmt+09:00 代替 zoneid 吗?
  • 谢谢。原因是在我的数据库中,我将其保存为 GMT-05:00 和 -05:00。那么我最好使用 ZoneOffset.ofHours(9)。我可以将它用作 ZoneOffset.ofHours(-05:00)
猜你喜欢
  • 1970-01-01
  • 2011-11-21
  • 2011-07-01
  • 2015-08-09
  • 1970-01-01
  • 2012-12-21
  • 2015-07-01
  • 1970-01-01
相关资源
最近更新 更多