1#============================================================= -*-perl-*-
2#
3# t/core/timestamp.t
4#
5# Test the Badger::Timestamp module.
6#
7# Copyright (C) 2006-2009 Andy Wardley.  All Rights Reserved.
8#
9# This is free software; you can redistribute it and/or modify it
10# under the same terms as Perl itself.
11#
12#========================================================================
13
14use strict;
15use warnings;
16use lib qw( ./lib ../lib ../../lib );
17use Badger::Test
18    tests  => 168,
19    debug  => 'Badger::Timestamp',
20    args   => \@ARGV;
21
22use Badger::Timestamp 'Timestamp TS Now';
23use Badger::Utils 'refaddr';
24
25
26#-----------------------------------------------------------------------
27# check we barf on invalid dates
28#-----------------------------------------------------------------------
29
30eval { Timestamp->new('foobar') };
31is( $@, 'timestamp error - Invalid timestamp: foobar', 'bad timestamp format');
32my $n = 1;
33
34
35#-----------------------------------------------------------------------
36# check timestamp created now
37#-----------------------------------------------------------------------
38
39my $now = Timestamp->new();
40my ($second, $minute, $hour, $day, $month, $year ) = localtime(time());
41$year += 1900;
42$month++;
43is($now->day(), $day, 'day now' );
44is($now->month(), $month, 'month now' );
45is($now->year(), $year, 'year now' );
46is($now->hour(), $hour, 'hour now' );
47is($now->minute(), $minute, 'minute now' );
48
49$now = Timestamp->now;
50ok( $now, 'got now() timestamp' );
51
52$now = Now;
53ok( $now, 'got Now() timestamp' );
54
55
56#-----------------------------------------------------------------------
57# check timestamp parsing
58#-----------------------------------------------------------------------
59
60foreach my $timestamp (
61    '2006/08/04 21:22:23',
62    '2006-08-04 21:22:23',
63    '2006-08-04T21:22:23',
64    ) {
65    my $stamp = Timestamp->new($timestamp);
66    ok( $stamp, "created timestamp $n" );
67    is( "$stamp", '2006-08-04 21:22:23', "timestamp $n string" );
68    is( $stamp->timestamp(), '2006-08-04 21:22:23', "timestamp() $n" );
69    is( $stamp->date(), '2006-08-04', "date() $n" );
70    is( $stamp->year(), '2006', "year() $n" );
71    is( $stamp->month(), '8', "month() $n" );
72    is( $stamp->day(), '4', "day() $n" );
73    is( $stamp->time(), '21:22:23', "time() $n" );
74    is( $stamp->hours(), '21', "hours() $n" );
75    is( $stamp->minutes(), '22', "hours() $n" );
76    is( $stamp->seconds(), '23', "minutes() $n" );
77    $n++;
78}
79
80#-----------------------------------------------------------------------
81# check short numbers work
82#-----------------------------------------------------------------------
83my $short = Timestamp->new('2010/2/5 4:20:42');
84ok( $short, 'created timestamp with short numbers');
85is( $short->time, '04:20:42', 'got time' );
86is( $short->date, '2010-02-05', 'got date' );
87
88
89#-----------------------------------------------------------------------
90# check named parameters work
91#-----------------------------------------------------------------------
92
93my $time = Timestamp->new( hour => 1, minute => 2, second => 3 );
94is( $time->hour, 1, 'set 1 hour' );
95is( $time->minute, 2, 'set 2 minute' );
96is( $time->second, 3, 'set 3 second' );
97
98$time = Timestamp->new( hours => 4, minutes => 5, seconds => 6 );
99is( $time->hours, 4, 'set 4 hours' );
100is( $time->minutes, 5, 'set 5 minutes' );
101is( $time->seconds, 6, 'set 6 seconds' );
102
103my $date = Timestamp->new( day => 7, month => 8, year => 2009 );
104is( $date->date, '2009-08-07', 'set day' );
105
106
107#-----------------------------------------------------------------------
108# check we can change items
109#-----------------------------------------------------------------------
110
111my $stamp = Timestamp->new('2006-03-19 04:20:42');
112ok( $stamp, 'created new timestamp' );
113ok( $stamp->year(2007), 'changed year' );
114is( $stamp, '2007-03-19 04:20:42', 'new year set' );
115ok( $stamp->month(04), 'changed month' );
116is( $stamp, '2007-04-19 04:20:42', 'new month set' );
117ok( $stamp->day(20), 'changed year' );
118is( $stamp, '2007-04-20 04:20:42', 'new day set' );
119ok( $stamp->hours(05), 'changed hours' );
120is( $stamp, '2007-04-20 05:20:42', 'new hours set' );
121ok( $stamp->minutes(21), 'changed minutes' );
122is( $stamp, '2007-04-20 05:21:42', 'new minutes set' );
123ok( $stamp->seconds(43), 'changed seconds' );
124is( $stamp, '2007-04-20 05:21:43', 'new seconds set' );
125
126#-----------------------------------------------------------------------
127# test the adjust() method
128#-----------------------------------------------------------------------
129
130is( $stamp->adjust( year => 1, month => 2, day => 3,
131                    hours => 4, minutes => 5, seconds => 6 ), $stamp, 'adjusted time' );
132is( $stamp, '2008-06-23 09:26:49', 'time adjusted' );
133
134# roll over a minute, hour, day, and so on
135is( $stamp->adjust( seconds => 12 ), '2008-06-23 09:27:01', 'rolled over minute' );
136is( $stamp->adjust( minutes => 32, seconds => 63 ), '2008-06-23 10:00:04', 'rolled over hour' );
137is( $stamp->adjust( hours => 20 ), '2008-06-24 06:00:04', 'rolled over day' );
138is( $stamp->adjust( day => 8 ), '2008-07-02 06:00:04', 'rolled over 30 day month' );
139is( $stamp->adjust( days => 30 ), '2008-08-01 06:00:04', 'rolled over 31 day month' );
140
141# try with single argument
142is( $stamp->adjust("3 days"), '2008-08-04 06:00:04', 'adjust 3 days' );
143#is( $stamp->adjust("-1 month"), '2008-07-04 06:00:04', 'adjust -1 month' );
144is( $stamp->adjust(month => -1), '2008-07-04 06:00:04', 'adjust -1 month' );
145is( $stamp->adjust("-4 days"), '2008-06-30 06:00:04', 'adjust -4 days' );
146
147
148
149#-----------------------------------------------------------------------
150# test leap_year() and days_in_month()
151#-----------------------------------------------------------------------
152
153$stamp = Timestamp('2008-08-01 06:00:04');
154
155ok( ! $stamp->leap_year(1900), 'not leap year 1900' );
156ok( ! $stamp->leap_year(1999), 'not leap year 1999' );
157ok(   $stamp->leap_year(2000), 'leap year 2000' );
158ok( ! $stamp->leap_year(2001), 'not leap year 2001' );
159ok( ! $stamp->leap_year(2002), 'not leap year 2002' );
160ok( ! $stamp->leap_year(2003), 'not leap year 2003' );
161ok( $stamp->leap_year(2004), 'leap year 2004' );
162ok( ! $stamp->leap_year(2005), 'leap year 2005' );
163
164is( $stamp->days_in_month(), 31, 'august has 31 days' );
165is( $stamp->days_in_month(1), 31, 'january has 31 days' );
166is( $stamp->days_in_month(2, 2003), 28, 'january has 28 days in 2003' );
167is( $stamp->days_in_month(2, 2004), 29, 'january has 29 days in 2004' );
168is( $stamp->days_in_month(3), 31, 'march has 31 days' );
169is( $stamp->days_in_month(4), 30, 'april has 30 days' );
170is( $stamp->days_in_month(5), 31, 'may has 31 days' );
171is( $stamp->days_in_month(6), 30, 'june has 30 days' );
172is( $stamp->days_in_month(7), 31, 'july has 31 days' );
173is( $stamp->days_in_month(8), 31, 'august has 31 days' );
174is( $stamp->days_in_month(9), 30, 'september has 30 days' );
175is( $stamp->days_in_month(10), 31, 'october has 31 days' );
176is( $stamp->days_in_month(11), 30, 'november has 30 days' );
177is( $stamp->days_in_month(12), 31, 'december has 31 days' );
178
179
180#-----------------------------------------------------------------------
181# test compare() method
182#-----------------------------------------------------------------------
183
184$stamp= Timestamp->new();
185$stamp->adjust( second => -1 );
186is( $stamp->compare(time()), -1, 'compare earlier than now' );
187$stamp->adjust( minute => 1 );
188is( $stamp->compare(time()), 1, 'compare later than now' );
189
190$stamp = Timestamp->new();
191my $compare = Timestamp->new($stamp);
192
193is( $stamp->compare($compare), 0, 'compare the same' );
194foreach my $item (qw(second minute hour day month year )) {
195    $stamp->adjust( $item => -1 );
196    is( $stamp->compare($compare), -1, "$stamp $item earlier $compare" );
197    $stamp->adjust( $item => 2 );
198    is( $stamp->compare($compare), 1, "$stamp $item later $compare" );
199}
200
201
202#-----------------------------------------------------------------------
203# test before(), after() and equal()
204#-----------------------------------------------------------------------
205
206my $old = Timestamp->new('2009-07-05 12:47:42');
207my $new = Timestamp->new('2009-07-05 16:20:00');
208ok( $old->equal($old), 'old is equal to old' );
209ok( $new->equal($new), 'new is equal to new' );
210ok( $old->not_equal($new), 'old is not equal to new' );
211ok( $new->not_equal($old), 'new is not equal to old' );
212
213# before/after/compare/equal all accept another timestamp...
214ok( $old->before($new), 'old is before new' );
215ok( $new->after($old), 'new is after old' );
216
217# ...or a time in epoch seconds...
218ok( $old->before($new->epoch_time), 'old is before new epoch time' );
219ok( $new->after($old->epoch_time), 'new is after old epoch time' );
220
221# ...or a timestamp...
222ok( $old->before($new->timestamp), 'old is before new epoch timestamp' );
223ok( $new->after($old->timestamp), 'new is after old epoch timestamp' );
224
225# ...or a set of named params
226ok( $old->before( year => 2010 ), 'old is before new year' );
227ok( $new->after( year => 1969 ), 'new is after old year' );
228
229# test some negatives to make sure we're not using rose tinted methods
230ok( ! $new->equal($old), 'new is not equal to old' );
231ok( ! $old->equal($new), 'old is not equal to new' );
232ok( ! $new->before($old), 'new is not before old' );
233ok( ! $old->after($new), 'old is not after new' );
234ok( ! $new->equal($old), 'new is not equal to old' );
235ok( ! $old->equal($new), 'old is not equal to new' );
236ok( ! $new->before($old->epoch_time), 'new is not before old epoch time' );
237ok( ! $old->after($new->epoch_time), 'old is not after new epoch time' );
238ok( ! $new->equal($old->epoch_time), 'new is not equal to old epoch time' );
239ok( ! $old->equal($new->epoch_time), 'old is not equal to new epoch time' );
240
241
242#-----------------------------------------------------------------------
243# test comparison operators
244#-----------------------------------------------------------------------
245
246ok( $old == $old, 'old == old' );
247ok( $new == $new, 'new == new' );
248ok( $old != $new, 'old != new' );
249ok( $new != $old, 'new != old' );
250ok( $old < $new, 'old < new' );
251ok( $new > $old, 'new > old' );
252ok( $old <= $new, 'old <= new' );
253ok( $new >= $old, 'new >= old' );
254ok( $old <= $old, 'old <= old' );
255ok( $new >= $new, 'new >= new' );
256
257ok( ! ($old != $old), 'old != old is false' );
258ok( ! ($new != $new), 'new != new is false' );
259ok( ! ($old == $new), 'old == new is false' );
260ok( ! ($new == $old), 'new == old is false' );
261ok( ! ($old > $new), 'old > new is false' );
262ok( ! ($new < $old), 'new < old is false' );
263ok( ! ($old >= $new), 'old >= new is false' );
264ok( ! ($new <= $old), 'new <= old is false' );
265
266
267#-----------------------------------------------------------------------
268# test epoch_seconds()
269#-----------------------------------------------------------------------
270
271$now   = time();
272$stamp = Timestamp->new($now);
273my $epoch = $stamp->epoch_time();
274is( $now, $epoch, 'epoch_time()' );
275
276
277#-----------------------------------------------------------------------
278# test month rollover
279#-----------------------------------------------------------------------
280
281$stamp = Timestamp->new();
282#print "NOW: $stamp\n";
283$stamp->adjust( months => 12 );
284#print "ONE YEAR FROM NOW: $stamp (", $stamp->longmonth(), ")\n";
285
286
287#-----------------------------------------------------------------------
288# test format() method
289#-----------------------------------------------------------------------
290
291$stamp = Timestamp->new('2005-06-07 08:09:10');
292is( $stamp->format('%Y/%m/%d'), '2005/06/07', 'format test date' );
293is( $stamp->format('%Hh %Mm %Ss'), '08h 09m 10s', 'format test time' );
294
295
296#-----------------------------------------------------------------------
297# test copy constructor
298#-----------------------------------------------------------------------
299
300my $copy = Timestamp->new($stamp);
301ok( $copy, 'created object from object' );
302is( $copy->compare($stamp), 0, 'copy same as original' );
303
304my $other = $copy->copy;
305ok( $other, 'created new object from object new() method' );
306is( $other->compare($copy), 0, 'new object same as original' );
307
308isnt( refaddr($stamp), refaddr($copy), 'copy is new object' );
309isnt( refaddr($stamp), refaddr($other), 'new is new object' );
310
311
312#-----------------------------------------------------------------------
313# check Timestamp also works as constructor subroutine
314#-----------------------------------------------------------------------
315
316my $substamp = Timestamp('2009/01/10 19:11:12');
317ok( $substamp, 'created timestamp via Timestamp() subroutine' );
318is( $substamp->date, '2009-01-10', "Timestamp() date" );
319is( $substamp->year, 2009, "Timestamp() year" );
320is( $substamp->month, 1, "Timestamp() month" );
321
322
323#-----------------------------------------------------------------------
324# check TS is an alias to module name
325#-----------------------------------------------------------------------
326
327my $tstamp = TS->new('2009/01/10 19:14:12');
328ok( $tstamp, 'created timestamp via Timestamp() subroutine' );
329is( $tstamp->date, '2009-01-10', "TS stamp date" );
330is( $tstamp->year, 2009, "TS stamp year" );
331is( $tstamp->minutes, 14, "TS stamp month" );
332
333__END__
334
335# Local Variables:
336# mode: perl
337# perl-indent-level: 4
338# indent-tabs-mode: nil
339# End:
340#
341# vim: expandtab shiftwidth=4:
342