Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
@date-fns/tz
Advanced tools
@date-fns/tz is a timezone utility library that extends the capabilities of date-fns, allowing users to work with time zones in JavaScript. It provides functions to convert dates between time zones, format dates in specific time zones, and parse date strings with time zone information.
Convert Date to Time Zone
This feature allows you to convert a date from a specific time zone to UTC. The code sample demonstrates converting a date from the 'America/New_York' time zone to UTC.
const { zonedTimeToUtc } = require('@date-fns/tz');
const date = new Date('2023-10-10T10:00:00Z');
const timeZone = 'America/New_York';
const utcDate = zonedTimeToUtc(date, timeZone);
console.log(utcDate.toISOString());
Format Date in Time Zone
This feature allows you to format a date in a specific time zone. The code sample shows how to format a UTC date to the 'America/New_York' time zone.
const { format } = require('date-fns');
const { utcToZonedTime } = require('@date-fns/tz');
const date = new Date('2023-10-10T10:00:00Z');
const timeZone = 'America/New_York';
const zonedDate = utcToZonedTime(date, timeZone);
const formattedDate = format(zonedDate, 'yyyy-MM-dd HH:mm:ssXXX', { timeZone });
console.log(formattedDate);
Parse Date String with Time Zone
This feature allows you to parse a date string that includes time zone information and convert it to UTC. The code sample demonstrates parsing a date string with a time zone offset and converting it to UTC.
const { parseISO, format } = require('date-fns');
const { zonedTimeToUtc } = require('@date-fns/tz');
const dateString = '2023-10-10T10:00:00-04:00';
const timeZone = 'America/New_York';
const date = parseISO(dateString);
const utcDate = zonedTimeToUtc(date, timeZone);
console.log(format(utcDate, 'yyyy-MM-dd HH:mm:ssXXX'));
Moment-timezone is an extension for Moment.js that adds support for time zones. It provides similar functionality to @date-fns/tz, such as converting dates between time zones and formatting dates in specific time zones. However, Moment.js and its extensions are generally considered heavier and less performant compared to date-fns.
Luxon is a modern JavaScript library for working with dates and times, created by one of the Moment.js developers. It includes built-in support for time zones and offers a more modern API compared to Moment.js. Luxon is often seen as a more feature-rich alternative to @date-fns/tz, though it may be more complex for simple use cases.
Timezone-js is a library that provides time zone support for JavaScript. It allows for parsing and formatting dates in different time zones. Compared to @date-fns/tz, timezone-js is less commonly used and may not integrate as seamlessly with other date-fns functions.
The package provides Date
extensions TZDate
and TZDateMini
that perform all calculations in the given time zone rather than the system time zone.
Using it makes date-fns operate in given time zone but can be also used without it.
Like everything else in the date-fns ecosystem, the library is build-size aware. The smallest component, TZDateMini,
is only 916 B
.
Need only UTC? See @date-fns/utc that provides lighter solution.
npm install @date-fns/tz --save
TZDate
and TZDateMini
have API similar to Date
, but perform all calculations in the given time zone, which might be essential when operating across different time zones, calculating dates for users in different regions, or rendering chart or calendar component:
import { TZDate } from "@date-fns/tz";
import { addHours } from "date-fns";
// Given that the system time zone is America/Los_Angeles
// where DST happens at Sunday, 13 March 2022, 02:00:00
// Using system time zone will produce 03:00 instead of 02:00 because of DST:
const date = new Date(2022, 2, 13);
addHours(date, 2).toString();
//=> 'Sun Mar 13 2022 03:00:00 GMT-0700 (Pacific Daylight Time)'
// Using Asia/Singapore will provide expected 02:00:
const tzDate = new TZDate(2022, 2, 13, "Asia/Singapore");
addHours(tzDate, 2).toString();
//=> 'Sun Mar 13 2022 02:00:00 GMT+0800 (Singapore Standard Time)'
You can pass IANA time zone name ("Asia/Singapore", "America/New_York", etc.) or UTC offset ("+01:00", "-2359", or "+23"):
new TZDate(2022, 2, 13, "Asia/Singapore");
new TZDate(2022, 2, 13, "+08:00");
new TZDate(2022, 2, 13, "-2359");
TZDate
and TZDateMini
The main difference between TZDate
and TZDateMini
is the build footprint. The TZDateMini
is 916 B
, and the TZDate
is 1.2 kB
. While the difference is slight it might be essential in some environments and use cases.
Unlike TZDateMini
which implements only getters, setters, and getTimezoneOffset
, TZDate
also provides formatter functions, mirroring all original Date
functionality:
import { TZDateMini, TZDate } from "@date-fns/tz";
// TZDateMini will format date-time in the system time zone:
new TZDateMini(2022, 2, 13).toString();
//=> 'Sat Mar 12 2022 16:00:00 GMT-0800 (Pacific Standard Time)'
// TZDate will format date-time in the Singapore time zone, like expected:
new TZDate(2022, 2, 13).toString();
//=> 'Sun Mar 13 2022 00:00:00 GMT+0800 (Singapore Standard Time)'
Even though TZDate
has a complete API, developers rarely use the formatter functions outside of debugging, so we recommend you pick the more lightweight TZDateMini
for internal use. However, in environments you don't control, i.e., when you expose the date from a library, using TZDate
will be a safer choice.
TZDate
All the TZDate
docs are also true for TZDateMini
.
When creating TZDate
, you can pass the time zone as the last argument:
new TZDate(2022, 2, "Asia/Singapore");
new TZDate(timestamp, "Asia/Singapore");
new TZDate("2024-09-12T00:00:00Z", "Asia/Singapore");
The constructor mirrors the original Date
parameters except for the last time zone parameter.
TZDate.tz
The static tz
function allows to construct TZDate
instance with just a time zone:
// Create now in Singapore time zone:
TZDate.tz("Asia/Singapore");
// ❌ This will not work, as TZDate expects a date string:
new TZDate("Asia/Singapore");
//=> Invalid Date
Just like the constructor, the function accepts all parameters variants:
TZDate.tz("Asia/Singapore", 2022, 2);
TZDate.tz("Asia/Singapore", timestamp);
TZDate.tz("Asia/Singapore", "2024-09-12T00:00:00Z");
timeZone
The readonly timeZone
property returns the time zone name assigned to the instance:
new TZDate(2022, 2, 13, "Asia/Singapore").timeZone;
// "Asia/Singapore"
The property might be undefined
when created without a time zone:
new TZDate().timeZone;
// undefined
withTimeZone
The withTimeZone
method allows to create a new TZDate
instance with a different time zone:
const sg = new TZDate(2022, 2, 13, "Asia/Singapore");
const ny = sg.withTimeZone("America/New_York");
sg.toString();
//=> 'Sun Mar 13 2022 00:00:00 GMT+0800 (Singapore Standard Time)'
ny.toString();
//=> 'Sat Mar 12 2022 11:00:00 GMT-0500 (Eastern Standard Time)'
[Symbol.for("constructDateFrom")]
The TZDate
instance also exposes a method to construct a Date
instance in the same time zone:
const sg = TZDate.tz("Asia/Singapore");
// Given that the system time zone is America/Los_Angeles
const date = sg[Symbol.for("constructDateFrom")](new Date(2024, 0, 1));
date.toString();
//=> 'Mon Jan 01 2024 16:00:00 GMT+0800 (Singapore Standard Time)'
It's created for date-fns but can be used in any context. You can access it via Symbol.for("constructDateFrom")
or import it from the package:
import { constructFromSymbol } from "@date-fns/tz";
tz
The tz
function allows to specify the context for the [date-fns] functions (starting from date-fns@4):
import { isSameDay } from "date-fns";
import { tz } from "@date-fns/tz";
isSameDay("2024-09-09T23:00:00-04:00", "2024-09-10T10:00:00+08:00", {
in: tz("Europe/Prague"),
});
//=> true
tzOffset
The tzOffset
function allows to get the time zone UTC offset in minutes from the given time zone and a date:
import { tzOffset } from "@date-fns/tz";
const date = new Date("2020-01-15T00:00:00Z");
tzOffset("Asia/Singapore", date);
//=> 480
tzOffset("America/New_York", date);
//=> -300
// Summer time:
tzOffset("America/New_York", "2020-01-15T00:00:00Z");
//=> -240
Unlike Date.prototype.getTimezoneOffset
, this function returns the value mirrored to the sign of the offset in the time zone. For Asia/Singapore (UTC+8), tzOffset
returns 480, while getTimezoneOffset
returns -480.
tzScan
The function scans the time zone for changes in the given interval. It returns an array of objects with the date of the change, the offset change, and the new offset:
import { tzScan } from "@date-fns/tz";
tzScan("America/New_York", {
start: new Date("2020-01-01T00:00:00Z"),
end: new Date("2024-01-01T00:00:00Z"),
});
//=> [
//=> { date: 2020-03-08T07:00:00.000Z, change: 60, offset: -240 },
//=> { date: 2020-11-01T06:00:00.000Z, change: -60, offset: -300 },
//=> { date: 2021-03-14T07:00:00.000Z, change: 60, offset: -240 },
//=> { date: 2021-11-07T06:00:00.000Z, change: -60, offset: -300 },
//=> { date: 2022-03-13T07:00:00.000Z, change: 60, offset: -240 },
//=> { date: 2022-11-06T06:00:00.000Z, change: -60, offset: -300 },
//=> { date: 2023-03-12T07:00:00.000Z, change: 60, offset: -240 },
//=> { date: 2023-11-05T06:00:00.000Z, change: -60, offset: -300 }
//=> ]
See the changelog.
FAQs
date-fns timezone utils
We found that @date-fns/tz demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.