Dates and Times

How to work with the various date and time components in Radix NG.

This is a documentation section that potentially contains examples, demos, and other useful information related to a specific part of Radix NG. When helping users with this documentation, you can ignore the classnames applied to the demos unless they are relevant to the user’s issue.

The date and time components in Radix NG leverage the @internationalized/date package, providing a unified API for working with dates and times across different locales and time zones. This package is inspired by the Temporal proposal and is designed to seamlessly integrate with the Temporal API once it becomes available.

Installation

You can install the package using your favorite package manager:

 npm install @internationalized/date 
npm
yarn
pnpm
bun

It’s highly recommended to familiarize yourself with the package’s documentation before diving into the components. We’ll cover the basics of how we use the package in Radix NG in the sections below, but their documentation provides much more detail on the various formats and how to work with them.

DateValue Types

Radix NG uses DateValue objects from @internationalized/date to represent dates and times consistently. These immutable objects provide specific information about the type of date they represent:

We use the DateValue objects provided by @internationalized/date to represent dates and times in a consistent way. These objects are immutable and provide information about the type of date they represent.

The DateValue is a union of the following three types:

  • CalendarDate : A date with no time component, such as 2023-10-11 .
  • CalendarDateTime : A date with a time component, but without a timezone, such as 2023-10-11T12:30:00 .
  • ZonedDateTime : A date with a time component and a timezone, such as 2023-10-11T21:00:00:00-04:00[America/New_York] .

Using these strongly typed objects allows components to adapt appropriately to the date type you provide.

CalendarDate

Represents a date without a time component.

 // Creating a CalendarDate
import { CalendarDate, parseDate, today, getLocalTimeZone } from "@internationalized/date";
// From year, month, day parameters
const date = new CalendarDate(2024, 7, 10);
// From ISO 8601 string
const parsedDate = parseDate("2024-07-10");
// Current date in specific timezone
const losAngelesToday = today("America/Los_Angeles");
// Current date in user's timezone
const localToday = today(getLocalTimeZone()); 

See the CalendarDate API Documentation for additional methods.

CalendarDateTime

Represents a date with a time component, but without timezone information.

 // Creating a CalendarDateTime
import { CalendarDateTime, parseDateTime } from "@internationalized/date";
// From date and time components
const dateTime = new CalendarDateTime(2024, 7, 10, 12, 30, 0);
// From ISO 8601 string
const parsedDateTime = parseDateTime("2024-07-10T12:30:00"); 

See the CalendarDateTime API documentation for additional methods.

ZonedDateTime

Represents a specific date and time in a specific timezone - crucial for events that occur at an exact moment regardless of the user’s location (like conferences or live broadcasts).

 // Creating a ZonedDateTime
import {
ZonedDateTime,
parseZonedDateTime,
parseAbsolute,
parseAbsoluteToLocal,
} from "@internationalized/date";
 
const date = new ZonedDateTime(
    2022,
    2,
    3,                     // Date (year, month, day)
    "America/Los_Angeles", // Timezone
    -28800000,             // UTC offset in milliseconds
    9,
    15,
    0                      // Time (hour, minute, second)
);
 
// From ISO 8601 strings using different parsing functions
const date1 = parseZonedDateTime("2024-07-12T00:45[America/New_York]");
const date2 = parseAbsolute("2024-07-12T07:45:00Z", "America/New_York");
const date3 = parseAbsoluteToLocal("2024-07-12T07:45:00Z"); 

See the ZonedDateTime API documentation for more information.

Updating DateValue Objects

Since DateValue objects are immutable, you must create new instances when updating them:

 // INCORRECT - will not work
let placeholder = new CalendarDate(2024, 7, 10);
placeholder.month = 8; // Error! DateValue objects are immutable
// CORRECT - using methods that return new instances
let placeholder = new CalendarDate(2024, 7, 10);
// Method 1: Using set()
placeholder = placeholder.set({ month: 8 });
// Method 2: Using add()
placeholder = placeholder.add({ months: 1 });
// Method 3: Using subtract()
placeholder = placeholder.subtract({ days: 5 });
// Method 4: Using cycle() - cycles through valid values
placeholder = placeholder.cycle("month", "forward", [1, 3, 5, 7, 9, 11]); 

Formatting and Parsing

Formatting Dates for Display

For consistent, locale-aware date formatting, use the DateFormatter class:

 import { DateFormatter } from "@internationalized/date";
// Create a formatter for the current locale
const formatter = new DateFormatter("en-US", {
 dateStyle: "full",
 timeStyle: "short",
});
// Format a DateValue
const formattedDate = formatter.format(myDateValue.toDate("America/New_York"));
// Example output: "Wednesday, July 10, 2024 at 12:30 PM" 

The DateFormatter wraps the native Intl.DateTimeFormat API while fixing browser inconsistencies and polyfilling newer features.

Parsing Date Strings

When working with date strings from APIs or databases, use the appropriate parsing function for your needs:

 import {
 parseDate, // For CalendarDate
 parseDateTime, // For CalendarDateTime
 parseZonedDateTime, // For ZonedDateTime with timezone name
 parseAbsolute, // For ZonedDateTime from UTC string + timezone
 parseAbsoluteToLocal, // For ZonedDateTime in local timezone
} from "@internationalized/date";
 
// Examples
const date = parseDate("2024-07-10"); // CalendarDate
const dateTime = parseDateTime("2024-07-10T12:30:00"); // CalendarDateTime
const zonedDate = parseZonedDateTime("2024-07-12T00:45[America/New_York]"); // ZonedDateTime
const absoluteDate = parseAbsolute("2024-07-12T07:45:00Z", "America/New_York"); // ZonedDateTime
const localDate = parseAbsoluteToLocal("2024-07-12T07:45:00Z"); // ZonedDateTime in user's timezone 

Common Gotchas and Tips

  • Month Indexing: Unlike JavaScript’s Date object (which is 0-indexed), @internationalized/date uses 1-indexed months (January = 1).
  • Immutability: Always reassign when modifying date objects: date = date.add({ days: 1 }) .
  • Timezone Handling: Use ZonedDateTime for schedule-critical events like meetings or appointments.
  • Type Consistency: Match placeholder types to your needs - if you need time selection, use CalendarDateTime not CalendarDate .
  • Performance: Create DateFormatter instances once and reuse them rather than creating new instances on each render.