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

How to add LinkedTimezoneInfo to a DataSource #72

ggrochow opened this issue Sep 22, 2017 · 2 comments

How to add LinkedTimezoneInfo to a DataSource #72

ggrochow opened this issue Sep 22, 2017 · 2 comments


Copy link

@ggrochow ggrochow commented Sep 22, 2017

I have some an existing application, that uses some non-standard time-zone mappings, When trying to setup a rails API, I ran into some issues, saying they weren't valid timezones.

I would like to add some aliases to a few timezones, which appears to be do-able with the LinkedTimezoneInfo class, however, Im getting a little stumped on how to actually include these additional timezones in the data.

Its looking like I have to sub-class and fully implement my own data-source loading, Is this correct?

Is there an easy way to use an existing data-source loading method, and just add a few extra things to the data-source?

I want to be able to use 'GMT-07:00' which isn't a valid timezone identifier, and have it link to the existing, valid 'Etc/Gmt-7' TZ. How do I get TzInfo::Timezone.get('GMT-07:00') to return the TZ i want, instead of an 'TZ not found' exception

Copy link

@philr philr commented Sep 23, 2017

You can create a custom DataSource class that extends one of the built-in data source implementations. This class can handle requests for custom aliases, deferring any other request to the built-in implementation.

You'll need to decide which of the built-in DataSource implementations to extend: RubyDataSource if you want to use the tzinfo-data gem as the source of time zone data, or ZoneinfoDataSource if you want to use the system zoneinfo files. You can run TZInfo::DataSource.get to see which one you're using at the moment.

Your custom DataSource class would need to look something like this:

class CustomDataSource < TZInfo::ZoneinfoDataSource # or TZInfo::RubyDataSource
  def initialize
    @aliases = {
      'GMT-07:00' => 'Etc/GMT-7'
      # ...

  def load_timezone_info(identifier)
    if @aliases.include?(identifier), @aliases[identifier])

  def timezone_identifiers
    @timezone_identifiers_with_aliases ||= (super + @aliases.keys).sort.freeze

  def linked_timezone_identifiers
    @linked_timezone_identifiers_with_aliases ||= (super + @aliases.keys).sort.freeze

The CustomDataSource class will need to be selected before TZInfo is first used:


Once set, you'll be able to get zones using the custom aliases:

> tz = TZInfo::Timezone.get('GMT-07:00')
=> #<TZInfo::LinkedTimezone: GMT-07:00>
> tz.canonical_identifier
=> "Etc/GMT-7"

Note that the Etc/GMT+-n zones are backwards from what most people expect (see #69). You might want GMT-07:00 to map to Etc/GMT+7 instead.

The above code will work with TZInfo version 1.2.x. Some minor changes will be needed to work with the next major release of TZInfo, which will move the RubyDataSource, ZoneinfoDataSource and LinkedTimezoneInfo classes from the TZInfo namespace to TZInfo::DataSources.

Copy link

@ggrochow ggrochow commented Sep 23, 2017

Thanks so much for the quick and detailed reply, ( including
including the gotcha that I 100% would have fallen for and probably not noticed immediately ).

Got this sorted fairly quickly, stuck this in a rails initializer and things are working as expected.

@philr philr closed this Sep 23, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants