Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect abbreviation and alternativeName? #287

Open
marcoancona opened this issue May 22, 2023 · 4 comments
Open

Incorrect abbreviation and alternativeName? #287

marcoancona opened this issue May 22, 2023 · 4 comments

Comments

@marcoancona
Copy link

How is the mapping IANA -> abbreviation built? Let's take Europe/London as an example:

{
    "name": "Europe/London",
    "alternativeName": "Greenwich Mean Time",
    "group": [
        "Europe/London",
        "GB",
        "GB-Eire",
        "Europe/Guernsey",
        "Europe/Isle_of_Man",
        "Europe/Jersey",
        "Europe/Belfast"
    ],
    "continentCode": "EU",
    "continentName": "Europe",
    "countryName": "United Kingdom",
    "countryCode": "GB",
    "mainCities": [
        "London",
        "Birmingham",
        "Liverpool",
        "Glasgow"
    ],
    "rawOffsetInMinutes": 0,
    "abbreviation": "GMT",
    "rawFormat": "+00:00 Greenwich Mean Time - London, Birmingham, Liverpool, Glasgow",
    "currentTimeOffsetInMinutes": 60,
    "currentTimeFormat": "+01:00 Greenwich Mean Time - London, Birmingham, Liverpool, Glasgow"
}

Europe/London is equivalent to Greenwich Mean Time (GMT) only in Winter. In summer, shouldn't it be British Summer Time (BST)?
GMT has a fixed offset, so what is the meaning of +01:00 Greenwich Mean Time?

@cordosvictor
Copy link

@marcoancona did you find an answer by now? Or an alternative solution?
In summer I want to get "British Summer Time (BST)" for "Europe/London" time zone and only in winter "Greenwich Mean Time". This is not the case with the latest version of this library.

@harelcoman
Copy link

Any news about this issue, It makes us add tailor-made solution and we would love for this to be supported in the library,
We shows longer and shortened version of the tz so showing just GMT is just wrong in our case

@volstas
Copy link

volstas commented Aug 20, 2024

Kinda insane how hard it is to get correct list of timezones. Been looking for hours and every library has some kind of issues.

@volstas
Copy link

volstas commented Aug 21, 2024

So, i made a quick fix for myself that works for the most part.

	const alternativeNameCorrections: any = {
		'Antarctica/Palmer': 'Chile Time',
		'America/Punta_Arenas': 'Chile Time',
		'Africa/Casablanca': 'Western European Time',
		'Africa/El_Aaiun': 'Western European Time',
		'Europe/Istanbul': 'Turkey Time',
		'Asia/Urumqi': 'China Time',
		'Pacific/Bougainville': 'Bougainville Time'
	};

	let timeZonesWithUtc = getTimeZones({ includeUtc: true }).map((x) => {
		let date = DateTime.now().setLocale('en-US').setZone(x.name);
		// If the environment doesn't support this time zone, we just keep the default pre-generated options
		if (date.invalidReason != null) {
			return x;
		}

		const fullAltName = date.toFormat(`ZZZZZ`);
		const prevAltName = x.alternativeName;
		let nextAltName = fullAltName
			.replace(/Standard Time/g, 'Time')
			.replace(/Daylight Time/g, 'Time')
			.replace(/Summer Time/g, 'Time');

		if (prevAltName != nextAltName) {
			// there are some cases where Node.js tz data won't be giving actual alternative names
			// for time zones and instead will send GMT +03:00, so we fix that
			if (/^GMT[+-]\d{2}:\d{2}$/.test(nextAltName)) {
				nextAltName = alternativeNameCorrections[x.name] || nextAltName;
			}

			if (prevAltName != nextAltName) {
				x.alternativeName = nextAltName;
				console.log(prevAltName + '>' + nextAltName + '(' + x.name + ')');
			}
		}

		const prevAbr = x.abbreviation;
		let nextAbr = abbreviations[fullAltName] || prevAbr;
		if (prevAbr != nextAbr) {
			x.abbreviation = nextAbr;
			console.log(prevAbr + '>' + nextAbr + '(' + x.name + ')');
		}

		return x;
	});

Basically the issue is that the generate logic uses a hardcoded January date for everything(https://github.com/vvo/tzdb/blob/main/generate.js#L228). So it's always in winter time.
Here I recalculate the values based on current date.

The not so nice thing about this is that it needs to rerun and recalculate over 300 items every time unless you cache it somewhere.

If anyone wants to actually make a PR or a forked project based on this, it would be great.(if no one picks it up, I might do it myself after a month or two)
I checked, and if you generate the names in January and July you get all options. It includes all the variants of all timezones.

So generate the names on both dates, make the alternativeName and abbreviation into arrays to include all possible options. And add currentAltnernativeName and currentAbbreviation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants