コンテンツにスキップ
はじめる

はじめる

Project tzf は複数の言語とサービスに対応し、経度・緯度からタイムゾーンを検索できます。

言語 / サービスリポジトリAPI ドキュメント
Goringsaturn/tzf
Rustringsaturn/tzf-rs
Pythonringsaturn/tzfpytzfpy.pyi
Swiftringsaturn/tzf-swift
RubyHarlemSquirrel/tzf-rb
JS (ブラウザ Wasm)ringsaturn/tzf-wasm
HTTP APIracemap/rust-tz-service
オンラインデモringsaturn/tzf-web

Go

tzf v2 は新しいメジャーバージョンであるため、モジュールパスに /v2 サフィックスが付きます。

go get github.com/ringsaturn/tzf/v2
package main

import (
	"fmt"

	"github.com/ringsaturn/tzf/v2"
)

func main() {
	// 構築のコストはクエリと比べて大きいため、Finder は一度だけ構築します。
	finder, err := tzf.NewDefaultFinder()
	if err != nil {
		panic(err)
	}
	// 座標は (経度,緯度) の順です。
	fmt.Println(finder.GetTimezoneName(116.6386, 40.0786))
}

コンストラクタは 5 つあり、いずれも tzf.F インターフェイスを返します。

コンストラクタ対象
NewDefaultFinder()汎用用途:lite メモリイメージ、ヒープ約 12 MB + 読み取り専用データ 10 MB、クエリ 298 ns
NewEmbeddedFinder()組み込みおよびメモリ制約のある環境:合計約 4 MB、プレインデックスミス時のクエリ約 1.2 µs
NewFullFinder()完全精度データセットと一致する結果(約 145 MB)
NewFinderFromTZB(data)呼び出し側が用意した .tzb バイト列、ロード時に展開
NewFinderFromTZM(data)呼び出し側が用意した .tzm バイト列、インプレースで参照

数値は Apple M3 Max で 2026c データセットを対象に測定した値です。

100% 正確な結果が必要な場合は NewFullFinder を使用します。初期化コストが高いため、できるだけ再利用してください:

package main

import (
	"fmt"

	"github.com/ringsaturn/tzf/v2"
)

func main() {
	finder, err := tzf.NewFullFinder()
	if err != nil {
		panic(err)
	}
	fmt.Println(finder.GetTimezoneName(139.6917, 35.6895))
}

GeoJSON エクスポート、独自のバイト列に対するインプレースクエリ、v1 から v2 への移行表については Go ガイドを参照してください。

Rust

cargo add tzf-rs
use std::sync::LazyLock;
use tzf_rs::DefaultFinder;

static FINDER: LazyLock<DefaultFinder> = LazyLock::new(DefaultFinder::new);

fn main() {
    // 座標は (経度,緯度) の順です。
    print!("{:?}\n", FINDER.get_tz_name(116.3883, 39.9289));
    print!("{:?}\n", FINDER.get_tz_names(116.3883, 39.9289));
}

tzf-rs 2.1 は 2 つの Finder を提供します。デフォルトの DefaultFinder(ピーク RSS 約 47 MiB、ランダム都市検索 221 ns)と、埋め込みファイルをインプレースで参照する EmbeddedFinder(約 10 MiB、ランダム都市検索 293 ns、境界都市 666 ns)です。いずれも tz-benchmark の 2026-09-14 スナップショットにおいて、Apple M3 Max で 2026c データセットを対象に tzf-rs 2.1.1 を測定した値です。

完全精度サポート

オプションの Cargo feature で完全精度データを利用できます。完全データセットは約 14 MB あり、crates.io のサイズ制限を超えるため git 依存関係で参照する必要があり、バンドルされた lite データセットとは排他です:

[dependencies]
tzf-rs = { git = "https://github.com/ringsaturn/tzf-rs", rev = "v{X}.{Y}.{Z}", features = ["full"], default-features = false }
use tzf_rs::DefaultFinder;

fn main() {
    let finder = DefaultFinder::new_full();
    let tz_name = finder.get_tz_name(139.767125, 35.681236);
    println!("tz_name: {}", tz_name);
}

Python

# tzfpy のみインストール
pip install tzfpy

# pytz サポート付きでインストール
pip install "tzfpy[pytz]"

