/*
|
* @copyright (c) 2016, Philipp Thürwächter & Pattrick Hüper
|
* @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 } from '../assert';
|
import { Instant } from '../Instant';
|
import { LocalDate } from '../LocalDate';
|
import { MathUtil } from '../MathUtil';
|
|
import { ChronoUnit } from '../temporal/ChronoUnit';
|
import { Temporal } from '../temporal/Temporal';
|
import { TemporalQueries } from '../temporal/TemporalQueries';
|
|
export class ChronoZonedDateTime extends Temporal {
|
query(query) {
|
if (query === TemporalQueries.zoneId() || query === TemporalQueries.zone()) {
|
return this.zone();
|
} else if (query === TemporalQueries.chronology()) {
|
return this.toLocalDate().chronology();
|
} else if (query === TemporalQueries.precision()) {
|
return ChronoUnit.NANOS;
|
} else if (query === TemporalQueries.offset()) {
|
return this.offset();
|
} else if (query === TemporalQueries.localDate()) {
|
return LocalDate.ofEpochDay(this.toLocalDate().toEpochDay());
|
} else if (query === TemporalQueries.localTime()) {
|
return this.toLocalTime();
|
}
|
return super.query(query);
|
}
|
|
/**
|
* Outputs this date-time as a string using the formatter.
|
*
|
* @param {DateTimeFormatter} formatter - the formatter to use, not null
|
* @return {string} the formatted date-time string, not null
|
* @throws DateTimeException if an error occurs during printing
|
*/
|
format(formatter) {
|
requireNonNull(formatter, 'formatter');
|
return formatter.format(this);
|
}
|
|
/**
|
* Converts this date-time to an {@link Instant}.
|
*
|
* This returns an {@link Instant} representing the same point on the
|
* time-line as this date-time. The calculation combines the
|
* local date-time (see {@link toLocalDateTime}) and
|
* offset (see {@link getOffset}).
|
*
|
* @return {Instant} an {@link Instant} representing the same instant, not null
|
*/
|
toInstant() {
|
return Instant.ofEpochSecond(this.toEpochSecond(), this.toLocalTime().nano());
|
}
|
|
/**
|
* Converts this date-time to the number of seconds from the epoch
|
* of 1970-01-01T00:00:00Z.
|
*
|
* This uses the local date-time (see {@link toLocalDateTime}) and
|
* offset (see {@link getOffset}) to calculate the epoch-second value,
|
* which is the number of elapsed seconds from 1970-01-01T00:00:00Z.
|
* Instants on the time-line after the epoch are positive, earlier are negative.
|
*
|
* @return {number} the number of seconds from the epoch of 1970-01-01T00:00:00Z
|
*/
|
toEpochSecond() {
|
const epochDay = this.toLocalDate().toEpochDay();
|
let secs = epochDay * 86400 + this.toLocalTime().toSecondOfDay();
|
secs -= this.offset().totalSeconds();
|
return secs;
|
}
|
|
/**
|
* Compares this date-time to another date-time, including the chronology.
|
*
|
* The comparison is based first on the instant, then on the local date-time,
|
* then on the zone ID, then on the chronology.
|
* It is "consistent with equals", as defined by {@link Comparable}.
|
*
|
* If all the date-time objects being compared are in the same chronology, then the
|
* additional chronology stage is not required.
|
*
|
* @param {ChronoZonedDateTime} other - the other date-time to compare to, not null
|
* @return {number} the comparator value, negative if less, positive if greater
|
*/
|
compareTo(other) {
|
requireNonNull(other, 'other');
|
let cmp = MathUtil.compareNumbers(this.toEpochSecond(), other.toEpochSecond());
|
if (cmp === 0) {
|
cmp = this.toLocalTime().nano() - other.toLocalTime().nano();
|
if (cmp === 0) {
|
cmp = this.toLocalDateTime().compareTo(other.toLocalDateTime());
|
if (cmp === 0) {
|
cmp = strcmp(this.zone().id(), other.zone().id());
|
// we only support iso for now
|
//if (cmp === 0) {
|
// cmp = toLocalDate().getChronology().compareTo(other.toLocalDate().getChronology());
|
//}
|
}
|
}
|
}
|
return cmp;
|
}
|
|
//-----------------------------------------------------------------------
|
/**
|
* Checks if the instant of this date-time is after that of the specified date-time.
|
*
|
* This method differs from the comparison in {@link compareTo} in that it
|
* only compares the instant of the date-time. This is equivalent to using
|
* `dateTime1.toInstant().isAfter(dateTime2.toInstant())`.
|
*
|
* @param {!ChronoZonedDateTime} other - the other date-time to compare to, not null
|
* @return {boolean} true if this is after the specified date-time
|
*/
|
isAfter(other) {
|
requireNonNull(other, 'other');
|
const thisEpochSec = this.toEpochSecond();
|
const otherEpochSec = other.toEpochSecond();
|
return thisEpochSec > otherEpochSec ||
|
(thisEpochSec === otherEpochSec && this.toLocalTime().nano() > other.toLocalTime().nano());
|
}
|
|
/**
|
* Checks if the instant of this date-time is before that of the specified date-time.
|
*
|
* This method differs from the comparison in {@link compareTo} in that it
|
* only compares the instant of the date-time. This is equivalent to using
|
* `dateTime1.toInstant().isBefore(dateTime2.toInstant())`.
|
*
|
* @param {!ChronoZonedDateTime} other - the other date-time to compare to, not null
|
* @return {boolean} true if this point is before the specified date-time
|
*/
|
isBefore(other) {
|
requireNonNull(other, 'other');
|
const thisEpochSec = this.toEpochSecond();
|
const otherEpochSec = other.toEpochSecond();
|
return thisEpochSec < otherEpochSec ||
|
(thisEpochSec === otherEpochSec && this.toLocalTime().nano() < other.toLocalTime().nano());
|
}
|
|
/**
|
* Checks if the instant of this date-time is equal to that of the specified date-time.
|
*
|
* This method differs from the comparison in {@link compareTo} and {@link equals}
|
* in that it only compares the instant of the date-time. This is equivalent to using
|
* `dateTime1.toInstant().equals(dateTime2.toInstant())`.
|
*
|
* @param {!ChronoZonedDateTime} other - the other date-time to compare to, not null
|
* @return {boolean} true if the instant equals the instant of the specified date-time
|
*/
|
isEqual(other) {
|
requireNonNull(other, 'other');
|
return this.toEpochSecond() === other.toEpochSecond() &&
|
this.toLocalTime().nano() === other.toLocalTime().nano();
|
}
|
|
//-----------------------------------------------------------------------
|
/**
|
* Checks if this date-time is equal to another date-time.
|
*
|
* The comparison is based on the offset date-time and the zone.
|
* To compare for the same instant on the time-line, use {@link compareTo}.
|
* Only objects of type {@link ChronoZoneDateTime} are compared, other types return false.
|
*
|
* @param {*} other the object to check, null returns false
|
* @return {boolean} true if this is equal to the other date-time
|
*/
|
equals(other) {
|
if (this === other) {
|
return true;
|
}
|
if (other instanceof ChronoZonedDateTime) {
|
return this.compareTo(other) === 0;
|
}
|
return false;
|
}
|
|
}
|
|
function strcmp(a, b){
|
if (a < b) {
|
return -1;
|
}
|
if (a > b) {
|
return 1;
|
}
|
return 0;
|
}
|