File Coverage

blib/lib/DateTime/TimeZone/Local.pm
Criterion Covered Total %
statement 30 49 61.2
branch 2 14 14.2
condition 1 3 33.3
subroutine 9 13 69.2
pod 2 2 100.0
total 44 81 54.3


line stmt bran cond sub pod time code
1             package DateTime::TimeZone::Local;
2              
3 3     3   21 use strict;
  3         6  
  3         92  
4 3     3   35 use warnings;
  3         10  
  3         73  
5 3     3   16 use namespace::autoclean;
  3         6  
  3         20  
6              
7             our $VERSION = '2.60';
8              
9 3     3   251 use DateTime::TimeZone;
  3         6  
  3         99  
10 3     3   18 use File::Spec;
  3         6  
  3         109  
11 3     3   17 use Module::Runtime qw( require_module );
  3         5  
  3         37  
12 3     3   216 use Try::Tiny;
  3         7  
  3         1770  
13              
14             sub TimeZone {
15 1     1 1 3 my $class = shift;
16              
17 1         4 my $subclass = $class->_load_subclass();
18              
19 1         5 for my $meth ( $subclass->Methods() ) {
20 1         9 my $tz = $subclass->$meth();
21              
22 1 50       11 return $tz if $tz;
23             }
24              
25 0         0 die "Cannot determine local time zone\n";
26             }
27              
28             {
29             # Stolen from File::Spec. My theory is that other folks can write
30             # the non-existent modules if they feel a need, and release them
31             # to CPAN separately.
32             my %subclass = (
33             android => 'Android',
34             cygwin => 'Unix',
35             dos => 'OS2',
36             epoc => 'Epoc',
37             MacOS => 'Mac',
38             MSWin32 => 'Win32',
39             NetWare => 'Win32',
40             os2 => 'OS2',
41             symbian => 'Win32',
42             VMS => 'VMS',
43             );
44              
45             sub _load_subclass {
46 1     1   4 my $class = shift;
47              
48 1   33     8 my $os_name = $subclass{$^O} || $^O;
49 1         5 my $subclass = $class . '::' . $os_name;
50              
51 1 50       18 return $subclass if $subclass->can('Methods');
52              
53             return $subclass if try {
54             ## no critic (Variables::RequireInitializationForLocalVars)
55 0     0     local $SIG{__DIE__};
56 0           require_module($subclass);
57 0 0         };
58              
59 0           $subclass = $class . '::Unix';
60              
61 0           require_module($subclass);
62              
63 0           return $subclass;
64             }
65             }
66              
67             sub FromEnv {
68 0     0 1   my $class = shift;
69              
70 0           foreach my $var ( $class->EnvVars() ) {
71 0 0         if ( $class->_IsValidName( $ENV{$var} ) ) {
72             my $tz = try {
73             ## no critic (Variables::RequireInitializationForLocalVars)
74 0     0     local $SIG{__DIE__};
75 0           DateTime::TimeZone->new( name => $ENV{$var} );
76 0           };
77              
78 0 0         return $tz if $tz;
79             }
80             }
81              
82 0           return;
83             }
84              
85             sub _IsValidName {
86 0     0     shift;
87              
88 0 0         return 0 unless defined $_[0];
89 0 0         return 0 if $_[0] eq 'local';
90              
91 0           return $_[0] =~ m{^[\w/\-\+]+$};
92             }
93              
94             1;
95              
96             # ABSTRACT: Determine the local system's time zone
97              
98             __END__
99              
100             =pod
101              
102             =encoding UTF-8
103              
104             =head1 NAME
105              
106             DateTime::TimeZone::Local - Determine the local system's time zone
107              
108             =head1 VERSION
109              
110             version 2.60
111              
112             =head1 SYNOPSIS
113              
114             my $tz = DateTime::TimeZone->new( name => 'local' );
115              
116             my $tz = DateTime::TimeZone::Local->TimeZone();
117              
118             =head1 DESCRIPTION
119              
120             This module provides an interface for determining the local system's time zone.
121             Most of the functionality for doing this is in OS-specific subclasses.
122              
123             =head1 USAGE
124              
125             This class provides the following methods:
126              
127             =head2 DateTime::TimeZone::Local->TimeZone()
128              
129             This attempts to load an appropriate subclass and asks it to find the local
130             time zone. This method is called by when you pass "local" as the time zone name
131             to C<< DateTime:TimeZone->new() >>.
132              
133             If your OS is not explicitly handled, you can create a module with a name of
134             the form C<DateTime::TimeZone::Local::$^O>. If it exists, it will be used
135             instead of falling back to the Unix subclass.
136              
137             If no OS-specific module exists, we fall back to using the Unix subclass.
138              
139             See L<DateTime::TimeZone::Local::Unix>, L<DateTime::TimeZone::Local::Android>,
140             L<DateTime::TimeZone::Local::hpux>, L<DateTime::TimeZone::Local::Win32>, and
141             L<DateTime::TimeZone::Local::VMS> for OS-specific details.
142              
143             =head1 SUBCLASSING
144              
145             If you want to make a new OS-specific subclass, there are several methods
146             provided by this module you should know about.
147              
148             =head2 $class->Methods()
149              
150             This method should be provided by your class. It should provide a list of
151             methods that will be called to try to determine the local time zone.
152              
153             Each of these methods is expected to return a new C<DateTime::TimeZone> object
154             if it can successfully determine the time zone.
155              
156             =head2 $class->FromEnv()
157              
158             This method tries to find a valid time zone in an C<%ENV> value. It calls C<<
159             $class->EnvVars() >> to determine which keys to look at.
160              
161             To use this from a subclass, simply return "FromEnv" as one of the items from
162             C<< $class->Methods() >>.
163              
164             =head2 $class->EnvVars()
165              
166             This method should be provided by your subclass. It should return a list of env
167             vars to be checked by C<< $class->FromEnv() >>.
168              
169             Your class should always include the C<TZ> key as one of the variables to
170             check.
171              
172             =head2 $class->_IsValidName($name)
173              
174             Given a possible time zone name, this returns a boolean indicating whether or
175             not the name looks valid. It always return false for "local" in order to avoid
176             infinite loops.
177              
178             =head1 EXAMPLE SUBCLASS
179              
180             Here is a simple example subclass:
181              
182             package DateTime::TimeZone::SomeOS;
183              
184             use strict;
185             use warnings;
186              
187             use base 'DateTime::TimeZone::Local';
188              
189              
190             sub Methods { qw( FromEnv FromEther ) }
191              
192             sub EnvVars { qw( TZ ZONE ) }
193              
194             sub FromEther
195             {
196             my $class = shift;
197              
198             ...
199             }
200              
201             =head1 SUPPORT
202              
203             Bugs may be submitted at L<https://github.com/houseabsolute/DateTime-TimeZone/issues>.
204              
205             =head1 SOURCE
206              
207             The source code repository for DateTime-TimeZone can be found at L<https://github.com/houseabsolute/DateTime-TimeZone>.
208              
209             =head1 AUTHOR
210              
211             Dave Rolsky <autarch@urth.org>
212              
213             =head1 COPYRIGHT AND LICENSE
214              
215             This software is copyright (c) 2023 by Dave Rolsky.
216              
217             This is free software; you can redistribute it and/or modify it under
218             the same terms as the Perl 5 programming language system itself.
219              
220             The full text of the license can be found in the
221             F<LICENSE> file included with this distribution.
222              
223             =cut