【问题标题】:TimeZone validation in JavaJava 中的时区验证
【发布时间】:2012-10-26 19:04:05
【问题描述】:

我有一个字符串,我需要检查它是否是标准时区标识符。我不确定我需要使用哪种方法。

String timeZoneToCheck = "UTC";

我想检查它是否代表一个有效的时区。

【问题讨论】:

    标签: java validation timezone


    【解决方案1】:

    一行可以写

    public boolean validTimeZone(String timezone) {
        return Set.of(TimeZone.getAvailableIDs()).contains(timezone);
    }
    

    或者,您可以为其创建一个静态字段

    private static final Set<String> TIMEZONES = Set.of(TimeZone.getAvailableIDs())
    
    public boolean validTimeZone(String timezone) {
        return TIMEZONES.contains(timezone);
    }
    

    【讨论】:

    • 最好使用Set
    【解决方案2】:

    您可以使用getAvailableIDs() 获取所有支持的 ID

    然后循环supportedID数组并与您的字符串进行比较。

    例子:

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

    【讨论】:

      【解决方案3】:

      java.time.ZoneId

      很简单,只需使用ZoneId.of("Asia/Kolkata")

      try {
          ZoneId.of("Asia/Kolkataa");
      } catch (Exception e) {
          e.printStackTrace();
      }
      

      如果您插入的时区无效,则会抛出异常

      **java.time.zone.ZoneRulesException: Unknown time-zone ID: Asia/Kolkataa**
      

      【讨论】:

        【解决方案4】:

        与遍历所有可能的 ID 相比,这是一种更有效的解决方案。它检查getTimeZone 的输出。

        Java Docs (TimeZone#getTimeZone):

        返回: 指定的时区,如果无法理解给定的 ID,则为 GMT 时区。

        因此,如果输出为 GMT 时区,则输入无效,除非输入准确为“GMT”。

        public static boolean isValidTimeZone(@NonNull String timeZoneID) {
            return (timeZoneID.equals("GMT") || !TimeZone.getTimeZone(timeZoneID).getID().equals("GMT"));
        }
        

        或者如果您想使用有效时区而不调用两次getTimeZone

        TimeZone timeZone = TimeZone.getTimeZone(timeZoneToCheck);
        if(timeZoneToCheck.equals("GMT") || !timeZone.getID().equals("GMT")) {
            // TODO Valid - use timeZone
        } else {
            // TODO Invalid - handle the invalid input
        }
        

        【讨论】:

          【解决方案5】:

          我想提出下一个解决方法:

          public static final String GMT_ID = "GMT";
          public static TimeZone getTimeZone(String ID) {
              if (null == ID) {
                  return null;
              }
          
              TimeZone tz = TimeZone.getTimeZone(ID);
          
              // not nullable value - look at implementation of TimeZone.getTimeZone
              String tzID = tz.getID();
          
              // check if not fallback result 
              return GMT_ID.equals(tzID) && !tzID.equals(ID) ? null : tz;
          }
          

          如果时区 ID 无效或自定义时区无效,您将收到 null。此外,您可以引入相应的 null 值处理程序(取决于用例) - 抛出异常等。

          【讨论】:

          • 除了明显的事实之外,您的方法将为有效 id "GMT"(或任何等价物)返回 null。
          • 进一步扩展:有很多(大约 200 个?)有效的 tzid 字符串是其他 tzid 的别名。例如,当您询问“US/Pacific”时,您会返回有效且等效的时区“America/Los_Angeles”。
          【解决方案6】:
          private boolean isValidTimeZone(final String timeZone) {
              final String DEFAULT_GMT_TIMEZONE = "GMT";
              if (timeZone.equals(DEFAULT_GMT_TIMEZONE)) {
                  return true;
              } else {
                  // if custom time zone is invalid,
                  // time zone id returned is always "GMT" by default
                  String id = TimeZone.getTimeZone(timeZone).getID();
                  if (!id.equals(DEFAULT_GMT_TIMEZONE)) {
                      return true;
                  }
              }
              return false;
          }
          

          该方法对以下情况返回 true:

          assertTrue(this.isValidTimeZone("JST"));
          assertTrue(this.isValidTimeZone("UTC"));
          assertTrue(this.isValidTimeZone("GMT"));
          // GMT+00:00
          assertTrue(this.isValidTimeZone("GMT+0"));
          // GMT-00:00
          assertTrue(this.isValidTimeZone("GMT-0"));
          // GMT+09:00
          assertTrue(this.isValidTimeZone("GMT+9:00"));
          // GMT+10:30
          assertTrue(this.isValidTimeZone("GMT+10:30"));
          // GMT-04:00
          assertTrue(this.isValidTimeZone("GMT-0400"));
          // GMT+08:00
          assertTrue(this.isValidTimeZone("GMT+8"));
          // GMT-13:00
          assertTrue(this.isValidTimeZone("GMT-13"));
          // GMT-13:59
          assertTrue(this.isValidTimeZone("GMT+13:59"));
          // NOTE: valid time zone IDs (see TimeZone.getAvailableIDs())
          // GMT-08:00
          assertTrue(this.isValidTimeZone("America/Los_Angeles"));
          // GMT+09:00
          assertTrue(this.isValidTimeZone("Japan"));
          // GMT+01:00
          assertTrue(this.isValidTimeZone("Europe/Berlin"));
          // GMT+04:00
          assertTrue(this.isValidTimeZone("Europe/Moscow"));
          // GMT+08:00
          assertTrue(this.isValidTimeZone("Asia/Singapore"));
          

          ...以下时区为假:

          assertFalse(this.isValidTimeZone("JPY"));
          assertFalse(this.isValidTimeZone("USD"));
          assertFalse(this.isValidTimeZone("UTC+8"));
          assertFalse(this.isValidTimeZone("UTC+09:00"));
          assertFalse(this.isValidTimeZone("+09:00"));
          assertFalse(this.isValidTimeZone("-08:00"));
          assertFalse(this.isValidTimeZone("-1"));
          assertFalse(this.isValidTimeZone("GMT+10:-30"));
          // hours is 0-23 only
          assertFalse(this.isValidTimeZone("GMT+24:00"));
          // minutes 00-59 only
          assertFalse(this.isValidTimeZone("GMT+13:60"));
          

          【讨论】:

            【解决方案7】:

            由于TimeZone#getTimeZone(String id) 在值无效时返回默认值(而不是返回无效时区),如果重新解释的值与初始值不匹配,则它无效。

            private static boolean isValidTimeZone(@Nonnull String potentialTimeZone)
            {
                // If the input matches the re-interpreted value, then the time zone is valid.
                return TimeZone.getTimeZone(potentialTimeZone).getID().equals(potentialTimeZone);
            }
            

            【讨论】:

            • 不,因为有很多有效的 tzid 字符串是其他 tzid 的别名。例如,当您询问“US/Pacific”时,您会返回有效且等效的时区“America/Los_Angeles”。
            • 您可能仍需要按照上述答案 stackoverflow.com/a/17926927/3343801 中的建议进行 GMT 检查
            【解决方案8】:

            您可以使用TimeZone.getAvailableIDs() 获取支持的 Id 列表

            for (String str : TimeZone.getAvailableIDs()) {
                if (str.equals("UTC")) {
                    //found
                }
            }
            

            【讨论】:

              【解决方案9】:

              如果TimeZone.getAvailableIDs() 包含有问题的 ID,则它是有效的:

              public boolean validTimeZone(String id) {
                  for (String tzId : TimeZone.getAvailableIDs()) {
                          if (tzId.equals(id))
                              return true;
                  }
                  return false;
              }
              

              不幸的是,TimeZone.getTimeZone() 方法会默默地丢弃无效 ID 并返回 GMT:

              返回:

              指定的时区,如果无法理解给定的 ID,则为 GMT 时区。

              【讨论】:

              • 我想是否有任何方法可以验证 id 而不是遍历所有 id,因为它只是丢弃无效的 ID 并返回 GMT。感谢您的回答。
              猜你喜欢
              • 2018-10-18
              • 2020-07-15
              • 1970-01-01
              • 1970-01-01
              • 2020-04-23
              • 1970-01-01
              • 2021-10-25
              • 2015-10-25
              • 1970-01-01
              相关资源
              最近更新 更多