1use strict; 2use warnings; 3 4use Test::More; 5use Test::Fatal; 6 7use DateTime; 8 9{ 10 11 # Tests creating objects from epoch time 12 my $t1 = DateTime->from_epoch( epoch => 0 ); 13 is( $t1->epoch, 0, 'epoch should be 0' ); 14 15 is( $t1->second, 0, 'seconds are correct on epoch 0' ); 16 is( $t1->minute, 0, 'minutes are correct on epoch 0' ); 17 is( $t1->hour, 0, 'hours are correct on epoch 0' ); 18 is( $t1->day, 1, 'days are correct on epoch 0' ); 19 is( $t1->month, 1, 'months are correct on epoch 0' ); 20 is( $t1->year, 1970, 'year is correct on epoch 0' ); 21} 22 23{ 24 my $dt = DateTime->from_epoch( epoch => '3600' ); 25 is( 26 $dt->epoch, 3600, 27 'creation test from epoch = 3600 (compare to epoch)' 28 ); 29} 30 31{ 32 33 # these tests could break if the time changed during the next three lines 34 my $now = time; 35 my $nowtest = DateTime->now(); 36 my $nowtest2 = DateTime->from_epoch( epoch => $now ); 37 is( $nowtest->hour, $nowtest2->hour, 'Hour: Create without args' ); 38 is( $nowtest->month, $nowtest2->month, 'Month : Create without args' ); 39 is( $nowtest->minute, $nowtest2->minute, 'Minute: Create without args' ); 40} 41 42{ 43 my $epochtest = DateTime->from_epoch( epoch => '997121000' ); 44 45 is( 46 $epochtest->epoch, 997121000, 47 'epoch method returns correct value' 48 ); 49 is( $epochtest->hour, 18, 'hour' ); 50 is( $epochtest->min, 3, 'minute' ); 51} 52 53{ 54 my $dt = DateTime->from_epoch( epoch => 3600 ); 55 $dt->set_time_zone('+0100'); 56 57 is( $dt->epoch, 3600, 'epoch is 3600' ); 58 is( $dt->hour, 2, 'hour is 2' ); 59} 60 61{ 62 63 my $dt = DateTime->new( 64 year => 1970, 65 month => 1, 66 day => 1, 67 hour => 0, 68 time_zone => '-0100', 69 ); 70 71 is( $dt->epoch, 3600, 'epoch is 3600' ); 72} 73 74{ 75 76 my $dt = DateTime->from_epoch( 77 epoch => 0, 78 time_zone => '-0100', 79 ); 80 81 is( $dt->offset, -3600, 'offset should be -3600' ); 82 is( $dt->epoch, 0, 'epoch is 0' ); 83} 84 85# Adding/subtracting should affect epoch 86{ 87 my $expected = 1049160602; 88 my $epochtest = DateTime->from_epoch( epoch => $expected ); 89 90 is( 91 $epochtest->epoch, $expected, 92 "epoch method returns correct value ($expected)" 93 ); 94 is( $epochtest->hour, 1, 'hour' ); 95 is( $epochtest->min, 30, 'minute' ); 96 97 $epochtest->add( hours => 2 ); 98 $expected += 2 * 60 * 60; 99 100 is( $epochtest->hour, 3, 'adjusted hour' ); 101 is( 102 $epochtest->epoch, $expected, 103 "epoch method returns correct adjusted value ($expected)" 104 ); 105 106} 107 108{ 109 my $dt = DateTime->from_epoch( epoch => 0.5 ); 110 is( 111 $dt->nanosecond, 500_000_000, 112 'nanosecond should be 500,000,000 with 0.5 as epoch' 113 ); 114 115 is( $dt->epoch, 0, 'epoch should be 0' ); 116 is( $dt->hires_epoch, 0.5, 'hires_epoch should be 0.5' ); 117} 118 119{ 120 my $dt = DateTime->from_epoch( epoch => -0.5 ); 121 is( 122 $dt->nanosecond, 500_000_000, 123 'nanosecond should be 500,000,000 with -0.5 as epoch' 124 ); 125 126 is( $dt->epoch, -1, 'epoch should be -1' ); 127 is( $dt->hires_epoch, -0.5, 'hires_epoch should be -0.5' ); 128} 129 130{ 131 my $dt = DateTime->from_epoch( epoch => 1609459199.999999 ); 132 is( 133 $dt->nanosecond, 999999000, 134 'nanosecond should be 999,999,000 with 1609459199.999999 as epoch' 135 ); 136 137 is( $dt->epoch, 1609459199, 'epoch should be 1609459199' ); 138} 139 140{ 141 my $dt = DateTime->from_epoch( epoch => 0.1234567891 ); 142 is( 143 $dt->nanosecond, 123_457_000, 144 'nanosecond should be rounded to 123,457,000 when given 0.1234567891' 145 ); 146} 147 148{ 149 my $dt = DateTime->from_epoch( epoch => -0.1234567891 ); 150 is( 151 $dt->nanosecond, 876_543_000, 152 'nanosecond should be rounded to 876,543,000 when given -0.1234567891' 153 ); 154} 155 156{ 157 is( 158 DateTime->new( year => 1904 )->epoch, -2082844800, 159 'epoch should work back to at least 1904' 160 ); 161 162 my $dt = DateTime->from_epoch( epoch => -2082844800 ); 163 is( $dt->year, 1904, 'year should be 1904' ); 164 is( $dt->month, 1, 'month should be 1904' ); 165 is( $dt->day, 1, 'day should be 1904' ); 166} 167 168{ 169 for my $pair ( 170 [ 1 => -62135596800 ], 171 [ 99 => -59042995200 ], 172 [ 100 => -59011459200 ], 173 [ 999 => -30641760000 ], 174 ) { 175 176 my ( $year, $epoch ) = @{$pair}; 177 178 is( 179 DateTime->new( year => $year )->epoch, $epoch, 180 "epoch for $year is $epoch" 181 ); 182 } 183} 184 185{ 186 187 package Number::Overloaded; 188 use overload 189 '0+' => sub { $_[0]->{num} }, 190 fallback => 1; 191 192 sub new { bless { num => $_[1] }, $_[0] } 193} 194 195{ 196 my $time = Number::Overloaded->new(12345); 197 198 my $dt = DateTime->from_epoch( epoch => $time ); 199 is( $dt->epoch, 12345, 'can pass overloaded object to from_epoch' ); 200 201 $time = Number::Overloaded->new(12345.1234); 202 $dt = DateTime->from_epoch( epoch => $time ); 203 is( $dt->epoch, 12345, 'decimal epoch in overloaded object' ); 204} 205 206{ 207 my $time = Number::Overloaded->new(-12345); 208 my $dt = DateTime->from_epoch( epoch => $time ); 209 210 is( $dt->epoch, -12345, 'negative epoch in overloaded object' ); 211} 212 213{ 214 my @tests = ( 215 'asldkjlkjd', 216 '1234 foo', 217 'adlkj 1234', 218 ); 219 220 for my $test (@tests) { 221 like( 222 exception { DateTime->from_epoch( epoch => $test ) }, 223 qr/Validation failed for type named Num/, 224 qq{'$test' is not a valid epoch value} 225 ); 226 } 227} 228 229done_testing(); 230