Reputation: 21
I build for the user an list of timezones they can choose to setup their database application from where they live in the world. My problem is not all is listed, i.e. "America/Chicago" is in the list but not "America/Houston", there is no "America/Texas/Houston" which is same zone as Chicago. However "America/Texas/El_Paso" also not in list, different zone, so user can choose.
My question is this possible to add to the DateTime missing cities and areas as strings, from outside the CPAN provided library? Has anyone managed to do this and how?
Scenario is you create records in your local timezone, but also send as such some to another country. Which then observes/deals with them converted to their local timezone. i.e. Record received 2am, in another country is 5pm, previous day. You want that countries date stamp in your datetime, converted to be stored or turned into an object. For various reasons.
Upvotes: 2
Views: 348
Reputation: 241420
America/Chicago
is an IANA Time Zone Database Identifier. It is recognized across many different operating systems, platforms, languages, and frameworks. You should not try to add your own identifiers like America/Texas/Houston
, as they would only have meaning in your application. If you ever sent it anywhere else, it would be meaningless. You could make your own list of cities and map them to specific time zones, but don't try to make new time zones.
Within the time zone database, cities are used in the names of time zone identifiers - but not every city in the world is given an identifier. This is by design. You can read more about why, and how time zone identifiers are chosen, in Theory and pragmatics of the tz code and data, which is included in the time zone database itself.
Upvotes: 2
Reputation: 385506
Create a mapping (e.g. using a hash), and just look the correct name in the mapping.
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 );
As suggested above, you aren't constrained to using a hash. If you wanted to look it up in a database or whatever, that works too.
my $now = DateTime->now( time_zone => lookup_tz($tz_name) // $tz_name );
You could mess with DateTime::TimeZone's internals to achieve the same thing globally.
use DateTime::TimeZone::Catalog qw( );
%DateTime::TimeZone::Catalog::LINKS = (
'America/Texas' => 'America/Chicago',
'America/Texas/Houston' => 'America/Chicago',
...
%DateTime::TimeZone::Catalog::LINKS
);
This is not supported, and could break at any time.
Upvotes: 2