NAME
Geo::Location::TimeZoneFinder - Map geographic coordinates to time zone names
VERSION
version 1.001
SYNOPSIS
use Geo::Location::TimeZoneFinder;
my $finder = Geo::Location::TimeZoneFinder->new(
file_base => 'combined-shapefile');
my @time_zones = $finder->time_zones_at(lat => $lat, lon => $lon);
DESCRIPTION
A Perl module that maps geographic coordinates to time zone names, such as "Asia/Shanghai". The module uses database files that are published by the Timezone Boundary Builder project.
SUBROUTINES/METHODS
new
my $finder = Geo::Location::TimeZoneFinder->new(
file_base => 'combined-shapefile');
The "file_base" parameter is the base path name for your database files. The extensions .dbf and .shp will be added to the base path name.
Returns a new object. Dies on invalid parameters and file read errors.
time_zones_at
my @time_zones =
$finder->time_zones_at(latitude => $lat, longitude => $lon);
my $time_zone = $finder->time_zones_at(lat => $lat, lon => $lon);
Returns the names of the time zones at the coordinates given by the named parameters "latitude" und "longitude". In scalar context, only one name is returned.
The parameters "latitude" und "longitude" can be abbreviated to "lat" and "lon". The latitude and longitude must be in the ranges -90 to 90 and -180 to 180, respectively.
Dies on invalid parameters and file read errors.
The time zone names correspond to the names in the IANA time zone database, which is used by most Unix systems.
There is usually one time zone in a location, but there are disputed areas with multiple time zones as well as locations on boundaries, such as the North Pole at latitude 90° and the International Date Line at longitude 180°.
time_zone_at
my $time_zone = $finder->time_zone_at(lat => $lat, lon => $lon);
An alias for time_zones_at
that always returns a single value.
index
for my $shape (@{$finder->index}) {
my ($x_min, $y_min, $x_max, $y_max) = @{$shape->{bounding_box}};
my $file_offset = $shape->{file_offset};
my $time_zone = $shape->{time_zone};
}
Returns the internal index that is used to look up boundaries in the shape file.
DIAGNOSTICS
- The "file_base" parameter is mandatory
-
The constructor was called without a filename base.
- The "latitude" parameter is mandatory
-
No "latitude" parameter was given.
- The "longitude" parameter is mandatory
-
No "longitude" parameter was given.
- The "latitude" parameter N is not a number between -90 and 90
-
The latitude must be a number between -90 and 90.
- The "longitude" parameter N is not a number between -180 and 180
-
The longitude must be a number between -180 and 180.
- Error opening "FILE"
-
A file cannot be opened.
- Error reading "FILE"
-
A file cannot be read.
- Cannot set file position to N in "FILE"
-
The position in a file cannot be set.
- Expected N records, got M in "FILE"
-
The number of records does not match the information in the file's header or the number of records in another file.
CONFIGURATION AND ENVIRONMENT
None.
DEPENDENCIES
Requires the file timezones.shapefile.zip from https://github.com/evansiroky/timezone-boundary-builder. The zip archive must be extracted to a directory.
INCOMPATIBILITIES
None.
EXAMPLES
Most Unix systems accept time zone names in the environment variable TZ
.
use Geo::Location::TimeZoneFinder;
my $finder = Geo::Location::TimeZoneFinder->new(
file_base => 'combined-shapefile');
my $tz = $finder->time_zone_at(lat => 39.916, lon => 116.383);
my @time = do { local $ENV{TZ} = ":$tz"; localtime };
Speed up repeated lookups by using a cache.
use Geo::Location::TimeZoneFinder;
use Mojo::Cache;
my $cache = Mojo::Cache->new;
my $finder = Geo::Location::TimeZoneFinder->new(
file_base => 'combined-shapefile');
sub time_zone_at {
my %args = @_;
my $lat = $args{lat};
my $lon = $args{lon};
my $key = "$lat,$lon";
my $tz = $cache->get($key);
if (!defined $tz) {
$tz = $finder->time_zone_at(lat => $lat, lon => $lon);
$cache->set($key, $tz);
}
return $tz;
}
BUGS AND LIMITATIONS
This module uses the point-in-polygon algorithm described in [1], which is very accurate but "cannot solve the problem of instability that can result from the comparison operations of floating-point numbers".
[1] Jianqiang Hao, Jianzhi Sun, Yi Chen, Qiang Cai, and Li Tan. "Optimal Reliable Point-in-Polygon Test and Differential Coding Boolean Operations on Polygons". Symmetry, 10, 2018.
AUTHOR
Andreas Vögele <voegelas@cpan.org>
LICENSE AND COPYRIGHT
Copyright (C) 2023 Andreas Vögele
This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself.