ts-time/OffsetDateTime

Consumption

import OffsetDateTime from "ts-time/OffsetDateTime";

Default export#

Hierarchy#

  • class OffsetDateTime

Description#

Comprises a specific instant bound to a specific time zone offset. In other words, this is a tuple of (Instant, ZoneOffset). Unambiguously identifies a LocalDateTime.

Construct#

OffsetDateTime has a very limited number of usage scenarios, so it has a limited number of ways to be constructed to avoid its misuse. Always consider using other data structures (ZonedDateTime, LocalDateTime, Instant) before OffsetDateTime.

Typically you don't construct OffsetDateTime directly, but create it from other data structures:

OffsetDateTime.ofInstant(instant, offset);   // From Instant in a given ZoneOffset
instant.atOffset(offset);                    // Equivalent
OffsetDateTime.ofDateTime(dateTime, offset); // From LocalDateTime in a given ZoneOffset
dateTime.atOffset(offset);                   // Equivalent
zonedDateTime.offsetDateTime;                // From ZonedDateTime

Please notice that:

  • Conversion from Instant may be counter-intuitive, as string presentation of the date/time may change:
    const offset  = ZoneOffset.ofComponents(-2);
    const instant = Instant.parse("2022-06-14T00:00:00.000Z");
    console.log(instant.atOffset(offset));           // "2022-06-13T22:00:00.000-02:00"
    It happens, because OffsetDateTime preserves its instant component in this case, not dateTime:
    console.log(instant.atOffset(offset).instant);   // "2022-06-14T00:00:00.000Z"
    console.log(instant.atOffset(offset).dateTime);  // "2022-06-13T22:00:00.000"
  • Conversion from LocalDateTime, on the contrary, preserves dateTime component:
    const dateTime = LocalDateTime.parse("2022-06-14T00:00:00.000");
    console.log(dateTime.atOffset(offset));          // "2022-06-14T00:00:00.000-02:00"
    console.log(dateTime.atOffset(offset).dateTime); // "2022-06-14T00:00:00.000"
    console.log(dateTime.atOffset(offset).instant);  // "2022-06-14T02:00:00.000Z"
  • Conversion from ZonedDateTime may result in a partial data loss (if the time zone has dynamic offset).
Parse#

A common way to parse an ISO 8601 compliant string in ts-time is to call parse static method. For example, the following OffsetDateTime instance represents 18 hours, 30 minutes, 15 seconds, 225 milliseconds on 15th of February, 2022, UTC-2 offset:

OffsetDateTime.parse("2022-02-15T18:30:15.225-02:00");

The library doesn't yet support parsing non-compliant strings.

Inspect#

In the following example, we inspect various properties of a OffsetDateTime object. Please notice the difference in return value types:

const offsetDateTime = OffsetDateTime.parse("2022-02-15T18:30:15.225-02:00");
const year           = offsetDateTime.year;            // 2022
const month          = offsetDateTime.month;           // FEBRUARY
const monthValue     = offsetDateTime.month.value;     // 2
const dayOfMonth     = offsetDateTime.dayOfMonth;      // 15
const dayOfWeek      = offsetDateTime.dayOfWeek;       // TUESDAY
const dayOfWeekValue = offsetDateTime.dayOfWeek.value; // 2
const hour           = offsetDateTime.hour;            // 18
const minute         = offsetDateTime.minute;          // 30
const second         = offsetDateTime.second;          // 15
const ms             = offsetDateTime.ms;              // 225
const offset         = offsetDateTime.offset;          // Instance of ZoneOffset
const offsetHours    = offsetDateTime.offset.hours;    // -2
const offsetMinutes  = offsetDateTime.offset.minutes;  // 0
const offsetSeconds  = offsetDateTime.offset.seconds;  // 0

Other sophisticated features for OffsetDateTime inspection: epochMs, era, yearOfEra, weekBasedYear, weekOfWeekBasedYear, dayOfYear, dayOfWeekBasedYear, epochDay, quarterOfYear, isLeapYear, lengthOfYear.

Compare#

A common way to compare objects in ts-time is to call equals, compareTo methods:

const d1 = OffsetDateTime.parse("2022-02-15T18:30:15.225-02:00");
const d2 = OffsetDateTime.parse("2022-02-15T18:30:15.226-02:00");
d1.equals(d2);    // false
d1.compareTo(d2); // -1

The objects are first compared by instant, and then by offset.

For nullable objects, use static methods instead. Null and undefined are considered less than anything, except each other:

const d1: OffsetDateTime = null;
const d2 = OffsetDateTime.parse("2022-02-15T18:30:15.226-02:00");
OffsetDateTime.equal(d1, d2);   // false
OffsetDateTime.compare(d1, d2); // -1

