Formatting dates
OpenMRS provides several utilities to work with dates. These utilities have been designed with locale sensitivity in mind. Acceptable date formats vary by language and region, and the functions are intended to accommodate that variation.
Utilities for formatting dates for display
formatDate
This utility accepts a Date object and returns a string. It formats the input date according to the current locale and the given parameters:
formatDate(date: Date, options?: {
mode?: "standard" | "wide",
time?: boolean | "for today",
day?: boolean,
month?: boolean,
year?: boolean,
noToday?: boolean,
locale?: string,
calendar?: string,
numberingSystem?: string
}): stringThe mode parameter can be set to standard or wide.
For English dates, standard mode displays a date such as 16-May-2023, while wide mode displays a date such as 16 — May — 2023. Other locales may use locale-specific month names, calendars, and punctuation.
By default, formatDate uses { mode: "standard", time: "for today", day: true, month: true, year: true, noToday: false }. If the date is today, then Today is produced instead of the actual day in the locale language, and the time is appended because the default time option is "for today". Pass { time: false } to suppress the time for today’s date, or { noToday: true } to format today like any other date.
When the time option is set to true, the time is appended with a comma and a space, e.g. 16-May-2023, 08:21. This format agrees with the output of Date.prototype.toLocaleString for most locales.
Here’s an example of how to use formatDate with a Date object:
import { formatDate } from "@openmrs/esm-framework";
function AppointmentDetails({ appointment }: AppointmentDetailsProps) {
return <span>{formatDate(appointment.scheduledDate, { mode: "standard" })}</span>;
}For an English locale, the returned value would be a string in the format 18-May-2023.
formatPartialDate
Use formatPartialDate when a value may contain only a year or a year and month. This is common for approximate clinical dates. It parses the string using the current locale, hides date parts that were not present in the input, and then delegates formatting to formatDate.
formatPartialDate(dateString: string, options?: Partial<FormatDateOptions>): string | nullformatPartialDate("2021"); // "2021"
formatPartialDate("2021-04"); // "Apr 2021"
formatPartialDate("2021-04-09"); // "09-Apr-2021"formatDatetime
This utility function accepts a Date object and returns a string.
It formats the input date to display both the date and time, separated by a comma, according to the current locale and the given options.
formatDatetime accepts the same options as formatDate except for time, which is always included:
formatDatetime(date: Date, options?: Partial<Omit<FormatDateOptions, "time">>): stringHere’s an example of how to use formatDatetime:
import { formatDatetime } from "@openmrs/esm-framework";
function AppointmentDetails({ appointment }: AppointmentDetailsProps) {
return <span>{formatDatetime(appointment.scheduledDate)}</span>;
}For an English locale, the returned value would be a string such as 18-May-2023, 08:21.
formatTime
This utility function accepts a Date object and returns a string. It formats the time according to the current locale using the 12- or 24-hour format.
formatTime(date: Date): stringHere’s an example of how to use formatTime:
import { formatTime } from "@openmrs/esm-framework";
function AppointmentDetails({ appointment }: AppointmentDetailsProps) {
return <span>{formatTime(appointment.scheduledDate)}</span>;
}The returned value depends on the locale. For example, it may be 08:21 in a 24-hour locale or 08:21 AM in a 12-hour locale.
Durations
Use formatDuration when you already have a structured Intl.DurationInput value, or formatDurationBetween when you want to calculate and format the duration between two dates.
formatDuration(duration: Intl.DurationInput, options?: Intl.DurationFormatOptions): string
formatDurationBetween(
startDate: dayjs.ConfigType,
endDate?: dayjs.ConfigType,
options?: DurationUnit | DurationOptionsWithFormat
): string | nullimport { formatDurationBetween } from "@openmrs/esm-framework";
formatDurationBetween("2022-01-01", "2024-07-30"); // "2 yrs"
formatDurationBetween("2022-01-01", "2024-07-30", {
largestUnit: "years",
smallestUnit: "days",
formatOptions: { style: "long" },
}); // "2 years, 6 months, 29 days"The lower-level duration helper returns the structured Intl.DurationInput object instead of formatted text. It uses the same auto-selection thresholds as formatDurationBetween and accepts singular or plural unit names, such as "year" or "years".
isOmrsDateStrict
This utility strictly checks whether a date string matches the OpenMRS payload date-time format. The format should be YYYY-MM-DDTHH:mm:ss.SSSZZ.
It accepts an omrsPayloadString and returns a boolean.
isOmrsDateStrict(omrsPayloadString: string): booleanisOmrsDateToday
This utility checks if the provided date is today. Accepts a DateInput and returns a boolean.
isOmrsDateToday(date: DateInput): booleanparseDate
This utility function parses an arbitrary dateString into a Date. It uses dayjs(dateString).
Here’s an example of how to use parseDate with an OpenMRS date-time string:
import { formatDate, parseDate } from "@openmrs/esm-framework";
function EncounterDate({ encounter }: EncounterDateProps) {
return <span>{formatDate(parseDate(encounter.encounterDateTime))}</span>;
}For an English locale, the returned value would be a string in the format 18-May-2023.
toDateObjectStrict
This utility function converts an OpenMRS payload date-time string to a Date object. It accepts omrsDateString and returns a Date or null.
toDateObjectStrict(omrsDateString: string): Date | nulltoOmrsIsoString
This utility function formats the input date to a string using the format YYYY-MM-DDTHH:mm:ss.SSSZZ. It is mostly used to format dates before submitting data in payloads.
toOmrsIsoString(date: DateInput, toUTC?: boolean): stringThe toUTC parameter is optional and defaults to false. When set to true, the date will be converted to UTC before formatting.
Here’s an example of how to use toOmrsIsoString in a payload:
body: {
visit: visitUuid,
patientUuid: patientUuid,
startedAt: toOmrsIsoString(new Date()),
}Locale calendars
O3 can format dates using locale-specific calendars. The app shell registers implementation-level calendar preferences from the styleguide preferredCalendar configuration, and formatDate also accepts a calendar option for one-off overrides.
Use registerDefaultCalendar(locale, calendar) to register a default calendar for a locale, getDefaultCalendar(locale) to inspect the resolved calendar, and convertToLocaleCalendar(date, locale) when working with @internationalized/date calendar values.