日期时间 -> set_time_zone(...) 使用世界时区字符串,用于缺少城镇



我为用户构建了一个时区列表,用户可以选择在他们居住的地方设置数据库应用程序。我的问题不是所有的都列出了,即";美国/芝加哥";在列表中但不在";America/Houston";,不存在";美国/得克萨斯州/休斯顿";和芝加哥是同一地区。然而;America/Texxas/El_Paso";也不在列表中,不同的区域,所以用户可以选择。

我的问题是,这是否可以从CPAN提供的库之外将缺少的城市和地区作为字符串添加到DateTime?有人能做到这一点吗?是怎么做到的?

场景是您在本地时区创建记录,但也将一些记录发送到另一个国家。然后观察/处理转换到本地时区的数据。即收到的记录是前一天凌晨2点,在另一个国家是下午5点。您希望国家/地区的日期戳在您的日期时间中,转换为存储或转换为对象。由于各种原因。

创建一个映射(例如使用哈希(,然后在映射中查找正确的名称。

my %tz_aliases = (
'America/Texas'         => 'America/Chicago',
'America/Texas/Houston' => 'America/Chicago',
...
);
my $tz_name = ...;
my $now = DateTime->now( time_zone => $tz_aliases{$tz_name} // $tz_name );

如上所述,您不必局限于使用哈希。如果你想在数据库或其他什么地方查找它,这也很有效。

my $now = DateTime->now( time_zone => lookup_tz($tz_name) // $tz_name );

您可以篡改DateTime::TimeZone的内部结构,以在全局范围内实现相同的功能。

use DateTime::TimeZone::Catalog qw( );
%DateTime::TimeZone::Catalog::LINKS = (
'America/Texas'         => 'America/Chicago',
'America/Texas/Houston' => 'America/Chicago',
...
%DateTime::TimeZone::Catalog::LINKS
);

这是不受支持的,并且可能随时中断。

America/Chicago是IANA时区数据库标识符。它在许多不同的操作系统、平台、语言和框架中都得到了认可。您不应该像America/Texas/Houston那样尝试添加自己的标识符,因为它们只在您的应用程序中有意义。如果你把它寄到其他地方,那就没有意义了。你可以列出自己的城市列表,并将其映射到特定的时区,但不要试图创建新的时区。

在时区数据库中,城市被用于时区标识符的名称,但并不是世界上每个城市都有标识符。这是经过设计的。您可以在tz代码和数据的理论和语用学中阅读更多关于时区标识符选择的原因和方式的信息,该信息包含在时区数据库中。

最新更新