【发布时间】:2021-07-23 06:09:01
【问题描述】:
当我对目的地时间的唯一了解是经度和纬度时,我正在尝试本地化 UTC 时间。我想出了一些可行的方法,但感觉很笨拙:
# We need to get localized time for display purposes.
state $moduleGeoLocation = require Geo::Location::TimeZone;
my $gltzobj = Geo::Location::TimeZone->new();
my $tzName = $gltzobj->lookup( lon => $params->{'longitude'}, lat => $params->{'latitude'} );
say "TimeZone: " . $tzName;
到目前为止一切顺利。这就是杂乱无章的地方。我正在使用 Time::Piece 的 strptime 解析时间,但我没有时区的 GMT 偏移量,所以在我解析了 Time::Piece 中的 UTC 时间后,我将其发送到 DateTime 以进行时区计算。同时使用 DateTime 和 Time::Piece 似乎相当笨拙:
# Get TimeZoneOffset.
state $moduleDateTime = require DateTime;
state $moduleDateTimeTimeZone = require DateTime::TimeZone;
my $timeZone = DateTime::TimeZone->new( 'name' => $tzName );
my $timePiece = Time::Piece->strptime($hour->{'time'}, '%Y-%m-%dT%H:%M:%SZ');
my $time = DateTime->from_epoch( 'epoch' => $timePiece->epoch, 'time_zone' => $timeZone );
有没有更好的方法来完成我正在做的事情?我的目标是尽可能以最快的方式获得本地化时间的结果。
【问题讨论】:
-
有DateTime::Format::Strptime,所以不需要
Time::Piece。是这样吗? -
另外,由于 Geo::Location::TimeZone 返回
Etc/GMT+X形式的时区,这意味着不会遵守夏令时。 -
@ikegami 有没有你推荐的另一个模块,而不是你说的那样?这对您的时区来说非常糟糕。虽然,我从 G::L::TZ 中获得命名区域,而不是 GMT+X。例如。它给了我(CST/CDT)的“美国/芝加哥”,它应该适用于夏令时......
-
准确查找 lon、lat 的时区并不简单。除了这里使用的库之外,SO answer 中还有一个漂亮的工具列表(不是 Perl,但很多是 Web 服务)。我试过google API,它使用起来非常简单,而且我认为它是准确的。但它需要一个人获得API key ...
-
@simbabque 完美。谢谢。我跟着你的引导,它似乎真的工作得更好。 GeoNames 几乎可以取代我对 OpenStreetMap 的查询,除了找出时区之外,尽管 OSM 在将文本字符串转换为可能的最合乎逻辑的位置方面似乎更准确一些,所以我仍在查询 OSM,然后通过 long/纬度到 GeoNames API。谢谢指点!
标签: perl datetime geolocation timezone