{"id":13483834,"url":"https://github.com/tzinfo/tzinfo","last_synced_at":"2025-05-13T21:05:10.732Z","repository":{"id":9878088,"uuid":"11879463","full_name":"tzinfo/tzinfo","owner":"tzinfo","description":"TZInfo - Ruby Timezone Library","archived":false,"fork":false,"pushed_at":"2025-04-18T18:44:55.000Z","size":11399,"stargazers_count":368,"open_issues_count":1,"forks_count":100,"subscribers_count":20,"default_branch":"master","last_synced_at":"2025-04-25T05:03:13.742Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tzinfo.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2013-08-04T14:08:00.000Z","updated_at":"2025-04-18T18:40:35.000Z","dependencies_parsed_at":"2023-12-27T21:16:12.795Z","dependency_job_id":"3a5225b1-f691-4a7d-8141-a8ba8674c2a6","html_url":"https://github.com/tzinfo/tzinfo","commit_stats":{"total_commits":880,"total_committers":21,"mean_commits":"41.904761904761905","dds":"0.030681818181818143","last_synced_commit":"bfae9bda2c0057a62d837f590a77a85809768f44"},"previous_names":[],"tags_count":95,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tzinfo%2Ftzinfo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tzinfo%2Ftzinfo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tzinfo%2Ftzinfo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tzinfo%2Ftzinfo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tzinfo","download_url":"https://codeload.github.com/tzinfo/tzinfo/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250921935,"owners_count":21508242,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T17:01:15.763Z","updated_at":"2025-05-13T21:05:10.720Z","avatar_url":"https://github.com/tzinfo.png","language":"Ruby","readme":"# TZInfo - Ruby Time Zone Library\n\n[![RubyGems](https://img.shields.io/gem/v/tzinfo?logo=rubygems\u0026label=Gem)](https://rubygems.org/gems/tzinfo) [![Tests](https://github.com/tzinfo/tzinfo/actions/workflows/tests.yml/badge.svg?branch=master\u0026event=push)](https://github.com/tzinfo/tzinfo/actions?query=workflow%3ATests+branch%3Amaster+event%3Apush)\n\n[TZInfo](https://tzinfo.github.io) is a Ruby library that provides access to\ntime zone data and allows times to be converted using time zone rules.\n\n\n## Data Sources\n\nTZInfo requires a source of time zone data. There are two options:\n\n1. A zoneinfo directory containing timezone definition files. These files are\n   generated from the [IANA Time Zone Database](https://www.iana.org/time-zones)\n   using the `zic` utility. Most Unix-like systems include a zoneinfo directory.\n2. The TZInfo::Data library (the tzinfo-data gem). TZInfo::Data contains a set\n   of Ruby modules that are also generated from the IANA Time Zone Database.\n\nBy default, TZInfo will attempt to use TZInfo::Data. If TZInfo::Data is not\navailable (i.e. if `require 'tzinfo/data'` fails), then TZInfo will search for a\nzoneinfo directory instead (by checking the directories specified by\n`TZInfo::DataSources::ZoneinfoDataSource.search_path` in turn).\n\nIf no data source can be found, a `TZInfo::DataSourceNotFound` exception will be\nraised when TZInfo is used. Further information is available\n[in the wiki](https://tzinfo.github.io/datasourcenotfound) to help resolve\n`TZInfo::DataSourceNotFound` errors.\n\nThe default data source selection can be overridden by calling\n`TZInfo::DataSource.set`.\n\nCustom data sources can also be used. See the `TZInfo::DataSource.set`\ndocumentation for further details.\n\n\n## Installation\n\nThe TZInfo gem can be installed by running `gem install tzinfo` or by adding\n`gem 'tzinfo'` to your `Gemfile` and running `bundle install`.\n\nTo use the Ruby modules as the data source, TZInfo::Data will also need to be\ninstalled by running `gem install tzinfo-data` or by adding `gem 'tzinfo-data'`\nto your `Gemfile`.\n\n\n## IANA Time Zone Database\n\nThe data returned and used by TZInfo is sourced from the\n[IANA Time Zone Database](https://www.iana.org/time-zones). The\n[Theory and pragmatics of the tz code and data](https://data.iana.org/time-zones/theory.html)\ndocument gives details of how the data is organized and managed.\n\n\n## Example Usage\n\nTo use TZInfo, it must first be required with:\n\n```ruby\nrequire 'tzinfo'\n```\n\nThe `TZInfo::Timezone` class provides access to time zone data and methods for\nconverting times.\n\nThe `all_identifiers` method returns a list of valid time zone identifiers:\n\n```ruby\nidentifiers = TZInfo::Timezone.all_identifiers\n# =\u003e [\"Africa/Abidjan\", \"Africa/Accra\", ..., \"Zulu\"]\n```\n\nA `TZInfo::Timezone` instance representing an individual time zone can be\nobtained with `TZInfo::Timezone.get`:\n\n```ruby\ntz = TZInfo::Timezone.get('America/New_York')\n# =\u003e #\u003cTZInfo::DataTimezone: America/New_York\u003e\n```\n\nA time can be converted to the local time of the time zone with `to_local`:\n\n```ruby\ntz.to_local(Time.utc(2018, 2, 1, 12, 30, 0))\n# =\u003e 2018-02-01 07:30:00 -0500\ntz.to_local(Time.utc(2018, 7, 1, 12, 30, 0))\n# =\u003e 2018-07-01 08:30:00 -0400\ntz.to_local(Time.new(2018, 7, 1, 13, 30, 0, '+01:00'))\n# =\u003e 2018-07-01 08:30:00 -0400\n```\n\nLocal times with the appropriate offset for the time zone can be constructed\nwith `local_time`:\n\n```ruby\ntz.local_time(2018, 2, 1, 7, 30, 0)\n# =\u003e 2018-02-01 07:30:00 -0500\ntz.local_time(2018, 7, 1, 8, 30, 0)\n# =\u003e 2018-07-01 08:30:00 -0400\n```\n\nLocal times can be converted to UTC by using `local_time` and calling `utc` on\nthe result:\n\n```ruby\ntz.local_time(2018, 2, 1, 7, 30, 0).utc\n# =\u003e 2018-02-01 12:30:00 UTC\ntz.local_time(2018, 7, 1, 8, 30, 0).utc\n# =\u003e 2018-07-01 12:30:00 UTC\n```\n\nThe `local_to_utc` method can also be used to convert a time object to UTC. The\noffset of the time is ignored - it is treated as if it were a local time for the\ntime zone:\n\n```ruby\ntz.local_to_utc(Time.utc(2018, 2, 1, 7, 30, 0))\n# =\u003e 2018-02-01 12:30:00 UTC\ntz.local_to_utc(Time.new(2018, 2, 1, 7, 30, 0, '+01:00'))\n# =\u003e 2018-02-01 12:30:00 UTC\n```\n\nInformation about the time zone can be obtained from returned local times:\n\n```ruby\nlocal_time = tz.to_local(Time.utc(2018, 2, 1, 12, 30, 0))\nlocal_time.utc_offset  # =\u003e -18000\nlocal_time.dst?        # =\u003e false\nlocal_time.zone        # =\u003e \"EST\"\n\nlocal_time = tz.to_local(Time.utc(2018, 7, 1, 12, 30, 0))\nlocal_time.utc_offset  # =\u003e -14400\nlocal_time.dst?        # =\u003e true\nlocal_time.zone        # =\u003e \"EDT\"\n```\n\nTime zone information can be included when formatting times with `strftime`\nusing the `%z` and `%Z` directives:\n\n```ruby\ntz.to_local(Time.utc(2018, 2, 1, 12, 30, 0)).strftime('%Y-%m-%d %H:%M:%S %z %Z')\n# =\u003e \"2018-02-01 07:30:00 -0500 EST\"\ntz.to_local(Time.utc(2018, 7, 1, 12, 30, 0)).strftime('%Y-%m-%d %H:%M:%S %z %Z')\n# =\u003e \"2018-07-01 08:30:00 -0400 EDT\"\n```\n\nThe `period_for` method can be used to obtain information about the observed\ntime zone information at a particular time as a `TZInfo::TimezonePeriod` object:\n\n```ruby\nperiod = tz.period_for(Time.utc(2018, 7, 1, 12, 30, 0))\nperiod.base_utc_offset          # =\u003e -18000\nperiod.std_offset               # =\u003e 3600\nperiod.observed_utc_offset      # =\u003e -14400\nperiod.abbreviation             # =\u003e \"EDT\"\nperiod.dst?                     # =\u003e true\nperiod.local_starts_at.to_time  # =\u003e 2018-03-11 03:00:00 -0400\nperiod.local_ends_at.to_time    # =\u003e 2018-11-04 02:00:00 -0400\n```\n\nA list of transitions between periods where different rules are observed can be\nobtained with the `transitions_up_to` method. The result is returned as an\n`Array` of `TZInfo::TimezoneTransition` objects:\n\n```ruby\ntransitions = tz.transitions_up_to(Time.utc(2019, 1, 1), Time.utc(2017, 1, 1))\ntransitions.map do |t|\n  [t.local_end_at.to_time, t.offset.observed_utc_offset, t.offset.abbreviation]\nend\n# =\u003e [[2017-03-12 02:00:00 -0500, -14400, \"EDT\"],\n#     [2017-11-05 02:00:00 -0400, -18000, \"EST\"],\n#     [2018-03-11 02:00:00 -0500, -14400, \"EDT\"],\n#     [2018-11-04 02:00:00 -0400, -18000, \"EST\"]]\n```\n\nA list of the unique offsets used by a time zone can be obtained with the\n`offsets_up_to` method. The result is returned as an `Array` of\n`TZInfo::TimezoneOffset` objects:\n\n```ruby\noffsets = tz.offsets_up_to(Time.utc(2019, 1, 1))\noffsets.map {|o| [o.observed_utc_offset, o.abbreviation] }\n# =\u003e [[-17762, \"LMT\"],\n#     [-18000, \"EST\"],\n#     [-14400, \"EDT\"],\n#     [-14400, \"EWT\"],\n#     [-14400, \"EPT\"]]\n```\n\nAll `TZInfo::Timezone` methods that accept a time as a parameter can be used\nwith either instances of `Time`, `DateTime` or `TZInfo::Timestamp`. Arbitrary\n`Time`-like objects that respond to both `to_i` and `subsec` and optionally\n`utc_offset` will be treated as if they are instances of `Time`.\n\n`TZInfo::Timezone` methods that both accept and return times will return an\nobject with a type matching that of the parameter (actually a\n`TZInfo::TimeWithOffset`, `TZInfo::DateTimeWithOffset` or\n`TZInfo::TimestampWithOffset` subclass when returning a local time):\n\n```ruby\ntz.to_local(Time.utc(2018, 7, 1, 12, 30, 0))\n# =\u003e 2018-07-01 08:30:00 -0400\ntz.to_local(DateTime.new(2018, 7, 1, 12, 30, 0))\n# =\u003e #\u003cTZInfo::DateTimeWithOffset: 2018-07-01T08:30:00-04:00 ((2458301j,45000s,0n),-14400s,2299161j)\u003e\ntz.to_local(TZInfo::Timestamp.create(2018, 7, 1, 12, 30, 0, 0, :utc))\n# =\u003e #\u003cTZInfo::TimestampWithOffset: @value=1530448200, @sub_second=0, @utc_offset=-14400, @utc=false\u003e\n```\n\nIn addition to `local_time`, which returns `Time` instances, the\n`local_datetime` and `local_timestamp` methods can be used to construct local\n`DateTime` and `TZInfo::Timestamp` instances with the appropriate offset:\n\n```ruby\ntz.local_time(2018, 2, 1, 7, 30, 0)\n# =\u003e 2018-02-01 07:30:00 -0500\ntz.local_datetime(2018, 2, 1, 7, 30, 0)\n# =\u003e #\u003cTZInfo::DateTimeWithOffset: 2018-02-01T07:30:00-05:00 ((2458151j,45000s,0n),-18000s,2299161j)\u003e\ntz.local_timestamp(2018, 2, 1, 7, 30, 0)\n# =\u003e #\u003cTZInfo::TimestampWithOffset: @value=1517488200, @sub_second=0, @utc_offset=-18000, @utc=false\u003e\n```\n\nThe `local_to_utc`, `local_time`, `local_datetime` and `local_timestamp` methods\nmay raise a `TZInfo::PeriodNotFound` or a `TZInfo::AmbiguousTime` exception.\n`TZInfo::PeriodNotFound` signals that there is no equivalent UTC time (for\nexample, during the transition from standard time to daylight savings time when\nthe clocks are moved forward and an hour is skipped). `TZInfo::AmbiguousTime`\nsignals that there is more than one equivalent UTC time (for example, during the\ntransition from daylight savings time to standard time where the clocks are\nmoved back and an hour is repeated):\n\n```ruby\ntz.local_time(2018, 3, 11, 2, 30, 0, 0)\n# raises TZInfo::PeriodNotFound (2018-03-11 02:30:00 is an invalid local time.)\ntz.local_time(2018, 11, 4, 1, 30, 0, 0)\n# raises TZInfo::AmbiguousTime (2018-11-04 01:30:00 is an ambiguous local time.)\n```\n\n`TZInfo::PeriodNotFound` exceptions can only be resolved by adjusting the time,\nfor example, by advancing an hour:\n\n```ruby\ntz.local_time(2018, 3, 11, 3, 30, 0, 0)\n# =\u003e 2018-03-11 03:30:00 -0400\n```\n\n`TZInfo::AmbiguousTime` exceptions can be resolved by setting the `dst`\nparameter and/or specifying a block to choose one of the interpretations:\n\n```ruby\ntz.local_time(2018, 11, 4, 1, 30, 0, 0, true)\n# =\u003e 2018-11-04 01:30:00 -0400\ntz.local_time(2018, 11, 4, 1, 30, 0, 0, false)\n# =\u003e 2018-11-04 01:30:00 -0500\n\ntz.local_time(2018, 11, 4, 1, 30, 0, 0) {|p| p.first }\n# =\u003e 2018-11-04 01:30:00 -0400\ntz.local_time(2018, 11, 4, 1, 30, 0, 0) {|p| p.last }\n# =\u003e 2018-11-04 01:30:00 -0500\n```\n\nThe default value of the `dst` parameter can also be set globally:\n\n```ruby\nTZInfo::Timezone.default_dst = true\ntz.local_time(2018, 11, 4, 1, 30, 0, 0)\n# =\u003e 2018-11-04 01:30:00 -0400\nTZInfo::Timezone.default_dst = false\ntz.local_time(2018, 11, 4, 1, 30, 0, 0)\n# =\u003e 2018-11-04 01:30:00 -0500\n```\n\nTZInfo also provides information about\n[ISO 3166-1](https://www.iso.org/iso-3166-country-codes.html) countries and\ntheir associated time zones via the `TZInfo::Country` class.\n\nA list of valid ISO 3166-1 (alpha-2) country codes can be obtained by calling\n`TZInfo::Country.all_codes`:\n\n```ruby\nTZInfo::Country.all_codes\n# =\u003e [\"AD\", \"AE\", ..., \"ZW\"]\n```\n\nA `TZInfo::Country` instance representing an individual time zone can be\nobtained with `TZInfo::Country.get`:\n\n```ruby\nc = TZInfo::Country.get('US')\n# =\u003e #\u003cTZInfo::Country: US\u003e\nc.name\n# =\u003e \"United States\"\n```\n\nThe `zone_identifiers` method returns a list of the time zone identifiers used\nin a country:\n\n```ruby\nc.zone_identifiers\n# =\u003e [\"America/New_York\", \"America/Detroit\", ..., \"Pacific/Honolulu\"]\n```\n\nThe `zone_info` method returns further information about the time zones used in\na country as an `Array` of `TZInfo::CountryTimezone` instances:\n\n```ruby\nzi = c.zone_info.first\nzi.identifier               # =\u003e \"America/New_York\"\nzi.latitude.to_f.round(5)   # =\u003e 40.71417\nzi.longitude.to_f.round(5)  # =\u003e -74.00639\nzi.description              # =\u003e \"Eastern (most areas)\"\n```\n\nThe `zones` method returns an `Array` of `TZInfo::Timezone` instances for a\ncountry. A `TZInfo::Timezone` instance can be obtained from a\n`TZInfo::CountryTimezone` using the `timezone` method:\n\n```ruby\nzi.timezone.to_local(Time.utc(2018, 2, 1, 12, 30, 0))\n# =\u003e 2018-02-01 07:30:00 -0500\n```\n\nFor further detail, please refer to the API documentation for the\n`TZInfo::Timezone` and `TZInfo::Country` classes.\n\n\n## Time Zone Selection\n\nThe Time Zone Database maintainers recommend that time zone identifiers are not\nmade visible to end-users (see [Names of\ntimezones](https://data.iana.org/time-zones/theory.html#naming)).\n\nInstead of displaying a list of time zone identifiers, time zones can be\nselected by the user's country. Call `TZInfo::Country.all` to obtain a list of\n`TZInfo::Country` objects, each with a unique `code` and a `name` that can be\nused for display purposes.\n\nMost countries have a single time zone. When choosing such a country, the time\nzone can be inferred and selected automatically.\n\n```ruby\ncroatia = TZInfo::Country.get('HR')\n# =\u003e #\u003cTZInfo::Country: HR\u003e\ncroatia.zone_info.length\n# =\u003e 1\ncroatia.zone_info[0].identifier\n# =\u003e \"Europe/Belgrade\"\n```\n\nSome countries have multiple time zones. The `zone_info` method can be used\nto obtain a list of user-friendly descriptions of the available options:\n\n```ruby\naustralia = TZInfo::Country.get('AU')\n# =\u003e #\u003cTZInfo::Country: AU\u003e\naustralia.zone_info.length\n# =\u003e 13\naustralia.zone_info.map {|i| [i.identifier, i.description] }\n# =\u003e [[\"Australia/Lord_Howe\", \"Lord Howe Island\"],\n#     [\"Antarctica/Macquarie\", \"Macquarie Island\"],\n#     ...\n#     [\"Australia/Eucla\", \"Western Australia (Eucla)\"]]\n```\n\nPlease note that country information available through TZInfo is intended as an\naid to help users select a time zone data appropriate for their practical needs.\nIt is not intended to take or endorse any position on legal or territorial\nclaims.\n\n\n## Compatibility\n\nTZInfo v2.0.0 requires a minimum of Ruby MRI 1.9.3 or JRuby 1.7 (in 1.9 mode or\nlater).\n\n\n## Thread-Safety\n\nThe `TZInfo::Country` and `TZInfo::Timezone` classes are thread-safe. It is safe\nto use class and instance methods of `TZInfo::Country` and `TZInfo::Timezone` in\nconcurrently executing threads. Instances of both classes can be shared across\nthread boundaries.\n\n\n## Documentation\n\nAPI documentation for TZInfo is available on\n[RubyDoc.info](https://www.rubydoc.info/gems/tzinfo/).\n\n\n## License\n\nTZInfo is released under the MIT license, see LICENSE for details.\n\n\n## Source Code\n\nSource code for TZInfo is available on\n[GitHub](https://github.com/tzinfo/tzinfo).\n\n\n## Issue Tracker\n\nPlease post any bugs, issues, feature requests or questions about TZInfo to the\n[GitHub issue tracker](https://github.com/tzinfo/tzinfo/issues).\n\nIssues with the underlying time zone data should be raised on the\n[Time Zone Database Discussion mailing list](https://mm.icann.org/mailman/listinfo/tz).\n","funding_links":[],"categories":["Date and Time Processing","Ruby"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftzinfo%2Ftzinfo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftzinfo%2Ftzinfo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftzinfo%2Ftzinfo/lists"}