System Functions - Done
Format Date
Function
formatDate(date, pattern, isInputUTC, outputTZ)
Description
The formatDate function is designed for developers integrating it into various applications to handle date and time formatting across different timezones seamlessly.
- Automatic Timezone Detection:
- By default, the function detects the user's (client's) timezone using dayjs.tz.guess(). This makes it ideal for client-side applications where the user's timezone can be accurately determined.
- Client-Side Optimization:
- Since the function automatically detects the local timezone, it is primarily intended to be run client-side. This ensures that the formatted dates align with the user's local settings.
- Server-Side Usage:
- When running the function server-side, dayjs.tz.guess() may detect the server's timezone instead of the client's. To maintain consistency and avoid discrepancies, it is recommended to always set isInputUTC to true when using the function in a server-side environment. This treats the input date as UTC, ensuring that the output remains consistent regardless of the server's timezone.
- Timezone Handling:
- Input Timezone: Developers can specify if the input date is in UTC by setting the isInputUTC parameter to true. If not specified, the function uses the detected local timezone.
- Output Timezones: Developers can specify one or more additional output timezones. Regardless of the specified timezones, UTC is always included in the output.
- Flexible Formatting:
- Validation:
- Validates the input Date object and the format pattern to ensure accurate formatting.
- Handles invalid timezone inputs gracefully by skipping them and logging warnings, while still including UTC in the output.
- Consistent Output Structure:
- Returns an object containing:
- isValid: A boolean indicating the validity of the input date.
- formattedDates: An object mapping each specified timezone (including UTC) to its corresponding formatted date string.
Notes
- Assumed Local Timezone:
- For the examples provided, it's assumed that the user's local timezone is America/New_York (UTC-5). If your local timezone differs, adjust the expected outputs accordingly.
- Handling Invalid Timezones:
- If an invalid timezone is provided in outputTZ, the function will skip it and log a warning to the console. UTC will still be included in the output.
- Default Behavior:
- If outputTZ is not specified, the function defaults to including both 'Local' and 'UTC' formatted dates.
- Including UTC Always:
- The formatDate function is designed to always include UTC in the output, ensuring a consistent reference point regardless of other specified timezones.
- Pattern Flexibility:
- Ensure that the pattern provided is compatible with dayjs formatting tokens to achieve the desired date and time representations.
Usage Scenarios:
- Default Formatting: Format a date using the local timezone and UTC.
- Specify Input as UTC: Indicate that the input date is in UTC and format accordingly, especially useful in server-side applications.
- Multiple Output Timezones: Obtain formatted dates in multiple timezones alongside UTC.
- Handle Invalid Inputs: Safely handle invalid dates or timezones without disrupting the output structure.
Prerequisites
Install the dayjs library using npm:
npm install dayjs
npm install dayjs-plugin-utc
npm install dayjs-plugin-timezoneParameters
Parameter | Type | Description |
|---|---|---|
date | Date | The Date object to format. |
pattern | string | The format pattern following dayjs formatting tokens. |
isInputUTC | boolean | (Optional) If set to true, the input date is treated as UTC. Defaults to false (uses local timezone). |
outputTZ | string or string[] | (Optional) Specifies additional output timezones. UTC is always included in the output. |
Date Pattern Tokens
The pattern string in the formatDate function uses dayjs formatting tokens to define the output format. Below is a table of common tokens you can use:
Token | Description | Example Output |
|---|---|---|
YYYY | 4-digit year | 2025 |
YY | 2-digit year | 25 |
MMMM | Full name of the month | January |
MMM | Abbreviated name of the month | Jan |
MM | 2-digit month | 01 |
M | Month without leading zero | 1 |
DD | 2-digit day of the month | 07 |
D | Day of the month without leading zero | 7 |
dddd | Full name of the day of the week | Tuesday |
ddd | Abbreviated name of the day of the week | Tue |
HH | 2-digit hour (24-hour clock) | 14 |
H | Hour without leading zero (24-hour clock) | 14 |
hh | 2-digit hour (12-hour clock) | 02 |
h | Hour without leading zero (12-hour clock) | 2 |
mm | 2-digit minutes | 35 |
m | Minutes without leading zero | 5 |
ss | 2-digit seconds | 09 |
s | Seconds without leading zero | 9 |
A | AM/PM marker (uppercase) | PM |
a | am/pm marker (lowercase) | pm |
Z | UTC offset (e.g., +05:00) | +05:00 |
ZZ | UTC offset without colon (e.g., +0500) | +0500 |
For a complete list of tokens, refer to the dayjs documentation.
Timezone Patterns
The inputTZ and outputTZ parameters accept IANA timezone identifiers. Below is a table of common timezone options you can use. For a complete list, refer to the IANA Time Zone Database.
Timezone Identifier | Location | Description |
|---|---|---|
UTC | Coordinated Universal Time | The primary time standard by which the world regulates clocks and time. |
America/New_York | Eastern Time (US & Canada) | Observes Eastern Standard Time (EST) and Eastern Daylight Time (EDT). |
America/Chicago | Central Time (US & Canada) | Observes Central Standard Time (CST) and Central Daylight Time (CDT). |
America/Denver | Mountain Time (US & Canada) | Observes Mountain Standard Time (MST) and Mountain Daylight Time (MDT). |
America/Los_Angeles | Pacific Time (US & Canada) | Observes Pacific Standard Time (PST) and Pacific Daylight Time (PDT). |
Europe/London | London, United Kingdom | Observes Greenwich Mean Time (GMT) and British Summer Time (BST). |
Europe/Berlin | Berlin, Germany | Observes Central European Time (CET) and Central European Summer Time (CEST). |
Europe/Moscow | Moscow, Russia | Observes Moscow Standard Time (MSK). |
Asia/Tokyo | Tokyo, Japan | Observes Japan Standard Time (JST). |
Asia/Shanghai | Shanghai, China | Observes China Standard Time (CST). |
Asia/Kolkata | Kolkata, India | Observes India Standard Time (IST). |
Australia/Sydney | Sydney, Australia | Observes Australian Eastern Standard Time (AEST) and Australian Eastern Daylight Time (AEDT). |
Pacific/Auckland | Auckland, New Zealand | Observes New Zealand Standard Time (NZST) and New Zealand Daylight Time (NZDT). |
America/Sao_Paulo | São Paulo, Brazil | Observes Brasília Time (BRT) and Brasília Summer Time (BRST). |
America/Argentina/Buenos_Aires | Buenos Aires, Argentina | Observes Argentina Time (ART). |
Africa/Johannesburg | Johannesburg, South Africa | Observes South Africa Standard Time (SAST). |
Asia/Dubai | Dubai, United Arab Emirates | Observes Gulf Standard Time (GST). |
Asia/Singapore | Singapore | Observes Singapore Standard Time (SGT). |
Asia/Bangkok | Bangkok, Thailand | Observes Indochina Time (ICT). |
Asia/Hong_Kong | Hong Kong | Observes Hong Kong Time (HKT). |
America/Denver | Denver, USA | Observes Mountain Time (MT). |
America/Vancouver | Vancouver, Canada | Observes Pacific Time (PT). |
Timezone Notes
- Case Sensitivity: Timezone identifiers are case-sensitive. Ensure that you use the correct casing (e.g., America/New_York not america/new_york).
- Daylight Saving Time (DST): Many timezones observe DST. The dayjs library automatically adjusts for DST based on the provided timezone.
- Invalid Timezones: If an invalid timezone identifier is provided, the function will return that the date is invalid. Ensure that the timezone strings used are valid IANA identifiers.
Return Value
The function returns an object containing the validity of the date and the formatted date string.
Property | Type | Description |
|---|---|---|
isValid | boolean | true if the date is valid and formatted successfully, false otherwise. |
formattedDate | string | The formatted date string based on the provided pattern. If isValid is false, this will be an empty string. |
Notes
- Assumed Local Timezone:
- For these examples, it's assumed that the user's local timezone is America/New_York (UTC-5). If your local timezone differs, adjust the expected outputs accordingly.
- Function Parameters Explained:
- date (Date): The date to be formatted.
- isInputUTC (boolean, optional): If set to true, the input date is treated as UTC. Defaults to false (uses the user's local timezone).
- outputTZ (string or string[], optional): Specifies additional output timezones. UTC is always included in the output.
- Handling Invalid Timezones:
- If an invalid timezone is provided in outputTZ, the function will skip it and log a warning to the console. UTC will still be included in the output.
- Default Behavior:
- If outputTZ is not specified, the function defaults to including both 'Local' and 'UTC' formatted dates.
- Including UTC Always:
- The formatDate function is designed to always include UTC in the output, ensuring a consistent reference point regardless of other specified timezones.
- Pattern Flexibility:
- Ensure that the pattern provided is compatible with dayjs formatting tokens to achieve the desired date and time representations.
Example Usage
Description | Input | Output |
|---|---|---|
Valid Date in YYYY-MM-DD Format | formatDate(new Date('2025-01-07T14:35:12Z'), 'YYYY-MM-DD') | {
"isValid": true,
"formattedDates":
{
"Local": "2025-01-07",
"UTC": "2025-01-07"
}
} |
Full Day and Month Names with Time | formatDate(new Date('2025-01-07T14:35:12Z'), 'dddd, MMMM D, YYYY hh:mm A') | {
"isValid": true,
"formattedDates":
{
"Local": "Tuesday, January 7, 2025 09:35 AM",
"UTC": "Tuesday, January 7, 2025 02:35 PM"
}
} |
Date in Abbreviated Day and Month Format | formatDate(new Date('2025-01-07T14:35:12Z'), 'ddd, MMM D, YY') | {
"isValid": true,
"formattedDates":
{
"Local": "Tue, Jan 7, 25",
"UTC": "Tue, Jan 7, 25"
}
} |
Time in 12-Hour Clock with Minutes | formatDate(new Date('2025-01-07T14:35:12Z'), 'hh:mm A') | {
"isValid": true,
"formattedDates":
{
"Local": "09:35 AM",
"UTC": "02:35 PM"
}
} |
Invalid Date Object | formatDate(new Date('invalid-date'), 'YYYY-MM-DD') | {
"isValid": false,
"formattedDates": {}
} |
Specifying a Single Output Timezone | formatDate(new Date('2025-01-07T14:35:12Z'), 'YYYY-MM-DD hh A', true, 'America/New_York') | {
"isValid": true,
"formattedDates":
{
"UTC": "2025-01-07 02 PM",
"America/New_York": "2025-01-07 09 AM"
}
} |
Specifying Multiple Output Timezones | formatDate(new Date('2025-01-07T14:35:12Z'), 'YYYY-MM-DD hh A', true, ['America/New_York', 'Asia/Tokyo']) | {
"isValid": true,
"formattedDates":
{
"UTC": "2025-01-07 02 PM",
"America/New_York": "2025-01-07 09 AM",
"Asia/Tokyo": "2025-01-07 11 PM"
}
} |
Combining Default and Specified Timezones | formatDate(new Date('2025-01-07T14:35:12Z'), 'YYYY-MM-DD hh A', true, ['Local', 'Asia/Tokyo']) | {
"isValid": true,
"formattedDates":
{
"UTC": "2025-01-07 02 PM",
"Local": "2025-01-07 09 AM",
"Asia/Tokyo": "2025-01-07 11 PM"
}
} |
Handling Invalid Output Timezones | formatDate(new Date('2025-01-07T14:35:12Z'), 'YYYY-MM-DD hh A', true, ['Invalid/Timezone', 'Asia/Tokyo']) | {
"isValid": true,
"formattedDates":
{
"UTC": "2025-01-07 02 PM",
"Asia/Tokyo": "2025-01-07 11 PM"
}
} |
Non-String Pattern | formatDate(new Date(), 12345) | {
"isValid": false,
"formattedDates": {}
} |
Default Behavior (Local and UTC) | formatDate(new Date('2025-01-07T14:35:12Z'), 'YYYY-MM-DD HH:mm A') | {
"isValid": true,
"formattedDates":
{
"Local": "2025-01-07 09:35 AM",
"UTC": "2025-01-07 02:35 PM"
}
} |
Specifying Output Timezone Only | formatDate(new Date('2025-01-07T14:35:12Z'), 'dddd, MMMM D, YYYY h:mm A', false, 'Europe/London') | {
"isValid": true,
"formattedDates":
{ "UTC": "Tuesday, January 7, 2025 02:35 PM",
"Europe/London": "Tuesday, January 7, 2025 02:35 PM"
}
} |
Multiple Output Timezones Including Default | formatDate(new Date('2025-01-07T14:35:12Z'), 'YYYY-MM-DD HH:mm A', true, ['Local', 'UTC', 'Asia/Kolkata']) | {
"isValid": true,
"formattedDates":
{ "UTC": "2025-01-07 02:35 PM",
"Local": "2025-01-07 09:35 AM",
"Asia/Kolkata": "2025-01-07 08:05 PM"
}
} |
Script
const dayjs = require('dayjs');
const utc = require('dayjs/plugin/utc');
const timezone = require('dayjs/plugin/timezone');
// Extend dayjs with necessary plugins
dayjs.extend(utc);
dayjs.extend(timezone);
/**
* Formats a given Date object into specified patterns using dayjs.
*
* @param {Date} date - The Date object to format.
* @param {string} pattern - The pattern defining the output format.
* @param {boolean} [isInputUTC=false] - (Optional) If true, treats the input date as UTC. Otherwise, uses the user's local timezone.
* @param {string|string[]} [outputTZ] - (Optional) The timezone(s) for the output formatted date(s). Can be a single timezone string or an array of timezone strings.
* @returns {{
* isValid: boolean,
* formattedDates: { [timezone: string]: string }
* }} - An object containing the validity of the date and an object of formatted date strings keyed by timezone.
*
* @example
* formatDate(new Date(), 'YYYY-MM-DD HH:mm');
* // {
* // isValid: true,
* // formattedDates: {
* // 'Local': "2025-01-07 09:35 AM",
* // 'UTC': "2025-01-07 14:35 PM"
* // }
* // }
*/
function formatDate(date, pattern, isInputUTC = false, outputTZ) {
// Initialize return object
const result = {
isValid: false,
formattedDates: {}
};
// Validate the date object
if (!(date instanceof Date) || isNaN(date)) {
return result; // isValid remains false, formattedDates is empty
}
// Validate the pattern
if (typeof pattern !== 'string') {
return result; // isValid remains false, formattedDates is empty
}
// Determine the input timezone
const inputTZ = isInputUTC ? 'UTC' : dayjs.tz.guess();
// Create a dayjs instance with input timezone
let m;
if (inputTZ === 'UTC') {
m = dayjs.utc(date);
} else {
m = dayjs.tz(date, inputTZ);
}
// Check if the date is valid
if (m.isValid()) {
result.isValid = true;
// Always include UTC
result.formattedDates['UTC'] = m.clone().utc().format(pattern);
// Prepare the list of additional output timezones
let additionalTimezones = [];
if (outputTZ) {
if (Array.isArray(outputTZ)) {
additionalTimezones = outputTZ;
} else if (typeof outputTZ === 'string') {
additionalTimezones = [outputTZ];
} else {
console.warn('outputTZ should be a string or an array of strings representing valid IANA timezones.');
}
} else {
// Default to 'Local' if no outputTZ is specified
additionalTimezones = ['Local'];
}
// Iterate over each specified output timezone and format the date
additionalTimezones.forEach(tz => {
let formattedDate = '';
if (tz === 'Local') {
const localTZ = dayjs.tz.guess();
formattedDate = m.clone().tz(localTZ).format(pattern);
result.formattedDates['Local'] = formattedDate;
} else {
// Validate the timezone
if (dayjs.tz.zone(tz)) { // Checks if tz is a valid timezone
formattedDate = m.clone().tz(tz).format(pattern);
result.formattedDates[tz] = formattedDate;
} else {
console.warn(`Invalid timezone provided: "${tz}". Skipping this timezone.`);
}
}
});
}
return result;
}