Attached is the above module. Unless there's strenuous objections I'll CPAN it. I just wish for this and for ::Alias that we could hook in better without messing with the internals.
While I'm thinking of it, I'd like to be able to set names and short-names for offsets. I have a list of short names in Strptime, but I've love to be able to get these back from TimeZone somehow. Just like we do with Olsen (or is it Olson, one's the twins, one's the time, can't ever remember which!). Cheers! Rick
package DateTime::TimeZone::LMT; use strict; use Carp qw( croak ); use DateTime::TimeZoneCatalog; use vars qw( $VERSION $LONGITUDE $OFFSET ); $VERSION = 0.01; sub import { my $class = shift; return unless @_; $class->set( @_ ); } sub set { my $class = shift; my $longitude = shift; if ($longitude) { croak "You must supply a valid longitude. (-180 .. 180)" if ($longitude < -180 or $longitude > 180); # Offset in seconds: my $offset_seconds = ( $longitude / 180 ) * (12 * 60 * 60); my $sign = '+'; if ($offset_seconds < 0) { $offset_seconds *= -1; $sign = '-'; } my $hours = int($offset_seconds / (60 * 60) ); $offset_seconds -= $hours * (60 * 60); my $minutes = int($offset_seconds / 60); $offset_seconds -= $minutes * 60; my $seconds = sprintf("%.0f",$offset_seconds); $OFFSET = "$sign$hours:$minutes:$seconds"; $DateTime::TimeZone::LINKS{ LMT } = $OFFSET; $LONGITUDE = $longitude; } return $LONGITUDE; } sub offset {return $OFFSET}; 1; __END__ =pod =head1 NAME DateTime::TimeZone::Alias - Create aliases for DateTime timezones =head1 SYNOPSIS use DateTime::TimeZone::LMT qw/145.08009/; # or use DateTime::TimeZone::LMT; DateTime::TimeZone::LMT->set(145.08009); DateTime::TimeZone::LMT->longitude; # 145.08009 DateTime::TimeZone::LMT->offset; # +09:40:19 =head1 DESCRIPTION Creates LMT DateTime timezones. This module violates the encapsulation of the DateTime internals. User _Beware_. =head1 BACKGROUND Local Apparent Time If we are to tell the time by the sun's hour angle, no two points will share the same time unless they lie on the same meridian. The time is thus I<localised> to a particular meridian, and since it is also based on the apparent (think 'appear') motion of the sun we call it Local Apparent Time. This is the kind of time shown on most sundials, and until about a century ago was the kind of time used almost universally in daily life. Yet it suffers from disadvantages which have led most people to discard it in favor of some other kind of time. For one thing it is inconvenient to use a system of timekeeping which is so narrowly localised. Remember that no two points will share the same LAT unless they lie on the same meridian. Two cities 100 miles apart will differ by about 7.5 minutes. There is even a difference of about 0.25 seconds at opposite ends of a football field! Precisely set clocks would even show slightly different times in different rooms of the same house! Local Mean Time The second disadvantage of LAT arises from the fact that when we measure days by the sun they turn out to differ amongst themselves in length. About Christmas time the days are about 30 seconds longer than average and in mid-September are about 20 seconds shorter. These variations increase until in mid-February when the sun reaches its meridian almost 14.5 minutes later than it would if all days were of equal length. Then in early November the meridian falls back about 16.5 minutes. These variations amount to just over half-an-hour which would be decidedly inconvenient for scientific purposes, and today we would consider it unacceptable for even everyday affairs. Instead, then, of reckoning time from the irregularly moving real sun, we usually reckon it from an imaginary i<mean> sun -- a fictitious heavenly body which moves at a constant speed, equal to the average speed at which the real sun moves. Time measured accoring to this mean sun is known as I<Local Mean Time>. This is the time that this module works with. =head1 IMPORT PARAMETERS Accepts a scalar containing a valid longitude. =head1 METHODS =over 4 =item * set( $longitude ) Sets the longitude. =item * longitude( $longitude ) Sets the longitude if one is provided. Returns the current longitude. =item * offset() Returns the current longitude's UTC offset. =back =head1 NOTES =head2 Import Multiple C<use DateTime::TimeZone::LMT> statements in the same package will cause unexpected behaviour. If you need more than one LMT, consider using C<DateTime::TimeZone::Alias> as detailed in the Cookbook below. =head1 COOKBOOK =head2 What is my LMT? To determine the time right where you are, get your longitude. Look it up in an atlas or look it up online. There are online services that let you enter your address and they return a very accurate value. Then: use DateTime; use DateTime::TimeZone::LMT $your_longitude; print DateTime->now( time_zone => LMT )->datetime; =head2 Multiple LMTs If you want to add multiple LMTs to your work, use C<DateTime::TimeZone::Alias> use DateTime::TimeZone::LMT 145.08009; use DateTime::TimeZone::Alias( 'LMT/Melbourne' => DateTime::TimeZone::LMT->offset ); DateTime::TimeZone::LMT->set(0); DateTime::TimeZone::Alias->set( 'LMT/Greenwich' => DateTime::TimeZone::LMT->offset ); DateTime::TimeZone::LMT->set(180); DateTime::TimeZone::Alias->set( 'LMT/IDL' => DateTime::TimeZone::LMT->offset ); So now we have three Aliases to our offsets and can use them to create DateTimes: $now_melbourne = DateTime->now( time_zone => 'LMT/Melbourne' ); $now_greenwich = DateTime->now( time_zone => 'LMT/Greenwich' ); $now_idl = DateTime->now( time_zone => 'LMT/IDL' ); =head1 TODO I'm looking at extending this to also do LAT also (Local Apparent Time). This requires lookup tables and is date-dependent so it will probably be a little different in it's behaviour. =head1 CREDITS Joshua Hoblitt upon whose module (C<DateTime::TimeZone::Alias>) this module is built. =head1 SUPPORT Support for this module is provided via the [EMAIL PROTECTED] email list. See http://lists.perl.org/ for more details. =head1 AUTHOR Rick Measham <[EMAIL PROTECTED]> =head1 COPYRIGHT Copyright (c) 2003 Rick Measham. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. The full text of the license can be found in the LICENSE file included with this module. =head1 SEE ALSO [EMAIL PROTECTED] mailing list http://datetime.perl.org/ =cut