Skip to content

Replace "Europe/Kiev" timezone with "Europe/Kyiv" #51703

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

K-S-A
Copy link

@K-S-A K-S-A commented May 1, 2024

Motivation / Background

This Pull Request has been created because of the request to use common timezone name "Europe/Kyiv" instead of the "Europe/Kiev". There are a few approaches to introduce this change in the rails repo:

  1. Update Kyiv timezone mapping value #40959
  2. Fix TimeZone::MAPPING for 'Kyiv' #24375
  3. Rename Europe/Kiev to Europe/Kyiv in ActiveSupport::TimeZone #44273

All mentioned related sources are changed in the last couple of years:

  1. https://github.com/tzinfo/tzinfo-data (https://github.com/tzinfo/tzinfo-data/blame/master/lib/tzinfo/data/definitions/Europe/Kiev.rb is an alias for https://github.com/tzinfo/tzinfo-data/blame/master/lib/tzinfo/data/definitions/Europe/Kyiv.rb since this commit tzinfo/tzinfo-data@5a58dcb).
  2. https://www.iana.org/time-zones (eggert/tz@e13e9c5).

Detail

This Pull Request changes internal tzinfo data from "Europe/Kiev" to "Europe/Kyiv" for ActiveSupport::TimeZone.

Additional information

Current workaround:

{ 'Kyiv' => 'Europe/Kyiv' }.each do |zone_name, tzinfo_name|
  time_zone = ActiveSupport::TimeZone.send(:zones_map)[zone_name]
  tzinfo = ActiveSupport::TimeZone.find_tzinfo(tzinfo_name)

  warn("Remove timezone patch for '#{tzinfo_name}' at #{__FILE__}:#{__LINE__}") if time_zone.tzinfo.name == tzinfo_name

  time_zone.instance_variable_set(:@tzinfo, tzinfo)
end

This update may break some existing applications that rely on time zone names. Though, the data migration should be trivial.

Checklist

Before submitting the PR make sure the following are checked:

  • This Pull Request is related to one change. Unrelated changes should be opened in separate PRs.
  • Commit message has a detailed description of what changed and why. If this PR fixes a related issue include it in the commit message. Ex: [Fix #issue-number]
  • Tests are added or updated if you fix a bug or add a feature.
  • CHANGELOG files are updated for the changed libraries if there is a behavior change or additional feature. Minor bug fixes and documentation changes should not be included.

@mechnicov
Copy link
Contributor

Hi Serhii

I think it is not good idea because of backward compatibility in applications that use RDBMS timezones and map it using Active Support. For example, PostgreSQL

SELECT name FROM pg_timezone_names WHERE name ~ 'Kiev';
       name        
-------------------
 Europe/Kiev
 posix/Europe/Kiev
(2 rows)
SELECT name FROM pg_timezone_names WHERE name ~ 'Kyiv';
 name 
------
(0 rows)

I believe it's better firstly to add aliases to PostgreSQL (and other systems), and after that make this change

@K-S-A
Copy link
Author

K-S-A commented May 1, 2024

@mechnicov, thank you for raising these issues.

I work closely with PostgreSQL and MySQL. Can't provide much information about other RDBMSs.

PostgreSQL respects IANA (Olson) time zone database (https://www.postgresql.org/docs/16/datatype-datetime.html#DATATYPE-TIMEZONES) and there should be no issues in a long run.

MySQL does not follow IANA according to documentation (https://dev.mysql.com/doc/refman/8.0/en/time-zone-support.html#time-zone-installation). Though, it provides good tooling to import system timezone data.

With that information, I can state that the output of SELECT name FROM pg_timezone_names WHERE name ~ 'K(ie|yi)v'; query will include updated time zone version for maintained systems and the number of such cases will increase over time.

@zzak
Copy link
Member

zzak commented May 19, 2024

For reasons explained previously, we can't do this because it is a breaking change.

@zzak zzak closed this May 19, 2024
@zzak
Copy link
Member

zzak commented May 19, 2024

Sorry I just saw Rafael's comment:
#40959 (comment)

I would add that buster (which is not EoL for another 2 months) doesn't have the updated tzdata:
https://packages.debian.org/buster-updates/all/tzdata/filelist

@zzak zzak reopened this May 19, 2024
@jarthod
Copy link

jarthod commented Oct 1, 2024

For the record, I started having this problem after upgrading to Ubuntu 24.04.1 LTS. It looks like the alias is no longer present in TZinfo and now I get Invalid Timezone: Kyiv when trying to to Time.use_zone('Kyiv') (which is still working on Ubuntu 22.04 LTS).

I tried the monkeypatch in description as a temporary workaround (I understand it cannot be changed just like that as it could break with older version of TZinfo). But I can't get it to work, in my case I get:

patches.rb:18:in `block in <main>': undefined method `tzinfo' for nil:NilClass
  warn("Remove timezone patch for '#{tzinfo_name}' at #{__FILE__}:#{__LINE__}") if time_zone.tzinfo.name == tzinfo_name
                                                                                            ^^^^^^^ (NoMethodError)

Because the "Kyiv" key is not present in the ActiveSupport::TimeZone.send(:zones_map) hash (I suppose because it wasn't able to load the corresponding TZ).


Edit: In the end I patched the MAPPING hash directly in an initializer:

if ActiveSupport::TimeZone::MAPPING['Kyiv'] == "Europe/Kyiv"
  warn("Remove timezone patch for Kyiv at #{__FILE__}:#{__LINE__}")
else
  ActiveSupport::TimeZone::MAPPING['Kyiv'] = "Europe/Kyiv"
end

🟢 And it's working as expect now on both Ubuntu 24.04 and 22.04 because they both have "Europe/Kyiv" support (22.04 supported both options and 24.04 only supports "Europe/Kyiv")

@olliebennett
Copy link

olliebennett commented Oct 8, 2024

The workaround provided above (overriding the Kyiv mapping) has worked.

The trigger for the issues was updating our infrastructure from Ubuntu 22 to Ubuntu 24 (i.e. the heroku-24 stack).

This caused some frustration and confusion and it was hard to pinpoint either Rails, TZInfo or Ubuntu as the culprit. While not the "fault" of Rails, I think Rails could (and is best placed) to do more to ease the transition from Europe/Kiev to Europe/Kyiv (which presumably we'll all face eventually).

Would it be a potential solution to update the mapping in ActiveSupport::TimeZone to dynamically determine whether Europe/Kiev or Europe/Kyiv is present in the data provided by TZInfo, and set the mapping accordingly? I see that as the only behaviour which a) doesn't cause backward incompatibility and b) supports both the old (Europe/Kiev) and new (Europe/Kyiv) timezones (and OS versions) simultaneously.

This proposal could (crudely) be implemented as follows (and indeed this is an alternative / more robust of the above suggested workaround;

if TZInfo::Timezone.all.map(&:name).include?('Europe/Kyiv')
  # The underlying OS considers Europe/Kyiv a valid timezone, so map Kyiv to that
  ActiveSupport::TimeZone::MAPPING['Kyiv'] = 'Europe/Kyiv'
else
  # The underlying OS does not consider Europe/Kyiv a valid timezone, so leave mapping as Europe/Kiev
end

@jarthod
Copy link

jarthod commented Nov 7, 2024

For the record I noticed other problematic TZ after some time with Ubuntu 24.04 in production. namely Rangoon (which is now Asia/Yangon) and Greenland (which is now America/Nuuk). I ended up with the following patch in my initializer for the time being:

{ 'Kyiv' => 'Europe/Kyiv',
  'Rangoon' => 'Asia/Yangon',
  'Greenland' => 'America/Nuuk' }.each do |name, tzinfo|
  if ActiveSupport::TimeZone::MAPPING[name] == tzinfo
    warn("Timezone patch not necessary for #{name} at #{__FILE__}:#{__LINE__}")
  else
    ActiveSupport::TimeZone::MAPPING[name] = tzinfo
  end
end

@thisismydesign
Copy link

I validate timezones against ActiveSupport::TimeZone.all. This allows Europe/Kiev on rails latest (8.0.2). Time.current.utc.in_time_zone fails with Europe/Kiev on heroku-24

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

Successfully merging this pull request may close these issues.

6 participants