# Migrate from @internationalized/date to Temporal with GMT

Checked against @internationalized/date 3.12.4 on 2026-10-27.

[Migrate to Temporal with GMT](/gmt/migrate/) explains the one change that applies to every call below: GMT takes strings in and gives strings out.

## Call by call

| @internationalized/date | GMT | Note |
| --- | --- | --- |
| `parseDate(s)` | [`isValidDate`](/gmt/reference/plain/validate/isValidDate) | `parseDate` throws on 2024-02-30; `isValidDate` returns `false`. |
| `parseDateTime(s)` | [`isValidDateTime`](/gmt/reference/plain/validate/isValidDateTime) |  |
| `parseZonedDateTime(s, disambiguation)` | [`isValidZonedDateTime`](/gmt/reference/zoned/validate/isValidZonedDateTime), [`isValidCalendarZonedDateTime`](/gmt/reference/zoned/validate/isValidCalendarZonedDateTime) | The library rejects a string with a `[u-ca=…]` annotation. |
| `parseAbsolute(s, z)` | [`convertUtcToZoned`](/gmt/reference/utc/convert/convertUtcToZoned), [`convertZonedToZoned`](/gmt/reference/zoned/convert/convertZonedToZoned) | The library reads an offset with minutes before UTC one hour off. |
| `parseAbsoluteToLocal(s)` | [`convertUtcToZoned`](/gmt/reference/utc/convert/convertUtcToZoned), [`getSystemTimeZone`](/gmt/reference/zoned/get/getSystemTimeZone) |  |
| `today(z)` | [`getZonedToday`](/gmt/reference/zoned/get/getZonedToday) |  |
| `now(z)` | [`getZonedNow`](/gmt/reference/zoned/get/getZonedNow) |  |
| `d.add({ days: 1 })` | [`addDate`](/gmt/reference/plain/calculate/addDate), [`addZoned`](/gmt/reference/zoned/calculate/addZoned) | The Berlin gap result is the same. |
| `d.add({ months: 1 })` | [`addDate`](/gmt/reference/plain/calculate/addDate) | The day is clamped to the month length. |
| `d.subtract({ … })` | [`subtractDate`](/gmt/reference/plain/calculate/subtractDate), [`subtractZoned`](/gmt/reference/zoned/calculate/subtractZoned) |  |
| `zdt.add({ hours: 1 })` | [`addZoned`](/gmt/reference/zoned/calculate/addZoned) |  |
| `b.compare(a)` | [`diffDate`](/gmt/reference/plain/calculate/diffDate) | The library has no month difference; `diffDate(a, b, "months")` returns one. |
| `startOfMonth(d)`, `endOfMonth(d)` | [`startOfDate`](/gmt/reference/plain/calculate/startOfDate), [`endOfDate`](/gmt/reference/plain/calculate/endOfDate) |  |
| `startOfWeek(d, locale)` | [`getLocaleStartOfWeek`](/gmt/reference/plain/calculate/getLocaleStartOfWeek) | Both read the first day from the locale. |
| `a.compare(b) < 0` | [`isBeforeDate`](/gmt/reference/plain/compare/isBeforeDate) |  |
| `isSameDay(a, b)`, `isSameMonth(a, b)` | [`areDatesEqualBy`](/gmt/reference/plain/compare/areDatesEqualBy) |  |
| `isEqualDay(a, b)` | [`areDatesEqual`](/gmt/reference/plain/compare/areDatesEqual) |  |
| `minDate(a, b)`, `maxDate(a, b)` | [`minDate`](/gmt/reference/plain/calculate/minDate), [`maxDate`](/gmt/reference/plain/calculate/maxDate) | GMT takes an array. |
| `d.calendar.getDaysInMonth(d)` | [`getDaysInMonth`](/gmt/reference/plain/calculate/getDaysInMonth) |  |
| `getDayOfWeek(d, locale)` | [`getLocaleDayOfWeek`](/gmt/reference/plain/calculate/getLocaleDayOfWeek), [`parseDayOfWeekFromDate`](/gmt/reference/plain/parse/parseDayOfWeekFromDate) | `getLocaleDayOfWeek` counts from the locale's first day; `parseDayOfWeekFromDate` returns the ISO number 1 to 7. |
| `isWeekend(d, locale)` | [`isWeekend`](/gmt/reference/plain/compare/isWeekend) | Both read CLDR week data. |
| `toTimeZone(zdt, z)` | [`convertZonedToZoned`](/gmt/reference/zoned/convert/convertZonedToZoned) |  |
| `toZoned(dt, z, disambiguation)` | [`convertPlainDateTimeToZoned`](/gmt/reference/zoned/convert/convertPlainDateTimeToZoned) | The option takes the same four values. |
| `toCalendar(d, createCalendar("japanese"))` | [`convertDateToCalendar`](/gmt/reference/plain/convert/convertDateToCalendar) |  |
| `getHoursInDay(d, z)` | [`getHoursInZonedDay`](/gmt/reference/zoned/calculate/getHoursInZonedDay) |  |
| `parseDuration(s)`, `DateFormatter(locale, o).format(…)` | [`parseDuration`](/gmt/reference/duration/parse/parseDuration), [`formatDate`](/gmt/reference/plain/format/formatDate) |  |

