{"id":19210894,"url":"https://github.com/mathieuprog/tz_extra","last_synced_at":"2025-08-03T15:40:57.233Z","repository":{"id":62430583,"uuid":"240643407","full_name":"mathieuprog/tz_extra","owner":"mathieuprog","description":"A few utilities to work with time zones in Elixir","archived":false,"fork":false,"pushed_at":"2024-09-16T03:22:27.000Z","size":252,"stargazers_count":20,"open_issues_count":2,"forks_count":3,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-08T00:56:15.738Z","etag":null,"topics":["elixir","elixir-lang","time-zone","timezone"],"latest_commit_sha":null,"homepage":"","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mathieuprog.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","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},"funding":{"github":"mathieuprog"}},"created_at":"2020-02-15T04:15:50.000Z","updated_at":"2024-11-10T03:55:14.000Z","dependencies_parsed_at":"2024-11-09T13:39:55.973Z","dependency_job_id":null,"html_url":"https://github.com/mathieuprog/tz_extra","commit_stats":{"total_commits":80,"total_committers":3,"mean_commits":"26.666666666666668","dds":"0.025000000000000022","last_synced_commit":"a7c074d199d8808cd0665cbfdbbf0f9da202b128"},"previous_names":[],"tags_count":46,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mathieuprog%2Ftz_extra","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mathieuprog%2Ftz_extra/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mathieuprog%2Ftz_extra/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mathieuprog%2Ftz_extra/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mathieuprog","download_url":"https://codeload.github.com/mathieuprog/tz_extra/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243835959,"owners_count":20355613,"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":["elixir","elixir-lang","time-zone","timezone"],"created_at":"2024-11-09T13:39:39.116Z","updated_at":"2025-03-16T07:05:08.996Z","avatar_url":"https://github.com/mathieuprog.png","language":"Elixir","funding_links":["https://github.com/sponsors/mathieuprog"],"categories":[],"sub_categories":[],"readme":"# TzExtra\n\n`tz_extra` provides a few utilities to work with time zones. It uses [`Tz`](https://github.com/mathieuprog/tz) under the hood, which brings time zone support for Elixir.\n\n* [`TzExtra.countries_time_zones/0`](#tzextracountries_time_zones0): returns a list of time zone data by country\n* `TzExtra.country_time_zone/2`\n* `TzExtra.country_time_zone!/2`\n* [`TzExtra.time_zone_ids/1`](#tzextratime_zone_ids1): returns a list of time zone identifiers\n* `TzExtra.time_zone_id_exists?/1`\n* [`TzExtra.civil_time_zone_ids/1`](#tzextracivil_time_zone_ids1): returns a list of time zone identifiers that are tied to a country\n* [`TzExtra.countries/0`](#tzextracountries0): returns a list of ISO country codes with their English name\n* [`TzExtra.canonical_time_zone_id/1`](#tzextracanonical_time_zone_id1): returns the canonical time zone identifier for the given time zone identifier\n* [`TzExtra.Changeset.validate_time_zone_id/3`](#tzextraChangesetvalidate_time_zone_id3): an Ecto Changeset validator, validating that the user input is a valid time zone\n* [`TzExtra.Changeset.validate_civil_time_zone_id/3`](#tzextraChangesetvalidate_civil_time_zone_id3): an Ecto Changeset validator, validating that the user input is a valid civil time zone\n* [`TzExtra.Changeset.validate_iso_country_code/3`](#tzextraChangesetvalidate_iso_country_code3): an Ecto Changeset validator, validating that the user input is a valid ISO country code\n* `TzExtra.new_resolved_datetime!/4`\n* `TzExtra.utc_datetime_range/3`\n* `TzExtra.round_datetime/3`\n* `TzExtra.shifts_clock?/1`\n* `TzExtra.clock_shift/2`\n* `TzExtra.next_clock_shift_in_year_span/1`\n* `TzExtra.utc_offset_id/2`\n\n### `TzExtra.countries_time_zones/0`\n\nReturns a list of time zone data by country.\n\n#### Example\n\n```elixir\niex\u003e TzExtra.countries_time_zones() |\u003e Enum.find(\u0026 \u00261.country.code == \"BE\")\n```\n\n```elixir\n%{\n  time_zone_id: \"Europe/Brussels\",\n  time_zone_alias_ids: [\"Europe/Amsterdam\", \"Europe/Luxembourg\"],\n\n  country: %{code: \"BE\", name: \"Belgium\", local_names: [\"België\", \"Belgique\"]},\n  coordinates: \"+5050+00420\",\n\n  time_zone_abbr: \"CET\",\n  dst_time_zone_abbr: \"CEST\",\n\n  utc_to_std_offset: 3600,\n  utc_to_dst_offset: 7200,\n  utc_to_std_offset_id: \"UTC+01:00\",\n  utc_to_dst_offset_id: \"UTC+02:00\",\n  pretty_utc_to_std_offset_id: \"UTC+1\",\n  pretty_utc_to_dst_offset_id: \"UTC+2\"\n}\n```\n\nNote that a time zone may be observed by multiple countries. For example, the tz database version `2024a` lists 10\ncountries observing the time zone `\"Africa/Lagos\"`; this will result in 10 map entries for that time zone.\n\n### `TzExtra.CountryTimeZone.for_country_code/1`\n\nReturns a list of time zone data for the given country code (string or atom).\n\n### `TzExtra.CountryTimeZone.for_time_zone/1`\n\nReturns a list of time zone data for the given time zone.\n\nYou may also call `TzExtra.country_time_zone/1` which takes a country code or a time zone as argument.\n\n### `TzExtra.time_zone_ids/1`\n\n```elixir\niex\u003e TzExtra.time_zone_ids() |\u003e Enum.take(5)\n```\n\n```elixir\n[\n  \"Africa/Abidjan\",\n  \"Africa/Algiers\",\n  \"Africa/Bissau\",\n  \"Africa/Cairo\",\n  \"Africa/Casablanca\"\n]\n```\n\nThis function can take an option `:include_aliases` (by default set to `false`) to include time zone aliases. By default, only canonical time zones are returned. Set this option to `true` to include time zone aliases.\n\n### `TzExtra.civil_time_zone_ids/1`\n\n```elixir\niex\u003e TzExtra.civil_time_zone_ids()\n```\n\nThis function returns only the time zone identifiers attached to a country. It takes two options:\n* `:include_aliases` (by default set to `false`)\n  By default, only canonical time zones are returned. Set this option to `false` to include time zone aliases.\n\n### `TzExtra.countries/0`\n\n```elixir\niex\u003e TzExtra.countries() |\u003e Enum.take(5)\n```\n\n```elixir\n[\n  %{code: \"AF\", name: \"Afghanistan\"},\n  %{code: \"AL\", name: \"Albania\"},\n  %{code: \"DZ\", name: \"Algeria\"},\n  %{code: \"AD\", name: \"Andorra\"},\n  %{code: \"AO\", name: \"Angola\"}\n]\n```\n\n### `TzExtra.canonical_time_zone_id/1`\n\nReturns the canonical time zone identifier for the given time zone identifier.\n\nIf you pass a canonical time zone identifier, the same identifier will be returned.\n\n```elixir\niex\u003e TzExtra.canonical_time_zone_id(\"Asia/Phnom_Penh\")\n```\n\n```elixir\n\"Asia/Bangkok\"\n```\n\n```elixir\niex\u003e TzExtra.canonical_time_zone_id(\"Asia/Bangkok\")\n```\n\n```elixir\n\"Asia/Bangkok\"\n```\n\n### `TzExtra.Changeset.validate_time_zone_id/3`\n\n```elixir\nimport TzExtra.Changeset\n\nchangeset\n|\u003e validate_time_zone_id(:time_zone_id)\n```\n\nYou may pass the option `:allow_alias` to allow time zone aliases, as well as the `:message` option to customize the error message.\n\n### `TzExtra.Changeset.validate_civil_time_zone_id/3`\n\n```elixir\nimport TzExtra.Changeset\n\nchangeset\n|\u003e validate_civil_time_zone_id(:time_zone_id)\n```\n\nYou may pass the option `:allow_alias` to allow time zone aliases, as well as the `:message` option to customize the error message.\n\n### `TzExtra.Changeset.validate_iso_country_code/3`\n\n```elixir\nimport TzExtra.Changeset\n\nchangeset\n|\u003e validate_iso_country_code(:country_code)\n```\n\nYou may pass the `:message` option to customize the error message.\n\n### Automatic time zone data updates\n\n`tz_extra` can watch for IANA time zone database updates and automatically recompile the time zone data.\n\nTo enable automatic updates, add `TzExtra.UpdatePeriodically` as a child in your supervisor:\n\n```elixir\n{TzExtra.UpdatePeriodically, []}\n```\n\nYou may pass the option `:interval_in_days` in order to configure the frequency of the task.\n\n```elixir\n{TzExtra.UpdatePeriodically, [interval_in_days: 5]}\n```\n\n`TzExtra.UpdatePeriodically` also triggers `tz`'s time zone recompilation; so you don't need to add\n`Tz.UpdatePeriodically` if you added `TzExtra.UpdatePeriodically` in your supervisor.\n\nLastly, if you did not configure a custom http client for `tz`, add the default http client `mint` and ssl certificate store `castore` into your `mix.exs` file:\n\n```elixir\ndefp deps do\n  [\n    {:castore, \"~\u003e 1.0\"},\n    {:mint, \"~\u003e 1.6\"},\n    {:tz_extra, \"~\u003e 0.45\"}\n  ]\nend\n```\n\n### Dump JSON data for JavaScript\n\nDump time zone data into JSON files for JavaScript clients. The JSON files are written into `tz_extra`'s `priv` folder.\n\n```elixir\niex\u003e TzExtra.JsonDumper.dump_countries_time_zones()\n```\n\n```elixir\niex\u003e TzExtra.JsonDumper.dump_countries()\n```\n\n## Installation\n\nAdd `tz_extra` for Elixir as a dependency in your `mix.exs` file:\n\n```elixir\ndef deps do\n  [\n    {:tz_extra, \"~\u003e 0.45\"}\n  ]\nend\n```\n\n## HexDocs\n\nHexDocs documentation can be found at [https://hexdocs.pm/tz_extra](https://hexdocs.pm/tz_extra).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmathieuprog%2Ftz_extra","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmathieuprog%2Ftz_extra","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmathieuprog%2Ftz_extra/lists"}