iamkun / dayjs

⏰ Day.js 2kB immutable date-time library alternative to Moment.js with the same modern API
https://day.js.org
MIT License
46.93k stars 2.3k forks source link

Abbreviated Timezone for IST/GMT+5:30 #1154

Open rushvora opened 4 years ago

rushvora commented 4 years ago

When using the required plugins, the abbreviated timezone is not working for IST. With z, it shows GMT+5:30, but with zzz, it correctly shows Indian Standard Time.

import { Pipe, PipeTransform } from '@angular/core';
import * as dayjs from 'dayjs';
import * as advancedFormat from 'dayjs/plugin/advancedFormat';
import * as utc from 'dayjs/plugin/utc';
import * as timezone from 'dayjs/plugin/timezone';

@Pipe({
  name: 'dayjsTz'
})
export class DayJsDateTimePipe implements PipeTransform {
  public transform(value: Date, timeZone?: string, formatting = 'MMM Do YYYY, h:mm a z') {
    if (value) {
      dayjs.extend(advancedFormat);
      dayjs.extend(utc);
      dayjs.extend(timezone);
      if (timeZone) {
        return dayjs.tz(value, timeZone).format(formatting);
      }
      const userTimeZone = dayjs.tz.guess(); // here it guessed my timezone, Asia/Calcutta. I also tried hardcoding Asia/Kolkata, same result
      return dayjs.tz(value, userTimeZone).format(formatting);
    }
    return value;
  }
}

Current Output — Oct 20th 2020, 2:17 pm GMT+5:30 Expected Output — Oct 20th 2020, 2:17 pm IST

iamkun commented 4 years ago

I think this is not an issue related to Dayjs.

The Intl object gives us this result.

rushvora commented 4 years ago

Oh wow.. seems like localisation is also needed in combination. 😐

Screenshot 2020-10-20 at 22 22 38

So, the solution would to be also to guess the locale, like we are guessing the timezone?

rushvora commented 4 years ago

So if I were to get the user locale via navigator.language, how would I use that when formatting the date? I can't see where to pass the locale for timezone purposes.

iamkun commented 4 years ago

What do you mean by 'passing locale to timezone'?

rushvora commented 4 years ago

As you can see in the above screenshot from Chrome's console, when I pass a locale to Intl.DateTimeFormat, it returns the desired abbreviation. I need to pass en-IN to get the IST abbreviation instead of GMT+5:30, similary I need to pass en-AU to get the AEDT abbreviation instead of GMT+11.

So I am hoping to be able to do the same with dayjs, and I'm figuring out if we can pass the locale which dayjs will pass to the Intl API.

iamkun commented 4 years ago

Oh, I see. Unfortunately, we do not support this ATM.

rushvora commented 4 years ago

Should I leave this issue open since I hope this support can be added or is this not the right place for feature requests?

iamkun commented 4 years ago

I'm not sure if this should be supported or not, or the proper way to support it. One question is, how can our user know the correct locale name to pass in.

rushvora commented 4 years ago

Aren't the locale names standardised?

What I feel — If no locale name is passed, then there's no need to pass any locale to the Intl API/it would work as it does now. If a locale is passed, then the same can be passed to the Intl API (like how I did in the screenshot from Chrome's console above). Do let me know if I'm mistaken about how the above can work/not work.

iamkun commented 4 years ago

Seems a good choice. I'll dig it more if I got some time.

tanyaburlakova commented 3 years ago

hello @iamkun

could you please let me know if this issue/feature is done or maybe in progress? In the doc I see it says we can use z for timezone abr https://day.js.org/docs/ru/plugin/advanced-format but it doesnt work.

Thank you!

shubhi23994 commented 3 years ago

Hi@iamkun Any update on this thread would be very helpful :)

koooge commented 3 years ago

I expected such behavior like moment's zoneName() as well. https://momentjs.com/timezone/docs/#/using-timezones/formatting/

ztancinco commented 3 years ago

Any update on this issue ? @iamkun . Thanks!

VilOstreiko commented 3 years ago

@iamkun it'd be great to have any updates on the issue. thanks!

kaangokdemir commented 3 years ago

Any update? Thanks @iamkun

tukusejssirs commented 2 years ago

This issue bug should be fixed ASAP.

Until then, I worked the bug around using the following code (I don’t say it is the shortest nor fastest one, but it works).

const locale = 'en-GB'
const timezone = 'Europe/Bratislava'
const shortTimezone = new Intl.DateTimeFormat(locale, {
  timeZone: timezone,
  timeZoneName: 'short'
})
  .format(Date.now())
  .split(' ')[1]

// `shortTimezone` should be equal to 'CEST'
far0s commented 2 years ago

Hi, I'm also being plagued by this issue. @tukusejssirs's solution works but this is quite the workaround to implement. It sounds like the main culprit here is being able to specify the locale?

bilalbutt044 commented 1 year ago

any update ?

MariusBaci commented 11 months ago

Any news on this ?

5war00p commented 10 months ago

We can use dayjs().format('zzz').match(/\b(\w)/g)?.join("") for now.

itseramin commented 5 months ago

Please revisit this issue, thanks in advance!

Rey-Wang commented 5 months ago

@5war00p its not a common solution, try UTC then

5war00p commented 5 months ago

I couldn't check now, not sure why non UTC also not working, some problem with advanced formats. Some of them are not working.

image
5war00p commented 5 months ago

I couldn't check now, not sure why non UTC also not working, some problem with advanced formats. Some of them are not working.

image

My bad, I haven't imported dependent plugins. I was testing on browser. However, while testing on browser every plugin should be imported right?

5war00p commented 5 months ago

@Rey-Wang If it is UTC, then you are converting it into UTC right? then you can explicitly suffix it as UTC (if needed). As converting it to UTC and trying to get timezone still gives user's current timezone instead of converted one {dayjs().utc(true).format("zzz")} --> gives users timezone