tzf2 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +16 -0
- data/Cargo.lock +323 -0
- data/Cargo.toml +4 -0
- data/LICENSE +21 -0
- data/LICENSE_DATA +539 -0
- data/NOTICE +15 -0
- data/README.md +146 -0
- data/ext/tzf2/Cargo.toml +16 -0
- data/ext/tzf2/extconf.rb +6 -0
- data/ext/tzf2/src/lib.rs +39 -0
- data/lib/tzf.rb +3 -0
- data/lib/tzf2/coordinates.rb +37 -0
- data/lib/tzf2/errors.rb +9 -0
- data/lib/tzf2/version.rb +5 -0
- data/lib/tzf2.rb +53 -0
- data/sig/tzf.rbs +26 -0
- data/tzf2.gemspec +53 -0
- metadata +80 -0
data/README.md
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# tzf2
|
|
2
|
+
|
|
3
|
+
Offline latitude and longitude to IANA timezone lookup for Ruby. The gem wraps [tzf-rs](https://github.com/ringsaturn/tzf-rs) 2.0 and embeds current ocean-inclusive boundary data from [tzf-dist](https://github.com/ringsaturn/tzf-dist). Lookups do not use the network.
|
|
4
|
+
|
|
5
|
+
This gem is a drop-in successor to [`tzf`](https://github.com/HarlemSquirrel/tzf-rb) for Rails apps that already call `TZF.tz_name(lat, lng)`. The published gem name is `tzf2` so it does not collide with HarlemSquirrel's gem.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
You need Ruby 3.2 or newer (including 4.0).
|
|
10
|
+
|
|
11
|
+
Precompiled native gems ship for `x86_64-linux`, `aarch64-linux`, `x86_64-darwin`, and `arm64-darwin`. Other platforms compile from source and need clang plus Rust 1.88 or newer.
|
|
12
|
+
|
|
13
|
+
```ruby
|
|
14
|
+
# Gemfile
|
|
15
|
+
gem "tzf2"
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Then run:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
bundle install
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
`require "tzf2"` and `require "tzf"` both load the `TZF` module.
|
|
25
|
+
|
|
26
|
+
## Usage
|
|
27
|
+
|
|
28
|
+
Arguments are latitude first, then longitude. That matches the existing `tzf` gem. It is the opposite of the Rust and Python APIs.
|
|
29
|
+
|
|
30
|
+
```ruby
|
|
31
|
+
require "tzf2"
|
|
32
|
+
|
|
33
|
+
TZF.tz_name(40.7477, -73.9935)
|
|
34
|
+
# => "America/New_York"
|
|
35
|
+
|
|
36
|
+
TZF.tz_names(44.04, 87.416)
|
|
37
|
+
# => ["Asia/Shanghai", "Asia/Urumqi"]
|
|
38
|
+
|
|
39
|
+
TZF.data_version
|
|
40
|
+
# => "2026c"
|
|
41
|
+
|
|
42
|
+
TZF.engine_version
|
|
43
|
+
# => "2.0.0"
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
`tz_name` returns one IANA identifier. `tz_names` returns every match, sorted, which matters on shared borders.
|
|
47
|
+
|
|
48
|
+
Invalid coordinates raise `TZF::InvalidCoordinatesError`.
|
|
49
|
+
|
|
50
|
+
```ruby
|
|
51
|
+
TZF.tz_name(91, 0)
|
|
52
|
+
# TZF::InvalidCoordinatesError: latitude 91.0 is outside -90..90
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
A valid point with no covering polygon raises `TZF::UncoveredCoordinateError`. Rescue that in the application if you need a fallback. This gem does not guess a neighbor zone.
|
|
56
|
+
|
|
57
|
+
```ruby
|
|
58
|
+
TZF.tz_name(-54.1, -36.1)
|
|
59
|
+
# TZF::UncoveredCoordinateError: no timezone covers latitude -54.1, longitude -36.1
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
`raw_tz_name` and `raw_tz_names` return the engine result without raising (`""` / `[]` on a miss).
|
|
63
|
+
|
|
64
|
+
## Global coverage
|
|
65
|
+
|
|
66
|
+
The embedded dataset is timezone-boundary-builder `timezones-with-oceans` as packaged by tzf-dist release `2026c`. That product includes land zones, territorial waters, polar regions, and open-ocean `Etc/GMT*` zones. It does not tile the sphere without gaps.
|
|
67
|
+
|
|
68
|
+
Lite simplification and a few source/encoding slivers leave hairline holes. A 10-degree grid is fully covered in `spec/fixtures/differential_baseline.json`. A 0.1-degree walk is not. Full-precision `tzf-dist` data closes some lite holes and still misses others.
|
|
69
|
+
|
|
70
|
+
This gem returns `UncoveredCoordinateError` on those points. It does not snap to a neighbor.
|
|
71
|
+
|
|
72
|
+
This release reports 444 timezone names.
|
|
73
|
+
|
|
74
|
+
The default dataset is the lite `.tzb` file. Simplified boundaries stay within about 111 m of the full-precision border. See the [tzf-rs accuracy notes](https://github.com/ringsaturn/tzf-rs#accuracy).
|
|
75
|
+
|
|
76
|
+
## Ocean timezone semantics
|
|
77
|
+
|
|
78
|
+
Open ocean uses POSIX-signed `Etc/GMT*` identifiers.
|
|
79
|
+
|
|
80
|
+
- `Etc/GMT+8` is UTC-08:00.
|
|
81
|
+
- `Etc/GMT-5` is UTC+05:00.
|
|
82
|
+
|
|
83
|
+
Point Nemo (`-48.876667, -123.393333`) returns `Etc/GMT+8`. Coastal points inside territorial waters keep the land zone.
|
|
84
|
+
|
|
85
|
+
## Data provenance
|
|
86
|
+
|
|
87
|
+
| Layer | Source | License |
|
|
88
|
+
| --- | --- | --- |
|
|
89
|
+
| Ruby and Rust wrapper | this repository | MIT, see `LICENSE` |
|
|
90
|
+
| Lookup engine | [tzf-rs](https://github.com/ringsaturn/tzf-rs) 2.0.0 | MIT |
|
|
91
|
+
| Packed `.tzb` data | [tzf-dist](https://github.com/ringsaturn/tzf-dist) `2026c` | ODbL, see `LICENSE_DATA` |
|
|
92
|
+
| Original boundaries | [timezone-boundary-builder](https://github.com/evansiroky/timezone-boundary-builder) | ODbL |
|
|
93
|
+
|
|
94
|
+
The original database is built from OpenStreetMap. `NOTICE` names both upstreams.
|
|
95
|
+
|
|
96
|
+
## Version reporting
|
|
97
|
+
|
|
98
|
+
- `TZF::VERSION` is this gem.
|
|
99
|
+
- `TZF.engine_version` is the compiled `tzf-rs` crate.
|
|
100
|
+
- `TZF.data_version` is the tzf-dist / timezone-boundary-builder release inside the binary.
|
|
101
|
+
|
|
102
|
+
Pin all three when you record a production lookup result.
|
|
103
|
+
|
|
104
|
+
## Upgrades
|
|
105
|
+
|
|
106
|
+
1. Bump `tzf-rs` in `ext/tzf2/Cargo.toml`.
|
|
107
|
+
2. Run `cargo update -p tzf-rs` and `bundle exec rake compile`.
|
|
108
|
+
3. Run `bundle exec rake spec`.
|
|
109
|
+
4. Run `bundle exec ruby bin/differential`.
|
|
110
|
+
5. If the report lists timezone-id, timezone-names, UTC-offset, newly covered, or uncovered points, decide whether the new data is intended.
|
|
111
|
+
6. To accept the new table, run `bundle exec rake differential:write` and update `spec/fixtures/locations.yml`.
|
|
112
|
+
7. Set `TZF.engine_version` in `ext/tzf2/src/lib.rs` to the new crate version.
|
|
113
|
+
|
|
114
|
+
## Testing
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
bin/setup
|
|
118
|
+
bundle exec rake
|
|
119
|
+
bundle exec rake differential
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Specs cover major cities, ocean zones including Point Nemo, polar and antimeridian points, shared borders, latitude/longitude order, invalid input, and thread safety.
|
|
123
|
+
|
|
124
|
+
A 10-degree world grid and a 0.1-degree world grid are looked up in a standalone Rust binary (`crates/grid_parity`) and again through `TZF.raw_tz_name` / `TZF.raw_tz_names`. The answers must match, including empty engine results. That checks the Ruby wrapper against tzf-rs, not against a pinned Ruby table.
|
|
125
|
+
|
|
126
|
+
The differential suite compares the current engine to `spec/fixtures/differential_baseline.json`. It reports timezone-id changes, all-match list changes, UTC-offset changes at `2026-01-15T12:00:00Z`, and points that gained or lost coverage.
|
|
127
|
+
|
|
128
|
+
## Rollback
|
|
129
|
+
|
|
130
|
+
Keep the previous `tzf2` git SHA in the Gemfile if a data upgrade changes production answers.
|
|
131
|
+
|
|
132
|
+
```ruby
|
|
133
|
+
gem "tzf2", github: "joseph-lozano/tzf-2-rb", ref: "<known-good-sha>"
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
To go back to HarlemSquirrel's gem, restore `gem "tzf"` and `require "tzf"`. The call shape is the same. Answers can differ because that gem still tracks tzf-rs 1.x.
|
|
137
|
+
|
|
138
|
+
## Supported platforms
|
|
139
|
+
|
|
140
|
+
CI compiles and tests Ruby 3.2, 3.3, 3.4, and 4.0 on Ubuntu, plus Ruby 3.4 on `ubuntu-24.04-arm`, `macos-15-intel`, and `macos-latest`.
|
|
141
|
+
|
|
142
|
+
Release builds precompiled gems for Linux x86_64, Linux ARM64, Intel Mac, and Apple Silicon. Windows is not supported.
|
|
143
|
+
|
|
144
|
+
## License
|
|
145
|
+
|
|
146
|
+
MIT for the wrapper. ODbL for the embedded boundary database. See `LICENSE`, `LICENSE_DATA`, and `NOTICE`.
|
data/ext/tzf2/Cargo.toml
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
[package]
|
|
2
|
+
name = "tzf2"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
edition = "2021"
|
|
5
|
+
license = "MIT"
|
|
6
|
+
publish = false
|
|
7
|
+
|
|
8
|
+
[lib]
|
|
9
|
+
crate-type = ["cdylib"]
|
|
10
|
+
|
|
11
|
+
[dependencies]
|
|
12
|
+
magnus = { version = "0.8" }
|
|
13
|
+
tzf-rs = { version = "2.0.0", default-features = false, features = ["bundled"] }
|
|
14
|
+
rb-sys = { version = "0.9", default-features = false, features = [
|
|
15
|
+
"stable-api-compiled-fallback",
|
|
16
|
+
] }
|
data/ext/tzf2/extconf.rb
ADDED
data/ext/tzf2/src/lib.rs
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
use std::sync::LazyLock;
|
|
2
|
+
|
|
3
|
+
use magnus::{function, prelude::*, Error, Ruby};
|
|
4
|
+
use tzf_rs::DefaultFinder;
|
|
5
|
+
|
|
6
|
+
static FINDER: LazyLock<DefaultFinder> = LazyLock::new(DefaultFinder::new);
|
|
7
|
+
|
|
8
|
+
const ENGINE_VERSION: &str = "2.0.0";
|
|
9
|
+
|
|
10
|
+
fn raw_tz_name(lat: f64, lng: f64) -> &'static str {
|
|
11
|
+
FINDER.get_tz_name(lng, lat)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
fn raw_tz_names(lat: f64, lng: f64) -> Vec<&'static str> {
|
|
15
|
+
FINDER.get_tz_names(lng, lat)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
fn raw_data_version() -> &'static str {
|
|
19
|
+
FINDER.data_version()
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
fn raw_engine_version() -> &'static str {
|
|
23
|
+
ENGINE_VERSION
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
fn raw_timezone_names() -> Vec<&'static str> {
|
|
27
|
+
FINDER.timezonenames()
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
#[magnus::init]
|
|
31
|
+
fn init(ruby: &Ruby) -> Result<(), Error> {
|
|
32
|
+
let module = ruby.define_module("TZF")?;
|
|
33
|
+
module.define_singleton_method("raw_tz_name", function!(raw_tz_name, 2))?;
|
|
34
|
+
module.define_singleton_method("raw_tz_names", function!(raw_tz_names, 2))?;
|
|
35
|
+
module.define_singleton_method("raw_data_version", function!(raw_data_version, 0))?;
|
|
36
|
+
module.define_singleton_method("raw_engine_version", function!(raw_engine_version, 0))?;
|
|
37
|
+
module.define_singleton_method("raw_timezone_names", function!(raw_timezone_names, 0))?;
|
|
38
|
+
Ok(())
|
|
39
|
+
}
|
data/lib/tzf.rb
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module TZF
|
|
4
|
+
class Coordinates
|
|
5
|
+
attr_reader :latitude, :longitude
|
|
6
|
+
|
|
7
|
+
def self.parse(latitude, longitude)
|
|
8
|
+
new(latitude, longitude)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def initialize(latitude, longitude)
|
|
12
|
+
@latitude = finite_float(latitude, "latitude")
|
|
13
|
+
@longitude = finite_float(longitude, "longitude")
|
|
14
|
+
unless (-90.0..90.0).cover?(@latitude)
|
|
15
|
+
raise InvalidCoordinatesError, "latitude #{@latitude} is outside -90..90"
|
|
16
|
+
end
|
|
17
|
+
unless (-180.0..180.0).cover?(@longitude)
|
|
18
|
+
raise InvalidCoordinatesError, "longitude #{@longitude} is outside -180..180"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def finite_float(value, name)
|
|
25
|
+
unless value.is_a?(Numeric)
|
|
26
|
+
raise InvalidCoordinatesError, "#{name} must be numeric, got #{value.class}"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
float = Float(value)
|
|
30
|
+
unless float.finite?
|
|
31
|
+
raise InvalidCoordinatesError, "#{name} must be a finite number"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
float
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
data/lib/tzf2/errors.rb
ADDED
data/lib/tzf2/version.rb
ADDED
data/lib/tzf2.rb
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "tzf2/version"
|
|
4
|
+
require_relative "tzf2/errors"
|
|
5
|
+
require_relative "tzf2/coordinates"
|
|
6
|
+
|
|
7
|
+
ruby_minor_version = RUBY_VERSION.split(".")[0..1].join(".")
|
|
8
|
+
versioned = File.join(__dir__, "tzf2", ruby_minor_version, "tzf2")
|
|
9
|
+
if File.exist?("#{versioned}.bundle") || File.exist?("#{versioned}.so")
|
|
10
|
+
require versioned
|
|
11
|
+
else
|
|
12
|
+
require_relative "tzf2/tzf2"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
module TZF
|
|
16
|
+
class << self
|
|
17
|
+
def tz_name(latitude, longitude)
|
|
18
|
+
coords = Coordinates.parse(latitude, longitude)
|
|
19
|
+
name = raw_tz_name(coords.latitude, coords.longitude)
|
|
20
|
+
raise uncovered_error(coords) if name.empty?
|
|
21
|
+
|
|
22
|
+
name
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def tz_names(latitude, longitude)
|
|
26
|
+
coords = Coordinates.parse(latitude, longitude)
|
|
27
|
+
names = raw_tz_names(coords.latitude, coords.longitude)
|
|
28
|
+
raise uncovered_error(coords) if names.empty?
|
|
29
|
+
|
|
30
|
+
names
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def data_version
|
|
34
|
+
raw_data_version
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def engine_version
|
|
38
|
+
raw_engine_version
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def timezone_names
|
|
42
|
+
raw_timezone_names
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
def uncovered_error(coords)
|
|
48
|
+
UncoveredCoordinateError.new(
|
|
49
|
+
"no timezone covers latitude #{coords.latitude}, longitude #{coords.longitude}"
|
|
50
|
+
)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
data/sig/tzf.rbs
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module TZF
|
|
2
|
+
VERSION: String
|
|
3
|
+
|
|
4
|
+
class Error < StandardError
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
class InvalidCoordinatesError < Error
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
class UncoveredCoordinateError < Error
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
class Coordinates
|
|
14
|
+
attr_reader latitude: Float
|
|
15
|
+
attr_reader longitude: Float
|
|
16
|
+
|
|
17
|
+
def self.parse: (Numeric latitude, Numeric longitude) -> Coordinates
|
|
18
|
+
def initialize: (Numeric latitude, Numeric longitude) -> void
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def self.tz_name: (Numeric latitude, Numeric longitude) -> String
|
|
22
|
+
def self.tz_names: (Numeric latitude, Numeric longitude) -> Array[String]
|
|
23
|
+
def self.data_version: () -> String
|
|
24
|
+
def self.engine_version: () -> String
|
|
25
|
+
def self.timezone_names: () -> Array[String]
|
|
26
|
+
end
|
data/tzf2.gemspec
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "lib/tzf2/version"
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.name = "tzf2"
|
|
7
|
+
spec.version = TZF::VERSION
|
|
8
|
+
spec.authors = ["Joseph Lozano"]
|
|
9
|
+
spec.email = ["me@lozanojoseph.com"]
|
|
10
|
+
|
|
11
|
+
spec.summary = "Offline latitude/longitude to IANA timezone lookup via tzf-rs 2"
|
|
12
|
+
spec.description = <<~DESC
|
|
13
|
+
Ruby wrapper around tzf-rs v2 for offline timezone lookup from WGS84
|
|
14
|
+
coordinates. Embeds current ocean-inclusive timezone-boundary-builder data
|
|
15
|
+
from tzf-dist. No runtime network access.
|
|
16
|
+
DESC
|
|
17
|
+
spec.homepage = "https://github.com/joseph-lozano/tzf-2-rb"
|
|
18
|
+
spec.license = "MIT"
|
|
19
|
+
spec.required_ruby_version = ">= 3.2.0"
|
|
20
|
+
spec.required_rubygems_version = ">= 3.4.6"
|
|
21
|
+
|
|
22
|
+
spec.metadata["bug_tracker_uri"] = "#{spec.homepage}/issues"
|
|
23
|
+
spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/CHANGELOG.md"
|
|
24
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
|
25
|
+
spec.metadata["rubygems_mfa_required"] = "true"
|
|
26
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
|
27
|
+
|
|
28
|
+
spec.files = %w[
|
|
29
|
+
CHANGELOG.md
|
|
30
|
+
Cargo.lock
|
|
31
|
+
Cargo.toml
|
|
32
|
+
LICENSE
|
|
33
|
+
LICENSE_DATA
|
|
34
|
+
NOTICE
|
|
35
|
+
README.md
|
|
36
|
+
ext/tzf2/Cargo.toml
|
|
37
|
+
ext/tzf2/extconf.rb
|
|
38
|
+
ext/tzf2/src/lib.rs
|
|
39
|
+
lib/tzf.rb
|
|
40
|
+
lib/tzf2.rb
|
|
41
|
+
lib/tzf2/coordinates.rb
|
|
42
|
+
lib/tzf2/errors.rb
|
|
43
|
+
lib/tzf2/version.rb
|
|
44
|
+
sig/tzf.rbs
|
|
45
|
+
tzf2.gemspec
|
|
46
|
+
]
|
|
47
|
+
spec.bindir = "exe"
|
|
48
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
|
49
|
+
spec.require_paths = ["lib"]
|
|
50
|
+
spec.extensions = ["ext/tzf2/extconf.rb"]
|
|
51
|
+
|
|
52
|
+
spec.add_dependency "rb_sys", "~> 0.9.117"
|
|
53
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: tzf2
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Joseph Lozano
|
|
8
|
+
bindir: exe
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: rb_sys
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: 0.9.117
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: 0.9.117
|
|
26
|
+
description: |
|
|
27
|
+
Ruby wrapper around tzf-rs v2 for offline timezone lookup from WGS84
|
|
28
|
+
coordinates. Embeds current ocean-inclusive timezone-boundary-builder data
|
|
29
|
+
from tzf-dist. No runtime network access.
|
|
30
|
+
email:
|
|
31
|
+
- me@lozanojoseph.com
|
|
32
|
+
executables: []
|
|
33
|
+
extensions:
|
|
34
|
+
- ext/tzf2/extconf.rb
|
|
35
|
+
extra_rdoc_files: []
|
|
36
|
+
files:
|
|
37
|
+
- CHANGELOG.md
|
|
38
|
+
- Cargo.lock
|
|
39
|
+
- Cargo.toml
|
|
40
|
+
- LICENSE
|
|
41
|
+
- LICENSE_DATA
|
|
42
|
+
- NOTICE
|
|
43
|
+
- README.md
|
|
44
|
+
- ext/tzf2/Cargo.toml
|
|
45
|
+
- ext/tzf2/extconf.rb
|
|
46
|
+
- ext/tzf2/src/lib.rs
|
|
47
|
+
- lib/tzf.rb
|
|
48
|
+
- lib/tzf2.rb
|
|
49
|
+
- lib/tzf2/coordinates.rb
|
|
50
|
+
- lib/tzf2/errors.rb
|
|
51
|
+
- lib/tzf2/version.rb
|
|
52
|
+
- sig/tzf.rbs
|
|
53
|
+
- tzf2.gemspec
|
|
54
|
+
homepage: https://github.com/joseph-lozano/tzf-2-rb
|
|
55
|
+
licenses:
|
|
56
|
+
- MIT
|
|
57
|
+
metadata:
|
|
58
|
+
bug_tracker_uri: https://github.com/joseph-lozano/tzf-2-rb/issues
|
|
59
|
+
changelog_uri: https://github.com/joseph-lozano/tzf-2-rb/blob/main/CHANGELOG.md
|
|
60
|
+
homepage_uri: https://github.com/joseph-lozano/tzf-2-rb
|
|
61
|
+
rubygems_mfa_required: 'true'
|
|
62
|
+
allowed_push_host: https://rubygems.org
|
|
63
|
+
rdoc_options: []
|
|
64
|
+
require_paths:
|
|
65
|
+
- lib
|
|
66
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
67
|
+
requirements:
|
|
68
|
+
- - ">="
|
|
69
|
+
- !ruby/object:Gem::Version
|
|
70
|
+
version: 3.2.0
|
|
71
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - ">="
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: 3.4.6
|
|
76
|
+
requirements: []
|
|
77
|
+
rubygems_version: 3.6.9
|
|
78
|
+
specification_version: 4
|
|
79
|
+
summary: Offline latitude/longitude to IANA timezone lookup via tzf-rs 2
|
|
80
|
+
test_files: []
|