@rschedule/joda-date-adapter
Version:
An rSchedule DateAdapter for "js-joda" ZonedDateTime objects.
121 lines (118 loc) • 3.44 kB
JavaScript
import { ZoneId, ZonedDateTime } from '@js-joda/core';
import { DateAdapterBase, ArgumentError, InvalidDateAdapterError } from '@rschedule/core';
/**
* The `JodaDateAdapter` is a DateAdapter for "@js-joda/core" `ZonedDateTime`
* objects.
*
* It supports timezone handling in so far as js-joda supports
* timezone handling. That is, it only supports the SYSTEM and UTC
* time zones unless you have loaded the optional @js-joda/timezone
* package.
*/
class JodaDateAdapter extends DateAdapterBase {
constructor(date, options = {}) {
super(undefined, options);
this.date = date;
this.timezone = this.date.zone() === ZoneId.SYSTEM ? null : this.date.zone().toString();
if (this.timezone === 'Z') {
this.timezone = 'UTC';
}
if (options.metadata) {
Object.assign(this.metadata, options.metadata);
}
this.assertIsValid();
}
/**
* Checks if object is an instance of `ZonedDateTime`
*/
static isDate(object) {
return object instanceof ZonedDateTime;
}
static fromDate(date, options) {
return new JodaDateAdapter(date, options);
}
static fromJSON(json) {
const zone = json.timezone === null ? ZoneId.SYSTEM : ZoneId.of(json.timezone);
const date = new JodaDateAdapter(
ZonedDateTime.of(
json.year,
json.month,
json.day,
json.hour,
json.minute,
json.second,
json.millisecond * 1000000,
zone,
),
{ duration: json.duration },
);
if (json.metadata) {
Object.assign(date.metadata, json.metadata);
}
return date;
}
static fromDateTime(datetime) {
const date = JodaDateAdapter.fromJSON(datetime.toJSON());
date.generators.push(...datetime.generators);
if (datetime.metadata) {
Object.assign(date.metadata, datetime.metadata);
}
return date;
}
get end() {
if (!this.duration) return;
if (this._end) return this._end;
this._end = this.date.plusNanos(this.duration * 1000000);
return this._end;
}
set(prop, value) {
if (prop === 'timezone') {
if (this.timezone === value) return this;
else {
return new JodaDateAdapter(
this.date.withZoneSameInstant(value === null ? ZoneId.SYSTEM : ZoneId.of(value)),
{
duration: this.duration,
generators: this.generators,
},
);
}
} else if (prop === 'duration') {
if (this.duration === value) return this;
else {
return new JodaDateAdapter(this.date, {
duration: value,
generators: this.generators,
});
}
}
throw new ArgumentError(`Unknown prop "${prop}" for JodaDateAdapter#set()`);
}
valueOf() {
return this.date.toInstant().toEpochMilli();
}
toJSON() {
const json = {
timezone: this.timezone,
year: this.date.year(),
month: this.date.monthValue(),
day: this.date.dayOfMonth(),
hour: this.date.hour(),
minute: this.date.minute(),
second: this.date.second(),
millisecond: this.date.nano() / 1000000,
};
if (this.duration) {
json.duration = this.duration;
}
return json;
}
assertIsValid() {
if (this.duration && this.duration <= 0) {
throw new InvalidDateAdapterError('If provided, duration must be greater than 0.');
}
return true;
}
}
JodaDateAdapter.hasTimezoneSupport = true;
export { JodaDateAdapter };