1#!/usr/bin/perl -w 2 3use strict; 4 5use Test::More tests => 537; 6 7use DateTime; 8 9 10my $t = DateTime->new( year => 1996, month => 11, day => 22, 11 hour => 18, minute => 30, second => 20, 12 time_zone => 'UTC', 13 ); 14$t->add( weeks => 8); 15 16is( $t->year, 1997, "year rollover"); 17is( $t->month, 1, "month set on year rollover"); 18is( $t->datetime, '1997-01-17T18:30:20', 'okay on year rollover' ); 19 20$t->add( weeks => 2 ); 21is( $t->datetime, '1997-01-31T18:30:20', 'Adding weeks' ); 22 23$t->add( seconds => 15 ); 24is( $t->datetime, '1997-01-31T18:30:35', 'Adding seconds' ); 25 26$t->add( minutes => 12 ); 27is( $t->datetime, '1997-01-31T18:42:35', 'Adding minutes' ); 28 29$t->add( minutes => 25, hours => 3, seconds => 7 ); 30is( $t->datetime, '1997-01-31T22:07:42', 'Adding h,m,s' ); 31 32# Now, test the adding of durations 33$t = DateTime->new( year => 1986, month => 1, day => 28, 34 hour => 16, minute => 38, 35 time_zone => 'UTC' ); 36 37$t->add( minutes => 1, seconds => 12 ); 38is( $t->datetime, '1986-01-28T16:39:12', "Adding durations with minutes and seconds works"); 39 40$t = DateTime->new( year => 1986, month => 1, day => 28, 41 hour => 16, minute => 38, 42 time_zone => 'UTC' ); 43 44$t->add( seconds => 30 ); 45is( $t->datetime, '1986-01-28T16:38:30', "Adding durations with seconds only works"); 46 47$t = DateTime->new( year => 1986, month => 1, day => 28, 48 hour => 16, minute => 38, 49 time_zone => 'UTC' ); 50 51$t->add( hours => 1, minutes => 10 ); 52is( $t->datetime, '1986-01-28T17:48:00', "Adding durations with hours and minutes works"); 53 54$t = DateTime->new( year => 1986, month => 1, day => 28, 55 hour => 16, minute => 38, 56 time_zone => 'UTC' ); 57 58$t->add( days => 3 ); 59is( $t->datetime, '1986-01-31T16:38:00', "Adding durations with days only works"); 60 61 62$t = DateTime->new( year => 1986, month => 1, day => 28, 63 hour => 16, minute => 38, 64 time_zone => 'UTC' ); 65 66$t->add( days => 3, hours => 2 ); 67is( $t->datetime, '1986-01-31T18:38:00', "Adding durations with days and hours works"); 68 69 70$t = DateTime->new( year => 1986, month => 1, day => 28, 71 hour => 16, minute => 38, 72 time_zone => 'UTC' ); 73 74$t->add( days => 3, hours => 2, minutes => 20, seconds => 15 ); 75is( $t->datetime, '1986-01-31T18:58:15', "Adding durations with days, hours, minutes, and seconds works"); 76 77# Add 15M - this test failed at one point in N::I::Time 78$t = DateTime->new( year => 2001, month => 4, day => 5, 79 hour => 16, 80 time_zone => 'UTC' ); 81 82$t->add( minutes => 15 ); 83is( $t->datetime, '2001-04-05T16:15:00', "Adding minutes to an ical string"); 84 85# Subtract a duration 86$t->add( minutes => -15 ); 87is( $t->datetime, '2001-04-05T16:00:00', "Back where we started"); 88 89undef $t; 90 91$t = DateTime->new( year => 1986, month => 1, day => 28, 92 hour => 16, minute => 38, 93 time_zone => 'UTC' ); 94 95$t->add( seconds => 60 ); 96is( $t->datetime, "1986-01-28T16:39:00", "adding positive seconds with seconds works" ); 97$t->add( seconds => -120 ); 98is( $t->datetime, "1986-01-28T16:37:00", "adding negative seconds with seconds works" ); 99 100# test sub months 101$t = DateTime->new( year => 2001, month => 1, day => 31, 102 time_zone => 'UTC', 103 ); 104$t->add(days => 1); 105is( $t->date, '2001-02-01', 'february 1st' ); 106 107$t = DateTime->new( year => 2001, month => 2, day => 28, 108 time_zone => 'UTC', 109 ); 110$t->add(days => 1); 111is( $t->date, '2001-03-01', 'march 1st' ); 112 113$t = DateTime->new( year => 2001, month => 3, day => 31, 114 time_zone => 'UTC', 115 ); 116$t->add(days => 1); 117is( $t->date, '2001-04-01', 'april 1st' ); 118 119$t = DateTime->new( year => 2001, month => 4, day => 30, 120 time_zone => 'UTC', 121 ); 122$t->add(days => 1); 123is( $t->date, '2001-05-01', 'may 1st' ); 124 125$t = DateTime->new( year => 2001, month => 5, day => 31, 126 time_zone => 'UTC', 127 ); 128$t->add(days => 1); 129is( $t->date, '2001-06-01', 'june 1st' ); 130 131$t = DateTime->new( year => 2001, month => 6, day => 30, 132 time_zone => 'UTC', 133 ); 134$t->add(days => 1); 135is( $t->date, '2001-07-01', 'july 1st' ); 136 137$t = DateTime->new( year => 2001, month => 7, day => 31, 138 time_zone => 'UTC', 139 ); 140$t->add(days => 1); 141is( $t->date, '2001-08-01', 'august 1st' ); 142 143$t = DateTime->new( year => 2001, month => 8, day => 31, 144 time_zone => 'UTC', 145 ); 146$t->add(days => 1); 147is( $t->date, '2001-09-01', 'september 1st' ); 148 149$t = DateTime->new( year => 2001, month => 9, day => 30, 150 time_zone => 'UTC', 151 ); 152$t->add(days => 1); 153is( $t->date, '2001-10-01', 'october 1st' ); 154 155$t = DateTime->new( year => 2001, month => 10, day => 31, 156 time_zone => 'UTC', 157 ); 158$t->add(days => 1); 159is( $t->date, '2001-11-01', 'november 1st' ); 160 161$t = DateTime->new( year => 2001, month => 11, day => 30, 162 time_zone => 'UTC', 163 ); 164$t->add(days => 1); 165is( $t->date, '2001-12-01', 'december 1st' ); 166 167$t = DateTime->new( year => 2001, month => 12, day => 31, 168 time_zone => 'UTC', 169 ); 170$t->add(days => 1); 171is( $t->date, '2002-01-01', 'january 1st' ); 172 173# Adding years 174 175# Before leap day, not a leap year ... 176$t = DateTime->new( year => 2001, month => 2, day => 28, 177 time_zone => 'UTC', 178 ); 179$t->add( years => 1 ); 180is( $t->date, '2002-02-28', 'Adding a year' ); 181$t->add( years => 17 ); 182is( $t->date, '2019-02-28', 'Adding 17 years' ); 183 184# After leap day, not a leap year ... 185$t = DateTime->new( year => 2001, month => 3, day => 28, 186 time_zone => 'UTC', 187 ); 188$t->add( years => 1 ); 189is( $t->date, '2002-03-28', 'Adding a year' ); 190$t->add( years => 17 ); 191is( $t->date, '2019-03-28', 'Adding 17 years' ); 192 193# On leap day, in a leap year ... 194$t = DateTime->new( year => 2000, month => 2, day => 29, 195 time_zone => 'UTC', 196 ); 197$t->add( years => 1 ); 198is( $t->date, '2001-03-01', 'Adding a year' ); 199$t->add( years => 17 ); 200is( $t->date, '2018-03-01', 'Adding 17 years' ); 201 202# Before leap day, in a leap year ... 203$t = DateTime->new( year => 2000, month => 2, day => 28, 204 time_zone => 'UTC', 205 ); 206$t->add( years => 1 ); 207is( $t->date, '2001-02-28', 'Adding a year' ); 208$t->add( years => 17 ); 209is( $t->date, '2018-02-28', 'Adding 17 years' ); 210 211# After leap day, in a leap year ... 212$t = DateTime->new( year => 2000, month => 3, day => 28, 213 time_zone => 'UTC', 214 ); 215$t->add( years => 1 ); 216is( $t->date, '2001-03-28', 'Adding a year' ); 217$t->add( years => 17 ); 218is( $t->date, '2018-03-28', 'Adding 17 years' ); 219 220# Test a bunch of years, before leap day 221for (1..99) { 222 $t = DateTime->new( year => 2000, month => 2, day => 28, 223 time_zone => 'UTC', 224 ); 225 $t->add( years => $_ ); 226 my $x = sprintf '%02d', $_; 227 is( $t->date, "20${x}-02-28", "Adding $_ years"); 228} 229 230# Test a bunch of years, after leap day 231for (1..99) { 232 $t = DateTime->new( year => 2000, month => 3, day => 28, 233 time_zone => 'UTC', 234 ); 235 $t->add( years => $_ ); 236 my $x = sprintf '%02d', $_; 237 is( $t->date, "20${x}-03-28", "Adding $_ years"); 238} 239 240# And more of the same, starting on a non-leap year 241 242# Test a bunch of years, before leap day 243for (1..97) { 244 $t = DateTime->new( year => 2002, month => 2, day => 28, 245 time_zone => 'UTC', 246 ); 247 $t->add( years => $_ ); 248 my $x = sprintf '%02d', $_ + 2; 249 is( $t->date, "20${x}-02-28", "Adding $_ years"); 250} 251 252# Test a bunch of years, after leap day 253for (1..97) { 254 $t = DateTime->new( year => 2002, month => 3, day => 28, 255 time_zone => 'UTC', 256 ); 257 $t->add( years => $_ ); 258 my $x = sprintf '%02d', $_ + 2; 259 is( $t->date, "20${x}-03-28", "Adding $_ years"); 260} 261 262# subtract years 263for (1..97) { 264 $t = DateTime->new( year => 1999, month => 3, day => 1, 265 time_zone => 'UTC', 266 ); 267 $t->add( years => -$_ ); 268 my $x = sprintf '%02d', 99 - $_; 269 is( $t->date, "19${x}-03-01", "Subtracting $_ years"); 270} 271 272# test some old bugs 273 274# bug adding months where current month + months added were > 25 275$t = DateTime->new( year => 1997, month => 12, day => 1, 276 time_zone => 'UTC', 277 ); 278$t->add( months => 14 ); 279is( $t->date, '1999-02-01', 'Adding months--rollover year' ); 280 281# bug subtracting months with year rollover 282$t = DateTime->new( year => 1997, month => 1, day => 1, 283 time_zone => 'UTC', 284 ); 285$t->add( months => -1 ); 286is( $t->date, '1996-12-01', 'Subtracting months--rollover year' ); 287 288my $new = $t + DateTime::Duration->new( years => 2 ); 289is( $new->date, '1998-12-01', 'test + overloading' ); 290 291# test nanoseconds 292 293{ 294 my $t = DateTime->new( year => 1997, month => 1, day => 1, 295 hour => 1, minute => 1, second => 59, 296 nanosecond => 500000000, 297 time_zone => 'UTC', 298 ); 299 300 $t->add( nanoseconds => 500000000 ); 301 is( $t->second, 0, 'fractional second rollover' ); 302 $t->add( nanoseconds => 123000000 ); 303 is( $t->fractional_second, 0.123, 'as fractional_second' ); 304} 305 306{ 307 my $dt = DateTime->new( year => 2003, month => 2, day => 28 ); 308 $dt->add( months => 1, days => 1 ); 309 310 is( $dt->ymd, '2003-04-01', 'order of units in date math' ); 311} 312 313{ 314 my $dt = DateTime->new( year => 2003, hour => 12, minute => 1); 315 $dt->add( minutes => 30, seconds => -1 ); 316 317 is( $dt->hour, 12, 'hour is 12' ); 318 is( $dt->minute, 30, 'minute is 30' ); 319 is( $dt->second, 59, 'second is 59' ); 320} 321