File Coverage

blib/lib/XML/SRS/TimeStamp/Role.pm
Criterion Covered Total %
statement 5 7 71.4
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 8 10 80.0


line stmt bran cond sub pod time code
1              
2             package XML::SRS::TimeStamp::Role;
3             BEGIN {
4 1     1   1734 $XML::SRS::TimeStamp::Role::VERSION = '0.09';
5             }
6              
7 1     1   32 use 5.010;
  1         4  
  1         33  
8 1     1   44 use XML::SRS::Date;
  0            
  0            
9             use XML::SRS::Time;
10             use Moose::Role;
11             use MooseX::Params::Validate;
12              
13             use MooseX::Timestamp qw();
14             use MooseX::TimestampTZ
15             timestamptz => { -as => "_timestamptz" },
16             epoch => { -as => "_epoch" },
17             ;
18              
19             has 'timestamp' =>
20             is => "rw",
21             isa => "Timestamp",
22             coerce => 1,
23             lazy => 1,
24             default => sub {
25             my $self = shift;
26             sprintf(
27             "%.4d-%.2d-%.2d %.2d:%.2d:%.2d",
28             $self->year, $self->month, $self->day,
29             $self->hour, $self->minute, $self->second//0,
30             );
31             },
32             ;
33              
34             sub buildargs_timestamp {
35             my $inv = shift;
36             my ( $timestamp ) = pos_validated_list(
37             \@_,
38             { isa => 'Timestamp', coerce => 1 },
39             );
40            
41             my ($date, $time) = split " ", $timestamp;
42             ($inv->buildargs_time($time), $inv->buildargs_date($date));
43             }
44              
45             sub buildargs_timestamptz {
46             my $inv = shift;
47             my ( $timestamptz ) = pos_validated_list(
48             \@_,
49             { isa => 'TimestampTZ', coerce => 1 },
50             );
51            
52             $timestamptz =~ m{
53             (?<ymd>\d+-\d+-\d+)
54             \s(?<hms>\d+:\d+:\d+)
55             (?: (?<utc>Z) | (?<offset> [+-]\d{2} (?::?\d{2})? )
56             )}x or warn "$timestamptz didn't match";
57             my $hms = $+{hms};
58             my $ymd = $+{ymd};
59             my $offset = $+{utc} ? "+00:00" : $+{offset};
60             ( $inv->buildargs_time($hms, $offset),
61             $inv->buildargs_date($ymd)
62             );
63             }
64              
65             sub buildargs_epoch {
66             my $inv = shift;
67             my ( $epoch ) = pos_validated_list(
68             \@_,
69             { isa => 'time_t', coerce => 1 },
70             );
71            
72             $inv->buildargs_timestamptz(_timestamptz $epoch);
73             }
74              
75             has 'timestamptz' =>
76             is => "rw",
77             isa => "TimestampTZ",
78             coerce => 1,
79             lazy => 1,
80             default => sub {
81             my $self = shift;
82             sprintf(
83             "%.4d-%.2d-%.2d %.2d:%.2d:%.2d%s",
84             $self->year, $self->month, $self->day,
85             $self->hour, $self->minute, $self->second//0,
86             $self->tz_offset//"",
87             );
88             },
89             ;
90              
91             has 'epoch' =>
92             is => "rw",
93             isa => "time_t",
94             coerce => 1,
95             lazy => 1,
96             default => sub {
97             my $self = shift;
98             _epoch $self->timestamptz;
99             },
100             ;
101              
102             with 'XML::SRS::Date', 'XML::SRS::Time';
103              
104             1;
105              
106             __END__
107              
108             =head1 NAME
109              
110             XML::SRS::TimeStamp::Role - composable timestamp attributes
111              
112             =head1 SYNOPSIS
113              
114             package XML::SRS::Some::Class;
115             use Moose;
116              
117             with 'XML::SRS::TimeStamp::Role', 'XML::SRS::Node';
118              
119              
120             =head1 DESCRIPTION
121              
122             Sometimes, in the SRS schema, a timestamp is represented with its own
123             node, C<E<lt>TimeStampE<gt>>;
124              
125             <TimeStamp Hour="12" Minute="24" Second="0"
126             Day="31" Month="1" Year="2010"
127             TZOffset="+12:00" />
128              
129             For this purpose, the concrete class L<XML::SRS::TimeStamp> is used.
130              
131             However, when the attributes which represent the also appear alongside
132             other child elements or attributes, a concrete class would not be
133             appropriate to re-use. In that case, the role
134             L<XML::SRS::TimeStamp::Role> must be composed.
135              
136             An example of this is the L<XML::SRS::Domain::Transferred> class, as
137             in:
138              
139             <DomainTransfer
140             Hour="12" Minute="24" Second="0"
141             Day="31" Month="1" Year="2010"
142             TZOffset="+12:00">
143             <TransferredDomain>foo.co.nz</TransferredDomain>
144             </DomainTransfer>
145              
146             To avoid repetition, this class exists.
147              
148             It also adds various properties and psuedo-properties for convenience,
149             such as:
150              
151             =over
152              
153             =item B<timestamptz>
154              
155             (cached, derived, psuedo) this is a psuedo-property, which returns the value
156             of the timestamp within as an ISO-8601 timestamp, without the T, and
157             with a timezone offset (defaulting to the offset of this time
158             according to local rules). The L<XML::SRS::TimeStamp> class has a
159             BUILDARGS class method which allows this to be a "psuedo-property";
160             you can pass it to C<XML::SRS::TimeStamp-E<gt>new>, and it will fill
161             in all the other required accessors.
162              
163             eg
164              
165             XML::SRS::TimeStamp->new(
166             timestamptz => "2010-12-12 12:12:12+12:00",
167             );
168              
169             Will create an object:
170              
171             bless(
172             {
173             'hour' => '12',
174             'month' => '12',
175             'second' => '12',
176             'tz_offset' => '+1200',
177             'minute' => '12',
178             'day' => '12',
179             'timestamptz' => '2010-12-12 12:12:12+1200',
180             'year' => '2010'
181             },
182             'XML::SRS::TimeStamp'
183             );
184              
185             =item B<timestamp>
186              
187             (cached, derived, psuedo) Like B<timestamp>, but you don't end up
188             setting the C<tz_offset> property if passed in for construction, and
189             it does not have a time zone.
190              
191             =item B<epoch>
192              
193             (cached, derived, psuedo) Like B<timestamptz>, but the time is
194             expressed as a unix epoch time without a timezone.
195              
196             in construction it will also use the local time rules:
197              
198             perl -MXML::SRS::TimeStamp -MYAML -E 'say XML::SRS::TimeStamp->new(
199             epoch => time(),
200             )->dump;'
201             $VAR1 = bless( {
202             'hour' => '21',
203             'epoch' => 1283200164,
204             'month' => '08',
205             'second' => '24',
206             'tz_offset' => '+0100',
207             'minute' => '29',
208             'day' => '30',
209             'year' => '2010'
210             }, 'XML::SRS::TimeStamp' );
211              
212             (Above is a summer time time)
213              
214             perl -MXML::SRS::TimeStamp -MYAML -E 'say XML::SRS::TimeStamp->new(
215             epoch => time()+6*30*86400,
216             )->dump;'
217             $VAR1 = bless( {
218             'hour' => '20',
219             'epoch' => 1298752226,
220             'month' => '02',
221             'second' => '26',
222             'tz_offset' => '+0000',
223             'minute' => '30',
224             'day' => '26',
225             'year' => '2011'
226             }, 'XML::SRS::TimeStamp' );
227              
228             (and for comparison, a non-daylight savings time)
229              
230             =back
231              
232             =head1 XML::SRS::Time and XML::SRS::Date
233              
234             These roles contain the component parts of Date and Time, to keep them
235             independent. C<XML::SRS::TimeStamp::Role> composes both of these.
236             They are not used by any other classes.
237              
238             =head1 SEE ALSO
239              
240             L<XML::SRS>
241              
242             =head1 AUTHOR AND LICENCE
243              
244             Development commissioned by NZ Registry Services, and carried out by
245             Catalyst IT - L<http://www.catalyst.net.nz/>
246              
247             Copyright 2009, 2010, NZ Registry Services. This module is licensed
248             under the Artistic License v2.0, which permits relicensing under other
249             Free Software licenses.
250              
251             =cut