Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to guess user's timezone using date-fns?

I have a requirement, where I need to show a user's time in their local time zone. This needs to be done using date-fns.

The following code checks the current time and then given a timezone converts it into local time as per the time zone.

const { formatToTimeZone } = require('date-fns-timezone')

let date = new Date()
const format = 'D.M.YYYY HH:mm:ss [GMT]Z (z)'
const output = formatToTimeZone(date, format, { timeZone: 'Asia/Calcutta' })

However, how do I guess the user's timezone on the fly?

In moment.js, you can get it with moment.tz.guess(). But how can I do it without moment.js and by using date-fns?

https://runkit.com/embed/835tsn9a87so

UPDATE: I will be using this inside a VueJS application. So, if there are any other related solutions, those are welcomed as well. Thanks.

like image 496
asanas Avatar asked Feb 06 '19 14:02

asanas


2 Answers

To get the user's IANA time zone identifier, most modern browsers now support the following:

Intl.DateTimeFormat().resolvedOptions().timeZone

That said, the usual reason you would need to use formatToTimeZone from date-fns-timezone is when you need to use a different time zone other than the user's local zone. Otherwise, you can usually just use the format function from date-fns.

However, in your case, you are also trying to use the z format specifier to display the user's time zone abbreviation. This isn't provided by date-fns directly, so if that is critical then you will indeed need to get the user's time zone with the Intl api shown above and use formatToTimeZone.

Do keep in mind though that these abbreviations are whatever the IANA data has recorded, which are in English only, and it doesn't have abbreviations for every time zone. For those that don't, you will see a numeric value instead, such as -02.

Also, many abbreviations can be ambiguous (such as the I in IST possibly meaning India, Israel, or Ireland, and many others...). Thus, in most cases, if you don't need the abbreviation, you're often better off without it.

like image 59
Matt Johnson-Pint Avatar answered Nov 01 '22 20:11

Matt Johnson-Pint


Just solved a similar problem myself. The trick is to use the format function from date-fns-tz instead of the one from date-fns.

import { format } from "date-fns";
console.log(format(new Date(), "yyyy-MM-dd HH:mm z"));
// 2021-11-29 13:55 GMT-8

import { format } from "date-fns-tz";
console.log(format(new Date(), "yyyy-MM-dd HH:mm z"));
// 2021-11-29 13:55 PST

See documentation here: https://date-fns.org/v2.27.0/docs/Time-Zones

like image 33
Ben Harris Avatar answered Nov 01 '22 20:11

Ben Harris