As opposed to the majority of objects in ts-time, OffsetDateTime doesn't have isBefore and isAfter methods. You must explicitly specify which component you want to compare: instant or dateTime.

const d1 = OffsetDateTime.parse("2022-02-15T18:30:15.225-05:00");
const d2 = OffsetDateTime.parse("2022-02-15T20:30:15.226+01:00");
d1.instant.isBefore(d2.instant);   // false
d1.dateTime.isBefore(d2.dateTime); // true
Manipulate#

Every object in ts-time is immutable. Therefore every manipulation returns a new object.

To add/subtract a Period, call plusPeriod/minusPeriod method:

const offsetDateTime = OffsetDateTime.parse("2022-02-15T18:30:15.225-02:00");
const d1 = offsetDateTime.plusPeriod(DAY_PERIOD);                // 18:30:15.225 on 16th of February, 2022, UTC-2
const d2 = offsetDateTime.plusPeriod(Period.ofDays(2));          // 18:30:15.225 on 17th of February, 2022, UTC-2
const d3 = offsetDateTime.minusPeriod(MONTH_PERIOD);             // 18:30:15.225 on 15th of January, 2022, UTC-2

The algorithm respects dateTime to align periods, not instant. In the following example, offsetDateTime is the 1st of March in UTC+2, but still 28th of February in UTC. When adding a month, the library considers offsetDateTime to be the 1st of March, so it adds 31 days, not 28:

const offsetDateTime = OffsetDateTime.parse("2022-03-01T00:00:00.000+02:00");
const d1 = offsetDateTime.plusPeriod(MONTH_PERIOD);              // Midnight on 1st of April, 2022, UTC+2

If you expect a month to be added in UTC, convert the instant explicitly to UTC first:

const d2 = offsetDateTime.instant.atOffset(UTC).plusPeriod(MONTH_PERIOD); // 22:00 on 28th of March, 2022, UTC

To add/subtract a Duration, call plusDuration/minusDuration method:

const offsetDateTime = OffsetDateTime.parse("2022-02-15T18:30:15.225-02:00");
const d1 = offsetDateTime.plusDuration(MINUTE_DURATION);         // 18:31:15.225 on 15th of February, 2022, UTC-2
const d2 = offsetDateTime.plusDuration(Duration.ofHours(10));    // 04:30:15.225 on 16th of February, 2022, UTC-2
const d3 = offsetDateTime.minusDuration(Duration.ofSeconds(30)); // 18:29:45.225 on 15th of February, 2022, UTC-2

For difference between Period and Duration, see their documentation. For OffsetDateTime, they are interchangeable - apart for the list of supported date/time components.

To change one of the components, preserving all the rest, call with* methods:

const offsetDateTime = OffsetDateTime.parse("2022-02-15T18:30:15.225-02:00");
const d1 = offsetDateTime.withYear(2025);                        // 18:30:15.225 on 15th of February, 2025, UTC-2
const d2 = offsetDateTime.withMonth(APRIL);                      // 18:30:15.225 on 15th of April, 2022, UTC-2
const d3 = offsetDateTime.withDayOfMonth(10);                    // 18:30:15.225 on 10th of February, 2022, UTC-2
const d4 = offsetDateTime.withDayOfWeek(SUNDAY);                 // 18:30:15.225 on 20th of February, 2022, Sunday, UTC-2
const d5 = offsetDateTime.withHour(20);                          // 20:30:15.225 on 15th of February, 2022, UTC-2
const d6 = offsetDateTime.withMinute(20);                        // 18:20:15.225 on 15th of February, 2022, UTC-2
const d7 = offsetDateTime.withSecond(20);                        // 18:30:20.225 on 15th of February, 2022, UTC-2
const d8 = offsetDateTime.withMs(20);                            // 18:30:15.020 on 15th of February, 2022, UTC-2

For manipulating offset component, see Convert.

The library doesn't yet support OffsetDateTime truncating. Truncate its dateTime component instead.

Another sophisticated feature for OffsetDateTime manipulation: withDayOfYear.

Convert#

You can convert OffsetDateTime to other kinds of objects via its properties:

const offsetDateTime = OffsetDateTime.parse("2022-02-15T18:30:15.225-02:00");
offsetDateTime.instant;                   // To Instant: 2022-02-15T20:30:15.225Z
offsetDateTime.date;                      // To LocalDate: 2022-02-15
offsetDateTime.time;                      // To LocalTime: 18:30:15.225
offsetDateTime.dateTime;                  // To LocalDateTime: 2022-02-15T18:30:15.225
offsetDateTime.instant.atOffset(offset);  // To OffsetDateTime with another ZoneOffset, preserving instant component: 2022-02-16T00:30:15.225+04:00
offsetDateTime.dateTime.atOffset(offset); // To OffsetDateTime with another ZoneOffset, preserving dateTime component: 2022-02-15T18:30:15.225+04:00
offsetDateTime.instant.atZone(zone);      // To ZonedDateTime in a given ZoneId, preserving instant component: 2022-02-15T20:30:15.225Z
offsetDateTime.dateTime.atZone(zone);     // To ZonedDateTime in a given ZoneId, preserving dateTime component: 2022-02-15T18:30:15.225Z

Please notice that all conversions result in a partial data loss (date, time, original offset).

You can as well convert OffsetDateTime to a native JavaScript Date:

const offsetDateTime = OffsetDateTime.parse("2022-02-15T18:30:15.225-02:00");
offsetDateTime.native;                    // Date representing 20:30:15.225 on 15th of February, 2022 (UTC)

Please notice that native Date is always stored in UTC or local time zone, so you can see a different date/time when printing it as a string. It will be the same instant, just a different time zone.

For backward conversion, see Construct.

Format#

Every class in ts-time has ISO 8601 compliant toString method:

const offsetDateTime = OffsetDateTime.parse("2022-02-15T18:30:15.225-02:00");
offsetDateTime.toString(); // "2022-02-15T18:30:15.225-02:00"

For more sophisticated string formatting, add ts-time-format library to your list of dependencies:

npm install --save ts-time-format

Now you can construct an instance of OffsetDateTimeFormatter in order to format arbitrary OffsetDateTime instances:

const formatter = OffsetDateTimeFormatter.ofPattern("dd.MMM''yy, hh:mm a ('UTC'x)");
const offsetDateTime = OffsetDateTime.parse("2022-02-15T18:30:15.225-02:00");
formatter.format(offsetDateTime); // "15.Feb'22, 06:30 PM (UTC-02)"

You can define a custom context object to internationalize the formatted strings:

const context = {monthShortNames: ["Янв", "Фев", "Мар"]};
formatter.format(offsetDateTime, context); // "15.Фев'22, 06:30 PM (UTC-02)"

Fields#

dateTime#

readonly dateTime: LocalDateTime

Date/time representing instant in offset.
instant#

readonly instant: Instant

Instant representing dateTime in offset.
offset#

readonly offset: ZoneOffset

Time zone offset. Connection between instant and dateTime.
date#

readonly date: LocalDate

Date part.
time#

readonly time: LocalTime

Time part.
native#

readonly native: Date

Native JS Date representing instant, for compatibility with native and third party API.
epochMs#

readonly epochMs: number

Number of milliseconds since epoch.
era#

readonly era: Era

Era.
year#

readonly year: number

Absolute year.
yearOfEra#

readonly yearOfEra: number

Year in era. See Era for details.
weekBasedYear#

readonly weekBasedYear: number

Absolute week based year.

By definition, the 1st week of week based year contains the 1st Thursday of the year, and the week based year starts from the Monday of this week.

month#

readonly month: Month

Month.
weekOfWeekBasedYear#

readonly weekOfWeekBasedYear: number

1-based week of week-based year.

By definition, the 1st week of week based year contains the 1st Thursday of the year, and the week based year starts from the Monday of this week.

dayOfYear#

readonly dayOfYear: number

1-based day of year.
dayOfWeekBasedYear#

readonly dayOfWeekBasedYear: number

1-based day of week-based year.

By definition, the 1st week of week based year contains the 1st Thursday of the year, and the week based year starts from the Monday of this week.

dayOfMonth#

readonly dayOfMonth: number

1-based day of month.
dayOfWeek#

readonly dayOfWeek: DayOfWeek

Day of week.
epochDay#

readonly epochDay: number

1-based day since epoch (i.e. 1st of JANUARY 1970 is the 1st epoch day).
quarterOfYear#

readonly quarterOfYear: number

1-based quarter of year.
isLeapYear#

readonly isLeapYear: boolean

True if belongs to a leap year.
lengthOfYear#

readonly lengthOfYear: number

Number of days in year (365 for non-leap, 366 for leap).
hour#

readonly hour: number

Hour of a day (0-23).
minute#

readonly minute: number

Minute of an hour (0-59).
second#

readonly second: number

Second of a minute (0-59).
ms#

readonly ms: number

Millisecond of a second (0-999).

Methods#

compareTo#

(other: OffsetDateTime): number

other
Offset date/time to compare to.
returns
  • 0 if this is the same offset date/time;
  • positive value if this offset date/time goes after other;
  • negative value if this offset date/time goes before other.