# tzdata サポート付きでインストール
pip install "tzfpy[tzdata]"

# conda でインストール
conda install -c conda-forge tzfpy
>>> from tzfpy import get_tz, get_tzs
>>> get_tz(116.3883, 39.9289)   # (経度,緯度) の順
'Asia/Shanghai'
>>> get_tzs(87.4160, 44.0400)   # 一致するすべてのタイムゾーンを返す
['Asia/Shanghai', 'Asia/Urumqi']

tzfpy 2.0 は Python 3.10 以降が必要で、tzf-rs 2.0 をバインドします。timezonenames()data_version()get_tz_polygon_geojson(name)get_tz_index_geojson(name) も公開しています。完全精度モードは実験的な +full プレリリース wheel として tzfpy 独自のインデックスで提供され、PyPI には公開されません。Python ガイドを参照してください。

Swift

tzf-swift 2.0 は protobuf に依存しません。tzf-dist の lite.tzb を同梱し、2 つの Finder を提供します。DefaultFinder は読み込み時にポリゴンを展開し(約 16 ms、約 48 MB)、EmbeddedFinder.tzb のバイト列をインプレースで参照します(約 2 ms、約 10 MB。1 回あたりのレイテンシは高め)。どちらも init(tzb:) で呼び出し側が用意したバイト列を受け取れるため、tzf-dist の完全精度版 full.tzb も同じ方法で読み込めます。

Package.swift にパッケージを追加します:

dependencies: [
    .package(url: "https://github.com/ringsaturn/tzf-swift.git", from: "2.0.0")
]
import Foundation
import tzf

do {
    let finder = try DefaultFinder()

    let timezone = try finder.getTimezone(lng: 116.3833, lat: 39.9167)
    print("北京のタイムゾーン:", timezone)

    let timezones = try finder.getTimezones(lng: 87.5703, lat: 43.8146)
    print("複数の候補タイムゾーン:", timezones)

    print("データバージョン:", finder.dataVersion())

    // 省メモリの代替:.tzb のバイト列をインプレースで参照します。
    let embedded = try EmbeddedFinder()
    print("Embedded finder:", try embedded.getTimezone(lng: 139.6917, lat: 35.6895))
} catch {
    print("エラー:", error)
}

v1 からの移行:Finder()DefaultFinder() に、PreindexFinder は削除(プレインデックスはすべての Finder 内部の高速パスになりました)、FinderError.noTimezoneFoundTZFError.noTimezoneFound に、getTimezones の結果は辞書順でソートされるようになりました。

Ruby

Ruby 版は HarlemSquirrel が作成し、保守しています。2026-09-12 時点で v1 系列の上に構築されています。詳しい使い方は tzf-rb を参照してください。

bundle add tzf
# または
gem install tzf
require 'tzf'

TZF.tz_name(40.74771675713742, -73.99350390136448)
# => "America/New_York"

TZF.tz_names(40.74771675713742, -73.99350390136448)
# => ["America/New_York"]

WebAssembly

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>tzf-wasm 例</title>
    <script type="module">
      import init, { WasmFinder } from "https://www.unpkg.com/tzf-wasm@2.0.0/tzf_wasm.js";

      async function loadWasm() {
        await init();
        const finder = new WasmFinder();
        const timezone = finder.get_tz_name(-74.006, 40.7128);
        console.log("ニューヨークのタイムゾーン:", timezone);
      }

      loadWasm();
    </script>
  </head>
  <body></body>
</html>

オンラインプレビュー:http://ringsaturn.github.io/tzf-web/

CLI

Go と Rust の両方の実装にコマンドラインツールが付属しています。

Go CLI

go install github.com/ringsaturn/tzf/cmd/tzf@latest
tzf -lng 116.3883 -lat 39.9289

# stdin 経由のバッチ処理
echo -e "116.3883 39.9289\n116.3883, 39.9289" | tzf -stdin-order lng-lat

Rust CLI

cargo install tzf-rs
tzf --lng 116.3883 --lat 39.9289

# stdin 経由のバッチ処理
echo -e "116.3883 39.9289\n116.3883, 39.9289" | tzf --stdin-order lng-lat

NixOS ユーザーは Nix 経由で tzf-rs をインストールできます。詳細は NixOS packages を参照してください。

最終更新日