UNPKG

@rschedule/joda-date-adapter

Version:

An rSchedule DateAdapter for "js-joda" ZonedDateTime objects.

121 lines (118 loc) 3.44 kB
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 };