← Index
NYTProf Performance Profile   « block view • line view • sub view »
For xt/tapper-mcp-scheduler-with-db-longrun.t
  Run on Tue May 22 17:18:39 2012
Reported on Tue May 22 17:22:37 2012

Filename/2home/ss5/perl5/perlbrew/perls/perl-5.12.3/lib/site_perl/5.12.3/x86_64-linux/DateTime.pm
StatementsExecuted 31458 statements in 163ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
2941126.0ms101msDateTime::::_new DateTime::_new
2941115.2ms166msDateTime::::from_epoch DateTime::from_epoch
5901112.7ms15.1msDateTime::::_calc_local_components DateTime::_calc_local_components
5882110.4ms16.8msDateTime::::_handle_offset_modifier DateTime::_handle_offset_modifier
294119.86ms59.5msDateTime::::set_time_zone DateTime::set_time_zone
590428.44ms24.3msDateTime::::_calc_local_rd DateTime::_calc_local_rd
296325.41ms7.02msDateTime::::_calc_utc_rd DateTime::_calc_utc_rd
294113.94ms3.94msDateTime::::clone DateTime::clone
294113.66ms4.61msDateTime::::ymd DateTime::ymd
1112.64ms8.01msDateTime::::BEGIN@48 DateTime::BEGIN@48
294222.49ms168msDateTime::::now DateTime::now
294112.18ms2.81msDateTime::::_offset_for_local_datetime DateTime::_offset_for_local_datetime
294112.02ms2.02msDateTime::::hms DateTime::hms
294111.86ms2.53msDateTime::::offset DateTime::offset
295211.79ms5.46msDateTime::::DefaultLocale DateTime::DefaultLocale
1111.65ms1.90msDateTime::::BEGIN@46 DateTime::BEGIN@46
588111.46ms1.46msDateTime::::_rd2ymd DateTime::_rd2ymd (xsub)
1111.44ms58.1msDateTime::::BEGIN@47 DateTime::BEGIN@47
294111.30ms1.30msDateTime::::second DateTime::second
294111.24ms1.24msDateTime::::CORE:match DateTime::CORE:match (opcode)
294111.13ms1.13msDateTime::::_normalize_nanoseconds DateTime::_normalize_nanoseconds
29411953µs953µsDateTime::::year DateTime::year
58811933µs933µsDateTime::::_seconds_as_components DateTime::_seconds_as_components (xsub)
111932µs1.30msDateTime::::BEGIN@49 DateTime::BEGIN@49
29411895µs895µsDateTime::::_ymd2rd DateTime::_ymd2rd (xsub)
29611855µs855µsDateTime::::_normalize_tai_seconds DateTime::_normalize_tai_seconds (xsub)
111775µs3.88msDateTime::::BEGIN@13 DateTime::BEGIN@13
29411515µs515µsDateTime::::_time_as_seconds DateTime::_time_as_seconds (xsub)
111179µs182µsDateTime::::BEGIN@704 DateTime::BEGIN@704
111171µs206µsDateTime::::BEGIN@12 DateTime::BEGIN@12
593183µs83µsDateTime::::CORE:qr DateTime::CORE:qr (opcode)
11143µs43µsDateTime::::CORE:regcomp DateTime::CORE:regcomp (opcode)
11127µs27µsDateTime::::BEGIN@6 DateTime::BEGIN@6
11122µs27µsDateTime::::BEGIN@1858 DateTime::BEGIN@1858
11113µs56µsDateTime::::BEGIN@11 DateTime::BEGIN@11
11113µs73µsDateTime::::BEGIN@50 DateTime::BEGIN@50
1118µs93µsDateTime::::BEGIN@59 DateTime::BEGIN@59
1117µs7µsDateTime::::BEGIN@86 DateTime::BEGIN@86
1116µs14µsDateTime::::BEGIN@9 DateTime::BEGIN@9
1116µs35µsDateTime::::BEGIN@74 DateTime::BEGIN@74
1116µs8µsDateTime::::BEGIN@8 DateTime::BEGIN@8
1115µs27µsDateTime::::BEGIN@77 DateTime::BEGIN@77
1115µs28µsDateTime::::BEGIN@78 DateTime::BEGIN@78
1115µs30µsDateTime::::BEGIN@76 DateTime::BEGIN@76
1115µs28µsDateTime::::BEGIN@80 DateTime::BEGIN@80
1115µs28µsDateTime::::BEGIN@82 DateTime::BEGIN@82
0000s0sDateTime::::STORABLE_freeze DateTime::STORABLE_freeze
0000s0sDateTime::::STORABLE_thaw DateTime::STORABLE_thaw
0000s0sDateTime::_Thawed::::time_zoneDateTime::_Thawed::time_zone
0000s0sDateTime::_Thawed::::utc_rd_valuesDateTime::_Thawed::utc_rd_values
0000s0sDateTime::::__ANON__[:1000] DateTime::__ANON__[:1000]
0000s0sDateTime::::__ANON__[:1001] DateTime::__ANON__[:1001]
0000s0sDateTime::::__ANON__[:1002] DateTime::__ANON__[:1002]
0000s0sDateTime::::__ANON__[:1004] DateTime::__ANON__[:1004]
0000s0sDateTime::::__ANON__[:1005] DateTime::__ANON__[:1005]
0000s0sDateTime::::__ANON__[:1006] DateTime::__ANON__[:1006]
0000s0sDateTime::::__ANON__[:1007] DateTime::__ANON__[:1007]
0000s0sDateTime::::__ANON__[:1008] DateTime::__ANON__[:1008]
0000s0sDateTime::::__ANON__[:1009] DateTime::__ANON__[:1009]
0000s0sDateTime::::__ANON__[:1010] DateTime::__ANON__[:1010]
0000s0sDateTime::::__ANON__[:1011] DateTime::__ANON__[:1011]
0000s0sDateTime::::__ANON__[:1012] DateTime::__ANON__[:1012]
0000s0sDateTime::::__ANON__[:1016] DateTime::__ANON__[:1016]
0000s0sDateTime::::__ANON__[:1017] DateTime::__ANON__[:1017]
0000s0sDateTime::::__ANON__[:1021] DateTime::__ANON__[:1021]
0000s0sDateTime::::__ANON__[:1025] DateTime::__ANON__[:1025]
0000s0sDateTime::::__ANON__[:1028] DateTime::__ANON__[:1028]
0000s0sDateTime::::__ANON__[:1031] DateTime::__ANON__[:1031]
0000s0sDateTime::::__ANON__[:1032] DateTime::__ANON__[:1032]
0000s0sDateTime::::__ANON__[:1033] DateTime::__ANON__[:1033]
0000s0sDateTime::::__ANON__[:1034] DateTime::__ANON__[:1034]
0000s0sDateTime::::__ANON__[:1035] DateTime::__ANON__[:1035]
0000s0sDateTime::::__ANON__[:1036] DateTime::__ANON__[:1036]
0000s0sDateTime::::__ANON__[:1085] DateTime::__ANON__[:1085]
0000s0sDateTime::::__ANON__[:1090] DateTime::__ANON__[:1090]
0000s0sDateTime::::__ANON__[:1098] DateTime::__ANON__[:1098]
0000s0sDateTime::::__ANON__[:1099] DateTime::__ANON__[:1099]
0000s0sDateTime::::__ANON__[:1100] DateTime::__ANON__[:1100]
0000s0sDateTime::::__ANON__[:1102] DateTime::__ANON__[:1102]
0000s0sDateTime::::__ANON__[:1107] DateTime::__ANON__[:1107]
0000s0sDateTime::::__ANON__[:1112] DateTime::__ANON__[:1112]
0000s0sDateTime::::__ANON__[:1116] DateTime::__ANON__[:1116]
0000s0sDateTime::::__ANON__[:1118] DateTime::__ANON__[:1118]
0000s0sDateTime::::__ANON__[:1121] DateTime::__ANON__[:1121]
0000s0sDateTime::::__ANON__[:1125] DateTime::__ANON__[:1125]
0000s0sDateTime::::__ANON__[:1129] DateTime::__ANON__[:1129]
0000s0sDateTime::::__ANON__[:1132] DateTime::__ANON__[:1132]
0000s0sDateTime::::__ANON__[:1136] DateTime::__ANON__[:1136]
0000s0sDateTime::::__ANON__[:1137] DateTime::__ANON__[:1137]
0000s0sDateTime::::__ANON__[:1140] DateTime::__ANON__[:1140]
0000s0sDateTime::::__ANON__[:1144] DateTime::__ANON__[:1144]
0000s0sDateTime::::__ANON__[:1146] DateTime::__ANON__[:1146]
0000s0sDateTime::::__ANON__[:1149] DateTime::__ANON__[:1149]
0000s0sDateTime::::__ANON__[:1153] DateTime::__ANON__[:1153]
0000s0sDateTime::::__ANON__[:1159] DateTime::__ANON__[:1159]
0000s0sDateTime::::__ANON__[:1164] DateTime::__ANON__[:1164]
0000s0sDateTime::::__ANON__[:1169] DateTime::__ANON__[:1169]
0000s0sDateTime::::__ANON__[:1172] DateTime::__ANON__[:1172]
0000s0sDateTime::::__ANON__[:1176] DateTime::__ANON__[:1176]
0000s0sDateTime::::__ANON__[:1178] DateTime::__ANON__[:1178]
0000s0sDateTime::::__ANON__[:1183] DateTime::__ANON__[:1183]
0000s0sDateTime::::__ANON__[:1184] DateTime::__ANON__[:1184]
0000s0sDateTime::::__ANON__[:1186] DateTime::__ANON__[:1186]
0000s0sDateTime::::__ANON__[:1188] DateTime::__ANON__[:1188]
0000s0sDateTime::::__ANON__[:1195] DateTime::__ANON__[:1195]
0000s0sDateTime::::__ANON__[:1198] DateTime::__ANON__[:1198]
0000s0sDateTime::::__ANON__[:1201] DateTime::__ANON__[:1201]
0000s0sDateTime::::__ANON__[:1212] DateTime::__ANON__[:1212]
0000s0sDateTime::::__ANON__[:1214] DateTime::__ANON__[:1214]
0000s0sDateTime::::__ANON__[:1216] DateTime::__ANON__[:1216]
0000s0sDateTime::::__ANON__[:1217] DateTime::__ANON__[:1217]
0000s0sDateTime::::__ANON__[:1221] DateTime::__ANON__[:1221]
0000s0sDateTime::::__ANON__[:1223] DateTime::__ANON__[:1223]
0000s0sDateTime::::__ANON__[:1224] DateTime::__ANON__[:1224]
0000s0sDateTime::::__ANON__[:1225] DateTime::__ANON__[:1225]
0000s0sDateTime::::__ANON__[:1226] DateTime::__ANON__[:1226]
0000s0sDateTime::::__ANON__[:1227] DateTime::__ANON__[:1227]
0000s0sDateTime::::__ANON__[:123] DateTime::__ANON__[:123]
0000s0sDateTime::::__ANON__[:131] DateTime::__ANON__[:131]
0000s0sDateTime::::__ANON__[:139] DateTime::__ANON__[:139]
0000s0sDateTime::::__ANON__[:147] DateTime::__ANON__[:147]
0000s0sDateTime::::__ANON__[:155] DateTime::__ANON__[:155]
0000s0sDateTime::::__ANON__[:163] DateTime::__ANON__[:163]
0000s0sDateTime::::__ANON__[:170] DateTime::__ANON__[:170]
0000s0sDateTime::::__ANON__[:186] DateTime::__ANON__[:186]
0000s0sDateTime::::__ANON__[:620] DateTime::__ANON__[:620]
0000s0sDateTime::::__ANON__[:981] DateTime::__ANON__[:981]
0000s0sDateTime::::__ANON__[:982] DateTime::__ANON__[:982]
0000s0sDateTime::::__ANON__[:983] DateTime::__ANON__[:983]
0000s0sDateTime::::__ANON__[:984] DateTime::__ANON__[:984]
0000s0sDateTime::::__ANON__[:987] DateTime::__ANON__[:987]
0000s0sDateTime::::__ANON__[:988] DateTime::__ANON__[:988]
0000s0sDateTime::::__ANON__[:989] DateTime::__ANON__[:989]
0000s0sDateTime::::__ANON__[:990] DateTime::__ANON__[:990]
0000s0sDateTime::::__ANON__[:991] DateTime::__ANON__[:991]
0000s0sDateTime::::__ANON__[:992] DateTime::__ANON__[:992]
0000s0sDateTime::::__ANON__[:993] DateTime::__ANON__[:993]
0000s0sDateTime::::__ANON__[:994] DateTime::__ANON__[:994]
0000s0sDateTime::::__ANON__[:995] DateTime::__ANON__[:995]
0000s0sDateTime::::__ANON__[:996] DateTime::__ANON__[:996]
0000s0sDateTime::::__ANON__[:997] DateTime::__ANON__[:997]
0000s0sDateTime::::__ANON__[:998] DateTime::__ANON__[:998]
0000s0sDateTime::::__ANON__[:999] DateTime::__ANON__[:999]
0000s0sDateTime::::_add_overload DateTime::_add_overload
0000s0sDateTime::::_adjust_for_positive_difference DateTime::_adjust_for_positive_difference
0000s0sDateTime::::_calc_utc_components DateTime::_calc_utc_components
0000s0sDateTime::::_cldr_pattern DateTime::_cldr_pattern
0000s0sDateTime::::_compare DateTime::_compare
0000s0sDateTime::::_compare_overload DateTime::_compare_overload
0000s0sDateTime::::_era_index DateTime::_era_index
0000s0sDateTime::::_format_nanosecs DateTime::_format_nanosecs
0000s0sDateTime::::_month_length DateTime::_month_length
0000s0sDateTime::::_new_from_self DateTime::_new_from_self
0000s0sDateTime::::_normalize_seconds DateTime::_normalize_seconds
0000s0sDateTime::::_space_padded_string DateTime::_space_padded_string
0000s0sDateTime::::_string_compare_overload DateTime::_string_compare_overload
0000s0sDateTime::::_string_equals_overload DateTime::_string_equals_overload
0000s0sDateTime::::_string_not_equals_overload DateTime::_string_not_equals_overload
0000s0sDateTime::::_stringify DateTime::_stringify
0000s0sDateTime::::_subtract_overload DateTime::_subtract_overload
0000s0sDateTime::::_utc_hms DateTime::_utc_hms
0000s0sDateTime::::_utc_ymd DateTime::_utc_ymd
0000s0sDateTime::::_weeks_in_year DateTime::_weeks_in_year
0000s0sDateTime::::_zero_padded_number DateTime::_zero_padded_number
0000s0sDateTime::::add DateTime::add
0000s0sDateTime::::add_duration DateTime::add_duration
0000s0sDateTime::::am_or_pm DateTime::am_or_pm
0000s0sDateTime::::ce_year DateTime::ce_year
0000s0sDateTime::::christian_era DateTime::christian_era
0000s0sDateTime::::compare DateTime::compare
0000s0sDateTime::::compare_ignore_floating DateTime::compare_ignore_floating
0000s0sDateTime::::day_abbr DateTime::day_abbr
0000s0sDateTime::::day_name DateTime::day_name
0000s0sDateTime::::day_of_month DateTime::day_of_month
0000s0sDateTime::::day_of_month_0 DateTime::day_of_month_0
0000s0sDateTime::::day_of_quarter DateTime::day_of_quarter
0000s0sDateTime::::day_of_quarter_0 DateTime::day_of_quarter_0
0000s0sDateTime::::day_of_week DateTime::day_of_week
0000s0sDateTime::::day_of_week_0 DateTime::day_of_week_0
0000s0sDateTime::::day_of_year DateTime::day_of_year
0000s0sDateTime::::day_of_year_0 DateTime::day_of_year_0
0000s0sDateTime::::delta_days DateTime::delta_days
0000s0sDateTime::::delta_md DateTime::delta_md
0000s0sDateTime::::delta_ms DateTime::delta_ms
0000s0sDateTime::::dmy DateTime::dmy
0000s0sDateTime::::epoch DateTime::epoch
0000s0sDateTime::::era_abbr DateTime::era_abbr
0000s0sDateTime::::era_name DateTime::era_name
0000s0sDateTime::::format_cldr DateTime::format_cldr
0000s0sDateTime::::formatter DateTime::formatter
0000s0sDateTime::::fractional_second DateTime::fractional_second
0000s0sDateTime::::from_day_of_year DateTime::from_day_of_year
0000s0sDateTime::::from_object DateTime::from_object
0000s0sDateTime::::hires_epoch DateTime::hires_epoch
0000s0sDateTime::::hour DateTime::hour
0000s0sDateTime::::hour_1 DateTime::hour_1
0000s0sDateTime::::hour_12 DateTime::hour_12
0000s0sDateTime::::hour_12_0 DateTime::hour_12_0
0000s0sDateTime::::is_dst DateTime::is_dst
0000s0sDateTime::::is_finite DateTime::is_finite
0000s0sDateTime::::is_infinite DateTime::is_infinite
0000s0sDateTime::::is_leap_year DateTime::is_leap_year
0000s0sDateTime::::iso8601 DateTime::iso8601
0000s0sDateTime::::jd DateTime::jd
0000s0sDateTime::::last_day_of_month DateTime::last_day_of_month
0000s0sDateTime::::leap_seconds DateTime::leap_seconds
0000s0sDateTime::::local_day_of_week DateTime::local_day_of_week
0000s0sDateTime::::local_rd_as_seconds DateTime::local_rd_as_seconds
0000s0sDateTime::::local_rd_values DateTime::local_rd_values
0000s0sDateTime::::locale DateTime::locale
0000s0sDateTime::::mdy DateTime::mdy
0000s0sDateTime::::microsecond DateTime::microsecond
0000s0sDateTime::::millisecond DateTime::millisecond
0000s0sDateTime::::minute DateTime::minute
0000s0sDateTime::::mjd DateTime::mjd
0000s0sDateTime::::month DateTime::month
0000s0sDateTime::::month_0 DateTime::month_0
0000s0sDateTime::::month_abbr DateTime::month_abbr
0000s0sDateTime::::month_name DateTime::month_name
0000s0sDateTime::::nanosecond DateTime::nanosecond
0000s0sDateTime::::new DateTime::new
0000s0sDateTime::::quarter DateTime::quarter
0000s0sDateTime::::quarter_0 DateTime::quarter_0
0000s0sDateTime::::quarter_abbr DateTime::quarter_abbr
0000s0sDateTime::::quarter_name DateTime::quarter_name
0000s0sDateTime::::secular_era DateTime::secular_era
0000s0sDateTime::::set DateTime::set
0000s0sDateTime::::set_day DateTime::set_day
0000s0sDateTime::::set_formatter DateTime::set_formatter
0000s0sDateTime::::set_hour DateTime::set_hour
0000s0sDateTime::::set_locale DateTime::set_locale
0000s0sDateTime::::set_minute DateTime::set_minute
0000s0sDateTime::::set_month DateTime::set_month
0000s0sDateTime::::set_nanosecond DateTime::set_nanosecond
0000s0sDateTime::::set_second DateTime::set_second
0000s0sDateTime::::set_year DateTime::set_year
0000s0sDateTime::::strftime DateTime::strftime
0000s0sDateTime::::subtract DateTime::subtract
0000s0sDateTime::::subtract_datetime DateTime::subtract_datetime
0000s0sDateTime::::subtract_datetime_absolute DateTime::subtract_datetime_absolute
0000s0sDateTime::::subtract_duration DateTime::subtract_duration
0000s0sDateTime::::time_zone DateTime::time_zone
0000s0sDateTime::::time_zone_long_name DateTime::time_zone_long_name
0000s0sDateTime::::time_zone_short_name DateTime::time_zone_short_name
0000s0sDateTime::::today DateTime::today
0000s0sDateTime::::truncate DateTime::truncate
0000s0sDateTime::::utc_rd_as_seconds DateTime::utc_rd_as_seconds
0000s0sDateTime::::utc_rd_values DateTime::utc_rd_values
0000s0sDateTime::::utc_year DateTime::utc_year
0000s0sDateTime::::week DateTime::week
0000s0sDateTime::::week_number DateTime::week_number
0000s0sDateTime::::week_of_month DateTime::week_of_month
0000s0sDateTime::::week_year DateTime::week_year
0000s0sDateTime::::weekday_of_month DateTime::weekday_of_month
0000s0sDateTime::::year_with_christian_era DateTime::year_with_christian_era
0000s0sDateTime::::year_with_era DateTime::year_with_era
0000s0sDateTime::::year_with_secular_era DateTime::year_with_secular_era
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1package DateTime;
2{
323µs $DateTime::VERSION = '0.74';
4}
5
6336µs127µs
# spent 27µs within DateTime::BEGIN@6 which was called: # once (27µs+0s) by Tapper::Schema::TestrunDB::ResultSet::Testrun::BEGIN@12 at line 6
use 5.008001;
# spent 27µs making 1 call to DateTime::BEGIN@6
7
8316µs210µs
# spent 8µs (6+2) within DateTime::BEGIN@8 which was called: # once (6µs+2µs) by Tapper::Schema::TestrunDB::ResultSet::Testrun::BEGIN@12 at line 8
use strict;
# spent 8µs making 1 call to DateTime::BEGIN@8 # spent 2µs making 1 call to strict::import
9320µs221µs
# spent 14µs (6+7) within DateTime::BEGIN@9 which was called: # once (6µs+7µs) by Tapper::Schema::TestrunDB::ResultSet::Testrun::BEGIN@12 at line 9
use warnings;
# spent 14µs making 1 call to DateTime::BEGIN@9 # spent 7µs making 1 call to warnings::import
10
11320µs299µs
# spent 56µs (13+43) within DateTime::BEGIN@11 which was called: # once (13µs+43µs) by Tapper::Schema::TestrunDB::ResultSet::Testrun::BEGIN@12 at line 11
use Carp;
# spent 56µs making 1 call to DateTime::BEGIN@11 # spent 43µs making 1 call to Exporter::import
12384µs1206µs
# spent 206µs (171+35) within DateTime::BEGIN@12 which was called: # once (171µs+35µs) by Tapper::Schema::TestrunDB::ResultSet::Testrun::BEGIN@12 at line 12
use DateTime::Helpers;
# spent 206µs making 1 call to DateTime::BEGIN@12
133211µs23.94ms
# spent 3.88ms (775µs+3.10) within DateTime::BEGIN@13 which was called: # once (775µs+3.10ms) by Tapper::Schema::TestrunDB::ResultSet::Testrun::BEGIN@12 at line 13
use Math::Round qw( nearest round );
# spent 3.88ms making 1 call to DateTime::BEGIN@13 # spent 61µs making 1 call to Exporter::import
14
15{
1621µs my $loaded = 0;
17
1814µs unless ( $ENV{PERL_DATETIME_PP} ) {
191400ns local $@;
2011µs eval {
2112µs require XSLoader;
22 XSLoader::load(
23 __PACKAGE__,
24 exists $DateTime::{VERSION}
251352µs1336µs ? ${ $DateTime::{VERSION} }
# spent 336µs making 1 call to XSLoader::load
26 : ()
27 );
28
2911µs $DateTime::IsPurePerl = 0;
30 };
31
321200ns die $@ if $@ && $@ !~ /object version|loadable object/;
33
341900ns $loaded = 1 unless $@;
35 }
36
371800ns if ($loaded) {
38 require DateTimePPExtra
39 unless defined &DateTime::_normalize_tai_seconds;
40 }
41 else {
42 require DateTimePP;
43 }
44}
45
463135µs11.90ms
# spent 1.90ms (1.65+248µs) within DateTime::BEGIN@46 which was called: # once (1.65ms+248µs) by Tapper::Schema::TestrunDB::ResultSet::Testrun::BEGIN@12 at line 46
use DateTime::Duration;
# spent 1.90ms making 1 call to DateTime::BEGIN@46
473138µs258.2ms
# spent 58.1ms (1.44+56.7) within DateTime::BEGIN@47 which was called: # once (1.44ms+56.7ms) by Tapper::Schema::TestrunDB::ResultSet::Testrun::BEGIN@12 at line 47
use DateTime::Locale 0.41;
# spent 58.1ms making 1 call to DateTime::BEGIN@47 # spent 23µs making 1 call to UNIVERSAL::VERSION
483158µs28.03ms
# spent 8.01ms (2.64+5.37) within DateTime::BEGIN@48 which was called: # once (2.64ms+5.37ms) by Tapper::Schema::TestrunDB::ResultSet::Testrun::BEGIN@12 at line 48
use DateTime::TimeZone 1.09;
# spent 8.01ms making 1 call to DateTime::BEGIN@48 # spent 21µs making 1 call to UNIVERSAL::VERSION
493151µs31.36ms
# spent 1.30ms (932µs+371µs) within DateTime::BEGIN@49 which was called: # once (932µs+371µs) by Tapper::Schema::TestrunDB::ResultSet::Testrun::BEGIN@12 at line 49
use Time::Local 1.04 qw( timegm_nocheck );
# spent 1.30ms making 1 call to DateTime::BEGIN@49 # spent 36µs making 1 call to Exporter::import # spent 17µs making 1 call to UNIVERSAL::VERSION
50
# spent 73µs (13+61) within DateTime::BEGIN@50 which was called: # once (13µs+61µs) by Tapper::Schema::TestrunDB::ResultSet::Testrun::BEGIN@12 at line 51
use Params::Validate 0.76
51361µs3134µs qw( validate validate_pos UNDEF SCALAR BOOLEAN HASHREF OBJECT );
# spent 73µs making 1 call to DateTime::BEGIN@50 # spent 49µs making 1 call to Exporter::import # spent 12µs making 1 call to UNIVERSAL::VERSION
52
53# for some reason, overloading doesn't work unless fallback is listed
54# early.
55#
56# 3rd parameter ( $_[2] ) means the parameters are 'reversed'.
57# see: "Calling conventions for binary operations" in overload docs.
58#
59
# spent 93µs (8+85) within DateTime::BEGIN@59 which was called: # once (8µs+85µs) by Tapper::Schema::TestrunDB::ResultSet::Testrun::BEGIN@12 at line 68
use overload (
60185µs 'fallback' => 1,
# spent 85µs making 1 call to overload::import
61 '<=>' => '_compare_overload',
62 'cmp' => '_string_compare_overload',
63 '""' => '_stringify',
64 '-' => '_subtract_overload',
65 '+' => '_add_overload',
66 'eq' => '_string_equals_overload',
67 'ne' => '_string_not_equals_overload',
68330µs193µs);
# spent 93µs making 1 call to DateTime::BEGIN@59
69
70# Have to load this after overloading is defined, after BEGIN blocks
71# or else weird crashes ensue
721106µsrequire DateTime::Infinite;
73
74326µs264µs
# spent 35µs (6+29) within DateTime::BEGIN@74 which was called: # once (6µs+29µs) by Tapper::Schema::TestrunDB::ResultSet::Testrun::BEGIN@12 at line 74
use constant MAX_NANOSECONDS => 1_000_000_000; # 1E9 = almost 32 bits
# spent 35µs making 1 call to DateTime::BEGIN@74 # spent 29µs making 1 call to constant::import
75
76323µs255µs
# spent 30µs (5+25) within DateTime::BEGIN@76 which was called: # once (5µs+25µs) by Tapper::Schema::TestrunDB::ResultSet::Testrun::BEGIN@12 at line 76
use constant INFINITY => ( 9**9**9 );
# spent 30µs making 1 call to DateTime::BEGIN@76 # spent 25µs making 1 call to constant::import
77321µs248µs
# spent 27µs (5+22) within DateTime::BEGIN@77 which was called: # once (5µs+22µs) by Tapper::Schema::TestrunDB::ResultSet::Testrun::BEGIN@12 at line 77
use constant NEG_INFINITY => -1 * ( 9**9**9 );
# spent 27µs making 1 call to DateTime::BEGIN@77 # spent 22µs making 1 call to constant::import
78318µs250µs
# spent 28µs (5+23) within DateTime::BEGIN@78 which was called: # once (5µs+23µs) by Tapper::Schema::TestrunDB::ResultSet::Testrun::BEGIN@12 at line 78
use constant NAN => INFINITY - INFINITY;
# spent 28µs making 1 call to DateTime::BEGIN@78 # spent 22µs making 1 call to constant::import
79
80318µs250µs
# spent 28µs (5+23) within DateTime::BEGIN@80 which was called: # once (5µs+23µs) by Tapper::Schema::TestrunDB::ResultSet::Testrun::BEGIN@12 at line 80
use constant SECONDS_PER_DAY => 86400;
# spent 28µs making 1 call to DateTime::BEGIN@80 # spent 23µs making 1 call to constant::import
81
82344µs250µs
# spent 28µs (5+22) within DateTime::BEGIN@82 which was called: # once (5µs+22µs) by Tapper::Schema::TestrunDB::ResultSet::Testrun::BEGIN@12 at line 82
use constant duration_class => 'DateTime::Duration';
# spent 28µs making 1 call to DateTime::BEGIN@82 # spent 22µs making 1 call to constant::import
83
8411µsmy ( @MonthLengths, @LeapYearMonthLengths );
85
86
# spent 7µs within DateTime::BEGIN@86 which was called: # once (7µs+0s) by Tapper::Schema::TestrunDB::ResultSet::Testrun::BEGIN@12 at line 91
BEGIN {
8737µs @MonthLengths = ( 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 );
88
89 @LeapYearMonthLengths = @MonthLengths;
90 $LeapYearMonthLengths[1]++;
9112.44ms17µs}
# spent 7µs making 1 call to DateTime::BEGIN@86
92
93{
94
95 # I'd rather use Class::Data::Inheritable for this, but there's no
96 # way to add the module-loading behavior to an accessor it
97 # creates, despite what its docs say!
9821µs my $DefaultLocale;
99
100
# spent 5.46ms (1.79+3.66) within DateTime::DefaultLocale which was called 295 times, avg 18µs/call: # 294 times (1.78ms+0s) by DateTime::_new at line 229, avg 6µs/call # once (12µs+3.66ms) by Tapper::Schema::TestrunDB::ResultSet::Testrun::BEGIN@12 at line 117
sub DefaultLocale {
1018882.46ms my $class = shift;
102
103 if (@_) {
104 my $lang = shift;
105
10613.66ms DateTime::Locale->load($lang);
# spent 3.66ms making 1 call to DateTime::Locale::load
107
108 $DefaultLocale = $lang;
109 }
110
111 return $DefaultLocale;
112 }
113
114 # backwards compat
11513µs *DefaultLanguage = \&DefaultLocale;
116}
11712µs13.68ms__PACKAGE__->DefaultLocale('en_US');
# spent 3.68ms making 1 call to DateTime::DefaultLocale
118
119my $BasicValidate = {
120 year => {
121 type => SCALAR,
122 callbacks => {
123 'is an integer' => sub { $_[0] =~ /^-?\d+$/ }
124 },
125 },
126 month => {
127 type => SCALAR,
128 default => 1,
129 callbacks => {
130 'an integer between 1 and 12' =>
131 sub { $_[0] =~ /^\d+$/ && $_[0] >= 1 && $_[0] <= 12 }
132 },
133 },
134 day => {
135 type => SCALAR,
136 default => 1,
137 callbacks => {
138 'an integer which is a possible valid day of month' =>
139 sub { $_[0] =~ /^\d+$/ && $_[0] >= 1 && $_[0] <= 31 }
140 },
141 },
142 hour => {
143 type => SCALAR,
144 default => 0,
145 callbacks => {
146 'an integer between 0 and 23' =>
147 sub { $_[0] =~ /^\d+$/ && $_[0] >= 0 && $_[0] <= 23 },
148 },
149 },
150 minute => {
151 type => SCALAR,
152 default => 0,
153 callbacks => {
154 'an integer between 0 and 59' =>
155 sub { $_[0] =~ /^\d+$/ && $_[0] >= 0 && $_[0] <= 59 },
156 },
157 },
158 second => {
159 type => SCALAR,
160 default => 0,
161 callbacks => {
162 'an integer between 0 and 61' =>
163 sub { $_[0] =~ /^\d+$/ && $_[0] >= 0 && $_[0] <= 61 },
164 },
165 },
166 nanosecond => {
167 type => SCALAR,
168 default => 0,
169 callbacks => {
170 'a positive integer' => sub { $_[0] =~ /^\d+$/ && $_[0] >= 0 },
171 }
172 },
173 locale => {
174 type => SCALAR | OBJECT,
175 default => undef
176 },
177 language => {
178 type => SCALAR | OBJECT,
179 optional => 1
180 },
181 formatter => {
182 type => UNDEF | SCALAR | OBJECT,
183 optional => 1,
184 callbacks => {
185 'can format_datetime' =>
186 sub { defined $_[0] ? $_[0]->can('format_datetime') : 1 },
187 },
188 },
189135µs};
190
19115µsmy $NewValidate = {
192 %$BasicValidate,
193 time_zone => {
194 type => SCALAR | OBJECT,
195 default => 'floating'
196 },
197};
198
199sub new {
200 my $class = shift;
201 my %p = validate( @_, $NewValidate );
202
203 Carp::croak(
204 "Invalid day of month (day = $p{day} - month = $p{month} - year = $p{year})\n"
205 )
206 if $p{day} > 28
207 && $p{day} > $class->_month_length( $p{year}, $p{month} );
208
209 return $class->_new(%p);
210}
211
212
# spent 101ms (26.0+75.1) within DateTime::_new which was called 294 times, avg 344µs/call: # 294 times (26.0ms+75.1ms) by DateTime::from_epoch at line 507, avg 344µs/call
sub _new {
213793824.9ms my $class = shift;
214 my %p = @_;
215
216 # If this method is called from somewhere other than new(), then some of
217 # these default may not get applied.
218 $p{month} = 1 unless exists $p{month};
219 $p{day} = 1 unless exists $p{day};
220 $p{hour} = 0 unless exists $p{hour};
221 $p{minute} = 0 unless exists $p{minute};
222 $p{second} = 0 unless exists $p{second};
223 $p{nanosecond} = 0 unless exists $p{nanosecond};
224 $p{time_zone} = 'floating' unless exists $p{time_zone};
225
226 my $self = bless {}, $class;
227
228 $p{locale} = delete $p{language} if exists $p{language};
2292941.78ms $p{locale} = $class->DefaultLocale unless defined $p{locale};
# spent 1.78ms making 294 calls to DateTime::DefaultLocale, avg 6µs/call
230
231 if ( ref $p{locale} ) {
232 $self->{locale} = $p{locale};
233 }
234 else {
23529416.6ms $self->{locale} = DateTime::Locale->load( $p{locale} );
# spent 16.6ms making 294 calls to DateTime::Locale::load, avg 57µs/call
236 }
237
23829424.8ms $self->{tz} = (
# spent 24.8ms making 294 calls to DateTime::TimeZone::new, avg 84µs/call
239 ref $p{time_zone}
240 ? $p{time_zone}
241 : DateTime::TimeZone->new( name => $p{time_zone} )
242 );
243
244294895µs $self->{local_rd_days} = $class->_ymd2rd( @p{qw( year month day )} );
# spent 895µs making 294 calls to DateTime::_ymd2rd, avg 3µs/call
245
246294515µs $self->{local_rd_secs}
# spent 515µs making 294 calls to DateTime::_time_as_seconds, avg 2µs/call
247 = $class->_time_as_seconds( @p{qw( hour minute second )} );
248
249 $self->{offset_modifier} = 0;
250
251 $self->{rd_nanosecs} = $p{nanosecond};
252 $self->{formatter} = $p{formatter};
253
2542941.13ms $self->_normalize_nanoseconds( $self->{local_rd_secs},
# spent 1.13ms making 294 calls to DateTime::_normalize_nanoseconds, avg 4µs/call
255 $self->{rd_nanosecs} );
256
257 # Set this explicitly since it can't be calculated accurately
258 # without knowing our time zone offset, and it's possible that the
259 # offset can't be calculated without having at least a rough guess
260 # of the datetime's year. This year need not be correct, as long
261 # as its equal or greater to the correct number, so we fudge by
262 # adding one to the local year given to the constructor.
263 $self->{utc_year} = $p{year} + 1;
264
2652946.98ms $self->_calc_utc_rd;
# spent 6.98ms making 294 calls to DateTime::_calc_utc_rd, avg 24µs/call
266
2672949.33ms $self->_handle_offset_modifier( $p{second} );
# spent 9.33ms making 294 calls to DateTime::_handle_offset_modifier, avg 32µs/call
268
26929413.0ms $self->_calc_local_rd;
# spent 13.0ms making 294 calls to DateTime::_calc_local_rd, avg 44µs/call
270
271 if ( $p{second} > 59 ) {
272 if (
273 $self->{tz}->is_floating
274 ||
275
276 # If true, this means that the actual calculated leap
277 # second does not occur in the second given to new()
278 ( $self->{utc_rd_secs} - 86399 < $p{second} - 59 )
279 ) {
280 Carp::croak("Invalid second value ($p{second})\n");
281 }
282 }
283
284 return $self;
285}
286
287# This method exists for the benefit of internal methods which create
288# a new object based on the current object, like set() and truncate().
289sub _new_from_self {
290 my $self = shift;
291 my %p = @_;
292
293 my %old = map { $_ => $self->$_() }
294 qw( year month day hour minute second nanosecond
295 locale time_zone );
296 $old{formatter} = $self->formatter()
297 if defined $self->formatter();
298
299 my $method = delete $p{_skip_validation} ? '_new' : 'new';
300
301 return ( ref $self )->$method( %old, %p );
302}
303
304
# spent 16.8ms (10.4+6.41) within DateTime::_handle_offset_modifier which was called 588 times, avg 29µs/call: # 294 times (5.79ms+3.54ms) by DateTime::_new at line 267, avg 32µs/call # 294 times (4.58ms+2.87ms) by DateTime::set_time_zone at line 1963, avg 25µs/call
sub _handle_offset_modifier {
30552929.44ms my $self = shift;
306
307 $self->{offset_modifier} = 0;
308
3095881.07ms return if $self->{tz}->is_floating;
# spent 1.07ms making 588 calls to DateTime::TimeZone::is_floating, avg 2µs/call
310
311 my $second = shift;
312 my $utc_is_valid = shift;
313
314 my $utc_rd_days = $self->{utc_rd_days};
315
3165885.34ms my $offset
# spent 2.81ms making 294 calls to DateTime::_offset_for_local_datetime, avg 10µs/call # spent 2.53ms making 294 calls to DateTime::offset, avg 9µs/call
317 = $utc_is_valid ? $self->offset : $self->_offset_for_local_datetime;
318
319 if ( $offset >= 0
320 && $self->{local_rd_secs} >= $offset ) {
321 if ( $second < 60 && $offset > 0 ) {
322 $self->{offset_modifier}
323 = $self->_day_length( $utc_rd_days - 1 ) - SECONDS_PER_DAY;
324
325 $self->{local_rd_secs} += $self->{offset_modifier};
326 }
327 elsif (
328 $second == 60
329 && (
330 ( $self->{local_rd_secs} == $offset && $offset > 0 )
331 || ( $offset == 0
332 && $self->{local_rd_secs} > 86399 )
333 )
334 ) {
335 my $mod
336 = $self->_day_length( $utc_rd_days - 1 ) - SECONDS_PER_DAY;
337
338 unless ( $mod == 0 ) {
339 $self->{utc_rd_secs} -= $mod;
340
341 $self->_normalize_seconds;
342 }
343 }
344 }
345 elsif ($offset < 0
346 && $self->{local_rd_secs} >= SECONDS_PER_DAY + $offset ) {
347 if ( $second < 60 ) {
348 $self->{offset_modifier}
349 = $self->_day_length( $utc_rd_days - 1 ) - SECONDS_PER_DAY;
350
351 $self->{local_rd_secs} += $self->{offset_modifier};
352 }
353 elsif ($second == 60
354 && $self->{local_rd_secs} == SECONDS_PER_DAY + $offset ) {
355 my $mod
356 = $self->_day_length( $utc_rd_days - 1 ) - SECONDS_PER_DAY;
357
358 unless ( $mod == 0 ) {
359 $self->{utc_rd_secs} -= $mod;
360
361 $self->_normalize_seconds;
362 }
363 }
364 }
365}
366
367
# spent 7.02ms (5.41+1.62) within DateTime::_calc_utc_rd which was called 296 times, avg 24µs/call: # 294 times (5.38ms+1.60ms) by DateTime::_new at line 265, avg 24µs/call # once (24µs+10µs) by Tapper::Schema::TestrunDB::ResultSet::Testrun::BEGIN@12 at line 57 of DateTime/Infinite.pm # once (10µs+2µs) by Tapper::Schema::TestrunDB::ResultSet::Testrun::BEGIN@12 at line 81 of DateTime/Infinite.pm
sub _calc_utc_rd {
36817765.89ms my $self = shift;
369
370 delete $self->{utc_c};
371
372298760µs if ( $self->{tz}->is_utc || $self->{tz}->is_floating ) {
# spent 755µs making 294 calls to DateTime::TimeZone::UTC::is_utc, avg 3µs/call # spent 2µs making 2 calls to DateTime::TimeZone::OffsetOnly::is_utc, avg 1µs/call # spent 2µs making 2 calls to DateTime::TimeZone::Floating::is_floating, avg 950ns/call
373 $self->{utc_rd_days} = $self->{local_rd_days};
374 $self->{utc_rd_secs} = $self->{local_rd_secs};
375 }
376 else {
377 my $offset = $self->_offset_for_local_datetime;
378
379 $offset += $self->{offset_modifier};
380
381 $self->{utc_rd_days} = $self->{local_rd_days};
382 $self->{utc_rd_secs} = $self->{local_rd_secs} - $offset;
383 }
384
385 # We account for leap seconds in the new() method and nowhere else
386 # except date math.
387296855µs $self->_normalize_tai_seconds( $self->{utc_rd_days},
# spent 855µs making 296 calls to DateTime::_normalize_tai_seconds, avg 3µs/call
388 $self->{utc_rd_secs} );
389}
390
391sub _normalize_seconds {
392 my $self = shift;
393
394 return if $self->{utc_rd_secs} >= 0 && $self->{utc_rd_secs} <= 86399;
395
396 if ( $self->{tz}->is_floating ) {
397 $self->_normalize_tai_seconds( $self->{utc_rd_days},
398 $self->{utc_rd_secs} );
399 }
400 else {
401 $self->_normalize_leap_seconds( $self->{utc_rd_days},
402 $self->{utc_rd_secs} );
403 }
404}
405
406
# spent 24.3ms (8.44+15.9) within DateTime::_calc_local_rd which was called 590 times, avg 41µs/call: # 294 times (4.53ms+8.48ms) by DateTime::_new at line 269, avg 44µs/call # 294 times (3.87ms+7.34ms) by DateTime::set_time_zone at line 1966, avg 38µs/call # once (21µs+31µs) by Tapper::Schema::TestrunDB::ResultSet::Testrun::BEGIN@12 at line 58 of DateTime/Infinite.pm # once (9µs+19µs) by Tapper::Schema::TestrunDB::ResultSet::Testrun::BEGIN@12 at line 82 of DateTime/Infinite.pm
sub _calc_local_rd {
40735407.04ms my $self = shift;
408
409 delete $self->{local_c};
410
411 # We must short circuit for UTC times or else we could end up with
412 # loops between DateTime.pm and DateTime::TimeZone
413592794µs if ( $self->{tz}->is_utc || $self->{tz}->is_floating ) {
# spent 791µs making 588 calls to DateTime::TimeZone::UTC::is_utc, avg 1µs/call # spent 1µs making 2 calls to DateTime::TimeZone::Floating::is_floating, avg 700ns/call # spent 1µs making 2 calls to DateTime::TimeZone::OffsetOnly::is_utc, avg 600ns/call
414 $self->{local_rd_days} = $self->{utc_rd_days};
415 $self->{local_rd_secs} = $self->{utc_rd_secs};
416 }
417 else {
418 my $offset = $self->offset;
419
420 $self->{local_rd_days} = $self->{utc_rd_days};
421 $self->{local_rd_secs} = $self->{utc_rd_secs} + $offset;
422
423 # intentionally ignore leap seconds here
424 $self->_normalize_tai_seconds( $self->{local_rd_days},
425 $self->{local_rd_secs} );
426
427 $self->{local_rd_secs} += $self->{offset_modifier};
428 }
429
43059015.1ms $self->_calc_local_components;
# spent 15.1ms making 590 calls to DateTime::_calc_local_components, avg 26µs/call
431}
432
433
# spent 15.1ms (12.7+2.40) within DateTime::_calc_local_components which was called 590 times, avg 26µs/call: # 590 times (12.7ms+2.40ms) by DateTime::_calc_local_rd at line 430, avg 26µs/call
sub _calc_local_components {
434177016.1ms my $self = shift;
435
436 @{ $self->{local_c} }{
4375901.46ms qw( year month day day_of_week
# spent 1.46ms making 588 calls to DateTime::_rd2ymd, avg 2µs/call # spent 6µs making 2 calls to DateTime::Infinite::_rd2ymd, avg 3µs/call
438 day_of_year quarter day_of_quarter)
439 }
440 = $self->_rd2ymd( $self->{local_rd_days}, 1 );
441
442590936µs @{ $self->{local_c} }{qw( hour minute second )}
# spent 933µs making 588 calls to DateTime::_seconds_as_components, avg 2µs/call # spent 3µs making 2 calls to DateTime::Infinite::_seconds_as_components, avg 2µs/call
443 = $self->_seconds_as_components( $self->{local_rd_secs},
444 $self->{utc_rd_secs}, $self->{offset_modifier} );
445}
446
447sub _calc_utc_components {
448 my $self = shift;
449
450 die "Cannot get UTC components before UTC RD has been calculated\n"
451 unless defined $self->{utc_rd_days};
452
453 @{ $self->{utc_c} }{qw( year month day )}
454 = $self->_rd2ymd( $self->{utc_rd_days} );
455
456 @{ $self->{utc_c} }{qw( hour minute second )}
457 = $self->_seconds_as_components( $self->{utc_rd_secs} );
458}
459
460sub _utc_ymd {
461 my $self = shift;
462
463 $self->_calc_utc_components unless exists $self->{utc_c}{year};
464
465 return @{ $self->{utc_c} }{qw( year month day )};
466}
467
468sub _utc_hms {
469 my $self = shift;
470
471 $self->_calc_utc_components unless exists $self->{utc_c}{hour};
472
473 return @{ $self->{utc_c} }{qw( hour minute second )};
474}
475
476{
477218µs17µs my $spec = {
# spent 7µs making 1 call to DateTime::CORE:qr
478 epoch => { regex => qr/^-?(?:\d+(?:\.\d*)?|\.\d+)$/ },
479 locale => { type => SCALAR | OBJECT, optional => 1 },
480 language => { type => SCALAR | OBJECT, optional => 1 },
481 time_zone => { type => SCALAR | OBJECT, optional => 1 },
482 formatter => {
483 type => SCALAR | OBJECT, can => 'format_datetime',
484 optional => 1
485 },
486 };
487
488
# spent 166ms (15.2+151) within DateTime::from_epoch which was called 294 times, avg 564µs/call: # 294 times (15.2ms+151ms) by DateTime::now at line 516, avg 564µs/call
sub from_epoch {
489352842.3ms my $class = shift;
490113.3ms58855.4ms my %p = validate( @_, $spec );
# spent 48.3ms making 294 calls to Params::Validate::XS::validate, avg 164µs/call # spent 7.11ms making 294 calls to Params::Validate::XS::_check_regex_from_xs, avg 24µs/call
# spent 2.05ms executing statements in 294 string evals (merged)
491
492 my %args;
493 # Epoch may come from Time::HiRes, so it may not be an integer.
4942941.24ms my ( $int, $dec ) = $p{epoch} =~ /^(-?\d+)?(\.\d+)?/;
# spent 1.24ms making 294 calls to DateTime::CORE:match, avg 4µs/call
495 $int ||= 0;
496
497 $args{nanosecond} = int( $dec * MAX_NANOSECONDS )
498 if $dec;
499
500 # Note, for very large negative values this may give a
501 # blatantly wrong answer.
502 @args{qw( second minute hour day month year )}
503 = ( gmtime($int) )[ 0 .. 5 ];
504 $args{year} += 1900;
505 $args{month}++;
506
507294101ms my $self = $class->_new( %p, %args, time_zone => 'UTC' );
# spent 101ms making 294 calls to DateTime::_new, avg 344µs/call
508
509 $self->set_time_zone( $p{time_zone} ) if exists $p{time_zone};
510
511 return $self;
512 }
513}
514
515# use scalar time in case someone's loaded Time::Piece
5162942.42ms294166ms
# spent 168ms (2.49+166) within DateTime::now which was called 294 times, avg 572µs/call: # 147 times (1.63ms+108ms) by Tapper::MCP::Scheduler::Controller::mark_job_as_running at line 135 of lib/Tapper/MCP/Scheduler/Controller.pm, avg 749µs/call # 147 times (858µs+57.4ms) by Tapper::Schema::TestrunDB::Result::Testrun::rerun at line 122 of Tapper/Schema/TestrunDB/Result/Testrun.pm, avg 396µs/call
sub now { shift->from_epoch( epoch => ( scalar time ), @_ ) }
# spent 166ms making 294 calls to DateTime::from_epoch, avg 564µs/call
517
518sub today { shift->now(@_)->truncate( to => 'day' ) }
519
520{
52127µs my $spec = {
522 object => {
523 type => OBJECT,
524 can => 'utc_rd_values',
525 },
526 locale => { type => SCALAR | OBJECT, optional => 1 },
527 language => { type => SCALAR | OBJECT, optional => 1 },
528 formatter => {
529 type => SCALAR | OBJECT, can => 'format_datetime',
530 optional => 1
531 },
532 };
533
534 sub from_object {
535 my $class = shift;
536 my %p = validate( @_, $spec );
537
538 my $object = delete $p{object};
539
540 my ( $rd_days, $rd_secs, $rd_nanosecs ) = $object->utc_rd_values;
541
542 # A kludge because until all calendars are updated to return all
543 # three values, $rd_nanosecs could be undef
544 $rd_nanosecs ||= 0;
545
546 # This is a big hack to let _seconds_as_components operate naively
547 # on the given value. If the object _is_ on a leap second, we'll
548 # add that to the generated seconds value later.
549 my $leap_seconds = 0;
550 if ( $object->can('time_zone')
551 && !$object->time_zone->is_floating
552 && $rd_secs > 86399
553 && $rd_secs <= $class->_day_length($rd_days) ) {
554 $leap_seconds = $rd_secs - 86399;
555 $rd_secs -= $leap_seconds;
556 }
557
558 my %args;
559 @args{qw( year month day )} = $class->_rd2ymd($rd_days);
560 @args{qw( hour minute second )}
561 = $class->_seconds_as_components($rd_secs);
562 $args{nanosecond} = $rd_nanosecs;
563
564 $args{second} += $leap_seconds;
565
566 my $new = $class->new( %p, %args, time_zone => 'UTC' );
567
568 if ( $object->can('time_zone') ) {
569 $new->set_time_zone( $object->time_zone );
570 }
571 else {
572 $new->set_time_zone('floating');
573 }
574
575 return $new;
576 }
577}
578
57913µsmy $LastDayOfMonthValidate = {%$NewValidate};
58013µsforeach ( keys %$LastDayOfMonthValidate ) {
5811120µs my %copy = %{ $LastDayOfMonthValidate->{$_} };
582
583113µs delete $copy{default};
584115µs $copy{optional} = 1 unless $_ eq 'year' || $_ eq 'month';
585
586118µs $LastDayOfMonthValidate->{$_} = \%copy;
587}
588
589sub last_day_of_month {
590 my $class = shift;
591 my %p = validate( @_, $LastDayOfMonthValidate );
592
593 my $day = $class->_month_length( $p{year}, $p{month} );
594
595 return $class->_new( %p, day => $day );
596}
597
598sub _month_length {
599 return (
600 $_[0]->_is_leap_year( $_[1] )
601 ? $LeapYearMonthLengths[ $_[2] - 1 ]
602 : $MonthLengths[ $_[2] - 1 ]
603 );
604}
605
60613µsmy $FromDayOfYearValidate = {%$NewValidate};
60712µsforeach ( keys %$FromDayOfYearValidate ) {
608113µs next if $_ eq 'month' || $_ eq 'day';
609
610913µs my %copy = %{ $FromDayOfYearValidate->{$_} };
611
61292µs delete $copy{default};
61393µs $copy{optional} = 1 unless $_ eq 'year' || $_ eq 'month';
614
61596µs $FromDayOfYearValidate->{$_} = \%copy;
616}
617$FromDayOfYearValidate->{day_of_year} = {
618 type => SCALAR,
619 callbacks => {
620 'is between 1 and 366' => sub { $_[0] >= 1 && $_[0] <= 366 }
621 }
62214µs};
623
624sub from_day_of_year {
625 my $class = shift;
626 my %p = validate( @_, $FromDayOfYearValidate );
627
628 Carp::croak("$p{year} is not a leap year.\n")
629 if $p{day_of_year} == 366 && !$class->_is_leap_year( $p{year} );
630
631 my $month = 1;
632 my $day = delete $p{day_of_year};
633
634 if ( $day > 31 ) {
635 my $length = $class->_month_length( $p{year}, $month );
636
637 while ( $day > $length ) {
638 $day -= $length;
639 $month++;
640 $length = $class->_month_length( $p{year}, $month );
641 }
642 }
643
644 return $class->_new(
645 %p,
646 month => $month,
647 day => $day,
648 );
649}
650
651sub formatter { $_[0]->{formatter} }
652
6532944.55ms
# spent 3.94ms within DateTime::clone which was called 294 times, avg 13µs/call: # 294 times (3.94ms+0s) by DateTime::Format::SQLite::format_datetime at line 102 of DateTime/Format/SQLite.pm, avg 13µs/call
sub clone { bless { %{ $_[0] } }, ref $_[0] }
654
655
# spent 953µs within DateTime::year which was called 294 times, avg 3µs/call: # 294 times (953µs+0s) by DateTime::ymd at line 768, avg 3µs/call
sub year {
6565881.49ms Carp::carp('year() is a read-only accessor') if @_ > 1;
657 return $_[0]->{local_c}{year};
658}
659
660sub ce_year {
661 $_[0]->{local_c}{year} <= 0
662 ? $_[0]->{local_c}{year} - 1
663 : $_[0]->{local_c}{year};
664}
665
666sub era_name { $_[0]->{locale}->era_wide->[ $_[0]->_era_index() ] }
667
668sub era_abbr { $_[0]->{locale}->era_abbreviated->[ $_[0]->_era_index() ] }
669
670# deprecated
67117µs*era = \&era_abbr;
672
673sub _era_index { $_[0]->{local_c}{year} <= 0 ? 0 : 1 }
674
675sub christian_era { $_[0]->ce_year > 0 ? 'AD' : 'BC' }
676sub secular_era { $_[0]->ce_year > 0 ? 'CE' : 'BCE' }
677
678sub year_with_era { ( abs $_[0]->ce_year ) . $_[0]->era_abbr }
679sub year_with_christian_era { ( abs $_[0]->ce_year ) . $_[0]->christian_era }
680sub year_with_secular_era { ( abs $_[0]->ce_year ) . $_[0]->secular_era }
681
682sub month {
683 Carp::carp('month() is a read-only accessor') if @_ > 1;
684 return $_[0]->{local_c}{month};
685}
68612µs*mon = \&month;
687
688sub month_0 { $_[0]->{local_c}{month} - 1 }
68912µs*mon_0 = \&month_0;
690
691sub month_name { $_[0]->{locale}->month_format_wide->[ $_[0]->month_0() ] }
692
693sub month_abbr {
694 $_[0]->{locale}->month_format_abbreviated->[ $_[0]->month_0() ];
695}
696
697sub day_of_month {
698 Carp::carp('day_of_month() is a read-only accessor') if @_ > 1;
699 $_[0]->{local_c}{day};
700}
70112µs*day = \&day_of_month;
70212µs*mday = \&day_of_month;
703
70436.16ms2186µs
# spent 182µs (179+4) within DateTime::BEGIN@704 which was called: # once (179µs+4µs) by Tapper::Schema::TestrunDB::ResultSet::Testrun::BEGIN@12 at line 704
sub weekday_of_month { use integer; ( ( $_[0]->day - 1 ) / 7 ) + 1 }
# spent 182µs making 1 call to DateTime::BEGIN@704 # spent 4µs making 1 call to integer::import
705
706sub quarter { $_[0]->{local_c}{quarter} }
707
708sub quarter_name {
709 $_[0]->{locale}->quarter_format_wide->[ $_[0]->quarter_0() ];
710}
711
712sub quarter_abbr {
713 $_[0]->{locale}->quarter_format_abbreviated->[ $_[0]->quarter_0() ];
714}
715
716sub quarter_0 { $_[0]->{local_c}{quarter} - 1 }
717
718sub day_of_month_0 { $_[0]->{local_c}{day} - 1 }
71912µs*day_0 = \&day_of_month_0;
72012µs*mday_0 = \&day_of_month_0;
721
722sub day_of_week { $_[0]->{local_c}{day_of_week} }
72312µs*wday = \&day_of_week;
72412µs*dow = \&day_of_week;
725
726sub day_of_week_0 { $_[0]->{local_c}{day_of_week} - 1 }
72712µs*wday_0 = \&day_of_week_0;
72812µs*dow_0 = \&day_of_week_0;
729
730sub local_day_of_week {
731 my $self = shift;
732
733 my $day = $self->day_of_week();
734
735 my $local_first_day = $self->{locale}->first_day_of_week();
736
737 my $d = ( ( 8 - $local_first_day ) + $day ) % 7;
738
739 return $d == 0 ? 7 : $d;
740}
741
742sub day_name { $_[0]->{locale}->day_format_wide->[ $_[0]->day_of_week_0() ] }
743
744sub day_abbr {
745 $_[0]->{locale}->day_format_abbreviated->[ $_[0]->day_of_week_0() ];
746}
747
748sub day_of_quarter { $_[0]->{local_c}{day_of_quarter} }
74912µs*doq = \&day_of_quarter;
750
751sub day_of_quarter_0 { $_[0]->day_of_quarter - 1 }
75212µs*doq_0 = \&day_of_quarter_0;
753
754sub day_of_year { $_[0]->{local_c}{day_of_year} }
75512µs*doy = \&day_of_year;
756
757sub day_of_year_0 { $_[0]->{local_c}{day_of_year} - 1 }
75812µs*doy_0 = \&day_of_year_0;
759
760sub am_or_pm {
761 $_[0]->{locale}->am_pm_abbreviated->[ $_[0]->hour() < 12 ? 0 : 1 ];
762}
763
764
# spent 4.61ms (3.66+953µs) within DateTime::ymd which was called 294 times, avg 16µs/call: # 294 times (3.66ms+953µs) by DateTime::Format::SQLite::format_datetime at line 105 of DateTime/Format/SQLite.pm, avg 16µs/call
sub ymd {
7658823.43ms my ( $self, $sep ) = @_;
766 $sep = '-' unless defined $sep;
767
768294953µs return sprintf(
# spent 953µs making 294 calls to DateTime::year, avg 3µs/call
769 "%0.4d%s%0.2d%s%0.2d",
770 $self->year, $sep,
771 $self->{local_c}{month}, $sep,
772 $self->{local_c}{day}
773 );
774}
77512µs*date = \&ymd;
776
777sub mdy {
778 my ( $self, $sep ) = @_;
779 $sep = '-' unless defined $sep;
780
781 return sprintf(
782 "%0.2d%s%0.2d%s%0.4d",
783 $self->{local_c}{month}, $sep,
784 $self->{local_c}{day}, $sep,
785 $self->year
786 );
787}
788
789sub dmy {
790 my ( $self, $sep ) = @_;
791 $sep = '-' unless defined $sep;
792
793 return sprintf(
794 "%0.2d%s%0.2d%s%0.4d",
795 $self->{local_c}{day}, $sep,
796 $self->{local_c}{month}, $sep,
797 $self->year
798 );
799}
800
801sub hour {
802 Carp::carp('hour() is a read-only accessor') if @_ > 1;
803 return $_[0]->{local_c}{hour};
804}
805sub hour_1 { $_[0]->{local_c}{hour} == 0 ? 24 : $_[0]->{local_c}{hour} }
806
807sub hour_12 { my $h = $_[0]->hour % 12; return $h ? $h : 12 }
808sub hour_12_0 { $_[0]->hour % 12 }
809
810sub minute {
811 Carp::carp('minute() is a read-only accessor') if @_ > 1;
812 return $_[0]->{local_c}{minute};
813}
81412µs*min = \&minute;
815
816
# spent 1.30ms within DateTime::second which was called 294 times, avg 4µs/call: # 294 times (1.30ms+0s) by DateTime::set_time_zone at line 1963, avg 4µs/call
sub second {
8175881.50ms Carp::carp('second() is a read-only accessor') if @_ > 1;
818 return $_[0]->{local_c}{second};
819}
82012µs*sec = \&second;
821
822sub fractional_second { $_[0]->second + $_[0]->nanosecond / MAX_NANOSECONDS }
823
824sub nanosecond {
825 Carp::carp('nanosecond() is a read-only accessor') if @_ > 1;
826 return $_[0]->{rd_nanosecs};
827}
828
829sub millisecond { round( $_[0]->{rd_nanosecs} / 1000000 ) }
830
831sub microsecond { round( $_[0]->{rd_nanosecs} / 1000 ) }
832
833sub leap_seconds {
834 my $self = shift;
835
836 return 0 if $self->{tz}->is_floating;
837
838 return DateTime->_accumulated_leap_seconds( $self->{utc_rd_days} );
839}
840
841sub _stringify {
842 my $self = shift;
843
844 return $self->iso8601 unless $self->{formatter};
845 return $self->{formatter}->format_datetime($self);
846}
847
848
# spent 2.02ms within DateTime::hms which was called 294 times, avg 7µs/call: # 294 times (2.02ms+0s) by DateTime::Format::SQLite::format_datetime at line 105 of DateTime/Format/SQLite.pm, avg 7µs/call
sub hms {
8498822.23ms my ( $self, $sep ) = @_;
850 $sep = ':' unless defined $sep;
851
852 return sprintf(
853 "%0.2d%s%0.2d%s%0.2d",
854 $self->{local_c}{hour}, $sep,
855 $self->{local_c}{minute}, $sep,
856 $self->{local_c}{second}
857 );
858}
859
860# don't want to override CORE::time()
86112µs*DateTime::time = \&hms;
862
863sub iso8601 { join 'T', $_[0]->ymd('-'), $_[0]->hms(':') }
86412µs*datetime = \&iso8601;
865
866sub is_leap_year { $_[0]->_is_leap_year( $_[0]->year ) }
867
868sub week {
869 my $self = shift;
870
871 unless ( defined $self->{local_c}{week_year} ) {
872
873 # This algorithm was taken from Date::Calc's DateCalc.c file
874 my $jan_one_dow_m1
875 = ( ( $self->_ymd2rd( $self->year, 1, 1 ) + 6 ) % 7 );
876
877 $self->{local_c}{week_number}
878 = int( ( ( $self->day_of_year - 1 ) + $jan_one_dow_m1 ) / 7 );
879 $self->{local_c}{week_number}++ if $jan_one_dow_m1 < 4;
880
881 if ( $self->{local_c}{week_number} == 0 ) {
882 $self->{local_c}{week_year} = $self->year - 1;
883 $self->{local_c}{week_number}
884 = $self->_weeks_in_year( $self->{local_c}{week_year} );
885 }
886 elsif ($self->{local_c}{week_number} == 53
887 && $self->_weeks_in_year( $self->year ) == 52 ) {
888 $self->{local_c}{week_number} = 1;
889 $self->{local_c}{week_year} = $self->year + 1;
890 }
891 else {
892 $self->{local_c}{week_year} = $self->year;
893 }
894 }
895
896 return @{ $self->{local_c} }{ 'week_year', 'week_number' };
897}
898
899sub _weeks_in_year {
900 my $self = shift;
901 my $year = shift;
902
903 my $dow = $self->_ymd2rd( $year, 1, 1 ) % 7;
904
905 # Tears starting with a Thursday and leap years starting with a Wednesday
906 # have 53 weeks.
907 return ( $dow == 4 || ( $dow == 3 && $self->_is_leap_year($year) ) )
908 ? 53
909 : 52;
910}
911
912sub week_year { ( $_[0]->week )[0] }
913sub week_number { ( $_[0]->week )[1] }
914
915# ISO says that the first week of a year is the first week containing
916# a Thursday. Extending that says that the first week of the month is
917# the first week containing a Thursday. ICU agrees.
918sub week_of_month {
919 my $self = shift;
920 my $thu = $self->day + 4 - $self->day_of_week;
921 return int( ( $thu + 6 ) / 7 );
922}
923
924sub time_zone {
925 Carp::carp('time_zone() is a read-only accessor') if @_ > 1;
926 return $_[0]->{tz};
927}
928
9292941.81ms294672µs
# spent 2.53ms (1.86+672µs) within DateTime::offset which was called 294 times, avg 9µs/call: # 294 times (1.86ms+672µs) by DateTime::_handle_offset_modifier at line 316, avg 9µs/call
sub offset { $_[0]->{tz}->offset_for_datetime( $_[0] ) }
# spent 672µs making 294 calls to DateTime::TimeZone::UTC::offset_for_datetime, avg 2µs/call
930
931
# spent 2.81ms (2.18+635µs) within DateTime::_offset_for_local_datetime which was called 294 times, avg 10µs/call: # 294 times (2.18ms+635µs) by DateTime::_handle_offset_modifier at line 316, avg 10µs/call
sub _offset_for_local_datetime {
9322941.99ms294635µs $_[0]->{tz}->offset_for_local_datetime( $_[0] );
# spent 635µs making 294 calls to DateTime::TimeZone::UTC::offset_for_local_datetime, avg 2µs/call
933}
934
935sub is_dst { $_[0]->{tz}->is_dst_for_datetime( $_[0] ) }
936
937sub time_zone_long_name { $_[0]->{tz}->name }
938sub time_zone_short_name { $_[0]->{tz}->short_name_for_datetime( $_[0] ) }
939
940sub locale {
941 Carp::carp('locale() is a read-only accessor') if @_ > 1;
942 return $_[0]->{locale};
943}
94412µs*language = \&locale;
945
946sub utc_rd_values {
947 @{ $_[0] }{ 'utc_rd_days', 'utc_rd_secs', 'rd_nanosecs' };
948}
949
950sub local_rd_values {
951 @{ $_[0] }{ 'local_rd_days', 'local_rd_secs', 'rd_nanosecs' };
952}
953
954# NOTE: no nanoseconds, no leap seconds
955sub utc_rd_as_seconds {
956 ( $_[0]->{utc_rd_days} * SECONDS_PER_DAY ) + $_[0]->{utc_rd_secs};
957}
958
959# NOTE: no nanoseconds, no leap seconds
960sub local_rd_as_seconds {
961 ( $_[0]->{local_rd_days} * SECONDS_PER_DAY ) + $_[0]->{local_rd_secs};
962}
963
964# RD 1 is JD 1,721,424.5 - a simple offset
965sub jd {
966 my $self = shift;
967
968 my $jd = $self->{utc_rd_days} + 1_721_424.5;
969
970 my $day_length = $self->_day_length( $self->{utc_rd_days} );
971
972 return ( $jd
973 + ( $self->{utc_rd_secs} / $day_length )
974 + ( $self->{rd_nanosecs} / $day_length / MAX_NANOSECONDS ) );
975}
976
977sub mjd { $_[0]->jd - 2_400_000.5 }
978
979{
9801700ns my %strftime_patterns = (
981 'a' => sub { $_[0]->day_abbr },
982 'A' => sub { $_[0]->day_name },
983 'b' => sub { $_[0]->month_abbr },
984 'B' => sub { $_[0]->month_name },
985 'c' => sub {
986 $_[0]->format_cldr( $_[0]->{locale}->datetime_format_default() );
987 },
988 'C' => sub { int( $_[0]->year / 100 ) },
989 'd' => sub { sprintf( '%02d', $_[0]->day_of_month ) },
990 'D' => sub { $_[0]->strftime('%m/%d/%y') },
991 'e' => sub { sprintf( '%2d', $_[0]->day_of_month ) },
992 'F' => sub { $_[0]->ymd('-') },
993 'g' => sub { substr( $_[0]->week_year, -2 ) },
994 'G' => sub { $_[0]->week_year },
995 'H' => sub { sprintf( '%02d', $_[0]->hour ) },
996 'I' => sub { sprintf( '%02d', $_[0]->hour_12 ) },
997 'j' => sub { $_[0]->day_of_year },
998 'k' => sub { sprintf( '%2d', $_[0]->hour ) },
999 'l' => sub { sprintf( '%2d', $_[0]->hour_12 ) },
1000 'm' => sub { sprintf( '%02d', $_[0]->month ) },
1001 'M' => sub { sprintf( '%02d', $_[0]->minute ) },
1002 'n' => sub {"\n"}, # should this be OS-sensitive?
1003 'N' => \&_format_nanosecs,
1004 'p' => sub { $_[0]->am_or_pm() },
1005 'P' => sub { lc $_[0]->am_or_pm() },
1006 'r' => sub { $_[0]->strftime('%I:%M:%S %p') },
1007 'R' => sub { $_[0]->strftime('%H:%M') },
1008 's' => sub { $_[0]->epoch },
1009 'S' => sub { sprintf( '%02d', $_[0]->second ) },
1010 't' => sub {"\t"},
1011 'T' => sub { $_[0]->strftime('%H:%M:%S') },
1012 'u' => sub { $_[0]->day_of_week },
1013 'U' => sub {
1014 my $sun = $_[0]->day_of_year - ( $_[0]->day_of_week + 7 ) % 7;
1015 return sprintf( '%02d', int( ( $sun + 6 ) / 7 ) );
1016 },
1017 'V' => sub { sprintf( '%02d', $_[0]->week_number ) },
1018 'w' => sub {
1019 my $dow = $_[0]->day_of_week;
1020 return $dow % 7;
1021 },
1022 'W' => sub {
1023 my $mon = $_[0]->day_of_year - ( $_[0]->day_of_week + 6 ) % 7;
1024 return sprintf( '%02d', int( ( $mon + 6 ) / 7 ) );
1025 },
1026 'x' => sub {
1027 $_[0]->format_cldr( $_[0]->{locale}->date_format_default() );
1028 },
1029 'X' => sub {
1030 $_[0]->format_cldr( $_[0]->{locale}->time_format_default() );
1031 },
1032 'y' => sub { sprintf( '%02d', substr( $_[0]->year, -2 ) ) },
1033 'Y' => sub { return $_[0]->year },
1034 'z' => sub { DateTime::TimeZone->offset_as_string( $_[0]->offset ) },
1035 'Z' => sub { $_[0]->{tz}->short_name_for_datetime( $_[0] ) },
1036 '%' => sub {'%'},
1037191µs );
1038
103915µs $strftime_patterns{h} = $strftime_patterns{b};
1040
1041 sub strftime {
1042 my $self = shift;
1043
1044 # make a copy or caller's scalars get munged
1045 my @patterns = @_;
1046
1047 my @r;
1048 foreach my $p (@patterns) {
1049 $p =~ s/
1050 (?:
1051 %{(\w+)} # method name like %{day_name}
1052 |
1053 %([%a-zA-Z]) # single character specifier like %d
1054 |
1055 %(\d+)N # special case for %N
1056 )
1057 /
1058 ( $1
1059 ? ( $self->can($1) ? $self->$1() : "\%{$1}" )
1060 : $2
1061 ? ( $strftime_patterns{$2} ? $strftime_patterns{$2}->($self) : "\%$2" )
1062 : $3
1063 ? $strftime_patterns{N}->($self, $3)
1064 : '' # this won't happen
1065 )
1066 /sgex;
1067
1068 return $p unless wantarray;
1069
1070 push @r, $p;
1071 }
1072
1073 return @r;
1074 }
1075}
1076
1077{
1078
1079 # It's an array because the order in which the regexes are checked
1080 # is important. These patterns are similar to the ones Java uses,
1081 # but not quite the same. See
1082 # http://www.unicode.org/reports/tr35/tr35-9.html#Date_Format_Patterns.
108312µs my @patterns = (
1084 qr/GGGGG/ =>
1085 sub { $_[0]->{locale}->era_narrow->[ $_[0]->_era_index() ] },
1086 qr/GGGG/ => 'era_name',
1087 qr/G{1,3}/ => 'era_abbr',
1088
1089 qr/(y{3,5})/ =>
1090 sub { $_[0]->_zero_padded_number( $1, $_[0]->year() ) },
1091
1092 # yy is a weird special case, where it must be exactly 2 digits
1093 qr/yy/ => sub {
1094 my $year = $_[0]->year();
1095 my $y2 = substr( $year, -2, 2 ) if length $year > 2;
1096 $y2 *= -1 if $year < 0;
1097 $_[0]->_zero_padded_number( 'yy', $y2 );
1098 },
1099 qr/y/ => sub { $_[0]->year() },
1100 qr/(u+)/ => sub { $_[0]->_zero_padded_number( $1, $_[0]->year() ) },
1101 qr/(Y+)/ =>
1102 sub { $_[0]->_zero_padded_number( $1, $_[0]->week_year() ) },
1103
1104 qr/QQQQ/ => 'quarter_name',
1105 qr/QQQ/ => 'quarter_abbr',
1106 qr/(QQ?)/ =>
1107 sub { $_[0]->_zero_padded_number( $1, $_[0]->quarter() ) },
1108
1109 qr/qqqq/ => sub {
1110 $_[0]->{locale}->quarter_stand_alone_wide()
1111 ->[ $_[0]->quarter_0() ];
1112 },
1113 qr/qqq/ => sub {
1114 $_[0]->{locale}->quarter_stand_alone_abbreviated()
1115 ->[ $_[0]->quarter_0() ];
1116 },
1117 qr/(qq?)/ =>
1118 sub { $_[0]->_zero_padded_number( $1, $_[0]->quarter() ) },
1119
1120 qr/MMMMM/ =>
1121 sub { $_[0]->{locale}->month_format_narrow->[ $_[0]->month_0() ] }
1122 ,
1123 qr/MMMM/ => 'month_name',
1124 qr/MMM/ => 'month_abbr',
1125 qr/(MM?)/ => sub { $_[0]->_zero_padded_number( $1, $_[0]->month() ) },
1126
1127 qr/LLLLL/ => sub {
1128 $_[0]->{locale}->month_stand_alone_narrow->[ $_[0]->month_0() ];
1129 },
1130 qr/LLLL/ => sub {
1131 $_[0]->{locale}->month_stand_alone_wide->[ $_[0]->month_0() ];
1132 },
1133 qr/LLL/ => sub {
1134 $_[0]->{locale}
1135 ->month_stand_alone_abbreviated->[ $_[0]->month_0() ];
1136 },
1137 qr/(LL?)/ => sub { $_[0]->_zero_padded_number( $1, $_[0]->month() ) },
1138
1139 qr/(ww?)/ =>
1140 sub { $_[0]->_zero_padded_number( $1, $_[0]->week_number() ) },
1141 qr/W/ => 'week_of_month',
1142
1143 qr/(dd?)/ =>
1144 sub { $_[0]->_zero_padded_number( $1, $_[0]->day_of_month() ) },
1145 qr/(D{1,3})/ =>
1146 sub { $_[0]->_zero_padded_number( $1, $_[0]->day_of_year() ) },
1147
1148 qr/F/ => 'weekday_of_month',
1149 qr/(g+)/ => sub { $_[0]->_zero_padded_number( $1, $_[0]->mjd() ) },
1150
1151 qr/EEEEE/ => sub {
1152 $_[0]->{locale}->day_format_narrow->[ $_[0]->day_of_week_0() ];
1153 },
1154 qr/EEEE/ => 'day_name',
1155 qr/E{1,3}/ => 'day_abbr',
1156
1157 qr/eeeee/ => sub {
1158 $_[0]->{locale}->day_format_narrow->[ $_[0]->day_of_week_0() ];
1159 },
1160 qr/eeee/ => 'day_name',
1161 qr/eee/ => 'day_abbr',
1162 qr/(ee?)/ => sub {
1163 $_[0]->_zero_padded_number( $1, $_[0]->local_day_of_week() );
1164 },
1165
1166 qr/ccccc/ => sub {
1167 $_[0]->{locale}
1168 ->day_stand_alone_narrow->[ $_[0]->day_of_week_0() ];
1169 },
1170 qr/cccc/ => sub {
1171 $_[0]->{locale}->day_stand_alone_wide->[ $_[0]->day_of_week_0() ];
1172 },
1173 qr/ccc/ => sub {
1174 $_[0]->{locale}
1175 ->day_stand_alone_abbreviated->[ $_[0]->day_of_week_0() ];
1176 },
1177 qr/(cc?)/ =>
1178 sub { $_[0]->_zero_padded_number( $1, $_[0]->day_of_week() ) },
1179
1180 qr/a/ => 'am_or_pm',
1181
1182 qr/(hh?)/ =>
1183 sub { $_[0]->_zero_padded_number( $1, $_[0]->hour_12() ) },
1184 qr/(HH?)/ => sub { $_[0]->_zero_padded_number( $1, $_[0]->hour() ) },
1185 qr/(KK?)/ =>
1186 sub { $_[0]->_zero_padded_number( $1, $_[0]->hour_12_0() ) },
1187 qr/(kk?)/ =>
1188 sub { $_[0]->_zero_padded_number( $1, $_[0]->hour_1() ) },
1189 qr/(jj?)/ => sub {
1190 my $h
1191 = $_[0]->{locale}->prefers_24_hour_time()
1192 ? $_[0]->hour()
1193 : $_[0]->hour_12();
1194 $_[0]->_zero_padded_number( $1, $h );
1195 },
1196
1197 qr/(mm?)/ =>
1198 sub { $_[0]->_zero_padded_number( $1, $_[0]->minute() ) },
1199
1200 qr/(ss?)/ =>
1201 sub { $_[0]->_zero_padded_number( $1, $_[0]->second() ) },
1202
1203 # I'm not sure this is what is wanted (notably the trailing
1204 # and leading zeros it can produce), but once again the LDML
1205 # spec is not all that clear.
1206 qr/(S+)/ => sub {
1207 my $l = length $1;
1208 my $val = sprintf( "%.${l}f",
1209 $_[0]->fractional_second() - $_[0]->second() );
1210 $val =~ s/^0\.//;
1211 $val || 0;
1212 },
1213 qr/A+/ =>
1214 sub { ( $_[0]->{local_rd_secs} * 1000 ) + $_[0]->millisecond() },
1215
1216 qr/zzzz/ => sub { $_[0]->time_zone_long_name() },
1217 qr/z{1,3}/ => sub { $_[0]->time_zone_short_name() },
1218 qr/ZZZZ/ => sub {
1219 $_[0]->time_zone_short_name()
1220 . DateTime::TimeZone->offset_as_string( $_[0]->offset() );
1221 },
1222 qr/Z{1,3}/ =>
1223 sub { DateTime::TimeZone->offset_as_string( $_[0]->offset() ) },
1224 qr/vvvv/ => sub { $_[0]->time_zone_long_name() },
1225 qr/v{1,3}/ => sub { $_[0]->time_zone_short_name() },
1226 qr/VVVV/ => sub { $_[0]->time_zone_long_name() },
1227 qr/V{1,3}/ => sub { $_[0]->time_zone_short_name() },
12281223µs5775µs );
# spent 75µs making 57 calls to DateTime::CORE:qr, avg 1µs/call
1229
1230 sub _zero_padded_number {
1231 my $self = shift;
1232 my $size = length shift;
1233 my $val = shift;
1234
1235 return sprintf( "%0${size}d", $val );
1236 }
1237
1238 sub _space_padded_string {
1239 my $self = shift;
1240 my $size = length shift;
1241 my $val = shift;
1242
1243 return sprintf( "% ${size}s", $val );
1244 }
1245
1246 sub format_cldr {
1247 my $self = shift;
1248
1249 # make a copy or caller's scalars get munged
1250 my @patterns = @_;
1251
1252 my @r;
1253 foreach my $p (@patterns) {
1254 $p =~ s/\G
1255 (?:
1256 '((?:[^']|'')*)' # quote escaped bit of text
1257 # it needs to end with one
1258 # quote not followed by
1259 # another
1260 |
1261 (([a-zA-Z])\3*) # could be a pattern
1262 |
1263 (.) # anything else
1264 )
1265 /
1266 defined $1
1267 ? $1
1268 : defined $2
1269 ? $self->_cldr_pattern($2)
1270 : defined $4
1271 ? $4
1272 : undef # should never get here
1273 /sgex;
1274
1275 $p =~ s/\'\'/\'/g;
1276
1277 return $p unless wantarray;
1278
1279 push @r, $p;
1280 }
1281
1282 return @r;
1283 }
1284
1285 sub _cldr_pattern {
1286 my $self = shift;
1287 my $pattern = shift;
1288
1289 for ( my $i = 0; $i < @patterns; $i += 2 ) {
1290 if ( $pattern =~ /$patterns[$i]/ ) {
1291 my $sub = $patterns[ $i + 1 ];
1292
1293 return $self->$sub();
1294 }
1295 }
1296
1297 return $pattern;
1298 }
1299}
1300
1301sub _format_nanosecs {
1302 my $self = shift;
1303 my $precision = @_ ? shift : 9;
1304
1305 my $divide_by = 10**( 9 - $precision );
1306
1307 return sprintf(
1308 '%0' . $precision . 'u',
1309 round( $self->{rd_nanosecs} / $divide_by )
1310 );
1311}
1312
1313sub epoch {
1314 my $self = shift;
1315
1316 return $self->{utc_c}{epoch}
1317 if exists $self->{utc_c}{epoch};
1318
1319 my ( $year, $month, $day ) = $self->_utc_ymd;
1320 my @hms = $self->_utc_hms;
1321
1322 $self->{utc_c}{epoch} = timegm_nocheck(
1323 ( reverse @hms ),
1324 $day,
1325 $month - 1,
1326 $year,
1327 );
1328
1329 return $self->{utc_c}{epoch};
1330}
1331
1332sub hires_epoch {
1333 my $self = shift;
1334
1335 my $epoch = $self->epoch;
1336
1337 return undef unless defined $epoch;
1338
1339 my $nano = $self->{rd_nanosecs} / MAX_NANOSECONDS;
1340
1341 return $epoch + $nano;
1342}
1343
1344sub is_finite {1}
1345sub is_infinite {0}
1346
1347# added for benefit of DateTime::TimeZone
1348sub utc_year { $_[0]->{utc_year} }
1349
1350# returns a result that is relative to the first datetime
1351sub subtract_datetime {
1352 my $dt1 = shift;
1353 my $dt2 = shift;
1354
1355 $dt2 = $dt2->clone->set_time_zone( $dt1->time_zone )
1356 unless $dt1->time_zone eq $dt2->time_zone;
1357
1358 # We only want a negative duration if $dt2 > $dt1 ($self)
1359 my ( $bigger, $smaller, $negative ) = (
1360 $dt1 >= $dt2
1361 ? ( $dt1, $dt2, 0 )
1362 : ( $dt2, $dt1, 1 )
1363 );
1364
1365 my $is_floating = $dt1->time_zone->is_floating
1366 && $dt2->time_zone->is_floating;
1367
1368 my $minute_length = 60;
1369 unless ($is_floating) {
1370 my ( $utc_rd_days, $utc_rd_secs ) = $smaller->utc_rd_values;
1371
1372 if ( $utc_rd_secs >= 86340 && !$is_floating ) {
1373
1374 # If the smaller of the two datetimes occurs in the last
1375 # UTC minute of the UTC day, then that minute may not be
1376 # 60 seconds long. If we need to subtract a minute from
1377 # the larger datetime's minutes count in order to adjust
1378 # the seconds difference to be positive, we need to know
1379 # how long that minute was. If one of the datetimes is
1380 # floating, we just assume a minute is 60 seconds.
1381
1382 $minute_length = $dt1->_day_length($utc_rd_days) - 86340;
1383 }
1384 }
1385
1386 # This is a gross hack that basically figures out if the bigger of
1387 # the two datetimes is the day of a DST change. If it's a 23 hour
1388 # day (switching _to_ DST) then we subtract 60 minutes from the
1389 # local time. If it's a 25 hour day then we add 60 minutes to the
1390 # local time.
1391 #
1392 # This produces the most "intuitive" results, though there are
1393 # still reversibility problems with the resultant duration.
1394 #
1395 # However, if the two objects are on the same (local) date, and we
1396 # are not crossing a DST change, we don't want to invoke the hack
1397 # - see 38local-subtract.t
1398 my $bigger_min = $bigger->hour * 60 + $bigger->minute;
1399 if ( $bigger->time_zone->has_dst_changes
1400 && $bigger->is_dst != $smaller->is_dst ) {
1401
1402 $bigger_min -= 60
1403
1404 # it's a 23 hour (local) day
1405 if (
1406 $bigger->is_dst
1407 && do {
1408 local $@;
1409 my $prev_day = eval { $bigger->clone->subtract( days => 1 ) };
1410 $prev_day && !$prev_day->is_dst ? 1 : 0;
1411 }
1412 );
1413
1414 $bigger_min += 60
1415
1416 # it's a 25 hour (local) day
1417 if (
1418 !$bigger->is_dst
1419 && do {
1420 local $@;
1421 my $prev_day = eval { $bigger->clone->subtract( days => 1 ) };
1422 $prev_day && $prev_day->is_dst ? 1 : 0;
1423 }
1424 );
1425 }
1426
1427 my ( $months, $days, $minutes, $seconds, $nanoseconds )
1428 = $dt1->_adjust_for_positive_difference(
1429 $bigger->year * 12 + $bigger->month,
1430 $smaller->year * 12 + $smaller->month,
1431
1432 $bigger->day, $smaller->day,
1433
1434 $bigger_min, $smaller->hour * 60 + $smaller->minute,
1435
1436 $bigger->second, $smaller->second,
1437
1438 $bigger->nanosecond, $smaller->nanosecond,
1439
1440 $minute_length,
1441
1442 # XXX - using the smaller as the month length is
1443 # somewhat arbitrary, we could also use the bigger -
1444 # either way we have reversibility problems
1445 $dt1->_month_length( $smaller->year, $smaller->month ),
1446 );
1447
1448 if ($negative) {
1449 for ( $months, $days, $minutes, $seconds, $nanoseconds ) {
1450
1451 # Some versions of Perl can end up with -0 if we do "0 * -1"!!
1452 $_ *= -1 if $_;
1453 }
1454 }
1455
1456 return $dt1->duration_class->new(
1457 months => $months,
1458 days => $days,
1459 minutes => $minutes,
1460 seconds => $seconds,
1461 nanoseconds => $nanoseconds,
1462 );
1463}
1464
1465sub _adjust_for_positive_difference {
1466 my (
1467 $self,
1468 $month1, $month2,
1469 $day1, $day2,
1470 $min1, $min2,
1471 $sec1, $sec2,
1472 $nano1, $nano2,
1473 $minute_length,
1474 $month_length,
1475 ) = @_;
1476
1477 if ( $nano1 < $nano2 ) {
1478 $sec1--;
1479 $nano1 += MAX_NANOSECONDS;
1480 }
1481
1482 if ( $sec1 < $sec2 ) {
1483 $min1--;
1484 $sec1 += $minute_length;
1485 }
1486
1487 # A day always has 24 * 60 minutes, though the minutes may vary in
1488 # length.
1489 if ( $min1 < $min2 ) {
1490 $day1--;
1491 $min1 += 24 * 60;
1492 }
1493
1494 if ( $day1 < $day2 ) {
1495 $month1--;
1496 $day1 += $month_length;
1497 }
1498
1499 return (
1500 $month1 - $month2,
1501 $day1 - $day2,
1502 $min1 - $min2,
1503 $sec1 - $sec2,
1504 $nano1 - $nano2,
1505 );
1506}
1507
1508sub subtract_datetime_absolute {
1509 my $self = shift;
1510 my $dt = shift;
1511
1512 my $utc_rd_secs1 = $self->utc_rd_as_seconds;
1513 $utc_rd_secs1
1514 += DateTime->_accumulated_leap_seconds( $self->{utc_rd_days} )
1515 if !$self->time_zone->is_floating;
1516
1517 my $utc_rd_secs2 = $dt->utc_rd_as_seconds;
1518 $utc_rd_secs2 += DateTime->_accumulated_leap_seconds( $dt->{utc_rd_days} )
1519 if !$dt->time_zone->is_floating;
1520
1521 my $seconds = $utc_rd_secs1 - $utc_rd_secs2;
1522 my $nanoseconds = $self->nanosecond - $dt->nanosecond;
1523
1524 if ( $nanoseconds < 0 ) {
1525 $seconds--;
1526 $nanoseconds += MAX_NANOSECONDS;
1527 }
1528
1529 return $self->duration_class->new(
1530 seconds => $seconds,
1531 nanoseconds => $nanoseconds,
1532 );
1533}
1534
1535sub delta_md {
1536 my $self = shift;
1537 my $dt = shift;
1538
1539 my ( $smaller, $bigger ) = sort $self, $dt;
1540
1541 my ( $months, $days, undef, undef, undef )
1542 = $dt->_adjust_for_positive_difference(
1543 $bigger->year * 12 + $bigger->month,
1544 $smaller->year * 12 + $smaller->month,
1545
1546 $bigger->day, $smaller->day,
1547
1548 0, 0,
1549
1550 0, 0,
1551
1552 0, 0,
1553
1554 60,
1555
1556 $smaller->_month_length( $smaller->year, $smaller->month ),
1557 );
1558
1559 return $self->duration_class->new(
1560 months => $months,
1561 days => $days
1562 );
1563}
1564
1565sub delta_days {
1566 my $self = shift;
1567 my $dt = shift;
1568
1569 my $days
1570 = abs( ( $self->local_rd_values )[0] - ( $dt->local_rd_values )[0] );
1571
1572 $self->duration_class->new( days => $days );
1573}
1574
1575sub delta_ms {
1576 my $self = shift;
1577 my $dt = shift;
1578
1579 my ( $smaller, $greater ) = sort $self, $dt;
1580
1581 my $days = int( $greater->jd - $smaller->jd );
1582
1583 my $dur = $greater->subtract_datetime($smaller);
1584
1585 my %p;
1586 $p{hours} = $dur->hours + ( $days * 24 );
1587 $p{minutes} = $dur->minutes;
1588 $p{seconds} = $dur->seconds;
1589
1590 return $self->duration_class->new(%p);
1591}
1592
1593sub _add_overload {
1594 my ( $dt, $dur, $reversed ) = @_;
1595
1596 if ($reversed) {
1597 ( $dur, $dt ) = ( $dt, $dur );
1598 }
1599
1600 unless ( DateTime::Helpers::isa( $dur, 'DateTime::Duration' ) ) {
1601 my $class = ref $dt;
1602 my $dt_string = overload::StrVal($dt);
1603
1604 Carp::croak( "Cannot add $dur to a $class object ($dt_string).\n"
1605 . " Only a DateTime::Duration object can "
1606 . " be added to a $class object." );
1607 }
1608
1609 return $dt->clone->add_duration($dur);
1610}
1611
1612sub _subtract_overload {
1613 my ( $date1, $date2, $reversed ) = @_;
1614
1615 if ($reversed) {
1616 ( $date2, $date1 ) = ( $date1, $date2 );
1617 }
1618
1619 if ( DateTime::Helpers::isa( $date2, 'DateTime::Duration' ) ) {
1620 my $new = $date1->clone;
1621 $new->add_duration( $date2->inverse );
1622 return $new;
1623 }
1624 elsif ( DateTime::Helpers::isa( $date2, 'DateTime' ) ) {
1625 return $date1->subtract_datetime($date2);
1626 }
1627 else {
1628 my $class = ref $date1;
1629 my $dt_string = overload::StrVal($date1);
1630
1631 Carp::croak(
1632 "Cannot subtract $date2 from a $class object ($dt_string).\n"
1633 . " Only a DateTime::Duration or DateTime object can "
1634 . " be subtracted from a $class object." );
1635 }
1636}
1637
1638sub add {
1639 my $self = shift;
1640
1641 return $self->add_duration( $self->duration_class->new(@_) );
1642}
1643
1644sub subtract {
1645 my $self = shift;
1646
1647 return $self->subtract_duration( $self->duration_class->new(@_) );
1648}
1649
1650sub subtract_duration { return $_[0]->add_duration( $_[1]->inverse ) }
1651
1652{
165323µs my @spec = ( { isa => 'DateTime::Duration' } );
1654
1655 sub add_duration {
1656 my $self = shift;
1657 my ($dur) = validate_pos( @_, @spec );
1658
1659 # simple optimization
1660 return $self if $dur->is_zero;
1661
1662 my %deltas = $dur->deltas;
1663
1664 # This bit isn't quite right since DateTime::Infinite::Future -
1665 # infinite duration should NaN
1666 foreach my $val ( values %deltas ) {
1667 my $inf;
1668 if ( $val == INFINITY ) {
1669 $inf = DateTime::Infinite::Future->new;
1670 }
1671 elsif ( $val == NEG_INFINITY ) {
1672 $inf = DateTime::Infinite::Past->new;
1673 }
1674
1675 if ($inf) {
1676 %$self = %$inf;
1677 bless $self, ref $inf;
1678
1679 return $self;
1680 }
1681 }
1682
1683 return $self if $self->is_infinite;
1684
1685 if ( $deltas{days} ) {
1686 $self->{local_rd_days} += $deltas{days};
1687
1688 $self->{utc_year} += int( $deltas{days} / 365 ) + 1;
1689 }
1690
1691 if ( $deltas{months} ) {
1692
1693 # For preserve mode, if it is the last day of the month, make
1694 # it the 0th day of the following month (which then will
1695 # normalize back to the last day of the new month).
1696 my ( $y, $m, $d ) = (
1697 $dur->is_preserve_mode
1698 ? $self->_rd2ymd( $self->{local_rd_days} + 1 )
1699 : $self->_rd2ymd( $self->{local_rd_days} )
1700 );
1701
1702 $d -= 1 if $dur->is_preserve_mode;
1703
1704 if ( !$dur->is_wrap_mode && $d > 28 ) {
1705
1706 # find the rd for the last day of our target month
1707 $self->{local_rd_days}
1708 = $self->_ymd2rd( $y, $m + $deltas{months} + 1, 0 );
1709
1710 # what day of the month is it? (discard year and month)
1711 my $last_day
1712 = ( $self->_rd2ymd( $self->{local_rd_days} ) )[2];
1713
1714 # if our original day was less than the last day,
1715 # use that instead
1716 $self->{local_rd_days} -= $last_day - $d if $last_day > $d;
1717 }
1718 else {
1719 $self->{local_rd_days}
1720 = $self->_ymd2rd( $y, $m + $deltas{months}, $d );
1721 }
1722
1723 $self->{utc_year} += int( $deltas{months} / 12 ) + 1;
1724 }
1725
1726 if ( $deltas{days} || $deltas{months} ) {
1727 $self->_calc_utc_rd;
1728
1729 $self->_handle_offset_modifier( $self->second );
1730 }
1731
1732 if ( $deltas{minutes} ) {
1733 $self->{utc_rd_secs} += $deltas{minutes} * 60;
1734
1735 # This intentionally ignores leap seconds
1736 $self->_normalize_tai_seconds( $self->{utc_rd_days},
1737 $self->{utc_rd_secs} );
1738 }
1739
1740 if ( $deltas{seconds} || $deltas{nanoseconds} ) {
1741 $self->{utc_rd_secs} += $deltas{seconds};
1742
1743 if ( $deltas{nanoseconds} ) {
1744 $self->{rd_nanosecs} += $deltas{nanoseconds};
1745 $self->_normalize_nanoseconds( $self->{utc_rd_secs},
1746 $self->{rd_nanosecs} );
1747 }
1748
1749 $self->_normalize_seconds;
1750
1751 # This might be some big number much bigger than 60, but
1752 # that's ok (there are tests in 19leap_second.t to confirm
1753 # that)
1754 $self->_handle_offset_modifier(
1755 $self->second + $deltas{seconds} );
1756 }
1757
1758 my $new = ( ref $self )->from_object(
1759 object => $self,
1760 locale => $self->{locale},
1761 ( $self->{formatter} ? ( formatter => $self->{formatter} ) : () ),
1762 );
1763
1764 %$self = %$new;
1765
1766 return $self;
1767 }
1768}
1769
1770sub _compare_overload {
1771
1772 # note: $_[1]->compare( $_[0] ) is an error when $_[1] is not a
1773 # DateTime (such as the INFINITY value)
1774 return $_[2] ? -$_[0]->compare( $_[1] ) : $_[0]->compare( $_[1] );
1775}
1776
1777sub _string_compare_overload {
1778 my ( $dt1, $dt2, $flip ) = @_;
1779
1780 # One is a DateTime object, one isn't. Just stringify and compare.
1781 if ( !DateTime::Helpers::can( $dt2, 'utc_rd_values' ) ) {
1782 my $sign = $flip ? -1 : 1;
1783 return $sign * ( "$dt1" cmp "$dt2" );
1784 }
1785 else {
1786 my $meth = $dt1->can('_compare_overload');
1787 goto $meth;
1788 }
1789}
1790
1791sub compare {
1792 shift->_compare( @_, 0 );
1793}
1794
1795sub compare_ignore_floating {
1796 shift->_compare( @_, 1 );
1797}
1798
1799sub _compare {
1800 my ( $class, $dt1, $dt2, $consistent ) = ref $_[0] ? ( undef, @_ ) : @_;
1801
1802 return undef unless defined $dt2;
1803
1804 if ( !ref $dt2 && ( $dt2 == INFINITY || $dt2 == NEG_INFINITY ) ) {
1805 return $dt1->{utc_rd_days} <=> $dt2;
1806 }
1807
1808 unless ( DateTime::Helpers::can( $dt1, 'utc_rd_values' )
1809 && DateTime::Helpers::can( $dt2, 'utc_rd_values' ) ) {
1810 my $dt1_string = overload::StrVal($dt1);
1811 my $dt2_string = overload::StrVal($dt2);
1812
1813 Carp::croak( "A DateTime object can only be compared to"
1814 . " another DateTime object ($dt1_string, $dt2_string)." );
1815 }
1816
1817 if ( !$consistent
1818 && DateTime::Helpers::can( $dt1, 'time_zone' )
1819 && DateTime::Helpers::can( $dt2, 'time_zone' ) ) {
1820 my $is_floating1 = $dt1->time_zone->is_floating;
1821 my $is_floating2 = $dt2->time_zone->is_floating;
1822
1823 if ( $is_floating1 && !$is_floating2 ) {
1824 $dt1 = $dt1->clone->set_time_zone( $dt2->time_zone );
1825 }
1826 elsif ( $is_floating2 && !$is_floating1 ) {
1827 $dt2 = $dt2->clone->set_time_zone( $dt1->time_zone );
1828 }
1829 }
1830
1831 my @dt1_components = $dt1->utc_rd_values;
1832 my @dt2_components = $dt2->utc_rd_values;
1833
1834 foreach my $i ( 0 .. 2 ) {
1835 return $dt1_components[$i] <=> $dt2_components[$i]
1836 if $dt1_components[$i] != $dt2_components[$i];
1837 }
1838
1839 return 0;
1840}
1841
1842sub _string_equals_overload {
1843 my ( $class, $dt1, $dt2 ) = ref $_[0] ? ( undef, @_ ) : @_;
1844
1845 if ( !DateTime::Helpers::can( $dt2, 'utc_rd_values' ) ) {
1846 return "$dt1" eq "$dt2";
1847 }
1848
1849 $class ||= ref $dt1;
1850 return !$class->compare( $dt1, $dt2 );
1851}
1852
1853sub _string_not_equals_overload {
1854 return !_string_equals_overload(@_);
1855}
1856
1857
# spent 1.13ms within DateTime::_normalize_nanoseconds which was called 294 times, avg 4µs/call: # 294 times (1.13ms+0s) by DateTime::_new at line 254, avg 4µs/call
sub _normalize_nanoseconds {
185831.80ms232µs
# spent 27µs (22+5) within DateTime::BEGIN@1858 which was called: # once (22µs+5µs) by Tapper::Schema::TestrunDB::ResultSet::Testrun::BEGIN@12 at line 1858
use integer;
# spent 27µs making 1 call to DateTime::BEGIN@1858 # spent 5µs making 1 call to integer::import
1859
1860 # seconds, nanoseconds
18612941.40ms if ( $_[2] < 0 ) {
1862 my $overflow = 1 + $_[2] / MAX_NANOSECONDS;
1863 $_[2] += $overflow * MAX_NANOSECONDS;
1864 $_[1] -= $overflow;
1865 }
1866 elsif ( $_[2] >= MAX_NANOSECONDS ) {
1867 my $overflow = $_[2] / MAX_NANOSECONDS;
1868 $_[2] -= $overflow * MAX_NANOSECONDS;
1869 $_[1] += $overflow;
1870 }
1871}
1872
1873# Many of the same parameters as new() but all of them are optional,
1874# and there are no defaults.
1875my $SetValidate = {
1876 map {
18771122µs my %copy = %{ $BasicValidate->{$_} };
1878103µs delete $copy{default};
1879103µs $copy{optional} = 1;
1880105µs $_ => \%copy
1881 }
1882 keys %$BasicValidate
1883};
1884
1885sub set {
1886 my $self = shift;
1887 my %p = validate( @_, $SetValidate );
1888
1889 my $new_dt = $self->_new_from_self(%p);
1890
1891 %$self = %$new_dt;
1892
1893 return $self;
1894}
1895
1896sub set_year { $_[0]->set( year => $_[1] ) }
1897sub set_month { $_[0]->set( month => $_[1] ) }
1898sub set_day { $_[0]->set( day => $_[1] ) }
1899sub set_hour { $_[0]->set( hour => $_[1] ) }
1900sub set_minute { $_[0]->set( minute => $_[1] ) }
1901sub set_second { $_[0]->set( second => $_[1] ) }
1902sub set_nanosecond { $_[0]->set( nanosecond => $_[1] ) }
1903sub set_locale { $_[0]->set( locale => $_[1] ) }
1904sub set_formatter { $_[0]->set( formatter => $_[1] ) }
1905
1906{
190723µs my %TruncateDefault = (
1908 month => 1,
1909 day => 1,
1910 hour => 0,
1911 minute => 0,
1912 second => 0,
1913 nanosecond => 0,
1914 );
1915 my $re = join '|', 'year', 'week',
191614µs grep { $_ ne 'nanosecond' } keys %TruncateDefault;
1917153µs244µs my $spec = { to => { regex => qr/^(?:$re)/ } };
# spent 43µs making 1 call to DateTime::CORE:regcomp # spent 1µs making 1 call to DateTime::CORE:qr
1918
1919 sub truncate {
1920 my $self = shift;
1921 my %p = validate( @_, $spec );
1922
1923 my %new;
1924 if ( $p{to} eq 'week' ) {
1925 my $day_diff = $self->day_of_week - 1;
1926
1927 if ($day_diff) {
1928 $self->add( days => -1 * $day_diff );
1929 }
1930
1931 return $self->truncate( to => 'day' );
1932 }
1933 else {
1934 my $truncate;
1935 foreach my $f (qw( year month day hour minute second nanosecond ))
1936 {
1937 $new{$f} = $truncate ? $TruncateDefault{$f} : $self->$f();
1938
1939 $truncate = 1 if $p{to} eq $f;
1940 }
1941 }
1942
1943 my $new_dt = $self->_new_from_self( %new, _skip_validation => 1 );
1944
1945 %$self = %$new_dt;
1946
1947 return $self;
1948 }
1949}
1950
1951
# spent 59.5ms (9.86+49.6) within DateTime::set_time_zone which was called 294 times, avg 202µs/call: # 294 times (9.86ms+49.6ms) by DateTime::Format::SQLite::format_datetime at line 103 of DateTime/Format/SQLite.pm, avg 202µs/call
sub set_time_zone {
195220587.96ms my ( $self, $tz ) = @_;
1953
1954 # This is a bit of a hack but it works because time zone objects
1955 # are singletons, and if it doesn't work all we lose is a little
1956 # bit of speed.
1957 return $self if $self->{tz} eq $tz;
1958
1959294588µs my $was_floating = $self->{tz}->is_floating;
# spent 588µs making 294 calls to DateTime::TimeZone::is_floating, avg 2µs/call
1960
196129428.7ms $self->{tz} = ref $tz ? $tz : DateTime::TimeZone->new( name => $tz );
# spent 28.7ms making 294 calls to DateTime::TimeZone::new, avg 98µs/call
1962
19635888.76ms $self->_handle_offset_modifier( $self->second, 1 );
# spent 7.46ms making 294 calls to DateTime::_handle_offset_modifier, avg 25µs/call # spent 1.30ms making 294 calls to DateTime::second, avg 4µs/call
1964
1965 # if it either was or now is floating (but not both)
196658811.6ms if ( $self->{tz}->is_floating xor $was_floating ) {
# spent 11.2ms making 294 calls to DateTime::_calc_local_rd, avg 38µs/call # spent 343µs making 294 calls to DateTime::TimeZone::is_floating, avg 1µs/call
1967 $self->_calc_utc_rd;
1968 }
1969 elsif ( !$was_floating ) {
1970 $self->_calc_local_rd;
1971 }
1972
1973 return $self;
1974}
1975
1976sub STORABLE_freeze {
1977 my $self = shift;
1978 my $cloning = shift;
1979
1980 my $serialized = '';
1981 foreach my $key (
1982 qw( utc_rd_days
1983 utc_rd_secs
1984 rd_nanosecs )
1985 ) {
1986 $serialized .= "$key:$self->{$key}|";
1987 }
1988
1989 # not used yet, but may be handy in the future.
1990 $serialized .= "version:$DateTime::VERSION";
1991
1992 # Formatter needs to be returned as a reference since it may be
1993 # undef or a class name, and Storable will complain if extra
1994 # return values aren't refs
1995 return $serialized, $self->{locale}, $self->{tz}, \$self->{formatter};
1996}
1997
1998sub STORABLE_thaw {
1999 my $self = shift;
2000 my $cloning = shift;
2001 my $serialized = shift;
2002
2003 my %serialized = map { split /:/ } split /\|/, $serialized;
2004
2005 my ( $locale, $tz, $formatter );
2006
2007 # more recent code version
2008 if (@_) {
2009 ( $locale, $tz, $formatter ) = @_;
2010 }
2011 else {
2012 $tz = DateTime::TimeZone->new( name => delete $serialized{tz} );
2013
2014 $locale = DateTime::Locale->load(
2015 exists $serialized{language}
2016 ? delete $serialized{language}
2017 : delete $serialized{locale}
2018 );
2019 }
2020
2021 delete $serialized{version};
2022
2023 my $object = bless {
2024 utc_vals => [
2025 $serialized{utc_rd_days},
2026 $serialized{utc_rd_secs},
2027 $serialized{rd_nanosecs},
2028 ],
2029 tz => $tz,
2030 },
2031 'DateTime::_Thawed';
2032
2033 my %formatter = defined $$formatter ? ( formatter => $$formatter ) : ();
2034 my $new = ( ref $self )->from_object(
2035 object => $object,
2036 locale => $locale,
2037 %formatter,
2038 );
2039
2040 %$self = %$new;
2041
2042 return $self;
2043}
2044
2045package
2046 DateTime::_Thawed;
2047
2048sub utc_rd_values { @{ $_[0]->{utc_vals} } }
2049
2050sub time_zone { $_[0]->{tz} }
2051
20521101µs1;
2053
2054# ABSTRACT: A date and time object
2055
- -
2058=pod
2059
2060=head1 NAME
2061
2062DateTime - A date and time object
2063
2064=head1 VERSION
2065
2066version 0.74
2067
2068=head1 SYNOPSIS
2069
2070 use DateTime;
2071
2072 $dt = DateTime->new(
2073 year => 1964,
2074 month => 10,
2075 day => 16,
2076 hour => 16,
2077 minute => 12,
2078 second => 47,
2079 nanosecond => 500000000,
2080 time_zone => 'Asia/Taipei',
2081 );
2082
2083 $dt = DateTime->from_epoch( epoch => $epoch );
2084 $dt = DateTime->now; # same as ( epoch => time() )
2085
2086 $year = $dt->year;
2087 $month = $dt->month; # 1-12
2088
2089 $day = $dt->day; # 1-31
2090
2091 $dow = $dt->day_of_week; # 1-7 (Monday is 1)
2092
2093 $hour = $dt->hour; # 0-23
2094 $minute = $dt->minute; # 0-59
2095
2096 $second = $dt->second; # 0-61 (leap seconds!)
2097
2098 $doy = $dt->day_of_year; # 1-366 (leap years)
2099
2100 $doq = $dt->day_of_quarter; # 1..
2101
2102 $qtr = $dt->quarter; # 1-4
2103
2104 # all of the start-at-1 methods above have corresponding start-at-0
2105 # methods, such as $dt->day_of_month_0, $dt->month_0 and so on
2106
2107 $ymd = $dt->ymd; # 2002-12-06
2108 $ymd = $dt->ymd('/'); # 2002/12/06
2109
2110 $mdy = $dt->mdy; # 12-06-2002
2111 $mdy = $dt->mdy('/'); # 12/06/2002
2112
2113 $dmy = $dt->dmy; # 06-12-2002
2114 $dmy = $dt->dmy('/'); # 06/12/2002
2115
2116 $hms = $dt->hms; # 14:02:29
2117 $hms = $dt->hms('!'); # 14!02!29
2118
2119 $is_leap = $dt->is_leap_year;
2120
2121 # these are localizable, see Locales section
2122 $month_name = $dt->month_name; # January, February, ...
2123 $month_abbr = $dt->month_abbr; # Jan, Feb, ...
2124 $day_name = $dt->day_name; # Monday, Tuesday, ...
2125 $day_abbr = $dt->day_abbr; # Mon, Tue, ...
2126
2127 # May not work for all possible datetime, see the docs on this
2128 # method for more details.
2129 $epoch_time = $dt->epoch;
2130
2131 $dt2 = $dt + $duration_object;
2132
2133 $dt3 = $dt - $duration_object;
2134
2135 $duration_object = $dt - $dt2;
2136
2137 $dt->set( year => 1882 );
2138
2139 $dt->set_time_zone( 'America/Chicago' );
2140
2141 $dt->set_formatter( $formatter );
2142
2143=head1 DESCRIPTION
2144
2145DateTime is a class for the representation of date/time combinations,
2146and is part of the Perl DateTime project. For details on this project
2147please see L<http://datetime.perl.org/>. The DateTime site has a FAQ
2148which may help answer many "how do I do X?" questions. The FAQ is at
2149L<http://datetime.perl.org/wiki/datetime/page/FAQ>.
2150
2151It represents the Gregorian calendar, extended backwards in time
2152before its creation (in 1582). This is sometimes known as the
2153"proleptic Gregorian calendar". In this calendar, the first day of
2154the calendar (the epoch), is the first day of year 1, which
2155corresponds to the date which was (incorrectly) believed to be the
2156birth of Jesus Christ.
2157
2158The calendar represented does have a year 0, and in that way differs
2159from how dates are often written using "BCE/CE" or "BC/AD".
2160
2161For infinite datetimes, please see the
2162L<DateTime::Infinite|DateTime::Infinite> module.
2163
2164=head1 USAGE
2165
2166=head2 0-based Versus 1-based Numbers
2167
2168The DateTime.pm module follows a simple consistent logic for
2169determining whether or not a given number is 0-based or 1-based.
2170
2171Month, day of month, day of week, and day of year are 1-based. Any
2172method that is 1-based also has an equivalent 0-based method ending in
2173"_0". So for example, this class provides both C<day_of_week()> and
2174C<day_of_week_0()> methods.
2175
2176The C<day_of_week_0()> method still treats Monday as the first day of
2177the week.
2178
2179All I<time>-related numbers such as hour, minute, and second are
21800-based.
2181
2182Years are neither, as they can be both positive or negative, unlike
2183any other datetime component. There I<is> a year 0.
2184
2185There is no C<quarter_0()> method.
2186
2187=head2 Error Handling
2188
2189Some errors may cause this module to die with an error string. This
2190can only happen when calling constructor methods, methods that change
2191the object, such as C<set()>, or methods that take parameters.
2192Methods that retrieve information about the object, such as C<year()>
2193or C<epoch()>, will never die.
2194
2195=head2 Locales
2196
2197All the object methods which return names or abbreviations return data
2198based on a locale. This is done by setting the locale when
2199constructing a DateTime object. There is also a C<DefaultLocale()>
2200class method which may be used to set the default locale for all
2201DateTime objects created. If this is not set, then "en_US" is used.
2202
2203=head2 Floating DateTimes
2204
2205The default time zone for new DateTime objects, except where stated
2206otherwise, is the "floating" time zone. This concept comes from the
2207iCal standard. A floating datetime is one which is not anchored to
2208any particular time zone. In addition, floating datetimes do not
2209include leap seconds, since we cannot apply them without knowing the
2210datetime's time zone.
2211
2212The results of date math and comparison between a floating datetime
2213and one with a real time zone are not really valid, because one
2214includes leap seconds and the other does not. Similarly, the results
2215of datetime math between two floating datetimes and two datetimes with
2216time zones are not really comparable.
2217
2218If you are planning to use any objects with a real time zone, it is
2219strongly recommended that you B<do not> mix these with floating
2220datetimes.
2221
2222=head2 Math
2223
2224If you are going to be using doing date math, please read the section L<How
2225Datetime Math Works>.
2226
2227=head2 Time Zone Warnings
2228
2229Determining the local time zone for a system can be slow. If C<$ENV{TZ}> is
2230not set, it may involve reading a number of files in F</etc> or elsewhere. If
2231you know that the local time zone won't change while your code is running, and
2232you need to make many objects for the local time zone, it is strongly
2233recommended that you retrieve the local time zone once and cache it:
2234
2235 our $App::LocalTZ = DateTime::TimeZone->new( name => 'local' );
2236
2237 ... # then everywhere else
2238
2239 my $dt = DateTime->new( ..., time_zone => $App::LocalTZ );
2240
2241DateTime itself does not do this internally because local time zones can
2242change, and there's no good way to determine if it's changed without doing all
2243the work to look it up.
2244
2245Do not try to use named time zones (like "America/Chicago") with dates
2246very far in the future (thousands of years). The current
2247implementation of C<DateTime::TimeZone> will use a huge amount of
2248memory calculating all the DST changes from now until the future
2249date. Use UTC or the floating time zone and you will be safe.
2250
2251=head2 Methods
2252
2253=head3 Constructors
2254
2255All constructors can die when invalid parameters are given.
2256
2257=over 4
2258
2259=item * DateTime->new( ... )
2260
2261This class method accepts parameters for each date and time component:
2262"year", "month", "day", "hour", "minute", "second", "nanosecond".
2263It also accepts "locale", "time_zone", and "formatter" parameters.
2264
2265 my $dt = DateTime->new(
2266 year => 1966,
2267 month => 10,
2268 day => 25,
2269 hour => 7,
2270 minute => 15,
2271 second => 47,
2272 nanosecond => 500000000,
2273 time_zone => 'America/Chicago',
2274 );
2275
2276DateTime validates the "month", "day", "hour", "minute", and "second",
2277and "nanosecond" parameters. The valid values for these parameters are:
2278
2279=over 8
2280
2281=item * month
2282
2283An integer from 1-12.
2284
2285=item * day
2286
2287An integer from 1-31, and it must be within the valid range of days for the
2288specified month.
2289
2290=item * hour
2291
2292An integer from 0-23.
2293
2294=item * minute
2295
2296An integer from 0-59.
2297
2298=item * second
2299
2300An integer from 0-61 (to allow for leap seconds). Values of 60 or 61 are only
2301allowed when they match actual leap seconds.
2302
2303=item * nanosecond
2304
2305An integer >= 0. If this number is greater than 1 billion, it will be
2306normalized into the second value for the DateTime object.
2307
2308=back
2309
2310Invalid parameter types (like an array reference) will cause the
2311constructor to die.
2312
2313The value for seconds may be from 0 to 61, to account for leap
2314seconds. If you give a value greater than 59, DateTime does check to
2315see that it really matches a valid leap second.
2316
2317All of the parameters are optional except for "year". The "month" and
2318"day" parameters both default to 1, while the "hour", "minute",
2319"second", and "nanosecond" parameters all default to 0.
2320
2321The "locale" parameter should be a string matching one of the valid
2322locales, or a C<DateTime::Locale> object. See the
2323L<DateTime::Locale|DateTime::Locale> documentation for details.
2324
2325The time_zone parameter can be either a scalar or a
2326C<DateTime::TimeZone> object. A string will simply be passed to the
2327C<< DateTime::TimeZone->new >> method as its "name" parameter. This
2328string may be an Olson DB time zone name ("America/Chicago"), an
2329offset string ("+0630"), or the words "floating" or "local". See the
2330C<DateTime::TimeZone> documentation for more details.
2331
2332The default time zone is "floating".
2333
2334The "formatter" can be either a scalar or an object, but the class
2335specified by the scalar or the object must implement a
2336C<format_datetime()> method.
2337
2338=back
2339
2340=head4 Parsing Dates
2341
2342B<This module does not parse dates!> That means there is no
2343constructor to which you can pass things like "March 3, 1970 12:34".
2344
2345Instead, take a look at the various C<DateTime::Format::*> modules on
2346CPAN. These parse all sorts of different date formats, and you're
2347bound to find something that can handle your particular needs.
2348
2349=head4 Ambiguous Local Times
2350
2351Because of Daylight Saving Time, it is possible to specify a local
2352time that is ambiguous. For example, in the US in 2003, the
2353transition from to saving to standard time occurred on October 26, at
235402:00:00 local time. The local clock changed from 01:59:59 (saving
2355time) to 01:00:00 (standard time). This means that the hour from
235601:00:00 through 01:59:59 actually occurs twice, though the UTC time
2357continues to move forward.
2358
2359If you specify an ambiguous time, then the latest UTC time is always
2360used, in effect always choosing standard time. In this case, you can
2361simply subtract an hour to the object in order to move to saving time,
2362for example:
2363
2364 # This object represent 01:30:00 standard time
2365 my $dt = DateTime->new(
2366 year => 2003,
2367 month => 10,
2368 day => 26,
2369 hour => 1,
2370 minute => 30,
2371 second => 0,
2372 time_zone => 'America/Chicago',
2373 );
2374
2375 print $dt->hms; # prints 01:30:00
2376
2377 # Now the object represent 01:30:00 saving time
2378 $dt->subtract( hours => 1 );
2379
2380 print $dt->hms; # still prints 01:30:00
2381
2382Alternately, you could create the object with the UTC time zone, and
2383then call the C<set_time_zone()> method to change the time zone. This
2384is a good way to ensure that the time is not ambiguous.
2385
2386=head4 Invalid Local Times
2387
2388Another problem introduced by Daylight Saving Time is that certain
2389local times just do not exist. For example, in the US in 2003, the
2390transition from standard to saving time occurred on April 6, at the
2391change to 2:00:00 local time. The local clock changes from 01:59:59
2392(standard time) to 03:00:00 (saving time). This means that there is
2393no 02:00:00 through 02:59:59 on April 6!
2394
2395Attempting to create an invalid time currently causes a fatal error.
2396This may change in future version of this module.
2397
2398=over 4
2399
2400=item * DateTime->from_epoch( epoch => $epoch, ... )
2401
2402This class method can be used to construct a new DateTime object from
2403an epoch time instead of components. Just as with the C<new()>
2404method, it accepts "time_zone", "locale", and "formatter" parameters.
2405
2406If the epoch value is not an integer, the part after the decimal will
2407be converted to nanoseconds. This is done in order to be compatible
2408with C<Time::HiRes>. If the floating portion extends past 9 decimal
2409places, it will be truncated to nine, so that 1.1234567891 will become
24101 second and 123,456,789 nanoseconds.
2411
2412By default, the returned object will be in the UTC time zone.
2413
2414=item * DateTime->now( ... )
2415
2416This class method is equivalent to calling C<from_epoch()> with the
2417value returned from Perl's C<time()> function. Just as with the
2418C<new()> method, it accepts "time_zone" and "locale" parameters.
2419
2420By default, the returned object will be in the UTC time zone.
2421
2422=item * DateTime->today( ... )
2423
2424This class method is equivalent to:
2425
2426 DateTime->now->truncate( to => 'day' );
2427
2428=item * DateTime->from_object( object => $object, ... )
2429
2430This class method can be used to construct a new DateTime object from
2431any object that implements the C<utc_rd_values()> method. All
2432C<DateTime::Calendar> modules must implement this method in order to
2433provide cross-calendar compatibility. This method accepts a
2434"locale" and "formatter" parameter
2435
2436If the object passed to this method has a C<time_zone()> method, that
2437is used to set the time zone of the newly created C<DateTime.pm>
2438object.
2439
2440Otherwise, the returned object will be in the floating time zone.
2441
2442=item * DateTime->last_day_of_month( ... )
2443
2444This constructor takes the same arguments as can be given to the
2445C<new()> method, except for "day". Additionally, both "year" and
2446"month" are required.
2447
2448=item * DateTime->from_day_of_year( ... )
2449
2450This constructor takes the same arguments as can be given to the
2451C<new()> method, except that it does not accept a "month" or "day"
2452argument. Instead, it requires both "year" and "day_of_year". The
2453day of year must be between 1 and 366, and 366 is only allowed for
2454leap years.
2455
2456=item * $dt->clone()
2457
2458This object method returns a new object that is replica of the object
2459upon which the method is called.
2460
2461=back
2462
2463=head3 "Get" Methods
2464
2465This class has many methods for retrieving information about an
2466object.
2467
2468=over 4
2469
2470=item * $dt->year()
2471
2472Returns the year.
2473
2474=item * $dt->ce_year()
2475
2476Returns the year according to the BCE/CE numbering system. The year
2477before year 1 in this system is year -1, aka "1 BCE".
2478
2479=item * $dt->era_name()
2480
2481Returns the long name of the current era, something like "Before
2482Christ". See the L<Locales|/Locales> section for more details.
2483
2484=item * $dt->era_abbr()
2485
2486Returns the abbreviated name of the current era, something like "BC".
2487See the L<Locales|/Locales> section for more details.
2488
2489=item * $dt->christian_era()
2490
2491Returns a string, either "BC" or "AD", according to the year.
2492
2493=item * $dt->secular_era()
2494
2495Returns a string, either "BCE" or "CE", according to the year.
2496
2497=item * $dt->year_with_era()
2498
2499Returns a string containing the year immediately followed by its era
2500abbreviation. The year is the absolute value of C<ce_year()>, so that
2501year 1 is "1AD" and year 0 is "1BC".
2502
2503=item * $dt->year_with_christian_era()
2504
2505Like C<year_with_era()>, but uses the christian_era() method to get the era
2506name.
2507
2508=item * $dt->year_with_secular_era()
2509
2510Like C<year_with_era()>, but uses the secular_era() method to get the
2511era name.
2512
2513=item * $dt->month()
2514
2515Returns the month of the year, from 1..12.
2516
2517Also available as C<< $dt->mon() >>.
2518
2519=item * $dt->month_name()
2520
2521Returns the name of the current month. See the
2522L<Locales|/Locales> section for more details.
2523
2524=item * $dt->month_abbr()
2525
2526Returns the abbreviated name of the current month. See the
2527L<Locales|/Locales> section for more details.
2528
2529=item * $dt->day()
2530
2531Returns the day of the month, from 1..31.
2532
2533Also available as C<< $dt->mday() >> and C<< $dt->day_of_month() >>.
2534
2535=item * $dt->day_of_week()
2536
2537Returns the day of the week as a number, from 1..7, with 1 being
2538Monday and 7 being Sunday.
2539
2540Also available as C<< $dt->wday() >> and C<< $dt->dow() >>.
2541
2542=item * $dt->local_day_of_week()
2543
2544Returns the day of the week as a number, from 1..7. The day
2545corresponding to 1 will vary based on the locale.
2546
2547=item * $dt->day_name()
2548
2549Returns the name of the current day of the week. See the
2550L<Locales|/Locales> section for more details.
2551
2552=item * $dt->day_abbr()
2553
2554Returns the abbreviated name of the current day of the week. See the
2555L<Locales|/Locales> section for more details.
2556
2557=item * $dt->day_of_year()
2558
2559Returns the day of the year.
2560
2561Also available as C<< $dt->doy() >>.
2562
2563=item * $dt->quarter()
2564
2565Returns the quarter of the year, from 1..4.
2566
2567=item * $dt->quarter_name()
2568
2569Returns the name of the current quarter. See the
2570L<Locales|/Locales> section for more details.
2571
2572=item * $dt->quarter_abbr()
2573
2574Returns the abbreviated name of the current quarter. See the
2575L<Locales|/Locales> section for more details.
2576
2577=item * $dt->day_of_quarter()
2578
2579Returns the day of the quarter.
2580
2581Also available as C<< $dt->doq() >>.
2582
2583=item * $dt->weekday_of_month()
2584
2585Returns a number from 1..5 indicating which week day of the month this
2586is. For example, June 9, 2003 is the second Monday of the month, and
2587so this method returns 2 for that day.
2588
2589=item * $dt->ymd( $optional_separator )
2590
2591=item * $dt->mdy( $optional_separator )
2592
2593=item * $dt->dmy( $optional_separator )
2594
2595Each method returns the year, month, and day, in the order indicated
2596by the method name. Years are zero-padded to four digits. Months and
2597days are 0-padded to two digits.
2598
2599By default, the values are separated by a dash (-), but this can be
2600overridden by passing a value to the method.
2601
2602The C<< $dt->ymd() >> method is also available as C<< $dt->date() >>.
2603
2604=item * $dt->hour()
2605
2606Returns the hour of the day, from 0..23.
2607
2608=item * $dt->hour_1()
2609
2610Returns the hour of the day, from 1..24.
2611
2612=item * $dt->hour_12()
2613
2614Returns the hour of the day, from 1..12.
2615
2616=item * $dt->hour_12_0()
2617
2618Returns the hour of the day, from 0..11.
2619
2620=item * $dt->am_or_pm()
2621
2622Returns the appropriate localized abbreviation, depending on the
2623current hour.
2624
2625=item * $dt->minute()
2626
2627Returns the minute of the hour, from 0..59.
2628
2629Also available as C<< $dt->min() >>.
2630
2631=item * $dt->second()
2632
2633Returns the second, from 0..61. The values 60 and 61 are used for
2634leap seconds.
2635
2636Also available as C<< $dt->sec() >>.
2637
2638=item * $dt->fractional_second()
2639
2640Returns the second, as a real number from 0.0 until 61.999999999
2641
2642The values 60 and 61 are used for leap seconds.
2643
2644=item * $dt->millisecond()
2645
2646Returns the fractional part of the second as milliseconds (1E-3 seconds).
2647
2648Half a second is 500 milliseconds.
2649
2650=item * $dt->microsecond()
2651
2652Returns the fractional part of the second as microseconds (1E-6
2653seconds). This value will be rounded to an integer.
2654
2655Half a second is 500_000 microseconds. This value will be rounded to
2656an integer.
2657
2658=item * $dt->nanosecond()
2659
2660Returns the fractional part of the second as nanoseconds (1E-9 seconds).
2661
2662Half a second is 500_000_000 nanoseconds.
2663
2664=item * $dt->hms( $optional_separator )
2665
2666Returns the hour, minute, and second, all zero-padded to two digits.
2667If no separator is specified, a colon (:) is used by default.
2668
2669Also available as C<< $dt->time() >>.
2670
2671=item * $dt->datetime()
2672
2673This method is equivalent to:
2674
2675 $dt->ymd('-') . 'T' . $dt->hms(':')
2676
2677Also available as C<< $dt->iso8601() >>.
2678
2679=item * $dt->is_leap_year()
2680
2681This method returns a true or false indicating whether or not the
2682datetime object is in a leap year.
2683
2684=item * $dt->week()
2685
2686 ($week_year, $week_number) = $dt->week;
2687
2688Returns information about the calendar week which contains this
2689datetime object. The values returned by this method are also available
2690separately through the week_year and week_number methods.
2691
2692The first week of the year is defined by ISO as the one which contains
2693the fourth day of January, which is equivalent to saying that it's the
2694first week to overlap the new year by at least four days.
2695
2696Typically the week year will be the same as the year that the object
2697is in, but dates at the very beginning of a calendar year often end up
2698in the last week of the prior year, and similarly, the final few days
2699of the year may be placed in the first week of the next year.
2700
2701=item * $dt->week_year()
2702
2703Returns the year of the week. See C<< $dt->week() >> for details.
2704
2705=item * $dt->week_number()
2706
2707Returns the week of the year, from 1..53. See C<< $dt->week() >> for details.
2708
2709=item * $dt->week_of_month()
2710
2711The week of the month, from 0..5. The first week of the month is the
2712first week that contains a Thursday. This is based on the ICU
2713definition of week of month, and correlates to the ISO8601 week of
2714year definition. A day in the week I<before> the week with the first
2715Thursday will be week 0.
2716
2717=item * $dt->jd()
2718
2719=item * $dt->mjd()
2720
2721These return the Julian Day and Modified Julian Day, respectively.
2722The value returned is a floating point number. The fractional portion
2723of the number represents the time portion of the datetime.
2724
2725=item * $dt->time_zone()
2726
2727This returns the C<DateTime::TimeZone> object for the datetime object.
2728
2729=item * $dt->offset()
2730
2731This returns the offset from UTC, in seconds, of the datetime object
2732according to the time zone.
2733
2734=item * $dt->is_dst()
2735
2736Returns a boolean indicating whether or not the datetime object is
2737currently in Daylight Saving Time or not.
2738
2739=item * $dt->time_zone_long_name()
2740
2741This is a shortcut for C<< $dt->time_zone->name >>. It's provided so
2742that one can use "%{time_zone_long_name}" as a strftime format
2743specifier.
2744
2745=item * $dt->time_zone_short_name()
2746
2747This method returns the time zone abbreviation for the current time
2748zone, such as "PST" or "GMT". These names are B<not> definitive, and
2749should not be used in any application intended for general use by
2750users around the world.
2751
2752=item * $dt->strftime( $format, ... )
2753
2754This method implements functionality similar to the C<strftime()>
2755method in C. However, if given multiple format strings, then it will
2756return multiple scalars, one for each format string.
2757
2758See the L<strftime Patterns> section for a list of all possible
2759strftime patterns.
2760
2761If you give a pattern that doesn't exist, then it is simply treated as
2762text.
2763
2764=item * $dt->format_cldr( $format, ... )
2765
2766This method implements formatting based on the CLDR date patterns. If
2767given multiple format strings, then it will return multiple scalars,
2768one for each format string.
2769
2770See the L<CLDR Patterns> section for a list of all possible CLDR
2771patterns.
2772
2773If you give a pattern that doesn't exist, then it is simply treated as
2774text.
2775
2776=item * $dt->epoch()
2777
2778Return the UTC epoch value for the datetime object. Internally, this
2779is implemented using C<Time::Local>, which uses the Unix epoch even on
2780machines with a different epoch (such as MacOS). Datetimes before the
2781start of the epoch will be returned as a negative number.
2782
2783The return value from this method is always an integer.
2784
2785Since the epoch does not account for leap seconds, the epoch time for
27861972-12-31T23:59:60 (UTC) is exactly the same as that for
27871973-01-01T00:00:00.
2788
2789This module uses C<Time::Local> to calculate the epoch, which may or
2790may not handle epochs before 1904 or after 2038 (depending on the size
2791of your system's integers, and whether or not Perl was compiled with
279264-bit int support).
2793
2794=item * $dt->hires_epoch()
2795
2796Returns the epoch as a floating point number. The floating point
2797portion of the value represents the nanosecond value of the object.
2798This method is provided for compatibility with the C<Time::HiRes>
2799module.
2800
2801=item * $dt->is_finite()
2802
2803=item * $dt->is_infinite()
2804
2805These methods allow you to distinguish normal datetime objects from
2806infinite ones. Infinite datetime objects are documented in
2807L<DateTime::Infinite|DateTime::Infinite>.
2808
2809=item * $dt->utc_rd_values()
2810
2811Returns the current UTC Rata Die days, seconds, and nanoseconds as a
2812three element list. This exists primarily to allow other calendar
2813modules to create objects based on the values provided by this object.
2814
2815=item * $dt->local_rd_values()
2816
2817Returns the current local Rata Die days, seconds, and nanoseconds as a
2818three element list. This exists for the benefit of other modules
2819which might want to use this information for date math, such as
2820C<DateTime::Event::Recurrence>.
2821
2822=item * $dt->leap_seconds()
2823
2824Returns the number of leap seconds that have happened up to the
2825datetime represented by the object. For floating datetimes, this
2826always returns 0.
2827
2828=item * $dt->utc_rd_as_seconds()
2829
2830Returns the current UTC Rata Die days and seconds purely as seconds.
2831This number ignores any fractional seconds stored in the object,
2832as well as leap seconds.
2833
2834=item * $dt->locale()
2835
2836Returns the current locale object.
2837
2838=item * $dt->formatter()
2839
2840Returns current formatter object or class. See L<Formatters And
2841Stringification> for details.
2842
2843=back
2844
2845=head3 "Set" Methods
2846
2847The remaining methods provided by C<DateTime.pm>, except where otherwise
2848specified, return the object itself, thus making method chaining
2849possible. For example:
2850
2851 my $dt = DateTime->now->set_time_zone( 'Australia/Sydney' );
2852
2853 my $first = DateTime
2854 ->last_day_of_month( year => 2003, month => 3 )
2855 ->add( days => 1 )
2856 ->subtract( seconds => 1 );
2857
2858=over 4
2859
2860=item * $dt->set( .. )
2861
2862This method can be used to change the local components of a date time,
2863or its locale. This method accepts any parameter allowed by the
2864C<new()> method except for "time_zone". Time zones may be set using
2865the C<set_time_zone()> method.
2866
2867This method performs parameters validation just as is done in the
2868C<new()> method.
2869
2870B<Do not use this method to do date math. Use the C<add()> and C<subtract()>
2871methods instead.>
2872
2873=item * $dt->set_year()
2874
2875=item * $dt->set_month()
2876
2877=item * $dt->set_day()
2878
2879=item * $dt->set_hour()
2880
2881=item * $dt->set_minute()
2882
2883=item * $dt->set_second()
2884
2885=item * $dt->set_nanosecond()
2886
2887=item * $dt->set_locale()
2888
2889These are shortcuts to calling C<set()> with a single key. They all
2890take a single parameter.
2891
2892=item * $dt->truncate( to => ... )
2893
2894This method allows you to reset some of the local time components in
2895the object to their "zero" values. The "to" parameter is used to
2896specify which values to truncate, and it may be one of "year",
2897"month", "week", "day", "hour", "minute", or "second". For example,
2898if "month" is specified, then the local day becomes 1, and the hour,
2899minute, and second all become 0.
2900
2901If "week" is given, then the datetime is set to the beginning of the
2902week in which it occurs, and the time components are all set to 0.
2903
2904=item * $dt->set_time_zone( $tz )
2905
2906This method accepts either a time zone object or a string that can be
2907passed as the "name" parameter to C<< DateTime::TimeZone->new() >>.
2908If the new time zone's offset is different from the old time zone,
2909then the I<local> time is adjusted accordingly.
2910
2911For example:
2912
2913 my $dt = DateTime->new(
2914 year => 2000,
2915 month => 5,
2916 day => 10,
2917 hour => 15,
2918 minute => 15,
2919 time_zone => 'America/Los_Angeles',
2920 );
2921
2922 print $dt->hour; # prints 15
2923
2924 $dt->set_time_zone( 'America/Chicago' );
2925
2926 print $dt->hour; # prints 17
2927
2928If the old time zone was a floating time zone, then no adjustments to
2929the local time are made, except to account for leap seconds. If the
2930new time zone is floating, then the I<UTC> time is adjusted in order
2931to leave the local time untouched.
2932
2933Fans of Tsai Ming-Liang's films will be happy to know that this does
2934work:
2935
2936 my $dt = DateTime->now( time_zone => 'Asia/Taipei' );
2937
2938 $dt->set_time_zone( 'Europe/Paris' );
2939
2940Yes, now we can know "ni3 na4 bian1 ji2dian3?"
2941
2942=item * $dt->set_formatter( $formatter )
2943
2944Set the formatter for the object. See L<Formatters And
2945Stringification> for details.
2946
2947You can set this to C<undef> to revert to the default formatter.
2948
2949=back
2950
2951=head3 Math Methods
2952
2953Like the set methods, math related methods always return the object
2954itself, to allow for chaining:
2955
2956 $dt->add( days => 1 )->subtract( seconds => 1 );
2957
2958=over 4
2959
2960=item * $dt->duration_class()
2961
2962This returns C<DateTime::Duration>, but exists so that a subclass of
2963C<DateTime.pm> can provide a different value.
2964
2965=item * $dt->add_duration( $duration_object )
2966
2967This method adds a C<DateTime::Duration> to the current datetime. See
2968the L<DateTime::Duration|DateTime::Duration> docs for more details.
2969
2970=item * $dt->add( DateTime::Duration->new parameters )
2971
2972This method is syntactic sugar around the C<add_duration()> method. It
2973simply creates a new C<DateTime::Duration> object using the parameters
2974given, and then calls the C<add_duration()> method.
2975
2976=item * $dt->subtract_duration( $duration_object )
2977
2978When given a C<DateTime::Duration> object, this method simply calls
2979C<invert()> on that object and passes that new duration to the
2980C<add_duration> method.
2981
2982=item * $dt->subtract( DateTime::Duration->new parameters )
2983
2984Like C<add()>, this is syntactic sugar for the C<subtract_duration()>
2985method.
2986
2987=item * $dt->subtract_datetime( $datetime )
2988
2989This method returns a new C<DateTime::Duration> object representing
2990the difference between the two dates. The duration is B<relative> to
2991the object from which C<$datetime> is subtracted. For example:
2992
2993 2003-03-15 00:00:00.00000000
2994 - 2003-02-15 00:00:00.00000000
2995 -------------------------------
2996 = 1 month
2997
2998Note that this duration is not an absolute measure of the amount of
2999time between the two datetimes, because the length of a month varies,
3000as well as due to the presence of leap seconds.
3001
3002The returned duration may have deltas for months, days, minutes,
3003seconds, and nanoseconds.
3004
3005=item * $dt->delta_md( $datetime )
3006
3007=item * $dt->delta_days( $datetime )
3008
3009Each of these methods returns a new C<DateTime::Duration> object
3010representing some portion of the difference between two datetimes.
3011The C<delta_md()> method returns a duration which contains only the
3012month and day portions of the duration is represented. The
3013C<delta_days()> method returns a duration which contains only days.
3014
3015The C<delta_md> and C<delta_days> methods truncate the duration so
3016that any fractional portion of a day is ignored. Both of these
3017methods operate on the date portion of a datetime only, and so
3018effectively ignore the time zone.
3019
3020Unlike the subtraction methods, B<these methods always return a
3021positive (or zero) duration>.
3022
3023=item * $dt->delta_ms( $datetime )
3024
3025Returns a duration which contains only minutes and seconds. Any day
3026and month differences to minutes are converted to minutes and
3027seconds. This method also B<always return a positive (or zero)
3028duration>.
3029
3030=item * $dt->subtract_datetime_absolute( $datetime )
3031
3032This method returns a new C<DateTime::Duration> object representing
3033the difference between the two dates in seconds and nanoseconds. This
3034is the only way to accurately measure the absolute amount of time
3035between two datetimes, since units larger than a second do not
3036represent a fixed number of seconds.
3037
3038=back
3039
3040=head3 Class Methods
3041
3042=over 4
3043
3044=item * DateTime->DefaultLocale( $locale )
3045
3046This can be used to specify the default locale to be used when
3047creating DateTime objects. If unset, then "en_US" is used.
3048
3049=item * DateTime->compare( $dt1, $dt2 )
3050
3051=item * DateTime->compare_ignore_floating( $dt1, $dt2 )
3052
3053 $cmp = DateTime->compare( $dt1, $dt2 );
3054
3055 $cmp = DateTime->compare_ignore_floating( $dt1, $dt2 );
3056
3057Compare two DateTime objects. The semantics are compatible with Perl's
3058C<sort()> function; it returns -1 if $dt1 < $dt2, 0 if $dt1 == $dt2, 1 if $dt1
3059> $dt2.
3060
3061If one of the two DateTime objects has a floating time zone, it will
3062first be converted to the time zone of the other object. This is what
3063you want most of the time, but it can lead to inconsistent results
3064when you compare a number of DateTime objects, some of which are
3065floating, and some of which are in other time zones.
3066
3067If you want to have consistent results (because you want to sort a
3068number of objects, for example), you can use the
3069C<compare_ignore_floating()> method:
3070
3071 @dates = sort { DateTime->compare_ignore_floating($a, $b) } @dates;
3072
3073In this case, objects with a floating time zone will be sorted as if
3074they were UTC times.
3075
3076Since DateTime objects overload comparison operators, this:
3077
3078 @dates = sort @dates;
3079
3080is equivalent to this:
3081
3082 @dates = sort { DateTime->compare($a, $b) } @dates;
3083
3084DateTime objects can be compared to any other calendar class that
3085implements the C<utc_rd_values()> method.
3086
3087=back
3088
3089=head2 How Datetime Math Works
3090
3091It's important to have some understanding of how datetime math is
3092implemented in order to effectively use this module and
3093C<DateTime::Duration>.
3094
3095=head3 Making Things Simple
3096
3097If you want to simplify your life and not have to think too hard about
3098the nitty-gritty of datetime math, I have several recommendations:
3099
3100=over 4
3101
3102=item * use the floating time zone
3103
3104If you do not care about time zones or leap seconds, use the
3105"floating" timezone:
3106
3107 my $dt = DateTime->now( time_zone => 'floating' );
3108
3109Math done on two objects in the floating time zone produces very
3110predictable results.
3111
3112Note that in most cases you will want to start by creating an object in a
3113specific zone and I<then> convert it to the floating time zone. When an object
3114goes from a real zone to the floating zone, the time for the object remains
3115the same.
3116
3117This means that passing the floating zone to a constructor may not do what you
3118want.
3119
3120 my $dt = DateTime->now( time_zone => 'floating' );
3121
3122is equivalent to
3123
3124 my $dt = DateTime->now( time_zone => 'UTC' )->set_time_zone('floating');
3125
3126This might not be what you wanted. Instead, you may prefer to do this:
3127
3128 my $dt = DateTime->now( time_zone => 'local' )->set_time_zone('floating');
3129
3130=item * use UTC for all calculations
3131
3132If you do care about time zones (particularly DST) or leap seconds,
3133try to use non-UTC time zones for presentation and user input only.
3134Convert to UTC immediately and convert back to the local time zone for
3135presentation:
3136
3137 my $dt = DateTime->new( %user_input, time_zone => $user_tz );
3138 $dt->set_time_zone('UTC');
3139
3140 # do various operations - store it, retrieve it, add, subtract, etc.
3141
3142 $dt->set_time_zone($user_tz);
3143 print $dt->datetime;
3144
3145=item * math on non-UTC time zones
3146
3147If you need to do date math on objects with non-UTC time zones, please
3148read the caveats below carefully. The results C<DateTime.pm> produces are
3149predictable and correct, and mostly intuitive, but datetime math gets
3150very ugly when time zones are involved, and there are a few strange
3151corner cases involving subtraction of two datetimes across a DST
3152change.
3153
3154If you can always use the floating or UTC time zones, you can skip
3155ahead to L<Leap Seconds and Date Math|Leap Seconds and Date Math>
3156
3157=item * date vs datetime math
3158
3159If you only care about the date (calendar) portion of a datetime, you
3160should use either C<delta_md()> or C<delta_days()>, not
3161C<subtract_datetime()>. This will give predictable, unsurprising
3162results, free from DST-related complications.
3163
3164=item * subtract_datetime() and add_duration()
3165
3166You must convert your datetime objects to the UTC time zone before
3167doing date math if you want to make sure that the following formulas
3168are always true:
3169
3170 $dt2 - $dt1 = $dur
3171 $dt1 + $dur = $dt2
3172 $dt2 - $dur = $dt1
3173
3174Note that using C<delta_days> ensures that this formula always works,
3175regardless of the timezone of the objects involved, as does using
3176C<subtract_datetime_absolute()>. Other methods of subtraction are not
3177always reversible.
3178
3179=back
3180
3181=head3 Adding a Duration to a Datetime
3182
3183The parts of a duration can be broken down into five parts. These are
3184months, days, minutes, seconds, and nanoseconds. Adding one month to
3185a date is different than adding 4 weeks or 28, 29, 30, or 31 days.
3186Similarly, due to DST and leap seconds, adding a day can be different
3187than adding 86,400 seconds, and adding a minute is not exactly the
3188same as 60 seconds.
3189
3190We cannot convert between these units, except for seconds and
3191nanoseconds, because there is no fixed conversion between the two
3192units, because of things like leap seconds, DST changes, etc.
3193
3194C<DateTime.pm> always adds (or subtracts) days, then months, minutes, and then
3195seconds and nanoseconds. If there are any boundary overflows, these are
3196normalized at each step. For the days and months the local (not UTC) values
3197are used. For minutes and seconds, the local values are used. This generally
3198just works.
3199
3200This means that adding one month and one day to February 28, 2003 will
3201produce the date April 1, 2003, not March 29, 2003.
3202
3203 my $dt = DateTime->new( year => 2003, month => 2, day => 28 );
3204
3205 $dt->add( months => 1, days => 1 );
3206
3207 # 2003-04-01 - the result
3208
3209On the other hand, if we add months first, and then separately add
3210days, we end up with March 29, 2003:
3211
3212 $dt->add( months => 1 )->add( days => 1 );
3213
3214 # 2003-03-29
3215
3216We see similar strangeness when math crosses a DST boundary:
3217
3218 my $dt = DateTime->new(
3219 year => 2003,
3220 month => 4,
3221 day => 5,
3222 hour => 1,
3223 minute => 58,
3224 time_zone => "America/Chicago",
3225 );
3226
3227 $dt->add( days => 1, minutes => 3 );
3228 # 2003-04-06 02:01:00
3229
3230 $dt->add( minutes => 3 )->add( days => 1 );
3231 # 2003-04-06 03:01:00
3232
3233Note that if you converted the datetime object to UTC first you would
3234get predictable results.
3235
3236If you want to know how many seconds a duration object represents, you
3237have to add it to a datetime to find out, so you could do:
3238
3239 my $now = DateTime->now( time_zone => 'UTC' );
3240 my $later = $now->clone->add_duration($duration);
3241
3242 my $seconds_dur = $later->subtract_datetime_absolute($now);
3243
3244This returns a duration which only contains seconds and nanoseconds.
3245
3246If we were add the duration to a different datetime object we might
3247get a different number of seconds.
3248
3249L<DateTime::Duration> supports three different end-of-month algorithms for
3250adding months. This comes into play when an addition results in a day past the
3251end of the month (for example, adding one month to January 30).
3252
3253 # 2010-08-31 + 1 month = 2010-10-01
3254 $dt->add( months => 1, end_of_month => 'wrap' );
3255
3256 # 2010-01-30 + 1 month = 2010-02-28
3257 $dt->add( months => 1, end_of_month => 'limit' );
3258
3259 # 2010-04-30 + 1 month = 2010-05-31
3260 $dt->add( months => 1, end_of_month => 'preserve' );
3261
3262By default, it uses "wrap" for positive durations and "preserve" for negative
3263durations. See L<DateTime::Duration> for a detailed explanation of these
3264algorithms.
3265
3266If you need to do lots of work with durations, take a look at Rick
3267Measham's C<DateTime::Format::Duration> module, which lets you present
3268information from durations in many useful ways.
3269
3270There are other subtract/delta methods in DateTime.pm to generate
3271different types of durations. These methods are
3272C<subtract_datetime()>, C<subtract_datetime_absolute()>,
3273C<delta_md()>, C<delta_days()>, and C<delta_ms()>.
3274
3275=head3 Datetime Subtraction
3276
3277Date subtraction is done solely based on the two object's local
3278datetimes, with one exception to handle DST changes. Also, if the two
3279datetime objects are in different time zones, one of them is converted
3280to the other's time zone first before subtraction. This is best
3281explained through examples:
3282
3283The first of these probably makes the most sense:
3284
3285 my $dt1 = DateTime->new(
3286 year => 2003,
3287 month => 5,
3288 day => 6,
3289 time_zone => 'America/Chicago',
3290 );
3291
3292 # not DST
3293
3294 my $dt2 = DateTime->new(
3295 year => 2003,
3296 month => 11,
3297 day => 6,
3298 time_zone => 'America/Chicago',
3299 );
3300
3301 # is DST
3302
3303 my $dur = $dt2->subtract_datetime($dt1);
3304 # 6 months
3305
3306Nice and simple.
3307
3308This one is a little trickier, but still fairly logical:
3309
3310 my $dt1 = DateTime->new(
3311 year => 2003,
3312 month => 4,
3313 day => 5,
3314 hour => 1,
3315 minute => 58,
3316 time_zone => "America/Chicago",
3317 );
3318
3319 # is DST
3320
3321 my $dt2 = DateTime->new(
3322 year => 2003,
3323 month => 4,
3324 day => 7,
3325 hour => 2,
3326 minute => 1,
3327 time_zone => "America/Chicago",
3328 );
3329
3330 # not DST
3331
3332 my $dur = $dt2->subtract_datetime($dt1);
3333
3334 # 2 days and 3 minutes
3335
3336Which contradicts the result this one gives, even though they both
3337make sense:
3338
3339 my $dt1 = DateTime->new(
3340 year => 2003,
3341 month => 4,
3342 day => 5,
3343 hour => 1,
3344 minute => 58,
3345 time_zone => "America/Chicago",
3346 );
3347
3348 # is DST
3349
3350 my $dt2 = DateTime->new(
3351 year => 2003,
3352 month => 4,
3353 day => 6,
3354 hour => 3,
3355 minute => 1,
3356 time_zone => "America/Chicago",
3357 );
3358
3359 # not DST
3360
3361 my $dur = $dt2->subtract_datetime($dt1);
3362
3363 # 1 day and 3 minutes
3364
3365This last example illustrates the "DST" exception mentioned earlier.
3366The exception accounts for the fact 2003-04-06 only lasts 23 hours.
3367
3368And finally:
3369
3370 my $dt2 = DateTime->new(
3371 year => 2003,
3372 month => 10,
3373 day => 26,
3374 hour => 1,
3375 time_zone => 'America/Chicago',
3376 );
3377
3378 my $dt1 = $dt2->clone->subtract( hours => 1 );
3379
3380 my $dur = $dt2->subtract_datetime($dt1);
3381 # 60 minutes
3382
3383This seems obvious until you realize that subtracting 60 minutes from
3384C<$dt2> in the above example still leaves the clock time at
3385"01:00:00". This time we are accounting for a 25 hour day.
3386
3387=head3 Reversibility
3388
3389Date math operations are not always reversible. This is because of
3390the way that addition operations are ordered. As was discussed
3391earlier, adding 1 day and 3 minutes in one call to C<add()> is not the
3392same as first adding 3 minutes and 1 day in two separate calls.
3393
3394If we take a duration returned from C<subtract_datetime()> and then
3395try to add or subtract that duration from one of the datetimes we just
3396used, we sometimes get interesting results:
3397
3398 my $dt1 = DateTime->new(
3399 year => 2003,
3400 month => 4,
3401 day => 5,
3402 hour => 1,
3403 minute => 58,
3404 time_zone => "America/Chicago",
3405 );
3406
3407 my $dt2 = DateTime->new(
3408 year => 2003,
3409 month => 4,
3410 day => 6,
3411 hour => 3,
3412 minute => 1,
3413 time_zone => "America/Chicago",
3414 );
3415
3416 my $dur = $dt2->subtract_datetime($dt1);
3417 # 1 day and 3 minutes
3418
3419 $dt1->add_duration($dur);
3420 # gives us $dt2
3421
3422 $dt2->subtract_duration($dur);
3423 # gives us 2003-04-05 02:58:00 - 1 hour later than $dt1
3424
3425The C<subtract_duration()> operation gives us a (perhaps) unexpected
3426answer because it first subtracts one day to get 2003-04-05T03:01:00
3427and then subtracts 3 minutes to get the final result.
3428
3429If we explicitly reverse the order we can get the original value of
3430C<$dt1>. This can be facilitated by C<DateTime::Duration>'s
3431C<calendar_duration()> and C<clock_duration()> methods:
3432
3433 $dt2->subtract_duration( $dur->clock_duration )
3434 ->subtract_duration( $dur->calendar_duration );
3435
3436=head3 Leap Seconds and Date Math
3437
3438The presence of leap seconds can cause even more anomalies in date
3439math. For example, the following is a legal datetime:
3440
3441 my $dt = DateTime->new(
3442 year => 1972,
3443 month => 12,
3444 day => 31,
3445 hour => 23,
3446 minute => 59,
3447 second => 60,
3448 time_zone => 'UTC'
3449 );
3450
3451If we do the following:
3452
3453 $dt->add( months => 1 );
3454
3455Then the datetime is now "1973-02-01 00:00:00", because there is no
345623:59:60 on 1973-01-31.
3457
3458Leap seconds also force us to distinguish between minutes and seconds
3459during date math. Given the following datetime:
3460
3461 my $dt = DateTime->new(
3462 year => 1972,
3463 month => 12,
3464 day => 31,
3465 hour => 23,
3466 minute => 59,
3467 second => 30,
3468 time_zone => 'UTC'
3469 );
3470
3471we will get different results when adding 1 minute than we get if we
3472add 60 seconds. This is because in this case, the last minute of the
3473day, beginning at 23:59:00, actually contains 61 seconds.
3474
3475Here are the results we get:
3476
3477 # 1972-12-31 23:59:30 - our starting datetime
3478
3479 $dt->clone->add( minutes => 1 );
3480 # 1973-01-01 00:00:30 - one minute later
3481
3482 $dt->clone->add( seconds => 60 );
3483 # 1973-01-01 00:00:29 - 60 seconds later
3484
3485 $dt->clone->add( seconds => 61 );
3486 # 1973-01-01 00:00:30 - 61 seconds later
3487
3488=head3 Local vs. UTC and 24 hours vs. 1 day
3489
3490When math crosses a daylight saving boundary, a single day may have
3491more or less than 24 hours.
3492
3493For example, if you do this:
3494
3495 my $dt = DateTime->new(
3496 year => 2003,
3497 month => 4,
3498 day => 5,
3499 hour => 2,
3500 time_zone => 'America/Chicago',
3501 );
3502
3503 $dt->add( days => 1 );
3504
3505then you will produce an I<invalid> local time, and therefore an
3506exception will be thrown.
3507
3508However, this works:
3509
3510 my $dt = DateTime->new(
3511 year => 2003,
3512 month => 4,
3513 day => 5,
3514 hour => 2,
3515 time_zone => 'America/Chicago',
3516 );
3517
3518 $dt->add( hours => 24 );
3519
3520and produces a datetime with the local time of "03:00".
3521
3522If all this makes your head hurt, there is a simple alternative. Just
3523convert your datetime object to the "UTC" time zone before doing date
3524math on it, and switch it back to the local time zone afterwards.
3525This avoids the possibility of having date math throw an exception,
3526and makes sure that 1 day equals 24 hours. Of course, this may not
3527always be desirable, so caveat user!
3528
3529=head2 Overloading
3530
3531This module explicitly overloads the addition (+), subtraction (-),
3532string and numeric comparison operators. This means that the
3533following all do sensible things:
3534
3535 my $new_dt = $dt + $duration_obj;
3536
3537 my $new_dt = $dt - $duration_obj;
3538
3539 my $duration_obj = $dt - $new_dt;
3540
3541 foreach my $dt ( sort @dts ) { ... }
3542
3543Additionally, the fallback parameter is set to true, so other
3544derivable operators (+=, -=, etc.) will work properly. Do not expect
3545increment (++) or decrement (--) to do anything useful.
3546
3547The string comparison operators, C<eq> or C<ne>, will use the string
3548value to compare with non-DateTime objects.
3549
3550DateTime objects do not have a numeric value, using C<==> or C<< <=>
3551>> to compare a DateTime object with a non-DateTime object will result
3552in an exception. To safely sort mixed DateTime and non-DateTime
3553objects, use C<sort { $a cmp $b } @dates>.
3554
3555The module also overloads stringification using the object's
3556formatter, defaulting to C<iso8601()> method. See L<Formatters And
3557Stringification> for details.
3558
3559=head2 Formatters And Stringification
3560
3561You can optionally specify a "formatter", which is usually a
3562DateTime::Format::* object/class, to control the stringification of
3563the DateTime object.
3564
3565Any of the constructor methods can accept a formatter argument:
3566
3567 my $formatter = DateTime::Format::Strptime->new(...);
3568 my $dt = DateTime->new(year => 2004, formatter => $formatter);
3569
3570Or, you can set it afterwards:
3571
3572 $dt->set_formatter($formatter);
3573 $formatter = $dt->formatter();
3574
3575Once you set the formatter, the overloaded stringification method will
3576use the formatter. If unspecified, the C<iso8601()> method is used.
3577
3578A formatter can be handy when you know that in your application you
3579want to stringify your DateTime objects into a special format all the
3580time, for example to a different language.
3581
3582If you provide a formatter class name or object, it must implement a
3583C<format_datetime> method. This method will be called with just the
3584DateTime object as its argument.
3585
3586=head2 CLDR Patterns
3587
3588The CLDR pattern language is both more powerful and more complex than
3589strftime. Unlike strftime patterns, you often have to explicitly
3590escape text that you do not want formatted, as the patterns are simply
3591letters without any prefix.
3592
3593For example, "yyyy-MM-dd" is a valid CLDR pattern. If you want to
3594include any lower or upper case ASCII characters as-is, you can
3595surround them with single quotes ('). If you want to include a single
3596quote, you must escape it as two single quotes ('').
3597
3598 'Today is ' EEEE
3599 'It is now' h 'o''clock' a
3600
3601Spaces and any non-letter text will always be passed through as-is.
3602
3603Many CLDR patterns which produce numbers will pad the number with
3604leading zeroes depending on the length of the format specifier. For
3605example, "h" represents the current hour from 1-12. If you specify
3606"hh" then the 1-9 will have a leading zero prepended.
3607
3608However, CLDR often uses five of a letter to represent the narrow form
3609of a pattern. This inconsistency is necessary for backwards
3610compatibility.
3611
3612CLDR often distinguishes between the "format" and "stand-alone" forms
3613of a pattern. The format pattern is used when the thing in question is
3614being placed into a larger string. The stand-alone form is used when
3615displaying that item by itself, for example in a calendar.
3616
3617It also often provides three sizes for each item, wide (the full
3618name), abbreviated, and narrow. The narrow form is often just a single
3619character, for example "T" for "Tuesday", and may not be unique.
3620
3621CLDR provides a fairly complex system for localizing time zones that
3622we ignore entirely. The time zone patterns just use the information
3623provided by C<DateTime::TimeZone>, and I<do not follow the CLDR spec>.
3624
3625The output of a CLDR pattern is always localized, when applicable.
3626
3627CLDR provides the following patterns:
3628
3629=over 4
3630
3631=item * G{1,3}
3632
3633The abbreviated era (BC, AD).
3634
3635=item * GGGG
3636
3637The wide era (Before Christ, Anno Domini).
3638
3639=item * GGGGG
3640
3641The narrow era, if it exists (and it mostly doesn't).
3642
3643=item * y and y{3,}
3644
3645The year, zero-prefixed as needed. Negative years will start with a "-",
3646and this will be included in the length calculation.
3647
3648In other, words the "yyyyy" pattern will format year -1234 as "-1234", not
3649"-01234".
3650
3651=item * yy
3652
3653This is a special case. It always produces a two-digit year, so "1976" becomes
3654"76". Negative years will start with a "-", making them one character longer.
3655
3656=item * Y{1,}
3657
3658The week of the year, from C<< $dt->week_year() >>.
3659
3660=item * u{1,}
3661
3662Same as "y" except that "uu" is not a special case.
3663
3664=item * Q{1,2}
3665
3666The quarter as a number (1..4).
3667
3668=item * QQQ
3669
3670The abbreviated format form for the quarter.
3671
3672=item * QQQQ
3673
3674The wide format form for the quarter.
3675
3676=item * q{1,2}
3677
3678The quarter as a number (1..4).
3679
3680=item * qqq
3681
3682The abbreviated stand-alone form for the quarter.
3683
3684=item * qqqq
3685
3686The wide stand-alone form for the quarter.
3687
3688=item * M{1,2]
3689
3690The numerical month.
3691
3692=item * MMM
3693
3694The abbreviated format form for the month.
3695
3696=item * MMMM
3697
3698The wide format form for the month.
3699
3700=item * MMMMM
3701
3702The narrow format form for the month.
3703
3704=item * L{1,2]
3705
3706The numerical month.
3707
3708=item * LLL
3709
3710The abbreviated stand-alone form for the month.
3711
3712=item * LLLL
3713
3714The wide stand-alone form for the month.
3715
3716=item * LLLLL
3717
3718The narrow stand-alone form for the month.
3719
3720=item * w{1,2}
3721
3722The week of the year, from C<< $dt->week_number() >>.
3723
3724=item * W
3725
3726The week of the month, from C<< $dt->week_of_month() >>.
3727
3728=item * d{1,2}
3729
3730The numeric day of of the month.
3731
3732=item * D{1,3}
3733
3734The numeric day of of the year.
3735
3736=item * F
3737
3738The day of the week in the month, from C<< $dt->weekday_of_month() >>.
3739
3740=item * g{1,}
3741
3742The modified Julian day, from C<< $dt->mjd() >>.
3743
3744=item * E{1,3} and eee
3745
3746The abbreviated format form for the day of the week.
3747
3748=item * EEEE and eeee
3749
3750The wide format form for the day of the week.
3751
3752=item * EEEEE and eeeee
3753
3754The narrow format form for the day of the week.
3755
3756=item * e{1,2}
3757
3758The I<local> numeric day of the week, from 1 to 7. This number depends
3759on what day is considered the first day of the week, which varies by
3760locale. For example, in the US, Sunday is the first day of the week,
3761so this returns 2 for Monday.
3762
3763=item * c
3764
3765The numeric day of the week from 1 to 7, treating Monday as the first
3766of the week, regardless of locale.
3767
3768=item * ccc
3769
3770The abbreviated stand-alone form for the day of the week.
3771
3772=item * cccc
3773
3774The wide stand-alone form for the day of the week.
3775
3776=item * ccccc
3777
3778The narrow format form for the day of the week.
3779
3780=item * a
3781
3782The localized form of AM or PM for the time.
3783
3784=item * h{1,2}
3785
3786The hour from 1-12.
3787
3788=item * H{1,2}
3789
3790The hour from 0-23.
3791
3792=item * K{1,2}
3793
3794The hour from 0-11.
3795
3796=item * k{1,2}
3797
3798The hour from 1-24.
3799
3800=item * j{1,2}
3801
3802The hour, in 12 or 24 hour form, based on the preferred form for the
3803locale. In other words, this is equivalent to either "h{1,2}" or
3804"H{1,2}".
3805
3806=item * m{1,2}
3807
3808The minute.
3809
3810=item * s{1,2}
3811
3812The second.
3813
3814=item * S{1,}
3815
3816The fractional portion of the seconds, rounded based on the length of
3817the specifier. This returned I<without> a leading decimal point, but
3818may have leading or trailing zeroes.
3819
3820=item * A{1,}
3821
3822The millisecond of the day, based on the current time. In other words,
3823if it is 12:00:00.00, this returns 43200000.
3824
3825=item * z{1,3}
3826
3827The time zone short name.
3828
3829=item * zzzz
3830
3831The time zone long name.
3832
3833=item * Z{1,3}
3834
3835The time zone offset.
3836
3837=item * ZZZZ
3838
3839The time zone short name and the offset as one string, so something
3840like "CDT-0500".
3841
3842=item * v{1,3}
3843
3844The time zone short name.
3845
3846=item * vvvv
3847
3848The time zone long name.
3849
3850=item * V{1,3}
3851
3852The time zone short name.
3853
3854=item * VVVV
3855
3856The time zone long name.
3857
3858=back
3859
3860=head2 strftime Patterns
3861
3862The following patterns are allowed in the format string given to the
3863C<< $dt->strftime() >> method:
3864
3865=over 4
3866
3867=item * %a
3868
3869The abbreviated weekday name.
3870
3871=item * %A
3872
3873The full weekday name.
3874
3875=item * %b
3876
3877The abbreviated month name.
3878
3879=item * %B
3880
3881The full month name.
3882
3883=item * %c
3884
3885The default datetime format for the object's locale.
3886
3887=item * %C
3888
3889The century number (year/100) as a 2-digit integer.
3890
3891=item * %d
3892
3893The day of the month as a decimal number (range 01 to 31).
3894
3895=item * %D
3896
3897Equivalent to %m/%d/%y. This is not a good standard format if you
3898want folks from both the United States and the rest of the world to
3899understand the date!
3900
3901=item * %e
3902
3903Like %d, the day of the month as a decimal number, but a leading zero
3904is replaced by a space.
3905
3906=item * %F
3907
3908Equivalent to %Y-%m-%d (the ISO 8601 date format)
3909
3910=item * %G
3911
3912The ISO 8601 year with century as a decimal number. The 4-digit year
3913corresponding to the ISO week number (see %V). This has the same
3914format and value as %Y, except that if the ISO week number belongs to
3915the previous or next year, that year is used instead. (TZ)
3916
3917=item * %g
3918
3919Like %G, but without century, i.e., with a 2-digit year (00-99).
3920
3921=item * %h
3922
3923Equivalent to %b.
3924
3925=item * %H
3926
3927The hour as a decimal number using a 24-hour clock (range 00 to 23).
3928
3929=item * %I
3930
3931The hour as a decimal number using a 12-hour clock (range 01 to 12).
3932
3933=item * %j
3934
3935The day of the year as a decimal number (range 001 to 366).
3936
3937=item * %k
3938
3939The hour (24-hour clock) as a decimal number (range 0 to 23); single
3940digits are preceded by a blank. (See also %H.)
3941
3942=item * %l
3943
3944The hour (12-hour clock) as a decimal number (range 1 to 12); single
3945digits are preceded by a blank. (See also %I.)
3946
3947=item * %m
3948
3949The month as a decimal number (range 01 to 12).
3950
3951=item * %M
3952
3953The minute as a decimal number (range 00 to 59).
3954
3955=item * %n
3956
3957A newline character.
3958
3959=item * %N
3960
3961The fractional seconds digits. Default is 9 digits (nanoseconds).
3962
3963 %3N milliseconds (3 digits)
3964 %6N microseconds (6 digits)
3965 %9N nanoseconds (9 digits)
3966
3967=item * %p
3968
3969Either `AM' or `PM' according to the given time value, or the
3970corresponding strings for the current locale. Noon is treated as `pm'
3971and midnight as `am'.
3972
3973=item * %P
3974
3975Like %p but in lowercase: `am' or `pm' or a corresponding string for
3976the current locale.
3977
3978=item * %r
3979
3980The time in a.m. or p.m. notation. In the POSIX locale this is
3981equivalent to `%I:%M:%S %p'.
3982
3983=item * %R
3984
3985The time in 24-hour notation (%H:%M). (SU) For a version including the
3986seconds, see %T below.
3987
3988=item * %s
3989
3990The number of seconds since the epoch.
3991
3992=item * %S
3993
3994The second as a decimal number (range 00 to 61).
3995
3996=item * %t
3997
3998A tab character.
3999
4000=item * %T
4001
4002The time in 24-hour notation (%H:%M:%S).
4003
4004=item * %u
4005
4006The day of the week as a decimal, range 1 to 7, Monday being 1. See
4007also %w.
4008
4009=item * %U
4010
4011The week number of the current year as a decimal number, range 00 to
401253, starting with the first Sunday as the first day of week 01. See
4013also %V and %W.
4014
4015=item * %V
4016
4017The ISO 8601:1988 week number of the current year as a decimal number,
4018range 01 to 53, where week 1 is the first week that has at least 4
4019days in the current year, and with Monday as the first day of the
4020week. See also %U and %W.
4021
4022=item * %w
4023
4024The day of the week as a decimal, range 0 to 6, Sunday being 0. See
4025also %u.
4026
4027=item * %W
4028
4029The week number of the current year as a decimal number, range 00 to
403053, starting with the first Monday as the first day of week 01.
4031
4032=item * %x
4033
4034The default date format for the object's locale.
4035
4036=item * %X
4037
4038The default time format for the object's locale.
4039
4040=item * %y
4041
4042The year as a decimal number without a century (range 00 to 99).
4043
4044=item * %Y
4045
4046The year as a decimal number including the century.
4047
4048=item * %z
4049
4050The time-zone as hour offset from UTC. Required to emit
4051RFC822-conformant dates (using "%a, %d %b %Y %H:%M:%S %z").
4052
4053=item * %Z
4054
4055The time zone or name or abbreviation.
4056
4057=item * %%
4058
4059A literal `%' character.
4060
4061=item * %{method}
4062
4063Any method name may be specified using the format C<%{method}> name
4064where "method" is a valid C<DateTime.pm> object method.
4065
4066=back
4067
4068=head2 DateTime.pm and Storable
4069
4070DateTime implements Storable hooks in order to reduce the size of a
4071serialized DateTime object.
4072
4073=head1 THE DATETIME PROJECT ECOSYSTEM
4074
4075This module is part of a larger ecosystem of modules in the DateTime
4076family.
4077
4078=head2 L<DateTime::Set>
4079
4080The L<DateTime::Set> module represents sets (including recurrences) of
4081datetimes. Many modules return sets or recurrences.
4082
4083=head2 Format Modules
4084
4085The various format modules exist to parse and format datetimes. For example,
4086L<DateTime::Format::HTTP> parses dates according to the RFC 1123 format:
4087
4088 my $datetime
4089 = DateTime::Format::HTTP->parse_datetime('Thu Feb 3 17:03:55 GMT 1994');
4090
4091 print DateTime::Format::HTTP->format_datetime($datetime);
4092
4093Most format modules are suitable for use as a C<formatter> with a DateTime
4094object.
4095
4096All format modules start with C<DateTime::Format::>.
4097
4098=head2 Calendar Modules
4099
4100There are a number of modules on CPAN that implement non-Gregorian calendars,
4101such as the Chinese, Mayan, and Julian calendars.
4102
4103All calendar modules start with C<DateTime::Calendar::>.
4104
4105=head2 Event Modules
4106
4107There are a number of modules that calculate the dates for events, such as
4108Easter, Sunrise, etc.
4109
4110All event modules start with C<DateTime::Event::>.
4111
4112=head2 Others
4113
4114There are many other modules that work with DateTime, including modules in the
4115C<DateTimeX> namespace, as well as others.
4116
4117See the L<datetime wiki|http://datetime.perl.org> and
4118L<search.cpan.org|http://search.cpan.org/search?query=datetime&mode=dist> for
4119more details.
4120
4121=head1 KNOWN BUGS
4122
4123The tests in F<20infinite.t> seem to fail on some machines,
4124particularly on Win32. This appears to be related to Perl's internal
4125handling of IEEE infinity and NaN, and seems to be highly
4126platform/compiler/phase of moon dependent.
4127
4128If you don't plan to use infinite datetimes you can probably ignore
4129this. This will be fixed (perhaps) in future versions.
4130
4131=head1 SUPPORT
4132
4133Support for this module is provided via the datetime@perl.org email list. See
4134http://datetime.perl.org/wiki/datetime/page/Mailing_List for details.
4135
4136Please submit bugs to the CPAN RT system at
4137http://rt.cpan.org/NoAuth/Bugs.html?Dist=DateTime or via email at
4138bug-datetime@rt.cpan.org.
4139
4140=head1 DONATIONS
4141
4142If you'd like to thank me for the work I've done on this module,
4143please consider making a "donation" to me via PayPal. I spend a lot of
4144free time creating free software, and would appreciate any support
4145you'd care to offer.
4146
4147Please note that B<I am not suggesting that you must do this> in order
4148for me to continue working on this particular software. I will
4149continue to do so, inasmuch as I have in the past, for as long as it
4150interests me.
4151
4152Similarly, a donation made in this way will probably not make me work
4153on this software much more, unless I get so many donations that I can
4154consider working on free software full time, which seems unlikely at
4155best.
4156
4157To donate, log into PayPal and send money to autarch@urth.org or use
4158the button on this page:
4159L<http://www.urth.org/~autarch/fs-donation.html>
4160
4161=head1 SEE ALSO
4162
4163datetime@perl.org mailing list
4164
4165http://datetime.perl.org/
4166
4167=head1 AUTHOR
4168
4169Dave Rolsky <autarch@urth.org>
4170
4171=head1 COPYRIGHT AND LICENSE
4172
4173This software is Copyright (c) 2012 by Dave Rolsky.
4174
4175This is free software, licensed under:
4176
4177 The Artistic License 2.0 (GPL Compatible)
4178
4179=cut
4180
4181
4182__END__
 
# spent 1.24ms within DateTime::CORE:match which was called 294 times, avg 4µs/call: # 294 times (1.24ms+0s) by DateTime::from_epoch at line 494, avg 4µs/call
sub DateTime::CORE:match; # opcode
# spent 83µs within DateTime::CORE:qr which was called 59 times, avg 1µs/call: # 57 times (75µs+0s) by Tapper::Schema::TestrunDB::ResultSet::Testrun::BEGIN@12 at line 1228, avg 1µs/call # once (7µs+0s) by Tapper::Schema::TestrunDB::ResultSet::Testrun::BEGIN@12 at line 477 # once (1µs+0s) by Tapper::Schema::TestrunDB::ResultSet::Testrun::BEGIN@12 at line 1917
sub DateTime::CORE:qr; # opcode
# spent 43µs within DateTime::CORE:regcomp which was called: # once (43µs+0s) by Tapper::Schema::TestrunDB::ResultSet::Testrun::BEGIN@12 at line 1917
sub DateTime::CORE:regcomp; # opcode
# spent 855µs within DateTime::_normalize_tai_seconds which was called 296 times, avg 3µs/call: # 296 times (855µs+0s) by DateTime::_calc_utc_rd at line 387, avg 3µs/call
sub DateTime::_normalize_tai_seconds; # xsub
# spent 1.46ms within DateTime::_rd2ymd which was called 588 times, avg 2µs/call: # 588 times (1.46ms+0s) by DateTime::_calc_local_components at line 437, avg 2µs/call
sub DateTime::_rd2ymd; # xsub
# spent 933µs within DateTime::_seconds_as_components which was called 588 times, avg 2µs/call: # 588 times (933µs+0s) by DateTime::_calc_local_components at line 442, avg 2µs/call
sub DateTime::_seconds_as_components; # xsub
# spent 515µs within DateTime::_time_as_seconds which was called 294 times, avg 2µs/call: # 294 times (515µs+0s) by DateTime::_new at line 246, avg 2µs/call
sub DateTime::_time_as_seconds; # xsub
# spent 895µs within DateTime::_ymd2rd which was called 294 times, avg 3µs/call: # 294 times (895µs+0s) by DateTime::_new at line 244, avg 3µs/call
sub DateTime::_ymd2rd; # xsub