The objects are first compared by instant, and then by offset. Null and undefined are considered less than anything, except each other.

Note that a method call on null or undefined always leads to an error. So, if your variable may contain null or undefined, use the respective static method instead.

equals#

(other: OffsetDateTime): boolean

other
Offset date/time to compare to.
returns
True if this offset date/time is equal to other, i.e. all components are equal. Null and undefined are only equal to each other.

Note that a method call on null or undefined always leads to an error. So, if your variable may contain null or undefined, use the respective static method instead.

plusDuration#

(duration: Duration): OffsetDateTime

duration
Duration to add.
returns
New OffsetDateTime shifted onwards from this one by the specified duration in the same offset.
plusPeriod#

(period: Period): OffsetDateTime

period
Period to add.
returns
New OffsetDateTime shifted onwards from this one by the specified period in the same offset. The algorithm respects dateTime to align periods.
minusDuration#

(duration: Duration): OffsetDateTime

duration
Duration to subtract.
returns
New OffsetDateTime shifted backwards from this one by the specified duration in the same offset.
minusPeriod#

(period: Period): OffsetDateTime

period
Period to subtract.
returns
New OffsetDateTime shifted backwards from this one by the specified period in the same offset. The algorithm respects dateTime to align periods.
withYear#

(year: number): OffsetDateTime

year
Absolute year.
returns
New OffsetDateTime with the specified year and its current month/day of month/time/offset. If such date doesn't exist, it shifts the date back to the nearest valid one, preserving the time (e.g. 29th of FEBRUARY in 2019, 18:30, UTC+3 gets shifted to 28th of FEBRUARY, 18:30, UTC+3).
withMonth#

(month: number | Month): OffsetDateTime

month
Month.
returns
New OffsetDateTime with the specified month and its current year/day of month/time/offset. If such date doesn't exist, it shifts the date back to the nearest valid one, preserving the time (e.g. 31st of APRIL, 18:30, UTC+3 gets shifted to 30th of APRIL, 18:30, UTC+3).
withDayOfMonth#

(dayOfMonth: number): OffsetDateTime

dayOfMonth
1-based day of month.
returns
New OffsetDateTime with the specified day of month and its current year/month/time/offset.
withDayOfWeek#

(dayOfWeek: number | DayOfWeek): OffsetDateTime

dayOfWeek
Day of week or its numeric value
returns
New OffsetDateTime with the specified day of week and its current week/time/offset.
withDayOfYear#

(dayOfYear: number): OffsetDateTime

dayOfYear
1-based day of year.
returns
New OffsetDateTime with the specified day of year and its current year/time/offset.
withHour#

(hour: number): OffsetDateTime

hour
Hour of a day.
returns
New OffsetDateTime with the specified hour of a day. All other properties don't change.
withMinute#

(minute: number): OffsetDateTime

minute
Minute of an hour.
returns
New OffsetDateTime with the specified minute of an hour. All other properties don't change.
withSecond#

(second: number): OffsetDateTime

second
Second of a minute.
returns
New OffsetDateTime with the specified second of a minute. All other properties don't change.
withMs#

(ms: number): OffsetDateTime

ms
Millisecond of a second.
returns
New OffsetDateTime with the specified millisecond of a second. All other properties don't change.
toString#

(): string

returns
String representation of the offset date/time in ISO format, such as "2019-12-30T18:30:15.225+03:00".

Static methods#

ofInstant#

(instant: Instant, offset: ZoneOffset): OffsetDateTime

instant
Instant.
offset
Time zone offset.
returns
New OffsetDateTime representing instant in offset.
ofDateTime#

(localDateTime: LocalDateTime, offset: ZoneOffset): OffsetDateTime

localDateTime
Local date/time.
offset
Time zone offset.
returns
New OffsetDateTime representing dateTime in offset.
parse#

(str: string): OffsetDateTime throws TemporalParsingError

str
String representation of offset date/time in ISO format, such as '2019-12-30T18:30:15.225+03:00'.
returns
OffsetDateTime representation.
compare#

(x: OffsetDateTime, y: OffsetDateTime): number

x
One offset date/time.
y
Another offset date/time.
returns
  • 0 if this x and y are the same offset date/time;
  • positive value if x goes after y;
  • negative value if x goes before y.
The objects are first compared by instant, and then by offset. Null and undefined are considered less than anything, except each other.
equal#

(x: OffsetDateTime, y: OffsetDateTime): boolean

x
One offset date/time.
y
Another offset date/time.
returns
True if x is equal to y, i.e. all components are equal. Null and undefined are only equal to each other.