/** * Obtains an instance of {@code ZoneOffset} specifying the total offset in seconds * * <p>The offset must be in the range {@code -18:00} to {@code +18:00}, which corresponds to * -64800 to +64800. * * @param totalSeconds the total time-zone offset in seconds, from -64800 to +64800 * @return the ZoneOffset, not null * @throws DateTimeException if the offset is not in the required range */ public static ZoneOffset ofTotalSeconds(int totalSeconds) { if (Math.abs(totalSeconds) > MAX_SECONDS) { throw new DateTimeException("Zone offset not in valid range: -18:00 to +18:00"); } if (totalSeconds % (15 * SECONDS_PER_MINUTE) == 0) { Integer totalSecs = totalSeconds; ZoneOffset result = SECONDS_CACHE.get(totalSecs); if (result == null) { result = new ZoneOffset(totalSeconds); SECONDS_CACHE.putIfAbsent(totalSecs, result); result = SECONDS_CACHE.get(totalSecs); ID_CACHE.putIfAbsent(result.getId(), result); } return result; } else { return new ZoneOffset(totalSeconds); } }
/** * Obtains an instance of {@code ZoneOffset} using the ID. * * <p>This method parses the string ID of a {@code ZoneOffset} to return an instance. The parsing * accepts all the formats generated by {@link #getId()}, plus some additional formats: * * <ul> * <li>{@code Z} - for UTC * <li>{@code +h} * <li>{@code +hh} * <li>{@code +hh:mm} * <li>{@code -hh:mm} * <li>{@code +hhmm} * <li>{@code -hhmm} * <li>{@code +hh:mm:ss} * <li>{@code -hh:mm:ss} * <li>{@code +hhmmss} * <li>{@code -hhmmss} * </ul> * * Note that ± means either the plus or minus symbol. * * <p>The ID of the returned offset will be normalized to one of the formats described by {@link * #getId()}. * * <p>The maximum supported range is from +18:00 to -18:00 inclusive. * * @param offsetId the offset ID, not null * @return the zone-offset, not null * @throws DateTimeException if the offset ID is invalid */ @SuppressWarnings("fallthrough") public static ZoneOffset of(String offsetId) { Objects.requireNonNull(offsetId, "offsetId"); // "Z" is always in the cache ZoneOffset offset = ID_CACHE.get(offsetId); if (offset != null) { return offset; } // parse - +h, +hh, +hhmm, +hh:mm, +hhmmss, +hh:mm:ss final int hours, minutes, seconds; switch (offsetId.length()) { case 2: offsetId = offsetId.charAt(0) + "0" + offsetId.charAt(1); // fallthru case 3: hours = parseNumber(offsetId, 1, false); minutes = 0; seconds = 0; break; case 5: hours = parseNumber(offsetId, 1, false); minutes = parseNumber(offsetId, 3, false); seconds = 0; break; case 6: hours = parseNumber(offsetId, 1, false); minutes = parseNumber(offsetId, 4, true); seconds = 0; break; case 7: hours = parseNumber(offsetId, 1, false); minutes = parseNumber(offsetId, 3, false); seconds = parseNumber(offsetId, 5, false); break; case 9: hours = parseNumber(offsetId, 1, false); minutes = parseNumber(offsetId, 4, true); seconds = parseNumber(offsetId, 7, true); break; default: throw new DateTimeException("Invalid ID for ZoneOffset, invalid format: " + offsetId); } char first = offsetId.charAt(0); if (first != '+' && first != '-') { throw new DateTimeException( "Invalid ID for ZoneOffset, plus/minus not found when expected: " + offsetId); } if (first == '-') { return ofHoursMinutesSeconds(-hours, -minutes, -seconds); } else { return ofHoursMinutesSeconds(hours, minutes, seconds); } }