8

I want to print timeZone abbreviation like: IST, UTC, PST, MST, CST, EST, etc...

I'm migrating my code from momentJS to date-fns and having the following issue. When I was using momentJS everything was working as expected. For example, the code below will print "IST"

const timeZone = 'Asia/Calcutta';
moment.tz(new Date(), timeZone).format('z'); // IST

Demo using MomentJS

Now my code using date-fns works but not all the way because it prints "India Standard Time" and I only want to print IST.

format(parisDate, 'zzzz', { timeZone: 'Asia/Calcutta', locale: enGB }); // India Standard Time

Can anyone tell me what I'm missing or doing wrong? Here's a live demo of my code: date-fns DEMO

Devmix
  • 1,599
  • 5
  • 36
  • 73
  • Interesting question. I found a solution but can't explain why... You should import a different locale (default is en-US). Importing `import enGB from 'date-fns/locale/en-GB'` and then changing to `const zoneString = format(utcToZonedTime(new Date(), timeZone), 'zzz', {locale: enGB});` on your example will do the job. I cannot however understand why the timezone abbreviation is tied with the library's locales. I will read the docs and maybe upload a proper answer. – antoniom Dec 22 '20 at 22:39
  • @antoniom I imported what you suggested and also made the changes but it prints "GMT+5:30". It doesn't work – Devmix Dec 22 '20 at 22:44
  • Strange... works for me... Have a look here https://github.com/marnusw/date-fns-tz#format – antoniom Dec 22 '20 at 22:50
  • @antoniom are you printing "India Standard Time" or IST"? I want to print "IST" – Devmix Dec 22 '20 at 22:53
  • Please retry once more using 'en-IN' as locale. And upgrade date-fns to the latest version (2.16.1) – antoniom Dec 22 '20 at 23:51

1 Answers1

4

After examining the date-fns-tz's code it turns out that it does not generate the timezone abbreviation's by itself but it uses the browser's Intl API. Timezone abbreviations differ from locale to locale. Locales such as 'en-US' or 'en-GB' do not include IST as timezone abbreviation while 'en-IN' does. You therefore need to

import enIN from 'date-fns/locale/en-IN'

and then pass it as a 3rd agument on your format call i.e.

import { utcToZonedTime, format } from "date-fns-tz";
const timeZone = "Asia/Kolkata"
const zoneString = format(utcToZonedTime(new Date(), timeZone), "zzz", {
  timeZone,
  locale: enIN
});

This however does not guarantee that other abbreviations (e.g. CET) will work with the proposed locale

antoniom
  • 3,143
  • 1
  • 37
  • 53
  • Your current solution works ONLY for India. Because if timeZone = 'Europe/Paris' the value of zoneString is GMT+1 instead of printing "CEST". Hope that makes sense. – Devmix Dec 23 '20 at 00:02
  • I wonder if there's a way to import everyting from date-fns/locale at once something like date-fns/locale/* ? – Devmix Dec 23 '20 at 00:05
  • I am afraid that you cannot achieve the desired effect. It seems that different locales return different abbreviated timezones. For example my country's locale ('el' / Greece) copes well with every European timezone (CEST, EET etc) but not with IST or EST. – antoniom Dec 23 '20 at 00:12
  • momentJS is able to accomplish this task but for some reason it seems to be tricky with date-fns – Devmix Dec 23 '20 at 00:13
  • 1
    Correct me if I am wrong but `moment-timezone` seems to be using lookup tables in order to report "IST". That's a totally different technique – antoniom Dec 23 '20 at 00:20
  • I'm not entirely sure on that one. – Devmix Dec 23 '20 at 00:36