Пример #1
0
  @Override
  public TransitionHistory load(String zoneID) {

    try {
      ZoneRules zoneRules = ZoneId.of(zoneID).getRules();
      ZonalOffset initialOffset =
          ZonalOffset.ofTotalSeconds(zoneRules.getOffset(Instant.MIN).getTotalSeconds());
      List<ZonalTransition> transitions = new ArrayList<>();
      List<DaylightSavingRule> rules = new ArrayList<>();

      for (ZoneOffsetTransition zot : zoneRules.getTransitions()) {
        Instant instant = zot.getInstant();
        long posixTime = instant.getEpochSecond();
        int previousOffset = zot.getOffsetBefore().getTotalSeconds();
        int totalOffset = zot.getOffsetAfter().getTotalSeconds();
        int dst = Math.toIntExact(zoneRules.getDaylightSavings(instant).getSeconds());
        transitions.add(new ZonalTransition(posixTime, previousOffset, totalOffset, dst));
      }

      for (ZoneOffsetTransitionRule zotr : zoneRules.getTransitionRules()) {
        DaylightSavingRule rule;

        int dom = zotr.getDayOfMonthIndicator(); // -28 bis +31 (ohne 0)
        DayOfWeek dayOfWeek = zotr.getDayOfWeek();

        Month month = Month.valueOf(zotr.getMonth().getValue());

        PlainTime timeOfDay =
            (zotr.isMidnightEndOfDay()
                ? PlainTime.midnightAtEndOfDay()
                : TemporalType.LOCAL_TIME.translate(zotr.getLocalTime()));

        OffsetIndicator indicator;
        switch (zotr.getTimeDefinition()) {
          case STANDARD:
            indicator = OffsetIndicator.STANDARD_TIME;
            break;
          case UTC:
            indicator = OffsetIndicator.UTC_TIME;
            break;
          case WALL:
            indicator = OffsetIndicator.WALL_TIME;
            break;
          default:
            throw new UnsupportedOperationException(zotr.getTimeDefinition().name());
        }

        int dst =
            (zotr.getOffsetAfter().getTotalSeconds() - zotr.getStandardOffset().getTotalSeconds());

        if (dayOfWeek == null) {
          rule = GregorianTimezoneRule.ofFixedDay(month, dom, timeOfDay, indicator, dst);
        } else {
          Weekday wd = Weekday.valueOf(dayOfWeek.getValue());
          if (dom == -1) {
            rule = GregorianTimezoneRule.ofLastWeekday(month, wd, timeOfDay, indicator, dst);
          } else if (dom < 0) {
            rule = new NegativeDayOfMonthPattern(month, dom, wd, timeOfDay, indicator, dst);
          } else {
            rule =
                GregorianTimezoneRule.ofWeekdayAfterDate(month, dom, wd, timeOfDay, indicator, dst);
          }
        }

        rules.add(rule);
      }

      return TransitionModel.of(initialOffset, transitions, rules);

    } catch (ZoneRulesException ex) {
      throw new IllegalArgumentException(ex);
    }
  }