PageRenderTime 65ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/tags/v2-104/lib/site/DateTime.pm

#
Perl | 2337 lines | 1701 code | 522 blank | 114 comment | 146 complexity | 313d3930f39bfc2a27110ecca317ec65 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, GPL-3.0
  1. package DateTime;
  2. use strict;
  3. use vars qw($VERSION);
  4. use Carp;
  5. use DateTime::Helpers;
  6. BEGIN
  7. {
  8. $VERSION = '0.39';
  9. my $loaded = 0;
  10. unless ( $ENV{PERL_DATETIME_PP} )
  11. {
  12. eval
  13. {
  14. if ( $] >= 5.006 )
  15. {
  16. require XSLoader;
  17. XSLoader::load( 'DateTime', $DateTime::VERSION );
  18. }
  19. else
  20. {
  21. require DynaLoader;
  22. @DateTime::ISA = 'DynaLoader';
  23. DateTime->bootstrap( $DateTime::VERSION );
  24. }
  25. $DateTime::IsPurePerl = 0;
  26. };
  27. die $@ if $@ && $@ !~ /object version|loadable object/;
  28. $loaded = 1 unless $@;
  29. }
  30. if ($loaded)
  31. {
  32. require DateTimePPExtra
  33. unless defined &DateTime::_normalize_tai_seconds;
  34. }
  35. else
  36. {
  37. require DateTimePP;
  38. }
  39. }
  40. use DateTime::Duration;
  41. use DateTime::Locale;
  42. use DateTime::TimeZone 0.38;
  43. use Params::Validate qw( validate validate_pos SCALAR BOOLEAN HASHREF OBJECT );
  44. use Time::Local ();
  45. # for some reason, overloading doesn't work unless fallback is listed
  46. # early.
  47. #
  48. # 3rd parameter ( $_[2] ) means the parameters are 'reversed'.
  49. # see: "Calling conventions for binary operations" in overload docs.
  50. #
  51. use overload ( 'fallback' => 1,
  52. '<=>' => '_compare_overload',
  53. 'cmp' => '_compare_overload',
  54. '""' => '_stringify',
  55. '-' => '_subtract_overload',
  56. '+' => '_add_overload',
  57. 'eq' => '_string_equals_overload',
  58. 'ne' => '_string_not_equals_overload',
  59. );
  60. # Have to load this after overloading is defined, after BEGIN blocks
  61. # or else weird crashes ensue
  62. require DateTime::Infinite;
  63. use constant MAX_NANOSECONDS => 1_000_000_000; # 1E9 = almost 32 bits
  64. use constant INFINITY => (9 ** 9 ** 9);
  65. use constant NEG_INFINITY => -1 * (9 ** 9 ** 9);
  66. use constant NAN => INFINITY - INFINITY;
  67. use constant SECONDS_PER_DAY => 86400;
  68. my( @MonthLengths, @LeapYearMonthLengths );
  69. BEGIN
  70. {
  71. @MonthLengths =
  72. ( 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 );
  73. @LeapYearMonthLengths = @MonthLengths;
  74. $LeapYearMonthLengths[1]++;
  75. }
  76. {
  77. # I'd rather use Class::Data::Inheritable for this, but there's no
  78. # way to add the module-loading behavior to an accessor it
  79. # creates, despite what its docs say!
  80. my $DefaultLocale;
  81. sub DefaultLocale
  82. {
  83. my $class = shift;
  84. if (@_)
  85. {
  86. my $lang = shift;
  87. DateTime::Locale->load($lang);
  88. $DefaultLocale = $lang;
  89. }
  90. return $DefaultLocale;
  91. }
  92. # backwards compat
  93. *DefaultLanguage = \&DefaultLocale;
  94. }
  95. __PACKAGE__->DefaultLocale('en_US');
  96. my $BasicValidate =
  97. { year => { type => SCALAR },
  98. month => { type => SCALAR, default => 1,
  99. callbacks =>
  100. { 'is between 1 and 12' =>
  101. sub { $_[0] >= 1 && $_[0] <= 12 }
  102. },
  103. },
  104. day => { type => SCALAR, default => 1,
  105. callbacks =>
  106. { 'is a possible valid day of month' =>
  107. sub { $_[0] >= 1 && $_[0] <= 31 }
  108. },
  109. },
  110. hour => { type => SCALAR, default => 0,
  111. callbacks =>
  112. { 'is between 0 and 23' =>
  113. sub { $_[0] >= 0 && $_[0] <= 23 },
  114. },
  115. },
  116. minute => { type => SCALAR, default => 0,
  117. callbacks =>
  118. { 'is between 0 and 59' =>
  119. sub { $_[0] >= 0 && $_[0] <= 59 },
  120. },
  121. },
  122. second => { type => SCALAR, default => 0,
  123. callbacks =>
  124. { 'is between 0 and 61' =>
  125. sub { $_[0] >= 0 && $_[0] <= 61 },
  126. },
  127. },
  128. nanosecond => { type => SCALAR, default => 0,
  129. callbacks =>
  130. { 'cannot be negative' =>
  131. sub { $_[0] >= 0 },
  132. }
  133. },
  134. locale => { type => SCALAR | OBJECT,
  135. default => undef },
  136. language => { type => SCALAR | OBJECT,
  137. optional => 1 },
  138. };
  139. my $NewValidate =
  140. { %$BasicValidate,
  141. time_zone => { type => SCALAR | OBJECT,
  142. default => 'floating' },
  143. formatter => { type => SCALAR | OBJECT, can => 'format_datetime', optional => 1 },
  144. };
  145. sub new
  146. {
  147. my $class = shift;
  148. my %p = validate( @_, $NewValidate );
  149. Carp::croak( "Invalid day of month (day = $p{day} - month = $p{month})\n" )
  150. if $p{day} > $class->_month_length( $p{year}, $p{month} );
  151. my $self = bless {}, $class;
  152. $p{locale} = delete $p{language} if exists $p{language};
  153. $p{locale} = $class->DefaultLocale unless defined $p{locale};
  154. if ( ref $p{locale} )
  155. {
  156. $self->{locale} = $p{locale};
  157. }
  158. else
  159. {
  160. $self->{locale} = DateTime::Locale->load( $p{locale} );
  161. }
  162. $self->{tz} =
  163. ( ref $p{time_zone} ?
  164. $p{time_zone} :
  165. DateTime::TimeZone->new( name => $p{time_zone} )
  166. );
  167. $self->{local_rd_days} =
  168. $class->_ymd2rd( @p{ qw( year month day ) } );
  169. $self->{local_rd_secs} =
  170. $class->_time_as_seconds( @p{ qw( hour minute second ) } );
  171. $self->{offset_modifier} = 0;
  172. $self->{rd_nanosecs} = $p{nanosecond};
  173. $self->{formatter} = $p{formatter};
  174. $self->_normalize_nanoseconds( $self->{local_rd_secs}, $self->{rd_nanosecs} );
  175. # Set this explicitly since it can't be calculated accurately
  176. # without knowing our time zone offset, and it's possible that the
  177. # offset can't be calculated without having at least a rough guess
  178. # of the datetime's year. This year need not be correct, as long
  179. # as its equal or greater to the correct number, so we fudge by
  180. # adding one to the local year given to the constructor.
  181. $self->{utc_year} = $p{year} + 1;
  182. $self->_calc_utc_rd;
  183. $self->_handle_offset_modifier( $p{second} );
  184. $self->_calc_local_rd;
  185. if ( $p{second} > 59 )
  186. {
  187. if ( $self->{tz}->is_floating ||
  188. # If true, this means that the actual calculated leap
  189. # second does not occur in the second given to new()
  190. ( $self->{utc_rd_secs} - 86399
  191. <
  192. $p{second} - 59 )
  193. )
  194. {
  195. Carp::croak( "Invalid second value ($p{second})\n" );
  196. }
  197. }
  198. return $self;
  199. }
  200. sub _handle_offset_modifier
  201. {
  202. my $self = shift;
  203. $self->{offset_modifier} = 0;
  204. return if $self->{tz}->is_floating;
  205. my $second = shift;
  206. my $utc_is_valid = shift;
  207. my $utc_rd_days = $self->{utc_rd_days};
  208. my $offset = $utc_is_valid ? $self->offset : $self->_offset_for_local_datetime;
  209. if ( $offset >= 0
  210. && $self->{local_rd_secs} >= $offset
  211. )
  212. {
  213. if ( $second < 60 && $offset > 0 )
  214. {
  215. $self->{offset_modifier} =
  216. $self->_day_length( $utc_rd_days - 1 ) - SECONDS_PER_DAY;
  217. $self->{local_rd_secs} += $self->{offset_modifier};
  218. }
  219. elsif ( $second == 60
  220. &&
  221. ( ( $self->{local_rd_secs} == $offset
  222. && $offset > 0 )
  223. ||
  224. ( $offset == 0
  225. && $self->{local_rd_secs} > 86399 ) )
  226. )
  227. {
  228. my $mod = $self->_day_length( $utc_rd_days - 1 ) - SECONDS_PER_DAY;
  229. unless ( $mod == 0 )
  230. {
  231. $self->{utc_rd_secs} -= $mod;
  232. $self->_normalize_seconds;
  233. }
  234. }
  235. }
  236. elsif ( $offset < 0
  237. && $self->{local_rd_secs} >= SECONDS_PER_DAY + $offset )
  238. {
  239. if ( $second < 60 )
  240. {
  241. $self->{offset_modifier} =
  242. $self->_day_length( $utc_rd_days - 1 ) - SECONDS_PER_DAY;
  243. $self->{local_rd_secs} += $self->{offset_modifier};
  244. }
  245. elsif ( $second == 60 && $self->{local_rd_secs} == SECONDS_PER_DAY + $offset )
  246. {
  247. my $mod = $self->_day_length( $utc_rd_days - 1 ) - SECONDS_PER_DAY;
  248. unless ( $mod == 0 )
  249. {
  250. $self->{utc_rd_secs} -= $mod;
  251. $self->_normalize_seconds;
  252. }
  253. }
  254. }
  255. }
  256. sub _calc_utc_rd
  257. {
  258. my $self = shift;
  259. delete $self->{utc_c};
  260. if ( $self->{tz}->is_utc || $self->{tz}->is_floating )
  261. {
  262. $self->{utc_rd_days} = $self->{local_rd_days};
  263. $self->{utc_rd_secs} = $self->{local_rd_secs};
  264. }
  265. else
  266. {
  267. my $offset = $self->_offset_for_local_datetime;
  268. $offset += $self->{offset_modifier};
  269. $self->{utc_rd_days} = $self->{local_rd_days};
  270. $self->{utc_rd_secs} = $self->{local_rd_secs} - $offset;
  271. }
  272. # We account for leap seconds in the new() method and nowhere else
  273. # except date math.
  274. $self->_normalize_tai_seconds( $self->{utc_rd_days}, $self->{utc_rd_secs} );
  275. }
  276. sub _normalize_seconds
  277. {
  278. my $self = shift;
  279. return if $self->{utc_rd_secs} >= 0 && $self->{utc_rd_secs} <= 86399;
  280. if ( $self->{tz}->is_floating )
  281. {
  282. $self->_normalize_tai_seconds( $self->{utc_rd_days}, $self->{utc_rd_secs} );
  283. }
  284. else
  285. {
  286. $self->_normalize_leap_seconds( $self->{utc_rd_days}, $self->{utc_rd_secs} );
  287. }
  288. }
  289. sub _calc_local_rd
  290. {
  291. my $self = shift;
  292. delete $self->{local_c};
  293. # We must short circuit for UTC times or else we could end up with
  294. # loops between DateTime.pm and DateTime::TimeZone
  295. if ( $self->{tz}->is_utc || $self->{tz}->is_floating )
  296. {
  297. $self->{local_rd_days} = $self->{utc_rd_days};
  298. $self->{local_rd_secs} = $self->{utc_rd_secs};
  299. }
  300. else
  301. {
  302. my $offset = $self->offset;
  303. $self->{local_rd_days} = $self->{utc_rd_days};
  304. $self->{local_rd_secs} = $self->{utc_rd_secs} + $offset;
  305. # intentionally ignore leap seconds here
  306. $self->_normalize_tai_seconds( $self->{local_rd_days}, $self->{local_rd_secs} );
  307. $self->{local_rd_secs} += $self->{offset_modifier};
  308. }
  309. $self->_calc_local_components;
  310. }
  311. sub _calc_local_components
  312. {
  313. my $self = shift;
  314. @{ $self->{local_c} }{ qw( year month day day_of_week
  315. day_of_year quarter day_of_quarter) } =
  316. $self->_rd2ymd( $self->{local_rd_days}, 1 );
  317. @{ $self->{local_c} }{ qw( hour minute second ) } =
  318. $self->_seconds_as_components
  319. ( $self->{local_rd_secs}, $self->{utc_rd_secs}, $self->{offset_modifier} );
  320. }
  321. sub _calc_utc_components
  322. {
  323. my $self = shift;
  324. die "Cannot get UTC components before UTC RD has been calculated\n"
  325. unless defined $self->{utc_rd_days};
  326. @{ $self->{utc_c} }{ qw( year month day ) } =
  327. $self->_rd2ymd( $self->{utc_rd_days} );
  328. @{ $self->{utc_c} }{ qw( hour minute second ) } =
  329. $self->_seconds_as_components( $self->{utc_rd_secs} );
  330. }
  331. sub _utc_ymd
  332. {
  333. my $self = shift;
  334. $self->_calc_utc_components unless exists $self->{utc_c}{year};
  335. return @{ $self->{utc_c} }{ qw( year month day ) };
  336. }
  337. sub _utc_hms
  338. {
  339. my $self = shift;
  340. $self->_calc_utc_components unless exists $self->{utc_c}{hour};
  341. return @{ $self->{utc_c} }{ qw( hour minute second ) };
  342. }
  343. sub from_epoch
  344. {
  345. my $class = shift;
  346. my %p = validate( @_,
  347. { epoch => { type => SCALAR },
  348. locale => { type => SCALAR | OBJECT, optional => 1 },
  349. language => { type => SCALAR | OBJECT, optional => 1 },
  350. time_zone => { type => SCALAR | OBJECT, optional => 1 },
  351. formatter => { type => SCALAR | OBJECT, can => 'format_datetime',
  352. optional => 1 },
  353. }
  354. );
  355. my %args;
  356. # Because epoch may come from Time::HiRes
  357. my $fraction = $p{epoch} - int( $p{epoch} );
  358. $args{nanosecond} = int( $fraction * MAX_NANOSECONDS )
  359. if $fraction;
  360. # Note, for very large negative values this may give a blatantly
  361. # wrong answer.
  362. @args{ qw( second minute hour day month year ) } =
  363. ( gmtime( int delete $p{epoch} ) )[ 0..5 ];
  364. $args{year} += 1900;
  365. $args{month}++;
  366. my $self = $class->new( %p, %args, time_zone => 'UTC' );
  367. $self->set_time_zone( $p{time_zone} ) if exists $p{time_zone};
  368. return $self;
  369. }
  370. # use scalar time in case someone's loaded Time::Piece
  371. sub now { shift->from_epoch( epoch => (scalar time), @_ ) }
  372. sub today { shift->now(@_)->truncate( to => 'day' ) }
  373. sub from_object
  374. {
  375. my $class = shift;
  376. my %p = validate( @_,
  377. { object => { type => OBJECT,
  378. can => 'utc_rd_values',
  379. },
  380. locale => { type => SCALAR | OBJECT, optional => 1 },
  381. language => { type => SCALAR | OBJECT, optional => 1 },
  382. formatter => { type => SCALAR | OBJECT, can => 'format_datetime',
  383. optional => 1 },
  384. },
  385. );
  386. my $object = delete $p{object};
  387. my ( $rd_days, $rd_secs, $rd_nanosecs ) = $object->utc_rd_values;
  388. # A kludge because until all calendars are updated to return all
  389. # three values, $rd_nanosecs could be undef
  390. $rd_nanosecs ||= 0;
  391. # This is a big hack to let _seconds_as_components operate naively
  392. # on the given value. If the object _is_ on a leap second, we'll
  393. # add that to the generated seconds value later.
  394. my $leap_seconds = 0;
  395. if ( $object->can('time_zone') && ! $object->time_zone->is_floating
  396. && $rd_secs > 86399 && $rd_secs <= $class->_day_length($rd_days) )
  397. {
  398. $leap_seconds = $rd_secs - 86399;
  399. $rd_secs -= $leap_seconds;
  400. }
  401. my %args;
  402. @args{ qw( year month day ) } = $class->_rd2ymd($rd_days);
  403. @args{ qw( hour minute second ) } =
  404. $class->_seconds_as_components($rd_secs);
  405. $args{nanosecond} = $rd_nanosecs;
  406. $args{second} += $leap_seconds;
  407. my $new = $class->new( %p, %args, time_zone => 'UTC' );
  408. if ( $object->can('time_zone') )
  409. {
  410. $new->set_time_zone( $object->time_zone );
  411. }
  412. else
  413. {
  414. $new->set_time_zone( 'floating' );
  415. }
  416. return $new;
  417. }
  418. my $LastDayOfMonthValidate = { %$NewValidate };
  419. foreach ( keys %$LastDayOfMonthValidate )
  420. {
  421. my %copy = %{ $LastDayOfMonthValidate->{$_} };
  422. delete $copy{default};
  423. $copy{optional} = 1 unless $_ eq 'year' || $_ eq 'month';
  424. $LastDayOfMonthValidate->{$_} = \%copy;
  425. }
  426. sub last_day_of_month
  427. {
  428. my $class = shift;
  429. my %p = validate( @_, $LastDayOfMonthValidate );
  430. my $day = $class->_month_length( $p{year}, $p{month} );
  431. return $class->new( %p, day => $day );
  432. }
  433. sub _month_length
  434. {
  435. return ( $_[0]->_is_leap_year( $_[1] ) ?
  436. $LeapYearMonthLengths[ $_[2] - 1 ] :
  437. $MonthLengths[ $_[2] - 1 ]
  438. );
  439. }
  440. my $FromDayOfYearValidate = { %$NewValidate };
  441. foreach ( keys %$FromDayOfYearValidate )
  442. {
  443. next if $_ eq 'month' || $_ eq 'day';
  444. my %copy = %{ $FromDayOfYearValidate->{$_} };
  445. delete $copy{default};
  446. $copy{optional} = 1 unless $_ eq 'year' || $_ eq 'month';
  447. $FromDayOfYearValidate->{$_} = \%copy;
  448. }
  449. $FromDayOfYearValidate->{day_of_year} =
  450. { type => SCALAR,
  451. callbacks =>
  452. { 'is between 1 and 366' =>
  453. sub { $_[0] >= 1 && $_[0] <= 366 }
  454. }
  455. };
  456. sub from_day_of_year
  457. {
  458. my $class = shift;
  459. my %p = validate( @_, $FromDayOfYearValidate );
  460. my $is_leap_year = $class->_is_leap_year( $p{year} );
  461. Carp::croak( "$p{year} is not a leap year.\n" )
  462. if $p{day_of_year} == 366 && ! $is_leap_year;
  463. my $month = 1;
  464. my $day = delete $p{day_of_year};
  465. while ( $month <= 12 && $day > $class->_month_length( $p{year}, $month ) )
  466. {
  467. $day -= $class->_month_length( $p{year}, $month );
  468. $month++;
  469. }
  470. return DateTime->new( %p,
  471. month => $month,
  472. day => $day,
  473. );
  474. }
  475. sub formatter { $_[0]->{formatter} }
  476. sub clone { bless { %{ $_[0] } }, ref $_[0] }
  477. sub year { $_[0]->{local_c}{year} }
  478. sub ce_year { $_[0]->{local_c}{year} <= 0 ?
  479. $_[0]->{local_c}{year} - 1 :
  480. $_[0]->{local_c}{year} }
  481. sub era_name { $_[0]->{locale}->era_name( $_[0] ) }
  482. sub era_abbr { $_[0]->{locale}->era_abbreviation( $_[0] ) }
  483. # deprecated
  484. *era = \&era_abbr;
  485. sub christian_era { $_[0]->ce_year > 0 ? 'AD' : 'BC' }
  486. sub secular_era { $_[0]->ce_year > 0 ? 'CE' : 'BCE' }
  487. sub year_with_era { (abs $_[0]->ce_year) . $_[0]->era_abbr }
  488. sub year_with_christian_era { (abs $_[0]->ce_year) . $_[0]->christian_era }
  489. sub year_with_secular_era { (abs $_[0]->ce_year) . $_[0]->secular_era }
  490. sub month { $_[0]->{local_c}{month} }
  491. *mon = \&month;
  492. sub month_0 { $_[0]->{local_c}{month} - 1 };
  493. *mon_0 = \&month_0;
  494. sub month_name { $_[0]->{locale}->month_name( $_[0] ) }
  495. sub month_abbr { $_[0]->{locale}->month_abbreviation( $_[0] ) }
  496. sub day_of_month { $_[0]->{local_c}{day} }
  497. *day = \&day_of_month;
  498. *mday = \&day_of_month;
  499. sub weekday_of_month { use integer; ( ( $_[0]->day - 1 ) / 7 ) + 1 }
  500. sub quarter {$_[0]->{local_c}{quarter} };
  501. sub quarter_name { $_[0]->{locale}->quarter_name( $_[0] ) }
  502. sub quarter_abbr { $_[0]->{locale}->quarter_abbreviation( $_[0] ) }
  503. sub day_of_month_0 { $_[0]->{local_c}{day} - 1 }
  504. *day_0 = \&day_of_month_0;
  505. *mday_0 = \&day_of_month_0;
  506. sub day_of_week { $_[0]->{local_c}{day_of_week} }
  507. *wday = \&day_of_week;
  508. *dow = \&day_of_week;
  509. sub day_of_week_0 { $_[0]->{local_c}{day_of_week} - 1 }
  510. *wday_0 = \&day_of_week_0;
  511. *dow_0 = \&day_of_week_0;
  512. sub day_name { $_[0]->{locale}->day_name( $_[0] ) }
  513. sub day_abbr { $_[0]->{locale}->day_abbreviation( $_[0] ) }
  514. sub day_of_quarter { $_[0]->{local_c}{day_of_quarter} }
  515. *doq = \&day_of_quarter;
  516. sub day_of_quarter_0 { $_[0]->day_of_quarter - 1 }
  517. *doq_0 = \&day_of_quarter_0;
  518. sub day_of_year { $_[0]->{local_c}{day_of_year} }
  519. *doy = \&day_of_year;
  520. sub day_of_year_0 { $_[0]->{local_c}{day_of_year} - 1 }
  521. *doy_0 = \&day_of_year_0;
  522. sub ymd
  523. {
  524. my ( $self, $sep ) = @_;
  525. $sep = '-' unless defined $sep;
  526. return sprintf( "%0.4d%s%0.2d%s%0.2d",
  527. $self->year, $sep,
  528. $self->{local_c}{month}, $sep,
  529. $self->{local_c}{day} );
  530. }
  531. *date = \&ymd;
  532. sub mdy
  533. {
  534. my ( $self, $sep ) = @_;
  535. $sep = '-' unless defined $sep;
  536. return sprintf( "%0.2d%s%0.2d%s%0.4d",
  537. $self->{local_c}{month}, $sep,
  538. $self->{local_c}{day}, $sep,
  539. $self->year );
  540. }
  541. sub dmy
  542. {
  543. my ( $self, $sep ) = @_;
  544. $sep = '-' unless defined $sep;
  545. return sprintf( "%0.2d%s%0.2d%s%0.4d",
  546. $self->{local_c}{day}, $sep,
  547. $self->{local_c}{month}, $sep,
  548. $self->year );
  549. }
  550. sub hour { $_[0]->{local_c}{hour} }
  551. sub hour_1 { $_[0]->{local_c}{hour} + 1 }
  552. sub hour_12 { my $h = $_[0]->hour % 12; return $h ? $h : 12 }
  553. sub hour_12_0 { $_[0]->hour % 12 }
  554. sub minute { $_[0]->{local_c}{minute} }
  555. *min = \&minute;
  556. sub second { $_[0]->{local_c}{second} }
  557. *sec = \&second;
  558. sub fractional_second { $_[0]->second + $_[0]->nanosecond / MAX_NANOSECONDS }
  559. sub nanosecond { $_[0]->{rd_nanosecs} }
  560. sub millisecond { _round( $_[0]->{rd_nanosecs} / 1000000 ) }
  561. sub microsecond { _round( $_[0]->{rd_nanosecs} / 1000 ) }
  562. sub _round
  563. {
  564. my $val = shift;
  565. my $int = int $val;
  566. return $val - $int >= 0.5 ? $int + 1 : $int;
  567. }
  568. sub leap_seconds
  569. {
  570. my $self = shift;
  571. return 0 if $self->{tz}->is_floating;
  572. return DateTime->_accumulated_leap_seconds( $self->{utc_rd_days} );
  573. }
  574. sub _stringify
  575. {
  576. my $self = shift;
  577. return $self->iso8601 unless $self->{formatter};
  578. return $self->{formatter}->format_datetime($self);
  579. }
  580. sub hms
  581. {
  582. my ( $self, $sep ) = @_;
  583. $sep = ':' unless defined $sep;
  584. return sprintf( "%0.2d%s%0.2d%s%0.2d",
  585. $self->{local_c}{hour}, $sep,
  586. $self->{local_c}{minute}, $sep,
  587. $self->{local_c}{second} );
  588. }
  589. # don't want to override CORE::time()
  590. *DateTime::time = \&hms;
  591. sub iso8601 { join 'T', $_[0]->ymd('-'), $_[0]->hms(':') }
  592. *datetime = \&iso8601;
  593. sub is_leap_year { $_[0]->_is_leap_year( $_[0]->year ) }
  594. sub week
  595. {
  596. my $self = shift;
  597. unless ( defined $self->{local_c}{week_year} )
  598. {
  599. # This algorithm was taken from Date::Calc's DateCalc.c file
  600. my $jan_one_dow_m1 =
  601. ( ( $self->_ymd2rd( $self->year, 1, 1 ) + 6 ) % 7 );
  602. $self->{local_c}{week_number} =
  603. int( ( ( $self->day_of_year - 1 ) + $jan_one_dow_m1 ) / 7 );
  604. $self->{local_c}{week_number}++ if $jan_one_dow_m1 < 4;
  605. if ( $self->{local_c}{week_number} == 0 )
  606. {
  607. $self->{local_c}{week_year} = $self->year - 1;
  608. $self->{local_c}{week_number} =
  609. $self->_weeks_in_year( $self->{local_c}{week_year} );
  610. }
  611. elsif ( $self->{local_c}{week_number} == 53 &&
  612. $self->_weeks_in_year( $self->year ) == 52 )
  613. {
  614. $self->{local_c}{week_number} = 1;
  615. $self->{local_c}{week_year} = $self->year + 1;
  616. }
  617. else
  618. {
  619. $self->{local_c}{week_year} = $self->year;
  620. }
  621. }
  622. return @{ $self->{local_c} }{ 'week_year', 'week_number' }
  623. }
  624. # Also from DateCalc.c
  625. sub _weeks_in_year
  626. {
  627. my $self = shift;
  628. my $year = shift;
  629. my $jan_one_dow =
  630. ( ( $self->_ymd2rd( $year, 1, 1 ) + 6 ) % 7 ) + 1;
  631. my $dec_31_dow =
  632. ( ( $self->_ymd2rd( $year, 12, 31 ) + 6 ) % 7 ) + 1;
  633. return $jan_one_dow == 4 || $dec_31_dow == 4 ? 53 : 52;
  634. }
  635. sub week_year { ($_[0]->week)[0] }
  636. sub week_number { ($_[0]->week)[1] }
  637. # ISO says that the first week of a year is the first week containing
  638. # a Thursday. Extending that says that the first week of the month is
  639. # the first week containing a Thursday. ICU agrees.
  640. #
  641. # Algorithm supplied by Rick Measham, who doesn't understand how it
  642. # works. Neither do I. Please feel free to explain this to me!
  643. sub week_of_month
  644. {
  645. my $self = shift;
  646. # Faster than cloning just to get the dow
  647. my $first_wday_of_month = ( 8 - ( $self->day - $self->dow ) % 7 ) % 7;
  648. $first_wday_of_month = 7 unless $first_wday_of_month;
  649. my $wom = int( ( $self->day + $first_wday_of_month - 2 ) / 7 );
  650. return ( $first_wday_of_month <= 4 ) ? $wom + 1 : $wom;
  651. }
  652. sub time_zone { $_[0]->{tz} }
  653. sub offset { $_[0]->{tz}->offset_for_datetime( $_[0] ) }
  654. sub _offset_for_local_datetime { $_[0]->{tz}->offset_for_local_datetime( $_[0] ) }
  655. sub is_dst { $_[0]->{tz}->is_dst_for_datetime( $_[0] ) }
  656. sub time_zone_long_name { $_[0]->{tz}->name }
  657. sub time_zone_short_name { $_[0]->{tz}->short_name_for_datetime( $_[0] ) }
  658. sub locale { $_[0]->{locale} }
  659. *language = \&locale;
  660. sub utc_rd_values { @{ $_[0] }{ 'utc_rd_days', 'utc_rd_secs', 'rd_nanosecs' } }
  661. sub local_rd_values { @{ $_[0] }{ 'local_rd_days', 'local_rd_secs', 'rd_nanosecs' } }
  662. # NOTE: no nanoseconds, no leap seconds
  663. sub utc_rd_as_seconds { ( $_[0]->{utc_rd_days} * SECONDS_PER_DAY ) + $_[0]->{utc_rd_secs} }
  664. # NOTE: no nanoseconds, no leap seconds
  665. sub local_rd_as_seconds { ( $_[0]->{local_rd_days} * SECONDS_PER_DAY ) + $_[0]->{local_rd_secs} }
  666. # RD 1 is JD 1,721,424.5 - a simple offset
  667. sub jd
  668. {
  669. my $self = shift;
  670. my $jd = $self->{utc_rd_days} + 1_721_424.5;
  671. my $day_length = $self->_day_length( $self->{utc_rd_days} );
  672. return ( $jd +
  673. ( $self->{utc_rd_secs} / $day_length ) +
  674. ( $self->{rd_nanosecs} / $day_length / MAX_NANOSECONDS )
  675. );
  676. }
  677. sub mjd { $_[0]->jd - 2_400_000.5 }
  678. my %formats =
  679. ( 'a' => sub { $_[0]->day_abbr },
  680. 'A' => sub { $_[0]->day_name },
  681. 'b' => sub { $_[0]->month_abbr },
  682. 'B' => sub { $_[0]->month_name },
  683. 'c' => sub { $_[0]->strftime( $_[0]->{locale}->default_datetime_format ) },
  684. 'C' => sub { int( $_[0]->year / 100 ) },
  685. 'd' => sub { sprintf( '%02d', $_[0]->day_of_month ) },
  686. 'D' => sub { $_[0]->strftime( '%m/%d/%y' ) },
  687. 'e' => sub { sprintf( '%2d', $_[0]->day_of_month ) },
  688. 'F' => sub { $_[0]->ymd('-') },
  689. 'g' => sub { substr( $_[0]->week_year, -2 ) },
  690. 'G' => sub { $_[0]->week_year },
  691. 'H' => sub { sprintf( '%02d', $_[0]->hour ) },
  692. 'I' => sub { sprintf( '%02d', $_[0]->hour_12 ) },
  693. 'j' => sub { $_[0]->day_of_year },
  694. 'k' => sub { sprintf( '%2d', $_[0]->hour ) },
  695. 'l' => sub { sprintf( '%2d', $_[0]->hour_12 ) },
  696. 'm' => sub { sprintf( '%02d', $_[0]->month ) },
  697. 'M' => sub { sprintf( '%02d', $_[0]->minute ) },
  698. 'n' => sub { "\n" }, # should this be OS-sensitive?
  699. 'N' => \&_format_nanosecs,
  700. 'p' => sub { $_[0]->{locale}->am_pm( $_[0] ) },
  701. 'P' => sub { lc $_[0]->{locale}->am_pm( $_[0] ) },
  702. 'r' => sub { $_[0]->strftime( '%I:%M:%S %p' ) },
  703. 'R' => sub { $_[0]->strftime( '%H:%M' ) },
  704. 's' => sub { $_[0]->epoch },
  705. 'S' => sub { sprintf( '%02d', $_[0]->second ) },
  706. 't' => sub { "\t" },
  707. 'T' => sub { $_[0]->strftime( '%H:%M:%S' ) },
  708. 'u' => sub { $_[0]->day_of_week },
  709. # algorithm from Date::Format::wkyr
  710. 'U' => sub { my $dow = $_[0]->day_of_week;
  711. $dow = 0 if $dow == 7; # convert to 0-6, Sun-Sat
  712. my $doy = $_[0]->day_of_year - 1;
  713. return sprintf( '%02d', int( ( $doy - $dow + 13 ) / 7 - 1 ) )
  714. },
  715. 'V' => sub { sprintf( '%02d', $_[0]->week_number ) },
  716. 'w' => sub { my $dow = $_[0]->day_of_week;
  717. return $dow % 7;
  718. },
  719. 'W' => sub { my $dow = $_[0]->day_of_week;
  720. my $doy = $_[0]->day_of_year - 1;
  721. return sprintf( '%02d', int( ( $doy - $dow + 13 ) / 7 - 1 ) )
  722. },
  723. 'x' => sub { $_[0]->strftime( $_[0]->{locale}->default_date_format ) },
  724. 'X' => sub { $_[0]->strftime( $_[0]->{locale}->default_time_format ) },
  725. 'y' => sub { sprintf( '%02d', substr( $_[0]->year, -2 ) ) },
  726. 'Y' => sub { return $_[0]->year },
  727. 'z' => sub { DateTime::TimeZone::offset_as_string( $_[0]->offset ) },
  728. 'Z' => sub { $_[0]->{tz}->short_name_for_datetime( $_[0] ) },
  729. '%' => sub { '%' },
  730. );
  731. $formats{h} = $formats{b};
  732. sub strftime
  733. {
  734. my $self = shift;
  735. # make a copy or caller's scalars get munged
  736. my @formats = @_;
  737. my @r;
  738. foreach my $f (@formats)
  739. {
  740. $f =~ s/
  741. (?:
  742. %{(\w+)} # method name like %{day_name}
  743. |
  744. %([%a-zA-Z]) # single character specifier like %d
  745. |
  746. %(\d+)N # special case for %N
  747. )
  748. /
  749. ( $1
  750. ? ( $self->can($1) ? $self->$1() : "\%{$1}" )
  751. : $2
  752. ? ( $formats{$2} ? $formats{$2}->($self) : "\%$2" )
  753. : $3
  754. ? $formats{N}->($self, $3)
  755. : '' # this won't happen
  756. )
  757. /sgex;
  758. return $f unless wantarray;
  759. push @r, $f;
  760. }
  761. return @r;
  762. }
  763. sub _format_nanosecs
  764. {
  765. my $self = shift;
  766. my $precision = shift;
  767. my $ret = sprintf( "%09d", $self->{rd_nanosecs} );
  768. return $ret unless $precision; # default = 9 digits
  769. # rd_nanosecs might contain a fractional separator
  770. my ( $int, $frac ) = split /[.,]/, $self->{rd_nanosecs};
  771. $ret .= $frac if $frac;
  772. return substr( $ret, 0, $precision );
  773. }
  774. sub epoch
  775. {
  776. my $self = shift;
  777. return $self->{utc_c}{epoch}
  778. if exists $self->{utc_c}{epoch};
  779. my ( $year, $month, $day ) = $self->_utc_ymd;
  780. my @hms = $self->_utc_hms;
  781. $self->{utc_c}{epoch} =
  782. eval { Time::Local::timegm_nocheck( ( reverse @hms ),
  783. $day,
  784. $month - 1,
  785. $year,
  786. ) };
  787. return $self->{utc_c}{epoch};
  788. }
  789. sub hires_epoch
  790. {
  791. my $self = shift;
  792. my $epoch = $self->epoch;
  793. return undef unless defined $epoch;
  794. my $nano = $self->{rd_nanosecs} / MAX_NANOSECONDS;
  795. return $epoch + $nano;
  796. }
  797. sub is_finite { 1 }
  798. sub is_infinite { 0 }
  799. # added for benefit of DateTime::TimeZone
  800. sub utc_year { $_[0]->{utc_year} }
  801. # returns a result that is relative to the first datetime
  802. sub subtract_datetime
  803. {
  804. my $dt1 = shift;
  805. my $dt2 = shift;
  806. $dt2 = $dt2->clone->set_time_zone( $dt1->time_zone )
  807. unless $dt1->time_zone->name eq $dt2->time_zone->name;
  808. # We only want a negative duration if $dt2 > $dt1 ($self)
  809. my ( $bigger, $smaller, $negative ) =
  810. ( $dt1 >= $dt2 ?
  811. ( $dt1, $dt2, 0 ) :
  812. ( $dt2, $dt1, 1 )
  813. );
  814. my $is_floating = $dt1->time_zone->is_floating &&
  815. $dt2->time_zone->is_floating;
  816. my $minute_length = 60;
  817. unless ($is_floating)
  818. {
  819. my ( $utc_rd_days, $utc_rd_secs ) = $smaller->utc_rd_values;
  820. if ( $utc_rd_secs >= 86340 && ! $is_floating )
  821. {
  822. # If the smaller of the two datetimes occurs in the last
  823. # UTC minute of the UTC day, then that minute may not be
  824. # 60 seconds long. If we need to subtract a minute from
  825. # the larger datetime's minutes count in order to adjust
  826. # the seconds difference to be positive, we need to know
  827. # how long that minute was. If one of the datetimes is
  828. # floating, we just assume a minute is 60 seconds.
  829. $minute_length = $dt1->_day_length($utc_rd_days) - 86340;
  830. }
  831. }
  832. # This is a gross hack that basically figures out if the bigger of
  833. # the two datetimes is the day of a DST change. If it's a 23 hour
  834. # day (switching _to_ DST) then we subtract 60 minutes from the
  835. # local time. If it's a 25 hour day then we add 60 minutes to the
  836. # local time.
  837. #
  838. # This produces the most "intuitive" results, though there are
  839. # still reversibility problems with the resultant duration.
  840. #
  841. # However, if the two objects are on the same (local) date, and we
  842. # are not crossing a DST change, we don't want to invoke the hack
  843. # - see 38local-subtract.t
  844. my $bigger_min = $bigger->hour * 60 + $bigger->minute;
  845. if ( $bigger->time_zone->has_dst_changes
  846. && ( $bigger->ymd ne $smaller->ymd
  847. || $bigger->is_dst != $smaller->is_dst )
  848. )
  849. {
  850. $bigger_min -= 60
  851. # it's a 23 hour (local) day
  852. if ( $bigger->is_dst
  853. &&
  854. do { my $prev_day = eval { $bigger->clone->subtract( days => 1 ) };
  855. $prev_day && ! $prev_day->is_dst ? 1 : 0 }
  856. );
  857. $bigger_min += 60
  858. # it's a 25 hour (local) day
  859. if ( ! $bigger->is_dst
  860. &&
  861. do { my $prev_day = eval { $bigger->clone->subtract( days => 1 ) };
  862. $prev_day && $prev_day->is_dst ? 1 : 0 }
  863. );
  864. }
  865. my ( $months, $days, $minutes, $seconds, $nanoseconds ) =
  866. $dt1->_adjust_for_positive_difference
  867. ( $bigger->year * 12 + $bigger->month, $smaller->year * 12 + $smaller->month,
  868. $bigger->day, $smaller->day,
  869. $bigger_min, $smaller->hour * 60 + $smaller->minute,
  870. $bigger->second, $smaller->second,
  871. $bigger->nanosecond, $smaller->nanosecond,
  872. $minute_length,
  873. # XXX - using the smaller as the month length is
  874. # somewhat arbitrary, we could also use the bigger -
  875. # either way we have reversibility problems
  876. $dt1->_month_length( $smaller->year, $smaller->month ),
  877. );
  878. if ($negative)
  879. {
  880. for ( $months, $days, $minutes, $seconds, $nanoseconds )
  881. {
  882. # Some versions of Perl can end up with -0 if we do "0 * -1"!!
  883. $_ *= -1 if $_;
  884. }
  885. }
  886. return
  887. DateTime::Duration->new
  888. ( months => $months,
  889. days => $days,
  890. minutes => $minutes,
  891. seconds => $seconds,
  892. nanoseconds => $nanoseconds,
  893. );
  894. }
  895. sub _adjust_for_positive_difference
  896. {
  897. my ( $self,
  898. $month1, $month2,
  899. $day1, $day2,
  900. $min1, $min2,
  901. $sec1, $sec2,
  902. $nano1, $nano2,
  903. $minute_length,
  904. $month_length,
  905. ) = @_;
  906. if ( $nano1 < $nano2 )
  907. {
  908. $sec1--;
  909. $nano1 += MAX_NANOSECONDS;
  910. }
  911. if ( $sec1 < $sec2 )
  912. {
  913. $min1--;
  914. $sec1 += $minute_length;
  915. }
  916. # A day always has 24 * 60 minutes, though the minutes may vary in
  917. # length.
  918. if ( $min1 < $min2 )
  919. {
  920. $day1--;
  921. $min1 += 24 * 60;
  922. }
  923. if ( $day1 < $day2 )
  924. {
  925. $month1--;
  926. $day1 += $month_length;
  927. }
  928. return ( $month1 - $month2,
  929. $day1 - $day2,
  930. $min1 - $min2,
  931. $sec1 - $sec2,
  932. $nano1 - $nano2,
  933. );
  934. }
  935. sub subtract_datetime_absolute
  936. {
  937. my $self = shift;
  938. my $dt = shift;
  939. my $utc_rd_secs1 = $self->utc_rd_as_seconds;
  940. $utc_rd_secs1 += DateTime->_accumulated_leap_seconds( $self->{utc_rd_days} )
  941. if ! $self->time_zone->is_floating;
  942. my $utc_rd_secs2 = $dt->utc_rd_as_seconds;
  943. $utc_rd_secs2 += DateTime->_accumulated_leap_seconds( $dt->{utc_rd_days} )
  944. if ! $dt->time_zone->is_floating;
  945. my $seconds = $utc_rd_secs1 - $utc_rd_secs2;
  946. my $nanoseconds = $self->nanosecond - $dt->nanosecond;
  947. if ( $nanoseconds < 0 )
  948. {
  949. $seconds--;
  950. $nanoseconds += MAX_NANOSECONDS;
  951. }
  952. return
  953. DateTime::Duration->new
  954. ( seconds => $seconds,
  955. nanoseconds => $nanoseconds,
  956. );
  957. }
  958. sub delta_md
  959. {
  960. my $self = shift;
  961. my $dt = shift;
  962. my ( $smaller, $bigger ) = sort $self, $dt;
  963. my ( $months, $days, undef, undef, undef ) =
  964. $dt->_adjust_for_positive_difference
  965. ( $bigger->year * 12 + $bigger->month, $smaller->year * 12 + $smaller->month,
  966. $bigger->day, $smaller->day,
  967. 0, 0,
  968. 0, 0,
  969. 0, 0,
  970. 60,
  971. $smaller->_month_length( $smaller->year, $smaller->month ),
  972. );
  973. return DateTime::Duration->new( months => $months,
  974. days => $days );
  975. }
  976. sub delta_days
  977. {
  978. my $self = shift;
  979. my $dt = shift;
  980. my ( $smaller, $bigger ) = sort( ($self->local_rd_values)[0], ($dt->local_rd_values)[0] );
  981. DateTime::Duration->new( days => $bigger - $smaller );
  982. }
  983. sub delta_ms
  984. {
  985. my $self = shift;
  986. my $dt = shift;
  987. my ( $smaller, $greater ) = sort $self, $dt;
  988. my $days = int( $greater->jd - $smaller->jd );
  989. my $dur = $greater->subtract_datetime($smaller);
  990. my %p;
  991. $p{hours} = $dur->hours + ( $days * 24 );
  992. $p{minutes} = $dur->minutes;
  993. $p{seconds} = $dur->seconds;
  994. return DateTime::Duration->new(%p);
  995. }
  996. sub _add_overload
  997. {
  998. my ( $dt, $dur, $reversed ) = @_;
  999. if ($reversed)
  1000. {
  1001. ( $dur, $dt ) = ( $dt, $dur );
  1002. }
  1003. unless ( DateTime::Helpers::isa( $dur, 'DateTime::Duration' ) )
  1004. {
  1005. my $class = ref $dt;
  1006. my $dt_string = overload::StrVal($dt);
  1007. Carp::croak( "Cannot add $dur to a $class object ($dt_string).\n"
  1008. . " Only a DateTime::Duration object can "
  1009. . " be added to a $class object." );
  1010. }
  1011. return $dt->clone->add_duration($dur);
  1012. }
  1013. sub _subtract_overload
  1014. {
  1015. my ( $date1, $date2, $reversed ) = @_;
  1016. if ($reversed)
  1017. {
  1018. ( $date2, $date1 ) = ( $date1, $date2 );
  1019. }
  1020. if ( DateTime::Helpers::isa( $date2, 'DateTime::Duration' ) )
  1021. {
  1022. my $new = $date1->clone;
  1023. $new->add_duration( $date2->inverse );
  1024. return $new;
  1025. }
  1026. elsif ( DateTime::Helpers::isa( $date2, 'DateTime' ) )
  1027. {
  1028. return $date1->subtract_datetime($date2);
  1029. }
  1030. else
  1031. {
  1032. my $class = ref $date1;
  1033. my $dt_string = overload::StrVal($date1);
  1034. Carp::croak( "Cannot subtract $date2 from a $class object ($dt_string).\n"
  1035. . " Only a DateTime::Duration or DateTime object can "
  1036. . " be subtracted from a $class object." );
  1037. }
  1038. }
  1039. sub add { return shift->add_duration( DateTime::Duration->new(@_) ) }
  1040. sub subtract { return shift->subtract_duration( DateTime::Duration->new(@_) ) }
  1041. sub subtract_duration { return $_[0]->add_duration( $_[1]->inverse ) }
  1042. sub add_duration
  1043. {
  1044. my $self = shift;
  1045. my ($dur) = validate_pos( @_, { isa => 'DateTime::Duration' } );
  1046. # simple optimization
  1047. return $self if $dur->is_zero;
  1048. my %deltas = $dur->deltas;
  1049. # This bit isn't quite right since DateTime::Infinite::Future -
  1050. # infinite duration should NaN
  1051. foreach my $val ( values %deltas )
  1052. {
  1053. my $inf;
  1054. if ( $val == INFINITY )
  1055. {
  1056. $inf = DateTime::Infinite::Future->new;
  1057. }
  1058. elsif ( $val == NEG_INFINITY )
  1059. {
  1060. $inf = DateTime::Infinite::Past->new;
  1061. }
  1062. if ($inf)
  1063. {
  1064. %$self = %$inf;
  1065. bless $self, ref $inf;
  1066. return $self;
  1067. }
  1068. }
  1069. return $self if $self->is_infinite;
  1070. if ( $deltas{days} )
  1071. {
  1072. $self->{local_rd_days} += $deltas{days};
  1073. $self->{utc_year} += int( $deltas{days} / 365 ) + 1;
  1074. }
  1075. if ( $deltas{months} )
  1076. {
  1077. # For preserve mode, if it is the last day of the month, make
  1078. # it the 0th day of the following month (which then will
  1079. # normalize back to the last day of the new month).
  1080. my ($y, $m, $d) = ( $dur->is_preserve_mode ?
  1081. $self->_rd2ymd( $self->{local_rd_days} + 1 ) :
  1082. $self->_rd2ymd( $self->{local_rd_days} )
  1083. );
  1084. $d -= 1 if $dur->is_preserve_mode;
  1085. if ( ! $dur->is_wrap_mode && $d > 28 )
  1086. {
  1087. # find the rd for the last day of our target month
  1088. $self->{local_rd_days} = $self->_ymd2rd( $y, $m + $deltas{months} + 1, 0 );
  1089. # what day of the month is it? (discard year and month)
  1090. my $last_day = ($self->_rd2ymd( $self->{local_rd_days} ))[2];
  1091. # if our original day was less than the last day,
  1092. # use that instead
  1093. $self->{local_rd_days} -= $last_day - $d if $last_day > $d;
  1094. }
  1095. else
  1096. {
  1097. $self->{local_rd_days} = $self->_ymd2rd( $y, $m + $deltas{months}, $d );
  1098. }
  1099. $self->{utc_year} += int( $deltas{months} / 12 ) + 1;
  1100. }
  1101. if ( $deltas{days} || $deltas{months} )
  1102. {
  1103. $self->_calc_utc_rd;
  1104. $self->_handle_offset_modifier( $self->second );
  1105. }
  1106. if ( $deltas{minutes} )
  1107. {
  1108. $self->{utc_rd_secs} += $deltas{minutes} * 60;
  1109. # This intentionally ignores leap seconds
  1110. $self->_normalize_tai_seconds( $self->{utc_rd_days}, $self->{utc_rd_secs} );
  1111. }
  1112. if ( $deltas{seconds} || $deltas{nanoseconds} )
  1113. {
  1114. $self->{utc_rd_secs} += $deltas{seconds};
  1115. if ( $deltas{nanoseconds} )
  1116. {
  1117. $self->{rd_nanosecs} += $deltas{nanoseconds};
  1118. $self->_normalize_nanoseconds( $self->{utc_rd_secs}, $self->{rd_nanosecs} );
  1119. }
  1120. $self->_normalize_seconds;
  1121. # This might be some big number much bigger than 60, but
  1122. # that's ok (there are tests in 19leap_second.t to confirm
  1123. # that)
  1124. $self->_handle_offset_modifier( $self->second + $deltas{seconds} );
  1125. }
  1126. my $new =
  1127. (ref $self)->from_object
  1128. ( object => $self,
  1129. locale => $self->{locale},
  1130. ( $self->{formatter} ? ( formatter => $self->{formatter} ) : () ),
  1131. );
  1132. %$self = %$new;
  1133. return $self;
  1134. }
  1135. sub _compare_overload
  1136. {
  1137. # note: $_[1]->compare( $_[0] ) is an error when $_[1] is not a
  1138. # DateTime (such as the INFINITY value)
  1139. return $_[2] ? - $_[0]->compare( $_[1] ) : $_[0]->compare( $_[1] );
  1140. }
  1141. sub compare
  1142. {
  1143. shift->_compare( @_, 0 );
  1144. }
  1145. sub compare_ignore_floating
  1146. {
  1147. shift->_compare( @_, 1 );
  1148. }
  1149. sub _compare
  1150. {
  1151. my ( $class, $dt1, $dt2, $consistent ) = ref $_[0] ? ( undef, @_ ) : @_;
  1152. return undef unless defined $dt2;
  1153. if ( ! ref $dt2 && ( $dt2 == INFINITY || $dt2 == NEG_INFINITY ) )
  1154. {
  1155. return $dt1->{utc_rd_days} <=> $dt2;
  1156. }
  1157. unless ( DateTime::Helpers::can( $dt1, 'utc_rd_values' )
  1158. && DateTime::Helpers::can( $dt2, 'utc_rd_values' ) )
  1159. {
  1160. my $dt1_string = overload::StrVal($dt1);
  1161. my $dt2_string = overload::StrVal($dt2);
  1162. Carp::croak( "A DateTime object can only be compared to"
  1163. . " another DateTime object ($dt1_string, $dt2_string)." );
  1164. }
  1165. if ( ! $consistent &&
  1166. DateTime::Helpers::can( $dt1, 'time_zone' ) &&
  1167. DateTime::Helpers::can( $dt2, 'time_zone' )
  1168. )
  1169. {
  1170. my $is_floating1 = $dt1->time_zone->is_floating;
  1171. my $is_floating2 = $dt2->time_zone->is_floating;
  1172. if ( $is_floating1 && ! $is_floating2 )
  1173. {
  1174. $dt1 = $dt1->clone->set_time_zone( $dt2->time_zone );
  1175. }
  1176. elsif ( $is_floating2 && ! $is_floating1 )
  1177. {
  1178. $dt2 = $dt2->clone->set_time_zone( $dt1->time_zone );
  1179. }
  1180. }
  1181. my @dt1_components = $dt1->utc_rd_values;
  1182. my @dt2_components = $dt2->utc_rd_values;
  1183. foreach my $i ( 0..2 )
  1184. {
  1185. return $dt1_components[$i] <=> $dt2_components[$i]
  1186. if $dt1_components[$i] != $dt2_components[$i]
  1187. }
  1188. return 0;
  1189. }
  1190. sub _string_equals_overload
  1191. {
  1192. my ( $class, $dt1, $dt2 ) = ref $_[0] ? ( undef, @_ ) : @_;
  1193. return unless
  1194. ( DateTime::Helpers::can( $dt1, 'utc_rd_values' )
  1195. && DateTime::Helpers::can( $dt2, 'utc_rd_values' )
  1196. );
  1197. $class ||= ref $dt1;
  1198. return ! $class->compare( $dt1, $dt2 );
  1199. }
  1200. sub _string_not_equals_overload
  1201. {
  1202. return ! _string_equals_overload(@_);
  1203. }
  1204. sub _normalize_nanoseconds
  1205. {
  1206. use integer;
  1207. # seconds, nanoseconds
  1208. if ( $_[2] < 0 )
  1209. {
  1210. my $overflow = 1 + $_[2] / MAX_NANOSECONDS;
  1211. $_[2] += $overflow * MAX_NANOSECONDS;
  1212. $_[1] -= $overflow;
  1213. }
  1214. elsif ( $_[2] >= MAX_NANOSECONDS )
  1215. {
  1216. my $overflow = $_[2] / MAX_NANOSECONDS;
  1217. $_[2] -= $overflow * MAX_NANOSECONDS;
  1218. $_[1] += $overflow;
  1219. }
  1220. }
  1221. # Many of the same parameters as new() but all of them are optional,
  1222. # and there are no defaults.
  1223. my $SetValidate =
  1224. { map { my %copy = %{ $BasicValidate->{$_} };
  1225. delete $copy{default};
  1226. $copy{optional} = 1;
  1227. $_ => \%copy }
  1228. keys %$BasicValidate };
  1229. sub set
  1230. {
  1231. my $self = shift;
  1232. my %p = validate( @_, $SetValidate );
  1233. my %old_p =
  1234. ( map { $_ => $self->$_() }
  1235. qw( year month day hour minute second nanosecond locale time_zone )
  1236. );
  1237. my $new_dt = (ref $self)->new( %old_p, %p );
  1238. %$self = %$new_dt;
  1239. return $self;
  1240. }
  1241. sub set_year { $_[0]->set( year => $_[1] ) }
  1242. sub set_month { $_[0]->set( month => $_[1] ) }
  1243. sub set_day { $_[0]->set( day => $_[1] ) }
  1244. sub set_hour { $_[0]->set( hour => $_[1] ) }
  1245. sub set_minute { $_[0]->set( minute => $_[1] ) }
  1246. sub set_second { $_[0]->set( second => $_[1] ) }
  1247. sub set_nanosecond { $_[0]->set( nanosecond => $_[1] ) }
  1248. sub set_locale { $_[0]->set( locale => $_[1] ) }
  1249. sub set_formatter { $_[0]->{formatter} = $_[1] }
  1250. sub truncate
  1251. {
  1252. my $self = shift;
  1253. my %p = validate( @_,
  1254. { to =>
  1255. { regex => qr/^(?:year|month|week|day|hour|minute|second)$/ },
  1256. },
  1257. );
  1258. my %new = ( locale => $self->{locale},
  1259. time_zone => $self->{tz},
  1260. );
  1261. if ( $p{to} eq 'week' )
  1262. {
  1263. my $day_diff = $self->day_of_week - 1;
  1264. if ($day_diff)
  1265. {
  1266. $self->add( days => -1 * $day_diff );
  1267. }
  1268. return $self->truncate( to => 'day' );
  1269. }
  1270. else
  1271. {
  1272. foreach my $f ( qw( year month day hour minute second ) )
  1273. {
  1274. $new{$f} = $self->$f();
  1275. last if $p{to} eq $f;
  1276. }
  1277. }
  1278. my $new_dt = (ref $self)->new(%new);
  1279. %$self = %$new_dt;
  1280. return $self;
  1281. }
  1282. sub set_time_zone
  1283. {
  1284. my ( $self, $tz ) = @_;
  1285. # This is a bit of a hack but it works because time zone objects
  1286. # are singletons, and if it doesn't work all we lose is a little
  1287. # bit of speed.
  1288. return $self if $self->{tz} eq $tz;
  1289. my $was_floating = $self->{tz}->is_floating;
  1290. $self->{tz} = ref $tz ? $tz : DateTime::TimeZone->new( name => $tz );
  1291. $self->_handle_offset_modifier( $self->second, 1 );
  1292. # if it either was or now is floating (but not both)
  1293. if ( $self->{tz}->is_floating xor $was_floating )
  1294. {
  1295. $self->_calc_utc_rd;
  1296. }
  1297. elsif ( ! $was_floating )
  1298. {
  1299. $self->_calc_local_rd;
  1300. }
  1301. return $self;
  1302. }
  1303. sub STORABLE_freeze
  1304. {
  1305. my $self = shift;
  1306. my $cloning = shift;
  1307. my $serialized = '';
  1308. foreach my $key ( qw( utc_rd_days
  1309. utc_rd_secs
  1310. rd_nanosecs ) )
  1311. {
  1312. $serialized .= "$key:$self->{$key}|";
  1313. }
  1314. # not used yet, but may be handy in the future.
  1315. $serialized .= "version:$VERSION";
  1316. # Formatter needs to be returned as a reference since it may be
  1317. # undef or a class name, and Storable will complain if extra
  1318. # return values aren't refs
  1319. return $serialized, $self->{locale}, $self->{tz}, \$self->{formatter};
  1320. }
  1321. sub STORABLE_thaw
  1322. {
  1323. my $self = shift;
  1324. my $cloning = shift;
  1325. my $serialized = shift;
  1326. my %serialized = map { split /:/ } split /\|/, $serialized;
  1327. my ( $locale, $tz, $formatter );
  1328. # more recent code version
  1329. if (@_)
  1330. {
  1331. ( $locale, $tz, $formatter ) = @_;
  1332. }
  1333. else
  1334. {
  1335. $tz = DateTime::TimeZone->new( name => delete $serialized{tz} );
  1336. $locale =
  1337. DateTime::Locale->load( exists $serialized{language}
  1338. ? delete $serialized{language}
  1339. : delete $serialized{locale}
  1340. );
  1341. }
  1342. delete $serialized{version};
  1343. my $object = bless { utc_vals => [ $serialized{utc_rd_days},
  1344. $serialized{utc_rd_secs},
  1345. $serialized{rd_nanosecs},
  1346. ],
  1347. tz => $tz,
  1348. }, 'DateTime::_Thawed';
  1349. my %formatter = defined $$formatter ? ( formatter => $$formatter ) : ();
  1350. my $new = (ref $self)->from_object( object => $object,
  1351. locale => $locale,
  1352. %formatter,
  1353. );
  1354. %$self = %$new;
  1355. return $self;
  1356. }
  1357. package DateTime::_Thawed;
  1358. sub utc_rd_values { @{ $_[0]->{utc_vals} } }
  1359. sub time_zone { $_[0]->{tz} }
  1360. 1;
  1361. __END__
  1362. =head1 NAME
  1363. DateTime - A date and time object
  1364. =head1 SYNOPSIS
  1365. use DateTime;
  1366. $dt = DateTime->new( year => 1964,
  1367. month => 10,
  1368. day => 16,
  1369. hour => 16,
  1370. minute => 12,
  1371. second => 47,
  1372. nanosecond => 500000000,
  1373. time_zone => 'Asia/Taipei',
  1374. );
  1375. $dt = DateTime->from_epoch( epoch => $epoch );
  1376. $dt = DateTime->now; # same as ( epoch => time() )
  1377. $year = $dt->year;
  1378. $month = $dt->month; # 1-12 - also mon
  1379. $day = $dt->day; # 1-31 - also day_of_month, mday
  1380. $dow = $dt->day_of_week; # 1-7 (Monday is 1) - also dow, wday
  1381. $hour = $dt->hour; # 0-23
  1382. $minute = $dt->minute; # 0-59 - also min
  1383. $second = $dt->second; # 0-61 (leap seconds!) - also sec
  1384. $doy = $dt->day_of_year; # 1-366 (leap years) - also doy
  1385. $doq = $dt->day_of_quarter; # 1.. - also doq
  1386. $qtr = $dt->quarter; # 1-4
  1387. # all of the start-at-1 methods above have correponding start-at-0
  1388. # methods, such as $dt->day_of_month_0, $dt->month_0 and so on
  1389. $ymd = $dt->ymd; # 2002-12-06
  1390. $ymd = $dt->ymd('/'); # 2002/12/06 - also date
  1391. $mdy = $dt->mdy; # 12-06-2002
  1392. $mdy = $dt->mdy('/'); # 12/06/2002
  1393. $dmy = $dt->dmy; # 06-12-2002
  1394. $dmy = $dt->dmy('/'); # 06/12/2002
  1395. $hms = $dt->hms; # 14:02:29
  1396. $hms = $dt->hms('!'); # 14!02!29 - also time
  1397. $is_leap = $dt->is_leap_year;
  1398. # these are localizable, see Locales section
  1399. $month_name = $dt->month_name; # January, February, ...
  1400. $month_abbr = $dt->month_abbr; # Jan, Feb, ...
  1401. $day_name = $dt->day_name; # Monday, Tuesday, ...
  1402. $day_abbr = $dt->day_abbr; # Mon, Tue, ...
  1403. $epoch_time = $dt->epoch;
  1404. # may return undef if the datetime is outside the range that is
  1405. # representable by your OS's epoch system.
  1406. $dt2 = $dt + $duration_object;
  1407. $dt3 = $dt - $duration_object;
  1408. $duration_object = $dt - $dt2;
  1409. $dt->set( year => 1882 );
  1410. $dt->set_time_zone( 'America/Chicago' );
  1411. $dt->set_formatter( $formatter );
  1412. =head1 DESCRIPTION
  1413. DateTime is a class for the representation of date/time combinations,
  1414. and is part of the Perl DateTime project. For details on this project
  1415. please see L<http://datetime.perl.org/>. The DateTime site has a FAQ
  1416. which may help answer many "how do I do X?" questions. The FAQ is at
  1417. L<http://datetime.perl.org/?FAQ>.
  1418. It represents the Gregorian calendar, extended backwards in time
  1419. before its creation (in 1582). This is sometimes known as the
  1420. "proleptic Gregorian calendar". In this calendar, the first day of
  1421. the calendar (the epoch), is the first day of year 1, which
  1422. corresponds to the date which was (incorrectly) believed to be the
  1423. birth of Jesus Christ.
  1424. The calendar represented does have a year 0, and in that way differs
  1425. from how dates are often written using "BCE/CE" or "BC/AD".
  1426. For infinite datetimes, please see the
  1427. L<DateTime::Infinite|DateTime::Infinite> module.
  1428. =head1 USAGE
  1429. =head2 0-based Versus 1-based Numbers
  1430. The DateTime.pm module follows a simple consistent logic for
  1431. determining whether or not a given number is 0-based or 1-based.
  1432. Month, day of month, day of week, and day of year are 1-based. Any
  1433. method that is 1-based also has an equivalent 0-based method ending in
  1434. "_0". So for example, this class provides both C<day_of_week()> and
  1435. C<day_of_week_0()> methods.
  1436. The C<day_of_week_0()> method still treats Monday as the first day of
  1437. the week.
  1438. All I<time>-related numbers such as hour, minute, and second are
  1439. 0-based.
  1440. Years are neither, as they can be both positive or negative, unlike
  1441. any other datetime component. There I<is> a year 0.
  1442. There is no C<quarter_0()> method.
  1443. =head2 Error Handling
  1444. Some errors may cause this module to die with an error string. This
  1445. can only happen when calling constructor methods, methods that change
  1446. the object, such as C<set()>, or methods that take parameters.
  1447. Methods that retrieve information about the object, such as C<year()>
  1448. or C<epoch()>, will never die.
  1449. =head2 Locales
  1450. All the object methods which return names or abbreviations return data
  1451. based on a locale. This is done by setting the locale when
  1452. constructing a DateTime object. There is also a C<DefaultLocale()>
  1453. class method which may be used to set the default locale for all
  1454. DateTime objects created. If this is not set, then "en_US" is used.
  1455. Some locales may return data as Unicode. When using Perl 5.6.0 or
  1456. greater, this will be a native Perl Unicode string. When using older
  1457. Perls, this will be a sequence of bytes representing the Unicode
  1458. character.
  1459. =head2 Floating DateTimes
  1460. The default time zone for new DateTime objects, except where stated
  1461. otherwise, is the "floating" time zone. This concept comes from the
  1462. iCal standard. A floating datetime is one which is not anchored to
  1463. any particular time zone. In addition, floating datetimes do not
  1464. include leap seconds, since we cannot apply them without knowing the
  1465. datetime's time zone.
  1466. The results of date math and comparison between a floating datetime
  1467. and one with a real time zone are not really valid, because one
  1468. includes leap seconds and the other does not. Similarly, the results
  1469. of datetime math between two floating datetimes and two datetimes with
  1470. time zones are not really comparable.
  1471. If you are planning to use any objects with a real time zone, it is
  1472. strongly recommended that you B<do not> mix these with floating
  1473. datetimes.
  1474. =head2 Math
  1475. If you are going to be using doing date math, please read the section
  1476. L<How Datetime Math is Done>.
  1477. =head2 Time Zone Warning
  1478. Do not try to use named time zones (like "America/Chicago") with dates
  1479. very far in the future (thousands of years). The current
  1480. implementation of C<DateTime::TimeZone> will use a huge amount of
  1481. memory calculating all the DST changes from now until the future
  1482. date. Use UTC or the floating time zone and you will be safe.
  1483. =head2 Methods
  1484. =head3 Constructors
  1485. All constructors can die when invalid parameters are given.
  1486. =over 4
  1487. =item * new( ... )
  1488. This class method accepts parameters for each date and time component:
  1489. "year", "month", "day", "hour", "minute", "second", "nanosecond".
  1490. It also accepts "locale", "time_zone", and "formatter" parameters.
  1491. my $dt = DateTime->new( year => 1066,
  1492. month => 10,
  1493. day => 25,
  1494. hour => 7,
  1495. minute => 15,
  1496. second => 47,
  1497. nanosecond => 500000000,
  1498. time_zone => 'America/Chicago',
  1499. );
  1500. DateTime validates the "month", "day", "hour", "minute", and "second",
  1501. and "nanosecond" parameters. The valid values for these parameters are:
  1502. =over 8
  1503. =item * month
  1504. 1-12
  1505. =item * day
  1506. 1-31, and it must be within the valid range of days for the specified
  1507. month
  1508. =item * hour
  1509. 0-23
  1510. =item * minute
  1511. 0-59
  1512. =item * second
  1513. 0-61 (to allow for leap seconds). Values of 60 or 61 are only allowed
  1514. when they match actual leap seconds.
  1515. =item * nanosecond
  1516. >= 0
  1517. =back
  1518. =back
  1519. Invalid parameter types (like an array reference) will cause the
  1520. constructor to die.
  1521. The value for seconds may be from 0 to 61, to account for leap
  1522. seconds. If you give a value greater than 59, DateTime does check to
  1523. see that it really matches a valid leap second.
  1524. All of the parameters are optional except for "year". The "month" and
  1525. "day" parameters both default to 1, while the "hour", "minute",
  1526. "second", and "nanosecond" parameters all default to 0.
  1527. The "locale" parameter should be a string matching one of the valid
  1528. locales, or a C<DateTime::Locale> object. See the
  1529. L<DateTime::Locale|DateTime::Locale> documentation for details.
  1530. The time_zone parameter can be either a scalar or a
  1531. C<DateTime::TimeZone> object. A string will simply be passed to the
  1532. C<< DateTime::TimeZone->new >> method as its "name" parameter. This
  1533. string may be an Olson DB time zone name ("America/Chicago"), an
  1534. offset string ("+0630"), or the words "floating" or "local". See the
  1535. C<DateTime::TimeZone> documentation for more details.
  1536. The default time zone is "floating".
  1537. The "formatter" can be either a scalar or an object, but the class
  1538. specified by the scalar or the object must implement a
  1539. C<format_datetime()> method.
  1540. =head4 Ambiguous Local Times
  1541. Because of Daylight Saving Time, it is possible to specify a local
  1542. time that is ambiguous. For example, in the US in 2003, the
  1543. transition from to saving to standard time occurred on October 26, at
  1544. 02:00:00 local time. The local clock changed from 01:59:59 (saving
  1545. time) to 01:00:00 (standard time). This means that the hour from
  1546. 01:00:00 through 01:59:59 actually occurs twice, though the UTC time
  1547. continues to move forward.
  1548. If you specify an ambiguous time, then the latest UTC time is always
  1549. used, in effect always choosing standard time. In this case, you can
  1550. simply subtract an hour to the object in order to move to saving time,
  1551. for example:
  1552. # This object represent 01:30:00 standard time
  1553. my $dt = DateTime->new( year => 2003,
  1554. month => 10,
  1555. day => 26,
  1556. hour => 1,
  1557. minute => 30,
  1558. second => 0,
  1559. time_zone => 'America/Chicago',
  1560. );
  1561. print $dt->hms; # prints 01:30:00
  1562. # Now the object represent 01:30:00 saving time
  1563. $dt->subtract( hours => 1 );
  1564. print $dt->hms; # still prints 01:30:00
  1565. Alternately, you could create the object with the UTC time zone, and
  1566. then call the C<set_time_zone()> method to change the time zone. This
  1567. is a good way to ensure that the time is not ambiguous.
  1568. =head4 Invalid Local Times
  1569. Another problem introduced by Daylight Saving Time is that certain
  1570. local times just do not exist. For example, in the US in 2003, the
  1571. transition from standard to saving time occurred on April 6, at the
  1572. change to 2:00:00 local time. The local clock changes from 01:59:59
  1573. (standard time) to 03:00:00 (saving time). This means that there is
  1574. no 02:00:00 through 02:59:59 on April 6!
  1575. Attempting to create an invalid time currently causes a fatal error.
  1576. This may change in future version of this module.
  1577. =over 4
  1578. =item * from_epoch( epoch => $epoch, ... )
  1579. This class method can be used to construct a new DateTime object from
  1580. an epoch time instead of components. Just as with the C<new()>
  1581. method, it accepts "time_zone", "locale", and "formatter" parameters.
  1582. If the epoch value is not an integer, the part after the decimal will
  1583. be converted to nanoseconds. This is done in order to be compatible
  1584. with C<Time::HiRes>. If the floating portion extends past 9 decimal
  1585. places, it will be truncated to nine, so that 1.1234567891 will become
  1586. 1 second and 123,456,789 nanoseconds.
  1587. By default, the returned object will be in the UTC time zone.
  1588. =item * now( ... )
  1589. This class method is equivalent to calling C<from_epoch()> with the
  1590. value returned from Perl's C<time()> function. Just as with the
  1591. C<new()> method, it accepts "time_zone" and "locale" parameters.
  1592. By default, the returned object will be in the UTC time zone.
  1593. =item * today( ... )
  1594. This class method is equivalent to:
  1595. DateTime->now->truncate( to => 'day' );
  1596. =item * from_object( object => $object, ... )
  1597. This class method can be used to construct a new DateTime object from
  1598. any object that implements the C<utc_rd_values()> method. All
  1599. C<DateTime::Calendar> modules must implement this method in order to
  1600. provide cross-calendar compatibility. This method accepts a
  1601. "locale" and "formatter" parameter
  1602. If the object passed to this method has a C<time_zone()> method, that
  1603. is used to set the time zone of the newly created C<DateTime.pm>
  1604. object.
  1605. Otherwise, the returned object will be in the floating time zone.
  1606. =item * last_day_of_month( ... )
  1607. This constructor takes the same arguments as can be given to the
  1608. C<new()> method, except for "day". Additionally, both "year" and
  1609. "month" are required.
  1610. =item * from_day_of_year( ... )
  1611. This constructor takes the same arguments as can be given to the
  1612. C<new()> method, except that it does not accept a "month" or "day"
  1613. argument. Instead, it requires both "year" and "day_of_year". The
  1614. day of year must be between 1 and 366, and 366 is only allowed for
  1615. leap years.
  1616. =item * clone
  1617. This object method returns a new object that is replica of the object
  1618. upon which the method is called.
  1619. =back
  1620. =head3 "Get" Methods
  1621. This class has many methods for retrieving information about an
  1622. object.
  1623. =over 4
  1624. =item * year
  1625. Returns the year.
  1626. =item * ce_year
  1627. Returns the year according to the BCE/CE numbering system. The year
  1628. before year 1 in this system is year -1, aka "1 BCE".
  1629. =item * era_name
  1630. Returns the long name of the current era, something like "Before
  1631. Christ". See the L<Locales|/Locales> section for more details.
  1632. =item * era_abbr
  1633. Returns the abbreviated name of the current era, something like "BC".
  1634. See the L<Locales|/Locales> section for more details.
  1635. =item * christian_era
  1636. Returns a string, either "BC" or "AD", according to the year.
  1637. =item * secular_era
  1638. Returns a string, either "BCE" or "CE", according to the year.
  1639. =item * year_with_era
  1640. Returns a string containing the year immediately followed by its era
  1641. abbreviation. The year is the absolute value of C<ce_year()>, so that
  1642. year 1 is "1BC" and year 0 is "1AD".
  1643. =item * year_with_christian_era
  1644. Like C<year_with_era()>, but uses the christian_era() to get the era
  1645. name.
  1646. =item * year_with_secular_era
  1647. Like C<year_with_era()>, but uses the secular_era() method to get the
  1648. era name.
  1649. =item * month, mon
  1650. Returns the month of the year, from 1..12.
  1651. =item * month_name
  1652. Returns the name of the current month. See the
  1653. L<Locales|/Locales> section for more details.
  1654. =item * month_abbr
  1655. Returns the abbreviated name of the current month. See the
  1656. L<Locales|/Locales> section for more details.
  1657. =item * day_of_month, day, mday
  1658. Returns the day of the month, from 1..31.
  1659. =item * day_of_week, wday, dow
  1660. Returns the day of the week as a number, from 1..7, with 1 being
  1661. Monday and 7 being Sunday.
  1662. =item * day_name
  1663. Returns the name of the current day of the week. See the
  1664. L<Locales|/Locales> section for more details.
  1665. =item * day_abbr
  1666. Returns the abbreviated name of the current day of the week. See the
  1667. L<Locales|/Locales> section for more details.
  1668. =item * day_of_year, doy
  1669. Returns the day of the year.
  1670. =item * quarter
  1671. Returns the quarter of the year, from 1..4.
  1672. =item * quarter_name
  1673. Returns the name of the current quarter. See the
  1674. L<Locales|/Locales> section for more details.
  1675. =item * quarter_abbr
  1676. Returns the abbreviated name of the current quarter. See the
  1677. L<Locales|/Locales> section for more details.
  1678. =item * day_of_quarter, doq
  1679. Returns the day of the quarter.
  1680. =item * weekday_of_month
  1681. Returns a number from 1..5 indicating which week day of the month this
  1682. is. For example, June 9, 2003 is the second Monday of the month, and
  1683. so this method returns 2 for that day.
  1684. =item * ymd( $optional_separator ), date
  1685. =item * mdy( $optional_separator )
  1686. =item * dmy( $optional_separator )
  1687. Each method returns the year, month, and day, in the order indicated
  1688. by the method name. Years are zero-padded to four digits. Months and
  1689. days are 0-padded to two digits.
  1690. By default, the values are separated by a dash (-), but this can be
  1691. overridden by passing a value to the method.
  1692. =item * hour
  1693. Returns the hour of the day, from 0..23.
  1694. =item * hour_1
  1695. Returns the hour of the day, from 1..24.
  1696. =item * hour_12
  1697. Returns the hour of the day, from 1..12.
  1698. =item * hour_12_0
  1699. Returns the hour of the day, from 0..11.
  1700. =item * minute, min
  1701. Returns the minute of the hour, from 0..59.
  1702. =item * second, sec
  1703. Returns the second, from 0..61. The values 60 and 61 are used for
  1704. leap seconds.
  1705. =item * fractional_second
  1706. Returns the second, as a real number from 0.0 until 61.999999999
  1707. The values 60 and 61 are used for leap seconds.
  1708. =item * millisecond
  1709. Returns the fractional part of the second as milliseconds (1E-3 seconds).
  1710. Half a second is 500 milliseconds.
  1711. =item * microsecond
  1712. Returns the fractional part of the second as microseconds (1E-6
  1713. seconds). This value will be rounded to an integer.
  1714. Half a second is 500_000 microseconds. This value will be rounded to
  1715. an integer.
  1716. =item * nanosecond
  1717. Returns the fractional part of the second as nanoseconds (1E-9 seconds).
  1718. Half a second is 500_000_000 nanoseconds.
  1719. =item * hms( $optional_separator ), time
  1720. Returns the hour, minute, and second, all zero-padded to two digits.
  1721. If no separator is specified, a colon (:) is used by default.
  1722. =item * datetime, iso8601
  1723. This method is equivalent to:
  1724. $dt->ymd('-') . 'T' . $dt->hms(':')
  1725. =item * is_leap_year
  1726. This method returns a true or false indicating whether or not the
  1727. datetime object is in a leap year.
  1728. =item * week
  1729. ($week_year, $week_number) = $dt->week;
  1730. Returns information about the calendar week which contains this
  1731. datetime object. The values returned by this method are also available
  1732. separately through the week_year and week_number methods.
  1733. The first week of the year is defined by ISO as the one which contains
  1734. the fourth day of January, which is equivalent to saying that it's the
  1735. first week to overlap the new year by at least four days.
  1736. Typically the week year will be the same as the year that the object
  1737. is in, but dates at the very beginning of a calendar year often end up
  1738. in the last week of the prior year, and similarly, the final few days
  1739. of the year may be placed in the first week of the next year.
  1740. =item * week_year
  1741. Returns the year of the week.
  1742. =item * week_number
  1743. Returns the week of the year, from 1..53.
  1744. =item * week_of_month
  1745. The week of the month, from 0..5. The first week of the month is the
  1746. first week that contains a Thursday. This is based on the ICU
  1747. definition of week of month, and correlates to the ISO8601 week of
  1748. year definition. A day in the week I<before> the week with the first
  1749. Thursday will be week 0.
  1750. =item * jd, mjd
  1751. These return the Julian Day and Modified Julian Day, respectively.
  1752. The value returned is a floating point n