DrHyde / perl-modules-Number-Phone

Number::Phone and friends
24 stars 32 forks source link

Support timezone mappings #132

Closed percivalalb closed 8 months ago

percivalalb commented 1 year ago

AFAICT Number::Phone does not support mapping a phone number to it's assoicated geographic timezone/s.

The libphonenumber project by Google which this project uses provides the data needed for this resources/timezones/map_data.txt.

Other ports in other programming languages do support this, for example:

I envision a method like the following:

Number::Phone->new("+1202-555-0000")->timezones;' # ('America/New_York')

Given that the libphonenumber generated stubs will have access to this data and to maintain backwards compatibility, if a stub doesn't implement the timezones method it should fall back to the libphonenumber data.

I plan to write more of my thoughts on this issue and develop the solution with your permission.

DrHyde commented 1 year ago

I'd certainly consider a patch that adds this.

There's a tricky little problem regarding those places which Google list as Foo/Bar&Baz/Barf - ie a number range covers two time zones. I think in the general case those should:

I think the best thing to do would be to examine all the timezones in the &-separated list and see if they are currently identical, and if they are return the most important of them. eg for Europe/Guernsey&Europe/Isle_of_Man&Europe/Jersey&Europe/London it should return ('Europe/London') because those are all currently identical. They only have different names because historically they handled summer time madness differently. How you tell which is most important I'm not sure. Perhaps the one which has a mapping on its own for the shortest prefix excluding the country code, with undef if there is no such unique best guess? We'd need very comprehensive tests for this! To tell if two timezones are currently identical, errm, excellent question. It's in the Olson tz database somewhere I'm sure but I have no idea where! DateTime::TimeZone->links is a partial but incomplete solution. But if that seems too much like hard work, doing as Google does would be fine too, I can always refine it later while remaining API-compatible.

Oh, and it's a very common error in perl code to use a function in scalar context when it returns a list. I think the method should always return a list-ref instead of a list, so that there's no possibility of accidentally dropping data on the floor.

percivalalb commented 1 year ago

they handled summer time madness differently

My favourite!

I think the method should always return a list-ref instead of a list, so that there's no possibility of accidentally dropping data on the floor.

I'm familiar with these perl whoes, perhaps in scalar context return a list-ref and in list context a list? Regardless if always a list-ref matches the rest of the module that sounds good.

my ($first) = Number::Phone->new("+1202-555-0000")->timezones;' # 'America/New_York'
my @list Number::Phone->new("+1202-555-0000")->timezones;' # ('America/New_York')
my $ref = Number::Phone->new("+1202-555-0000")->timezones;' # ['America/New_York']

Regardless if always a list-ref matches the rest of the module that sounds good.

DateTime::TimeZone->links is a partial but incomplete solution.

By incomplete do you mean that it will solve the easy case where the timezone name is identical but does't solve the case where the timezone name is different but still represents the same underlying timezone.

Following DateTime::TimeZone->links -> DateTime::TimeZone::Catalog%LINKS

Guernsey & Isle_of_Man are mapped to London as their new names, so this methodigy would solve the UKs timezones: UK tz mapping


I'm yet to check the coverage of this theory, so may fall flat on it's face:

I could see how far this gets us anyway.

Examples

Take the lines:

Arctic/Longyearbyen translates to Europe/Berlin (deprecated to new name) Europe/Guernsey & Europe/Isle_of_Man translates to Europe/London (deprecated to new name)

I'm unsure if Europe/Berlin & Europe/Oslo represente the same underlying timezone - from a quick look I believe they do.

47 country code is Norway with captial Oslo, so we choose Europe/Oslo 351 country code is Portugal with captial Lisbon, so we choose Europe/Lisbon and are left with

DrHyde commented 1 year ago

I'm away for a few days so will look at this in detail next week, but yes, returning either a list in list context or a list-ref in scalar context would be sensible.

percivalalb commented 1 year ago

Not a problem, I'm also going to be away for the next week. I've made a quick stab at returning all the country codes for libphonenumber stubs, I'll get that pushed and link it here.

DrHyde commented 8 months ago

PR merged, will be in the next release