src/zone/ZoneRules.js
/*
* @copyright (c) 2016, Philipp Thuerwaechter & Pattrick Hueper
* @copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos
* @license BSD-3-Clause (see LICENSE in the root directory of this source tree)
*/
import {requireNonNull, abstractMethodFail} from '../assert';
import {Instant} from '../Instant';
export class ZoneRules {
/**
* Obtains an instance of {@code ZoneRules} that always uses the same offset.
* <p>
* The returned rules always have the same offset.
*
* @param {ZoneOffset} offset - the offset, not null
* @return {ZoneRules} the zone rules, not null
*/
static of(offset) {
requireNonNull(offset, 'offset');
return new Fixed(offset);
}
//-----------------------------------------------------------------------
/**
* Checks of the zone rules are fixed, such that the offset never varies.
*
* @return {boolean} true if the time-zone is fixed and the offset never changes
*/
isFixedOffset(){
abstractMethodFail('ZoneRules.isFixedOffset');
}
//-----------------------------------------------------------------------
/**
*
* @param instantOrLocalDateTime
* @returns {ZoneOffset}
*/
offset(instantOrLocalDateTime){
if(instantOrLocalDateTime instanceof Instant){
return this.offsetOfInstant(instantOrLocalDateTime);
} else {
return this.offsetOfLocalDateTime(instantOrLocalDateTime);
}
}
/**
* Gets the offset applicable at the specified instant in these rules.
* <p>
* The mapping from an instant to an offset is simple, there is only
* one valid offset for each instant.
* This method returns that offset.
*
* @param {Instant} instant the instant to find the offset for, not null, but null
* may be ignored if the rules have a single offset for all instants
* @return {ZoneOffset} the offset, not null
*/
offsetOfInstant(instant){
abstractMethodFail('ZoneRules.offsetInstant');
}
/**
* Gets a suitable offset for the specified local date-time in these rules.
* <p>
* The mapping from a local date-time to an offset is not straightforward.
* There are three cases:
* <p><ul>
* <li>Normal, with one valid offset. For the vast majority of the year, the normal
* case applies, where there is a single valid offset for the local date-time.</li>
* <li>Gap, with zero valid offsets. This is when clocks jump forward typically
* due to the spring daylight savings change from "winter" to "summer".
* In a gap there are local date-time values with no valid offset.</li>
* <li>Overlap, with two valid offsets. This is when clocks are set back typically
* due to the autumn daylight savings change from "summer" to "winter".
* In an overlap there are local date-time values with two valid offsets.</li>
* </ul><p>
* Thus, for any given local date-time there can be zero, one or two valid offsets.
* This method returns the single offset in the Normal case, and in the Gap or Overlap
* case it returns the offset before the transition.
* <p>
* Since, in the case of Gap and Overlap, the offset returned is a "best" value, rather
* than the "correct" value, it should be treated with care. Applications that care
* about the correct offset should use a combination of this method,
* {@link #getValidOffsets(LocalDateTime)} and {@link #getTransition(LocalDateTime)}.
*
* @param {LocalDateTime} localDateTime - the local date-time to query, not null, but null
* may be ignored if the rules have a single offset for all instants
* @return {ZoneOffset} the best available offset for the local date-time, not null
*/
offsetOfLocalDateTime(localDateTime){
abstractMethodFail('ZoneRules.offsetLocalDateTime');
}
/**
* Checks if the offset date-time is valid for these rules.
* <p>
* To be valid, the local date-time must not be in a gap and the offset
* must match the valid offsets.
*
* @param {LocalDateTime} localDateTime - the date-time to check, not null, but null
* may be ignored if the rules have a single offset for all instants
* @param {ZoneOffset} offset - the offset to check, null returns false
* @return {boolean} true if the offset date-time is valid for these rules
*/
isValidOffset(localDateTime, offset){
abstractMethodFail('ZoneRules.isValidOffset');
}
}
class Fixed extends ZoneRules{
/**
*
* @param {ZoneOffset} offset
*/
constructor(offset){
super();
this._offset = offset;
}
isFixedOffset(){
return true;
}
offsetOfInstant(){
return this._offset;
}
offsetOfLocalDateTime(){
return this._offset;
}
/**
*
* @param {LocalDateTime} LocalDateTime
* @param {ZoneOffset} offset
* @return {boolean}
*/
isValidOffset(dateTime, offset) {
return this._offset.equals(offset);
}
//-----------------------------------------------------------------------
/**
*
* @param other
* @returns {boolean}
*/
equals(other) {
if (this === other) {
return true;
}
if (other instanceof Fixed) {
return this._offset.equals(other._offset);
}
return false;
}
/**
*
* @returns {string}
*/
toString() {
return 'FixedRules:' + this._offset.toString();
}
}