ts-time

TypeScript/JavaScript library of immutable date/time models with time zone support.


This library mimics Java 8 Date/Time API, adjusting its API to the best practices of TypeScript and JavaScript. It uses Intl.DateTimeFormat API to detect time zone offsets, providing efficient and reliable time zone support in your client code.

ts-time

ts-time is available as npm package.

  npm install --save ts-time

ts-time features:

ts-time is a pure definitely-typed object-oriented solution. Any code fragment developed with ts-time is easy to read, understand and maintain, because it manipulates data structures serving specific purposes:

  import LocalDate from "ts-time/LocalDate";
  import Period from "ts-time/Period";

  function buildGraduation(from: LocalDate, to: LocalDate, step: Period) {
    const result: LocalDate[] = [];
    while (from.isBefore(to)) {
      result.push(from);
      from = from.plus(step);
    }
    return result;
  }

All data structures defined in ts-time are immutable. Thanks to this, you can be sure that your values never get spoiled when you pass them to a third party function or component. For third parties that don't support ts-time data structures, you may convert the structures to native Date or milliseconds and back.

None of the defined data structures has public constructors. You should use static methods to initialize them. Methods starting with "of" create new instances by parameters. Methods starting with "from" convert the structures to each other. Methods "parse" create new instances by strings, that are always compatible with "toString".


ts-time-format

ts-time-format is an extension of ts-time library with date/time formatting capabilities.

  npm install --save ts-time-format

As opposed to ts-time, ts-time-format API is very different from Java 8 Date/Time API, because its author finds Java API for date/time formatting way too loose and error-prone. Implementation of ts-time-format is more strict - for every class of ts-time there's a specialized implementation of TemporalFormatter supporting its own set of features. The library doesn't support date/time parsing by an arbitrary pattern.

Examples

1. LocalDate, DateFormatter, Period: Print a calendar for June 2022

LocalDate stores a date without attachment to time or a time zone. It works the best when you want to build a time zone agnostic calendar.

  const startDate = LocalDate.of(2022, JUNE);
  const formatter = DateFormatter.ofPattern("d - EE");
  for (let date = startDate; date.month === startDate.month; date = date.plus(DAY_PERIOD)) {
    console.log(formatter.format(date));
  }

Prints:

  1 - Wednesday
  2 - Thursday
  3 - Friday
  ...
  30 - Thursday

2. LocalTime, Duration: School scheduling

LocalTime stores time without attachment to a date or a time zone. It works the best when you want to build a schedule for a day that can be reused all across the school semester.

  const startTime = LocalTime.of(9); // 9:00 AM
  const schedule: Duration[] = [
    Duration.ofMinutes(90), // First lesson
    Duration.ofMinutes(10), // Break
    Duration.ofMinutes(90), // Second lesson
    Duration.ofHours(1),    // Lunch time
    Duration.ofHours(2),    // Third lesson
  ];
  const endTime = schedule.reduce((time, duration) => time.plus(duration), startTime);

  // Alternatively:
  const totalDuration = schedule.reduce((x, y) => x.plus(y), NULL_DURATION);
  const endTime = startTime.plus(totalDuration);

  console.log(endTime.toString()); // Prints: 15:10:00.000

3. LocalDateTime: Simple in-game clock

LocalDateTime is a simple date and time presentation perfect for scenarios when you don't care about time zones. For example, when you develop a game like town construction simulator.

  const startInGameTime = LocalDateTime.parse("2200-01-01T00:00:00.000");
  const inGameTimeElapsed = Duration.ofComponents(45, 3, 12, 44); // 45 days 3 hours 12 minutes 44 seconds
  const currentInGameTime = startInGameTime.plusDuration(inGameTimeElapsed);
  console.log(currentInGameTime.toString()); // Prints: 2200-02-15T03:12:44.000

4. ZonedDateTime, ZoneId, Instant: Compute plane arrival time

ZonedDateTime stores date and time attached to a specific time zone. When converting it to a different time zone, you must make a decision: do you want to preserve an instant or a dateTime. In this example, we preserve an instant, because that's what is important for us.

  const departureTime = ZonedDateTime.parse("2022-06-15T18:30:00.000+02:00[Europe/Berlin]");
  const arrivalTimeZone = ZoneId.of("Europe/London");
  const flightDuration = Duration.ofComponents(0, 1, 50); // 0 days 1 hour 50 minutes

  const arrivalTime = departureTime.instant.plus(flightDuration).atZone(arrivalTimeZone);

  // Alternatively (less intuitive, but still correct):
  const arrivalTime = departureTime.plusDuration(flightDuration).instant.atZone(arrivalTimeZone);

  console.log(arrivalTime.toString()); // Prints: 2022-06-15T19:20:00.000+01:00[Europe/London]

OffsetDateTime is similar to ZonedDateTime, but it doesn't take time zone shifts (such as daylight saving time) into consideration, thus typically shouldn't be used.

Browser support

Microsoft Edge, Google Chrome, Mozilla Firefox, NodeJS: full support.

Internet Explorer 11: all features except local time zones are supported. All local time zones have zero offset.

Other browsers: not tested.

Project license is MIT.

Find source code and bug tracker at GitHub.