## What changes

- The library has immutable `CalendarDate`, `CalendarDateTime` and `ZonedDateTime` classes. GMT takes and returns strings.
- Months run from 1 to 12 in both.
- Its `Disambiguation` type has the same four values as Temporal and as GMT: `compatible`, `earlier`, `later` and `reject`.
- Invalid input throws. GMT returns `""`, `null`, `false` or `[]`.
- The library has no ISO-week call and no month difference between two dates.

```js
import { diffDate } from "@northguild/gmt/plain/calculate";

diffDate("2024-03-01", "2024-03-15", "days"); // 14
```

## Where @internationalized/date differs from Temporal

Each item is a case where the library's result differs from Temporal's. The [full matrix](/gmt/compare/behaviour/) also lists the cases where it matches.

- **M9c. Parse a date in basic format** Input: "20240212". The library returns Error: Invalid ISO 8601 date string: 20240212; Temporal returns 2024-02-12. Specification: [RFC 3339 section 5.6](https://www.rfc-editor.org/rfc/rfc3339#section-5.6). [Matrix row](/gmt/compare/behaviour/#m9c-internationalized-date).
- **M10c. Read a string with a calendar annotation** Input: 2024-03-31T03:30:00+02:00\[Europe/Berlin\]\[u-ca=japanese\]. The library returns RangeError: Invalid time zone specified: Europe/Berlin\]\[u-ca=japanese; Temporal returns accepted. Specification: [RFC 9557 section 3.3](https://www.rfc-editor.org/rfc/rfc9557#section-3.3). [Matrix row](/gmt/compare/behaviour/#m10c-internationalized-date).
- **M11. Read an offset with minutes before UTC** Input: 2024-01-15T12:00:00-03:30. The library returns 2024-01-15T14:30:00.000Z; Temporal returns 2024-01-15T15:30:00Z. Specification: [RFC 3339 section 4.2](https://www.rfc-editor.org/rfc/rfc3339#section-4.2). Upstream: [adobe/react-spectrum#10809](https://github.com/adobe/react-spectrum/issues/10809). [Matrix row](/gmt/compare/behaviour/#m11-internationalized-date).

## More calls

| @internationalized/date | GMT | Note |
| --- | --- | --- |
| `getLocalTimeZone()` | [`getSystemTimeZone`](/gmt/reference/zoned/get/getSystemTimeZone) |  |
| `d.set({ month: 2 })` | [`setDate`](/gmt/reference/plain/calculate/setDate) |  |
| `fromDate(date, z)` | [`convertUtcToZoned`](/gmt/reference/utc/convert/convertUtcToZoned) | Pass `date.toISOString()`. |
| ISO week | [`getIsoWeekDate`](/gmt/reference/calendar/calculate/getIsoWeekDate) | The library has no ISO-week call. |
