【问题标题】:Java: getTimeZone without returning a default valueJava:getTimeZone 不返回默认值
【发布时间】:2015-10-27 16:31:30
【问题描述】:

我有以下指令:

TimeZone zone = TimeZone.getTimeZone("Asia/Toyo");

显然,它应该返回 null,但它会返回默认时区,这不是我所希望的行为。来自 Java 文档:

返回指定的TimeZone,如果无法理解给定的 ID,则返回 GMT 区域。

如果String不表示有效的TimeZone,有没有办法获取对应的TimeZone和null值?

我没有找到一个很好的解决方案来获取所有 TimeZone 并对其进行迭代。

【问题讨论】:

  • 您可能会考虑仅在 GMT 时检查结果,而不是遍历所有可用的 tzid。如果是这样,请检查您的输入是否是“GMT”或“UTC”或“UT”或“GMT0”或类似的。如果是则 ok else 返回 null。

标签: java timezone


【解决方案1】:

java.time.ZoneId

旧的日期时间类现在是遗留的,被 java.time 类取代。

您应该使用ZoneId,而不是java.util.TimeZone。要解析proper time zone name,请调用ZoneId.of

ZoneId.of ( "Africa/Casablanca" ) 

ZoneRulesException 的陷阱

如果您传入的名称无法识别,该方法将抛出ZoneRulesException

所以,如果要将Asia/Tokyo 拼写为Asia/Toyo,请捕获ZoneRulesException

ZoneId z;
try {
    z = ZoneId.of ( "Asia/Toyo" );  // Misspell "Asia/Tokyo" as "Asia/Toyo".
} catch ( ZoneRulesException e ) {
    System.out.println ( "Oops! Failed to recognize your time zone name. ZoneRulesException message: " + e.getMessage () );
    return;
}
ZonedDateTime zdt = ZonedDateTime.now ( z );

看到这个code run live at IdeOne.com


关于java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendarSimpleDateFormat

Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310

从哪里获得 java.time 类?

ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

【讨论】:

    【解决方案2】:

    您也可以简单地使用:

    boolean exists = Arrays.asList(TimeZone.getAvailableIDs()).contains("Asia/Toyo");
    

    或:

    boolean exists = Arrays.stream(TimeZone.getAvailableIDs()).anyMatch("Asia/Toyo"::equals);
    

    如果您需要经常这样做,将可用的 ID 放入 HashSet 会更有效。

    【讨论】:

      【解决方案3】:

      这应该可以满足您的需求TimeZone validation in Java

      String[] validIDs = TimeZone.getAvailableIDs();
      for (String str : validIDs) {
            if (str != null && str.equals("yourString")) {
              System.out.println("Valid ID");
            }
      }
      

      【讨论】:

      • 我知道你刚刚复制了答案,但你真的认为getAvailableIDs() 会返回一个空值吗?
      • getAvailableIDs() 不会返回空值,但它可以让您知道时区是否有效(这是他的问题的一部分)
      • 我指的是str != null检查。
      • 哦,对不起;好吧,在这一行中检查 null 确实似乎没有用:D
      【解决方案4】:

      只需检查返回的TimeZone

      public static TimeZone getTimeZone(String timeZoneID) {
          TimeZone timeZone = TimeZone.getTimeZone(timeZoneID);
          if (timeZone.getID().equals(timeZoneID))
              return timeZone;
          throw new IllegalArgumentException("Unknown time zone: " + timeZoneID);
      }
      

      在 Java 8 中,使用新的ZoneId.of(String zoneId),如果您需要旧的TimeZone,则在未知时区时会失败,使用TimeZone.getTimeZone(ZoneId zoneId)

      ZoneId zoneId = ZoneId.of("Asia/Toyo");
      TimeZone timeZone = TimeZone.getTimeZone(zoneId);
      

      【讨论】:

      • documentation for TimeZone明确指出返回的对象可能有一个与你请求不同的ID字符串,例如TimeZone.getTimeZone("GMT-8")
      • @VGR 是的,但搜索可用 ID 的其他答案将因同样的原因而失败。非标准 ID 将被更改,并且不会出现在列表中。因此,这是一个更好但仍然不完美的解决方案。
      【解决方案5】:

      如果您不想遍历 TimeZone.getAvailableIDs()。你可以使用。

      boolean validateTimeZone(String timeZoneStr) {
          return TimeZone.getTimeZone(timeZoneStr).getID().matches(timeZoneStr);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-11-03
        • 2019-02-22
        • 2021-02-09
        • 1970-01-01
        • 1970-01-01
        • 2013-01-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多