Profile of DateTime.pm

← 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
Statements | Executed 31458 statements in 163ms

Subroutines
Calls | P | F | Exclusive Time | Inclusive Time | Subroutine
--- | --- | --- | --- | --- | ---
294 | 1 | 1 | 26.0ms | 101ms | DateTime::::_new DateTime::_new
294 | 1 | 1 | 15.2ms | 166ms | DateTime::::from_epoch DateTime::from_epoch
590 | 1 | 1 | 12.7ms | 15.1ms | DateTime::::_calc_local_components DateTime::_calc_local_components
588 | 2 | 1 | 10.4ms | 16.8ms | DateTime::::_handle_offset_modifier DateTime::_handle_offset_modifier
294 | 1 | 1 | 9.86ms | 59.5ms | DateTime::::set_time_zone DateTime::set_time_zone
590 | 4 | 2 | 8.44ms | 24.3ms | DateTime::::_calc_local_rd DateTime::_calc_local_rd
296 | 3 | 2 | 5.41ms | 7.02ms | DateTime::::_calc_utc_rd DateTime::_calc_utc_rd
294 | 1 | 1 | 3.94ms | 3.94ms | DateTime::::clone DateTime::clone
294 | 1 | 1 | 3.66ms | 4.61ms | DateTime::::ymd DateTime::ymd
1 | 1 | 1 | 2.64ms | 8.01ms | DateTime::::BEGIN@48 DateTime::BEGIN@48
294 | 2 | 2 | 2.49ms | 168ms | DateTime::::now DateTime::now
294 | 1 | 1 | 2.18ms | 2.81ms | DateTime::::_offset_for_local_datetime DateTime::_offset_for_local_datetime
294 | 1 | 1 | 2.02ms | 2.02ms | DateTime::::hms DateTime::hms
294 | 1 | 1 | 1.86ms | 2.53ms | DateTime::::offset DateTime::offset
295 | 2 | 1 | 1.79ms | 5.46ms | DateTime::::DefaultLocale DateTime::DefaultLocale
1 | 1 | 1 | 1.65ms | 1.90ms | DateTime::::BEGIN@46 DateTime::BEGIN@46
588 | 1 | 1 | 1.46ms | 1.46ms | DateTime::::_rd2ymd DateTime::_rd2ymd (xsub)
1 | 1 | 1 | 1.44ms | 58.1ms | DateTime::::BEGIN@47 DateTime::BEGIN@47
294 | 1 | 1 | 1.30ms | 1.30ms | DateTime::::second DateTime::second
294 | 1 | 1 | 1.24ms | 1.24ms | DateTime::::CORE:match DateTime::CORE:match (opcode)
294 | 1 | 1 | 1.13ms | 1.13ms | DateTime::::_normalize_nanoseconds DateTime::_normalize_nanoseconds
294 | 1 | 1 | 953µs | 953µs | DateTime::::year DateTime::year
588 | 1 | 1 | 933µs | 933µs | DateTime::::_seconds_as_components DateTime::_seconds_as_components (xsub)
1 | 1 | 1 | 932µs | 1.30ms | DateTime::::BEGIN@49 DateTime::BEGIN@49
294 | 1 | 1 | 895µs | 895µs | DateTime::::_ymd2rd DateTime::_ymd2rd (xsub)
296 | 1 | 1 | 855µs | 855µs | DateTime::::_normalize_tai_seconds DateTime::_normalize_tai_seconds (xsub)
1 | 1 | 1 | 775µs | 3.88ms | DateTime::::BEGIN@13 DateTime::BEGIN@13
294 | 1 | 1 | 515µs | 515µs | DateTime::::_time_as_seconds DateTime::_time_as_seconds (xsub)
1 | 1 | 1 | 179µs | 182µs | DateTime::::BEGIN@704 DateTime::BEGIN@704
1 | 1 | 1 | 171µs | 206µs | DateTime::::BEGIN@12 DateTime::BEGIN@12
59 | 3 | 1 | 83µs | 83µs | DateTime::::CORE:qr DateTime::CORE:qr (opcode)
1 | 1 | 1 | 43µs | 43µs | DateTime::::CORE:regcomp DateTime::CORE:regcomp (opcode)
1 | 1 | 1 | 27µs | 27µs | DateTime::::BEGIN@6 DateTime::BEGIN@6
1 | 1 | 1 | 22µs | 27µs | DateTime::::BEGIN@1858 DateTime::BEGIN@1858
1 | 1 | 1 | 13µs | 56µs | DateTime::::BEGIN@11 DateTime::BEGIN@11
1 | 1 | 1 | 13µs | 73µs | DateTime::::BEGIN@50 DateTime::BEGIN@50
1 | 1 | 1 | 8µs | 93µs | DateTime::::BEGIN@59 DateTime::BEGIN@59
1 | 1 | 1 | 7µs | 7µs | DateTime::::BEGIN@86 DateTime::BEGIN@86
1 | 1 | 1 | 6µs | 14µs | DateTime::::BEGIN@9 DateTime::BEGIN@9
1 | 1 | 1 | 6µs | 35µs | DateTime::::BEGIN@74 DateTime::BEGIN@74
1 | 1 | 1 | 6µs | 8µs | DateTime::::BEGIN@8 DateTime::BEGIN@8
1 | 1 | 1 | 5µs | 27µs | DateTime::::BEGIN@77 DateTime::BEGIN@77
1 | 1 | 1 | 5µs | 28µs | DateTime::::BEGIN@78 DateTime::BEGIN@78
1 | 1 | 1 | 5µs | 30µs | DateTime::::BEGIN@76 DateTime::BEGIN@76
1 | 1 | 1 | 5µs | 28µs | DateTime::::BEGIN@80 DateTime::BEGIN@80
1 | 1 | 1 | 5µs | 28µs | DateTime::::BEGIN@82 DateTime::BEGIN@82
0 | 0 | 0 | 0s | 0s | DateTime::::STORABLE_freeze DateTime::STORABLE_freeze
0 | 0 | 0 | 0s | 0s | DateTime::::STORABLE_thaw DateTime::STORABLE_thaw
0 | 0 | 0 | 0s | 0s | DateTime::_Thawed::::time_zoneDateTime::_Thawed::time_zone
0 | 0 | 0 | 0s | 0s | DateTime::_Thawed::::utc_rd_valuesDateTime::_Thawed::utc_rd_values
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1000] DateTime::__ANON__[:1000]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1001] DateTime::__ANON__[:1001]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1002] DateTime::__ANON__[:1002]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1004] DateTime::__ANON__[:1004]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1005] DateTime::__ANON__[:1005]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1006] DateTime::__ANON__[:1006]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1007] DateTime::__ANON__[:1007]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1008] DateTime::__ANON__[:1008]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1009] DateTime::__ANON__[:1009]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1010] DateTime::__ANON__[:1010]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1011] DateTime::__ANON__[:1011]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1012] DateTime::__ANON__[:1012]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1016] DateTime::__ANON__[:1016]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1017] DateTime::__ANON__[:1017]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1021] DateTime::__ANON__[:1021]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1025] DateTime::__ANON__[:1025]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1028] DateTime::__ANON__[:1028]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1031] DateTime::__ANON__[:1031]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1032] DateTime::__ANON__[:1032]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1033] DateTime::__ANON__[:1033]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1034] DateTime::__ANON__[:1034]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1035] DateTime::__ANON__[:1035]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1036] DateTime::__ANON__[:1036]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1085] DateTime::__ANON__[:1085]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1090] DateTime::__ANON__[:1090]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1098] DateTime::__ANON__[:1098]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1099] DateTime::__ANON__[:1099]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1100] DateTime::__ANON__[:1100]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1102] DateTime::__ANON__[:1102]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1107] DateTime::__ANON__[:1107]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1112] DateTime::__ANON__[:1112]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1116] DateTime::__ANON__[:1116]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1118] DateTime::__ANON__[:1118]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1121] DateTime::__ANON__[:1121]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1125] DateTime::__ANON__[:1125]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1129] DateTime::__ANON__[:1129]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1132] DateTime::__ANON__[:1132]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1136] DateTime::__ANON__[:1136]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1137] DateTime::__ANON__[:1137]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1140] DateTime::__ANON__[:1140]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1144] DateTime::__ANON__[:1144]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1146] DateTime::__ANON__[:1146]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1149] DateTime::__ANON__[:1149]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1153] DateTime::__ANON__[:1153]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1159] DateTime::__ANON__[:1159]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1164] DateTime::__ANON__[:1164]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1169] DateTime::__ANON__[:1169]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1172] DateTime::__ANON__[:1172]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1176] DateTime::__ANON__[:1176]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1178] DateTime::__ANON__[:1178]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1183] DateTime::__ANON__[:1183]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1184] DateTime::__ANON__[:1184]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1186] DateTime::__ANON__[:1186]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1188] DateTime::__ANON__[:1188]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1195] DateTime::__ANON__[:1195]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1198] DateTime::__ANON__[:1198]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1201] DateTime::__ANON__[:1201]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1212] DateTime::__ANON__[:1212]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1214] DateTime::__ANON__[:1214]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1216] DateTime::__ANON__[:1216]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1217] DateTime::__ANON__[:1217]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1221] DateTime::__ANON__[:1221]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1223] DateTime::__ANON__[:1223]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1224] DateTime::__ANON__[:1224]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1225] DateTime::__ANON__[:1225]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1226] DateTime::__ANON__[:1226]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:1227] DateTime::__ANON__[:1227]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:123] DateTime::__ANON__[:123]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:131] DateTime::__ANON__[:131]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:139] DateTime::__ANON__[:139]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:147] DateTime::__ANON__[:147]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:155] DateTime::__ANON__[:155]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:163] DateTime::__ANON__[:163]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:170] DateTime::__ANON__[:170]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:186] DateTime::__ANON__[:186]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:620] DateTime::__ANON__[:620]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:981] DateTime::__ANON__[:981]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:982] DateTime::__ANON__[:982]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:983] DateTime::__ANON__[:983]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:984] DateTime::__ANON__[:984]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:987] DateTime::__ANON__[:987]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:988] DateTime::__ANON__[:988]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:989] DateTime::__ANON__[:989]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:990] DateTime::__ANON__[:990]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:991] DateTime::__ANON__[:991]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:992] DateTime::__ANON__[:992]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:993] DateTime::__ANON__[:993]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:994] DateTime::__ANON__[:994]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:995] DateTime::__ANON__[:995]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:996] DateTime::__ANON__[:996]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:997] DateTime::__ANON__[:997]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:998] DateTime::__ANON__[:998]
0 | 0 | 0 | 0s | 0s | DateTime::::__ANON__[:999] DateTime::__ANON__[:999]
0 | 0 | 0 | 0s | 0s | DateTime::::_add_overload DateTime::_add_overload
0 | 0 | 0 | 0s | 0s | DateTime::::_adjust_for_positive_difference DateTime::_adjust_for_positive_difference
0 | 0 | 0 | 0s | 0s | DateTime::::_calc_utc_components DateTime::_calc_utc_components
0 | 0 | 0 | 0s | 0s | DateTime::::_cldr_pattern DateTime::_cldr_pattern
0 | 0 | 0 | 0s | 0s | DateTime::::_compare DateTime::_compare
0 | 0 | 0 | 0s | 0s | DateTime::::_compare_overload DateTime::_compare_overload
0 | 0 | 0 | 0s | 0s | DateTime::::_era_index DateTime::_era_index
0 | 0 | 0 | 0s | 0s | DateTime::::_format_nanosecs DateTime::_format_nanosecs
0 | 0 | 0 | 0s | 0s | DateTime::::_month_length DateTime::_month_length
0 | 0 | 0 | 0s | 0s | DateTime::::_new_from_self DateTime::_new_from_self
0 | 0 | 0 | 0s | 0s | DateTime::::_normalize_seconds DateTime::_normalize_seconds
0 | 0 | 0 | 0s | 0s | DateTime::::_space_padded_string DateTime::_space_padded_string
0 | 0 | 0 | 0s | 0s | DateTime::::_string_compare_overload DateTime::_string_compare_overload
0 | 0 | 0 | 0s | 0s | DateTime::::_string_equals_overload DateTime::_string_equals_overload
0 | 0 | 0 | 0s | 0s | DateTime::::_string_not_equals_overload DateTime::_string_not_equals_overload
0 | 0 | 0 | 0s | 0s | DateTime::::_stringify DateTime::_stringify
0 | 0 | 0 | 0s | 0s | DateTime::::_subtract_overload DateTime::_subtract_overload
0 | 0 | 0 | 0s | 0s | DateTime::::_utc_hms DateTime::_utc_hms
0 | 0 | 0 | 0s | 0s | DateTime::::_utc_ymd DateTime::_utc_ymd
0 | 0 | 0 | 0s | 0s | DateTime::::_weeks_in_year DateTime::_weeks_in_year
0 | 0 | 0 | 0s | 0s | DateTime::::_zero_padded_number DateTime::_zero_padded_number
0 | 0 | 0 | 0s | 0s | DateTime::::add DateTime::add
0 | 0 | 0 | 0s | 0s | DateTime::::add_duration DateTime::add_duration
0 | 0 | 0 | 0s | 0s | DateTime::::am_or_pm DateTime::am_or_pm
0 | 0 | 0 | 0s | 0s | DateTime::::ce_year DateTime::ce_year
0 | 0 | 0 | 0s | 0s | DateTime::::christian_era DateTime::christian_era
0 | 0 | 0 | 0s | 0s | DateTime::::compare DateTime::compare
0 | 0 | 0 | 0s | 0s | DateTime::::compare_ignore_floating DateTime::compare_ignore_floating
0 | 0 | 0 | 0s | 0s | DateTime::::day_abbr DateTime::day_abbr
0 | 0 | 0 | 0s | 0s | DateTime::::day_name DateTime::day_name
0 | 0 | 0 | 0s | 0s | DateTime::::day_of_month DateTime::day_of_month
0 | 0 | 0 | 0s | 0s | DateTime::::day_of_month_0 DateTime::day_of_month_0
0 | 0 | 0 | 0s | 0s | DateTime::::day_of_quarter DateTime::day_of_quarter
0 | 0 | 0 | 0s | 0s | DateTime::::day_of_quarter_0 DateTime::day_of_quarter_0
0 | 0 | 0 | 0s | 0s | DateTime::::day_of_week DateTime::day_of_week
0 | 0 | 0 | 0s | 0s | DateTime::::day_of_week_0 DateTime::day_of_week_0
0 | 0 | 0 | 0s | 0s | DateTime::::day_of_year DateTime::day_of_year
0 | 0 | 0 | 0s | 0s | DateTime::::day_of_year_0 DateTime::day_of_year_0
0 | 0 | 0 | 0s | 0s | DateTime::::delta_days DateTime::delta_days
0 | 0 | 0 | 0s | 0s | DateTime::::delta_md DateTime::delta_md
0 | 0 | 0 | 0s | 0s | DateTime::::delta_ms DateTime::delta_ms
0 | 0 | 0 | 0s | 0s | DateTime::::dmy DateTime::dmy
0 | 0 | 0 | 0s | 0s | DateTime::::epoch DateTime::epoch
0 | 0 | 0 | 0s | 0s | DateTime::::era_abbr DateTime::era_abbr
0 | 0 | 0 | 0s | 0s | DateTime::::era_name DateTime::era_name
0 | 0 | 0 | 0s | 0s | DateTime::::format_cldr DateTime::format_cldr
0 | 0 | 0 | 0s | 0s | DateTime::::formatter DateTime::formatter
0 | 0 | 0 | 0s | 0s | DateTime::::fractional_second DateTime::fractional_second
0 | 0 | 0 | 0s | 0s | DateTime::::from_day_of_year DateTime::from_day_of_year
0 | 0 | 0 | 0s | 0s | DateTime::::from_object DateTime::from_object
0 | 0 | 0 | 0s | 0s | DateTime::::hires_epoch DateTime::hires_epoch
0 | 0 | 0 | 0s | 0s | DateTime::::hour DateTime::hour
0 | 0 | 0 | 0s | 0s | DateTime::::hour_1 DateTime::hour_1
0 | 0 | 0 | 0s | 0s | DateTime::::hour_12 DateTime::hour_12
0 | 0 | 0 | 0s | 0s | DateTime::::hour_12_0 DateTime::hour_12_0
0 | 0 | 0 | 0s | 0s | DateTime::::is_dst DateTime::is_dst
0 | 0 | 0 | 0s | 0s | DateTime::::is_finite DateTime::is_finite
0 | 0 | 0 | 0s | 0s | DateTime::::is_infinite DateTime::is_infinite
0 | 0 | 0 | 0s | 0s | DateTime::::is_leap_year DateTime::is_leap_year
0 | 0 | 0 | 0s | 0s | DateTime::::iso8601 DateTime::iso8601
0 | 0 | 0 | 0s | 0s | DateTime::::jd DateTime::jd
0 | 0 | 0 | 0s | 0s | DateTime::::last_day_of_month DateTime::last_day_of_month
0 | 0 | 0 | 0s | 0s | DateTime::::leap_seconds DateTime::leap_seconds
0 | 0 | 0 | 0s | 0s | DateTime::::local_day_of_week DateTime::local_day_of_week
0 | 0 | 0 | 0s | 0s | DateTime::::local_rd_as_seconds DateTime::local_rd_as_seconds
0 | 0 | 0 | 0s | 0s | DateTime::::local_rd_values DateTime::local_rd_values
0 | 0 | 0 | 0s | 0s | DateTime::::locale DateTime::locale
0 | 0 | 0 | 0s | 0s | DateTime::::mdy DateTime::mdy
0 | 0 | 0 | 0s | 0s | DateTime::::microsecond DateTime::microsecond
0 | 0 | 0 | 0s | 0s | DateTime::::millisecond DateTime::millisecond
0 | 0 | 0 | 0s | 0s | DateTime::::minute DateTime::minute
0 | 0 | 0 | 0s | 0s | DateTime::::mjd DateTime::mjd
0 | 0 | 0 | 0s | 0s | DateTime::::month DateTime::month
0 | 0 | 0 | 0s | 0s | DateTime::::month_0 DateTime::month_0
0 | 0 | 0 | 0s | 0s | DateTime::::month_abbr DateTime::month_abbr
0 | 0 | 0 | 0s | 0s | DateTime::::month_name DateTime::month_name
0 | 0 | 0 | 0s | 0s | DateTime::::nanosecond DateTime::nanosecond
0 | 0 | 0 | 0s | 0s | DateTime::::new DateTime::new
0 | 0 | 0 | 0s | 0s | DateTime::::quarter DateTime::quarter
0 | 0 | 0 | 0s | 0s | DateTime::::quarter_0 DateTime::quarter_0
0 | 0 | 0 | 0s | 0s | DateTime::::quarter_abbr DateTime::quarter_abbr
0 | 0 | 0 | 0s | 0s | DateTime::::quarter_name DateTime::quarter_name
0 | 0 | 0 | 0s | 0s | DateTime::::secular_era DateTime::secular_era
0 | 0 | 0 | 0s | 0s | DateTime::::set DateTime::set
0 | 0 | 0 | 0s | 0s | DateTime::::set_day DateTime::set_day
0 | 0 | 0 | 0s | 0s | DateTime::::set_formatter DateTime::set_formatter
0 | 0 | 0 | 0s | 0s | DateTime::::set_hour DateTime::set_hour
0 | 0 | 0 | 0s | 0s | DateTime::::set_locale DateTime::set_locale
0 | 0 | 0 | 0s | 0s | DateTime::::set_minute DateTime::set_minute
0 | 0 | 0 | 0s | 0s | DateTime::::set_month DateTime::set_month
0 | 0 | 0 | 0s | 0s | DateTime::::set_nanosecond DateTime::set_nanosecond
0 | 0 | 0 | 0s | 0s | DateTime::::set_second DateTime::set_second
0 | 0 | 0 | 0s | 0s | DateTime::::set_year DateTime::set_year
0 | 0 | 0 | 0s | 0s | DateTime::::strftime DateTime::strftime
0 | 0 | 0 | 0s | 0s | DateTime::::subtract DateTime::subtract
0 | 0 | 0 | 0s | 0s | DateTime::::subtract_datetime DateTime::subtract_datetime
0 | 0 | 0 | 0s | 0s | DateTime::::subtract_datetime_absolute DateTime::subtract_datetime_absolute
0 | 0 | 0 | 0s | 0s | DateTime::::subtract_duration DateTime::subtract_duration
0 | 0 | 0 | 0s | 0s | DateTime::::time_zone DateTime::time_zone
0 | 0 | 0 | 0s | 0s | DateTime::::time_zone_long_name DateTime::time_zone_long_name
0 | 0 | 0 | 0s | 0s | DateTime::::time_zone_short_name DateTime::time_zone_short_name
0 | 0 | 0 | 0s | 0s | DateTime::::today DateTime::today
0 | 0 | 0 | 0s | 0s | DateTime::::truncate DateTime::truncate
0 | 0 | 0 | 0s | 0s | DateTime::::utc_rd_as_seconds DateTime::utc_rd_as_seconds
0 | 0 | 0 | 0s | 0s | DateTime::::utc_rd_values DateTime::utc_rd_values
0 | 0 | 0 | 0s | 0s | DateTime::::utc_year DateTime::utc_year
0 | 0 | 0 | 0s | 0s | DateTime::::week DateTime::week
0 | 0 | 0 | 0s | 0s | DateTime::::week_number DateTime::week_number
0 | 0 | 0 | 0s | 0s | DateTime::::week_of_month DateTime::week_of_month
0 | 0 | 0 | 0s | 0s | DateTime::::week_year DateTime::week_year
0 | 0 | 0 | 0s | 0s | DateTime::::weekday_of_month DateTime::weekday_of_month
0 | 0 | 0 | 0s | 0s | DateTime::::year_with_christian_era DateTime::year_with_christian_era
0 | 0 | 0 | 0s | 0s | DateTime::::year_with_era DateTime::year_with_era
0 | 0 | 0 | 0s | 0s | DateTime::::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
--- | --- | --- | --- | --- | ---
1 |  |  |  |  | package DateTime;
2 |  |  |  |  | {
3 | 2 | 3µs |  |  | $DateTime::VERSION = '0.74';
4 |  |  |  |  | }
5 |  |  |  |  |
6 | 3 | 36µs | 1 | 27µ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 |  |  |  |  |
8 | 3 | 16µs | 2 | 10µ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
9 | 3 | 20µs | 2 | 21µ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 |  |  |  |  |
11 | 3 | 20µs | 2 | 99µ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
12 | 3 | 84µs | 1 | 206µ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
13 | 3 | 211µs | 2 | 3.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 |  |  |  |  | {
16 | 2 | 1µs |  |  | my $loaded = 0;
17 |  |  |  |  |
18 | 1 | 4µs |  |  | unless ( $ENV{PERL_DATETIME_PP} ) {
19 | 1 | 400ns |  |  | local $@;
20 | 1 | 1µs |  |  | eval {
21 | 1 | 2µs |  |  | require XSLoader;
22 |  |  |  |  | XSLoader::load(
23 |  |  |  |  | __PACKAGE__,
24 |  |  |  |  | exists $DateTime::{VERSION}
25 | 1 | 352µs | 1 | 336µs | ? ${ $DateTime::{VERSION} } # spent 336µs making 1 call to XSLoader::load
26 |  |  |  |  | : ()
27 |  |  |  |  | );
28 |  |  |  |  |
29 | 1 | 1µs |  |  | $DateTime::IsPurePerl = 0;
30 |  |  |  |  | };
31 |  |  |  |  |
32 | 1 | 200ns |  |  | die $@ if $@ && $@ !~ /object version|loadable object/;
33 |  |  |  |  |
34 | 1 | 900ns |  |  | $loaded = 1 unless $@;
35 |  |  |  |  | }
36 |  |  |  |  |
37 | 1 | 800ns |  |  | if ($loaded) {
38 |  |  |  |  | require DateTimePPExtra
39 |  |  |  |  | unless defined &DateTime::_normalize_tai_seconds;
40 |  |  |  |  | }
41 |  |  |  |  | else {
42 |  |  |  |  | require DateTimePP;
43 |  |  |  |  | }
44 |  |  |  |  | }
45 |  |  |  |  |
46 | 3 | 135µs | 1 | 1.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
47 | 3 | 138µs | 2 | 58.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
48 | 3 | 158µs | 2 | 8.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
49 | 3 | 151µs | 3 | 1.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
51 | 3 | 61µs | 3 | 134µ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 (
60 |  |  | 1 | 85µ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',
68 | 3 | 30µs | 1 | 93µ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
72 | 1 | 106µs |  |  | require DateTime::Infinite;
73 |  |  |  |  |
74 | 3 | 26µs | 2 | 64µ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 |  |  |  |  |
76 | 3 | 23µs | 2 | 55µ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
77 | 3 | 21µs | 2 | 48µ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
78 | 3 | 18µs | 2 | 50µ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 |  |  |  |  |
80 | 3 | 18µs | 2 | 50µ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 |  |  |  |  |
82 | 3 | 44µs | 2 | 50µ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 |  |  |  |  |
84 | 1 | 1µs |  |  | my ( @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 {
87 | 3 | 7µs |  |  | @MonthLengths = ( 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 );
88 |  |  |  |  |
89 |  |  |  |  | @LeapYearMonthLengths = @MonthLengths;
90 |  |  |  |  | $LeapYearMonthLengths[1]++;
91 | 1 | 2.44ms | 1 | 7µ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!
98 | 2 | 1µ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 {
101 | 888 | 2.46ms |  |  | my $class = shift;
102 |  |  |  |  |
103 |  |  |  |  | if (@_) {
104 |  |  |  |  | my $lang = shift;
105 |  |  |  |  |
106 |  |  | 1 | 3.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
115 | 1 | 3µs |  |  | *DefaultLanguage = \&DefaultLocale;
116 |  |  |  |  | }
117 | 1 | 2µs | 1 | 3.68ms | __PACKAGE__->DefaultLocale('en_US'); # spent 3.68ms making 1 call to DateTime::DefaultLocale
118 |  |  |  |  |
119 |  |  |  |  | my $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 |  |  |  |  | },
189 | 1 | 35µs |  |  | };
190 |  |  |  |  |
191 | 1 | 5µs |  |  | my $NewValidate = {
192 |  |  |  |  | %$BasicValidate,
193 |  |  |  |  | time_zone => {
194 |  |  |  |  | type => SCALAR | OBJECT,
195 |  |  |  |  | default => 'floating'
196 |  |  |  |  | },
197 |  |  |  |  | };
198 |  |  |  |  |
199 |  |  |  |  | sub 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 {
213 | 7938 | 24.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};
229 |  |  | 294 | 1.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 {
235 |  |  | 294 | 16.6ms | $self->{locale} = DateTime::Locale->load( $p{locale} ); # spent 16.6ms making 294 calls to DateTime::Locale::load, avg 57µs/call
236 |  |  |  |  | }
237 |  |  |  |  |
238 |  |  | 294 | 24.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 |  |  |  |  |
244 |  |  | 294 | 895µ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 |  |  |  |  |
246 |  |  | 294 | 515µ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 |  |  |  |  |
254 |  |  | 294 | 1.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 |  |  |  |  |
265 |  |  | 294 | 6.98ms | $self->_calc_utc_rd; # spent 6.98ms making 294 calls to DateTime::_calc_utc_rd, avg 24µs/call
266 |  |  |  |  |
267 |  |  | 294 | 9.33ms | $self->_handle_offset_modifier( $p{second} ); # spent 9.33ms making 294 calls to DateTime::_handle_offset_modifier, avg 32µs/call
268 |  |  |  |  |
269 |  |  | 294 | 13.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().
289 |  |  |  |  | sub _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 {
305 | 5292 | 9.44ms |  |  | my $self = shift;
306 |  |  |  |  |
307 |  |  |  |  | $self->{offset_modifier} = 0;
308 |  |  |  |  |
309 |  |  | 588 | 1.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 |  |  |  |  |
316 |  |  | 588 | 5.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 {
368 | 1776 | 5.89ms |  |  | my $self = shift;
369 |  |  |  |  |
370 |  |  |  |  | delete $self->{utc_c};
371 |  |  |  |  |
372 |  |  | 298 | 760µ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.
387 |  |  | 296 | 855µ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 |  |  |  |  |
391 |  |  |  |  | sub _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 {
407 | 3540 | 7.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
413 |  |  | 592 | 794µ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 |  |  |  |  |
430 |  |  | 590 | 15.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 {
434 | 1770 | 16.1ms |  |  | my $self = shift;
435 |  |  |  |  |
436 |  |  |  |  | @{ $self->{local_c} }{
437 |  |  | 590 | 1.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 |  |  |  |  |
442 |  |  | 590 | 936µ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 |  |  |  |  |
447 |  |  |  |  | sub _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 |  |  |  |  |
460 |  |  |  |  | sub _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 |  |  |  |  |
468 |  |  |  |  | sub _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 |  |  |  |  | {
477 | 2 | 18µs | 1 | 7µ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 {
489 | 3528 | 42.3ms |  |  | my $class = shift;
490 | 1 | 13.3ms | 588 | 55.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.
494 |  |  | 294 | 1.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 |  |  |  |  |
507 |  |  | 294 | 101ms | 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
516 | 294 | 2.42ms | 294 | 166ms | # 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 |  |  |  |  |
518 |  |  |  |  | sub today { shift->now(@_)->truncate( to => 'day' ) }
519 |  |  |  |  |
520 |  |  |  |  | {
521 | 2 | 7µ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 |  |  |  |  |
579 | 1 | 3µs |  |  | my $LastDayOfMonthValidate = {%$NewValidate};
580 | 1 | 3µs |  |  | foreach ( keys %$LastDayOfMonthValidate ) {
581 | 11 | 20µs |  |  | my %copy = %{ $LastDayOfMonthValidate->{$_} };
582 |  |  |  |  |
583 | 11 | 3µs |  |  | delete $copy{default};
584 | 11 | 5µs |  |  | $copy{optional} = 1 unless $_ eq 'year' || $_ eq 'month';
585 |  |  |  |  |
586 | 11 | 8µs |  |  | $LastDayOfMonthValidate->{$_} = \%copy;
587 |  |  |  |  | }
588 |  |  |  |  |
589 |  |  |  |  | sub 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 |  |  |  |  |
598 |  |  |  |  | sub _month_length {
599 |  |  |  |  | return (
600 |  |  |  |  | $_[0]->_is_leap_year( $_[1] )
601 |  |  |  |  | ? $LeapYearMonthLengths[ $_[2] - 1 ]
602 |  |  |  |  | : $MonthLengths[ $_[2] - 1 ]
603 |  |  |  |  | );
604 |  |  |  |  | }
605 |  |  |  |  |
606 | 1 | 3µs |  |  | my $FromDayOfYearValidate = {%$NewValidate};
607 | 1 | 2µs |  |  | foreach ( keys %$FromDayOfYearValidate ) {
608 | 11 | 3µs |  |  | next if $_ eq 'month' || $_ eq 'day';
609 |  |  |  |  |
610 | 9 | 13µs |  |  | my %copy = %{ $FromDayOfYearValidate->{$_} };
611 |  |  |  |  |
612 | 9 | 2µs |  |  | delete $copy{default};
613 | 9 | 3µs |  |  | $copy{optional} = 1 unless $_ eq 'year' || $_ eq 'month';
614 |  |  |  |  |
615 | 9 | 6µ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 |  |  |  |  | }
622 | 1 | 4µs |  |  | };
623 |  |  |  |  |
624 |  |  |  |  | sub 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 |  |  |  |  |
651 |  |  |  |  | sub formatter { $_[0]->{formatter} }
652 |  |  |  |  |
653 | 294 | 4.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 {
656 | 588 | 1.49ms |  |  | Carp::carp('year() is a read-only accessor') if @_ > 1;
657 |  |  |  |  | return $_[0]->{local_c}{year};
658 |  |  |  |  | }
659 |  |  |  |  |
660 |  |  |  |  | sub ce_year {
661 |  |  |  |  | $_[0]->{local_c}{year} <= 0
662 |  |  |  |  | ? $_[0]->{local_c}{year} - 1
663 |  |  |  |  | : $_[0]->{local_c}{year};
664 |  |  |  |  | }
665 |  |  |  |  |
666 |  |  |  |  | sub era_name { $_[0]->{locale}->era_wide->[ $_[0]->_era_index() ] }
667 |  |  |  |  |
668 |  |  |  |  | sub era_abbr { $_[0]->{locale}->era_abbreviated->[ $_[0]->_era_index() ] }
669 |  |  |  |  |
670 |  |  |  |  | # deprecated
671 | 1 | 7µs |  |  | *era = \&era_abbr;
672 |  |  |  |  |
673 |  |  |  |  | sub _era_index { $_[0]->{local_c}{year} <= 0 ? 0 : 1 }
674 |  |  |  |  |
675 |  |  |  |  | sub christian_era { $_[0]->ce_year > 0 ? 'AD' : 'BC' }
676 |  |  |  |  | sub secular_era { $_[0]->ce_year > 0 ? 'CE' : 'BCE' }
677 |  |  |  |  |
678 |  |  |  |  | sub year_with_era { ( abs $_[0]->ce_year ) . $_[0]->era_abbr }
679 |  |  |  |  | sub year_with_christian_era { ( abs $_[0]->ce_year ) . $_[0]->christian_era }
680 |  |  |  |  | sub year_with_secular_era { ( abs $_[0]->ce_year ) . $_[0]->secular_era }
681 |  |  |  |  |
682 |  |  |  |  | sub month {
683 |  |  |  |  | Carp::carp('month() is a read-only accessor') if @_ > 1;
684 |  |  |  |  | return $_[0]->{local_c}{month};
685 |  |  |  |  | }
686 | 1 | 2µs |  |  | *mon = \&month;
687 |  |  |  |  |
688 |  |  |  |  | sub month_0 { $_[0]->{local_c}{month} - 1 }
689 | 1 | 2µs |  |  | *mon_0 = \&month_0;
690 |  |  |  |  |
691 |  |  |  |  | sub month_name { $_[0]->{locale}->month_format_wide->[ $_[0]->month_0() ] }
692 |  |  |  |  |
693 |  |  |  |  | sub month_abbr {
694 |  |  |  |  | $_[0]->{locale}->month_format_abbreviated->[ $_[0]->month_0() ];
695 |  |  |  |  | }
696 |  |  |  |  |
697 |  |  |  |  | sub day_of_month {
698 |  |  |  |  | Carp::carp('day_of_month() is a read-only accessor') if @_ > 1;
699 |  |  |  |  | $_[0]->{local_c}{day};
700 |  |  |  |  | }
701 | 1 | 2µs |  |  | *day = \&day_of_month;
702 | 1 | 2µs |  |  | *mday = \&day_of_month;
703 |  |  |  |  |
704 | 3 | 6.16ms | 2 | 186µ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 |  |  |  |  |
706 |  |  |  |  | sub quarter { $_[0]->{local_c}{quarter} }
707 |  |  |  |  |
708 |  |  |  |  | sub quarter_name {
709 |  |  |  |  | $_[0]->{locale}->quarter_format_wide->[ $_[0]->quarter_0() ];
710 |  |  |  |  | }
711 |  |  |  |  |
712 |  |  |  |  | sub quarter_abbr {
713 |  |  |  |  | $_[0]->{locale}->quarter_format_abbreviated->[ $_[0]->quarter_0() ];
714 |  |  |  |  | }
715 |  |  |  |  |
716 |  |  |  |  | sub quarter_0 { $_[0]->{local_c}{quarter} - 1 }
717 |  |  |  |  |
718 |  |  |  |  | sub day_of_month_0 { $_[0]->{local_c}{day} - 1 }
719 | 1 | 2µs |  |  | *day_0 = \&day_of_month_0;
720 | 1 | 2µs |  |  | *mday_0 = \&day_of_month_0;
721 |  |  |  |  |
722 |  |  |  |  | sub day_of_week { $_[0]->{local_c}{day_of_week} }
723 | 1 | 2µs |  |  | *wday = \&day_of_week;
724 | 1 | 2µs |  |  | *dow = \&day_of_week;
725 |  |  |  |  |
726 |  |  |  |  | sub day_of_week_0 { $_[0]->{local_c}{day_of_week} - 1 }
727 | 1 | 2µs |  |  | *wday_0 = \&day_of_week_0;
728 | 1 | 2µs |  |  | *dow_0 = \&day_of_week_0;
729 |  |  |  |  |
730 |  |  |  |  | sub 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 |  |  |  |  |
742 |  |  |  |  | sub day_name { $_[0]->{locale}->day_format_wide->[ $_[0]->day_of_week_0() ] }
743 |  |  |  |  |
744 |  |  |  |  | sub day_abbr {
745 |  |  |  |  | $_[0]->{locale}->day_format_abbreviated->[ $_[0]->day_of_week_0() ];
746 |  |  |  |  | }
747 |  |  |  |  |
748 |  |  |  |  | sub day_of_quarter { $_[0]->{local_c}{day_of_quarter} }
749 | 1 | 2µs |  |  | *doq = \&day_of_quarter;
750 |  |  |  |  |
751 |  |  |  |  | sub day_of_quarter_0 { $_[0]->day_of_quarter - 1 }
752 | 1 | 2µs |  |  | *doq_0 = \&day_of_quarter_0;
753 |  |  |  |  |
754 |  |  |  |  | sub day_of_year { $_[0]->{local_c}{day_of_year} }
755 | 1 | 2µs |  |  | *doy = \&day_of_year;
756 |  |  |  |  |
757 |  |  |  |  | sub day_of_year_0 { $_[0]->{local_c}{day_of_year} - 1 }
758 | 1 | 2µs |  |  | *doy_0 = \&day_of_year_0;
759 |  |  |  |  |
760 |  |  |  |  | sub 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 {
765 | 882 | 3.43ms |  |  | my ( $self, $sep ) = @_;
766 |  |  |  |  | $sep = '-' unless defined $sep;
767 |  |  |  |  |
768 |  |  | 294 | 953µ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 |  |  |  |  | }
775 | 1 | 2µs |  |  | *date = \&ymd;
776 |  |  |  |  |
777 |  |  |  |  | sub 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 |  |  |  |  |
789 |  |  |  |  | sub 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 |  |  |  |  |
801 |  |  |  |  | sub hour {
802 |  |  |  |  | Carp::carp('hour() is a read-only accessor') if @_ > 1;
803 |  |  |  |  | return $_[0]->{local_c}{hour};
804 |  |  |  |  | }
805 |  |  |  |  | sub hour_1 { $_[0]->{local_c}{hour} == 0 ? 24 : $_[0]->{local_c}{hour} }
806 |  |  |  |  |
807 |  |  |  |  | sub hour_12 { my $h = $_[0]->hour % 12; return $h ? $h : 12 }
808 |  |  |  |  | sub hour_12_0 { $_[0]->hour % 12 }
809 |  |  |  |  |
810 |  |  |  |  | sub minute {
811 |  |  |  |  | Carp::carp('minute() is a read-only accessor') if @_ > 1;
812 |  |  |  |  | return $_[0]->{local_c}{minute};
813 |  |  |  |  | }
814 | 1 | 2µ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 {
817 | 588 | 1.50ms |  |  | Carp::carp('second() is a read-only accessor') if @_ > 1;
818 |  |  |  |  | return $_[0]->{local_c}{second};
819 |  |  |  |  | }
820 | 1 | 2µs |  |  | *sec = \&second;
821 |  |  |  |  |
822 |  |  |  |  | sub fractional_second { $_[0]->second + $_[0]->nanosecond / MAX_NANOSECONDS }
823 |  |  |  |  |
824 |  |  |  |  | sub nanosecond {
825 |  |  |  |  | Carp::carp('nanosecond() is a read-only accessor') if @_ > 1;
826 |  |  |  |  | return $_[0]->{rd_nanosecs};
827 |  |  |  |  | }
828 |  |  |  |  |
829 |  |  |  |  | sub millisecond { round( $_[0]->{rd_nanosecs} / 1000000 ) }
830 |  |  |  |  |
831 |  |  |  |  | sub microsecond { round( $_[0]->{rd_nanosecs} / 1000 ) }
832 |  |  |  |  |
833 |  |  |  |  | sub 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 |  |  |  |  |
841 |  |  |  |  | sub _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 {
849 | 882 | 2.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()
861 | 1 | 2µs |  |  | *DateTime::time = \&hms;
862 |  |  |  |  |
863 |  |  |  |  | sub iso8601 { join 'T', $_[0]->ymd('-'), $_[0]->hms(':') }
864 | 1 | 2µs |  |  | *datetime = \&iso8601;
865 |  |  |  |  |
866 |  |  |  |  | sub is_leap_year { $_[0]->_is_leap_year( $_[0]->year ) }
867 |  |  |  |  |
868 |  |  |  |  | sub 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 |  |  |  |  |
899 |  |  |  |  | sub _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 |  |  |  |  |
912 |  |  |  |  | sub week_year { ( $_[0]->week )[0] }
913 |  |  |  |  | sub 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.
918 |  |  |  |  | sub 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 |  |  |  |  |
924 |  |  |  |  | sub time_zone {
925 |  |  |  |  | Carp::carp('time_zone() is a read-only accessor') if @_ > 1;
926 |  |  |  |  | return $_[0]->{tz};
927 |  |  |  |  | }
928 |  |  |  |  |
929 | 294 | 1.81ms | 294 | 672µ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 {
932 | 294 | 1.99ms | 294 | 635µ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 |  |  |  |  |
935 |  |  |  |  | sub is_dst { $_[0]->{tz}->is_dst_for_datetime( $_[0] ) }
936 |  |  |  |  |
937 |  |  |  |  | sub time_zone_long_name { $_[0]->{tz}->name }
938 |  |  |  |  | sub time_zone_short_name { $_[0]->{tz}->short_name_for_datetime( $_[0] ) }
939 |  |  |  |  |
940 |  |  |  |  | sub locale {
941 |  |  |  |  | Carp::carp('locale() is a read-only accessor') if @_ > 1;
942 |  |  |  |  | return $_[0]->{locale};
943 |  |  |  |  | }
944 | 1 | 2µs |  |  | *language = \&locale;
945 |  |  |  |  |
946 |  |  |  |  | sub utc_rd_values {
947 |  |  |  |  | @{ $_[0] }{ 'utc_rd_days', 'utc_rd_secs', 'rd_nanosecs' };
948 |  |  |  |  | }
949 |  |  |  |  |
950 |  |  |  |  | sub local_rd_values {
951 |  |  |  |  | @{ $_[0] }{ 'local_rd_days', 'local_rd_secs', 'rd_nanosecs' };
952 |  |  |  |  | }
953 |  |  |  |  |
954 |  |  |  |  | # NOTE: no nanoseconds, no leap seconds
955 |  |  |  |  | sub 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
960 |  |  |  |  | sub 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
965 |  |  |  |  | sub 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 |  |  |  |  |
977 |  |  |  |  | sub mjd { $_[0]->jd - 2_400_000.5 }
978 |  |  |  |  |
979 |  |  |  |  | {
980 | 1 | 700ns |  |  | 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 {'%'},
1037 | 1 | 91µs |  |  | );
1038 |  |  |  |  |
1039 | 1 | 5µ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.
1083 | 1 | 2µ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() },
1228 | 1 | 223µs | 57 | 75µ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 |  |  |  |  |
1301 |  |  |  |  | sub _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 |  |  |  |  |
1313 |  |  |  |  | sub 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 |  |  |  |  |
1332 |  |  |  |  | sub 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 |  |  |  |  |
1344 |  |  |  |  | sub is_finite {1}
1345 |  |  |  |  | sub is_infinite {0}
1346 |  |  |  |  |
1347 |  |  |  |  | # added for benefit of DateTime::TimeZone
1348 |  |  |  |  | sub utc_year { $_[0]->{utc_year} }
1349 |  |  |  |  |
1350 |  |  |  |  | # returns a result that is relative to the first datetime
1351 |  |  |  |  | sub 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 |  |  |  |  |
1465 |  |  |  |  | sub _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 |  |  |  |  |
1508 |  |  |  |  | sub 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 |  |  |  |  |
1535 |  |  |  |  | sub 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 |  |  |  |  |
1565 |  |  |  |  | sub 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 |  |  |  |  |
1575 |  |  |  |  | sub 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 |  |  |  |  |
1593 |  |  |  |  | sub _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 |  |  |  |  |
1612 |  |  |  |  | sub _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 |  |  |  |  |
1638 |  |  |  |  | sub add {
1639 |  |  |  |  | my $self = shift;
1640 |  |  |  |  |
1641 |  |  |  |  | return $self->add_duration( $self->duration_class->new(@_) );
1642 |  |  |  |  | }
1643 |  |  |  |  |
1644 |  |  |  |  | sub subtract {
1645 |  |  |  |  | my $self = shift;
1646 |  |  |  |  |
1647 |  |  |  |  | return $self->subtract_duration( $self->duration_class->new(@_) );
1648 |  |  |  |  | }
1649 |  |  |  |  |
1650 |  |  |  |  | sub subtract_duration { return $_[0]->add_duration( $_[1]->inverse ) }
1651 |  |  |  |  |
1652 |  |  |  |  | {
1653 | 2 | 3µ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 |  |  |  |  |
1770 |  |  |  |  | sub _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 |  |  |  |  |
1777 |  |  |  |  | sub _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 |  |  |  |  |
1791 |  |  |  |  | sub compare {
1792 |  |  |  |  | shift->_compare( @_, 0 );
1793 |  |  |  |  | }
1794 |  |  |  |  |
1795 |  |  |  |  | sub compare_ignore_floating {
1796 |  |  |  |  | shift->_compare( @_, 1 );
1797 |  |  |  |  | }
1798 |  |  |  |  |
1799 |  |  |  |  | sub _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 |  |  |  |  |
1842 |  |  |  |  | sub _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 |  |  |  |  |
1853 |  |  |  |  | sub _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 {
1858 | 3 | 1.80ms | 2 | 32µ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
1861 | 294 | 1.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.
1875 |  |  |  |  | my $SetValidate = {
1876 |  |  |  |  | map {
1877 | 11 | 22µs |  |  | my %copy = %{ $BasicValidate->{$_} };
1878 | 10 | 3µs |  |  | delete $copy{default};
1879 | 10 | 3µs |  |  | $copy{optional} = 1;
1880 | 10 | 5µs |  |  | $_ => \%copy
1881 |  |  |  |  | }
1882 |  |  |  |  | keys %$BasicValidate
1883 |  |  |  |  | };
1884 |  |  |  |  |
1885 |  |  |  |  | sub 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 |  |  |  |  |
1896 |  |  |  |  | sub set_year { $_[0]->set( year => $_[1] ) }
1897 |  |  |  |  | sub set_month { $_[0]->set( month => $_[1] ) }
1898 |  |  |  |  | sub set_day { $_[0]->set( day => $_[1] ) }
1899 |  |  |  |  | sub set_hour { $_[0]->set( hour => $_[1] ) }
1900 |  |  |  |  | sub set_minute { $_[0]->set( minute => $_[1] ) }
1901 |  |  |  |  | sub set_second { $_[0]->set( second => $_[1] ) }
1902 |  |  |  |  | sub set_nanosecond { $_[0]->set( nanosecond => $_[1] ) }
1903 |  |  |  |  | sub set_locale { $_[0]->set( locale => $_[1] ) }
1904 |  |  |  |  | sub set_formatter { $_[0]->set( formatter => $_[1] ) }
1905 |  |  |  |  |
1906 |  |  |  |  | {
1907 | 2 | 3µ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',
1916 | 1 | 4µs |  |  | grep { $_ ne 'nanosecond' } keys %TruncateDefault;
1917 | 1 | 53µs | 2 | 44µ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 {
1952 | 2058 | 7.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 |  |  |  |  |
1959 |  |  | 294 | 588µs | my $was_floating = $self->{tz}->is_floating; # spent 588µs making 294 calls to DateTime::TimeZone::is_floating, avg 2µs/call
1960 |  |  |  |  |
1961 |  |  | 294 | 28.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 |  |  |  |  |
1963 |  |  | 588 | 8.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)
1966 |  |  | 588 | 11.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 |  |  |  |  |
1976 |  |  |  |  | sub 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 |  |  |  |  |
1998 |  |  |  |  | sub 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 |  |  |  |  |
2045 |  |  |  |  | package
2046 |  |  |  |  | DateTime::_Thawed;
2047 |  |  |  |  |
2048 |  |  |  |  | sub utc_rd_values { @{ $_[0]->{utc_vals} } }
2049 |  |  |  |  |
2050 |  |  |  |  | sub time_zone { $_[0]->{tz} }
2051 |  |  |  |  |
2052 | 1 | 101µs |  |  | 1;
2053 |  |  |  |  |
2054 |  |  |  |  | # ABSTRACT: A date and time object
2055 |  |  |  |  |
- - |  |  |  |  |
2058 |  |  |  |  | =pod
2059 |  |  |  |  |
2060 |  |  |  |  | =head1 NAME
2061 |  |  |  |  |
2062 |  |  |  |  | DateTime - A date and time object
2063 |  |  |  |  |
2064 |  |  |  |  | =head1 VERSION
2065 |  |  |  |  |
2066 |  |  |  |  | version 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 |  |  |  |  |
2145 |  |  |  |  | DateTime is a class for the representation of date/time combinations,
2146 |  |  |  |  | and is part of the Perl DateTime project. For details on this project
2147 |  |  |  |  | please see L<http://datetime.perl.org/>. The DateTime site has a FAQ
2148 |  |  |  |  | which may help answer many "how do I do X?" questions. The FAQ is at
2149 |  |  |  |  | L<http://datetime.perl.org/wiki/datetime/page/FAQ>.
2150 |  |  |  |  |
2151 |  |  |  |  | It represents the Gregorian calendar, extended backwards in time
2152 |  |  |  |  | before its creation (in 1582). This is sometimes known as the
2153 |  |  |  |  | "proleptic Gregorian calendar". In this calendar, the first day of
2154 |  |  |  |  | the calendar (the epoch), is the first day of year 1, which
2155 |  |  |  |  | corresponds to the date which was (incorrectly) believed to be the
2156 |  |  |  |  | birth of Jesus Christ.
2157 |  |  |  |  |
2158 |  |  |  |  | The calendar represented does have a year 0, and in that way differs
2159 |  |  |  |  | from how dates are often written using "BCE/CE" or "BC/AD".
2160 |  |  |  |  |
2161 |  |  |  |  | For infinite datetimes, please see the
2162 |  |  |  |  | L<DateTime::Infinite|DateTime::Infinite> module.
2163 |  |  |  |  |
2164 |  |  |  |  | =head1 USAGE
2165 |  |  |  |  |
2166 |  |  |  |  | =head2 0-based Versus 1-based Numbers
2167 |  |  |  |  |
2168 |  |  |  |  | The DateTime.pm module follows a simple consistent logic for
2169 |  |  |  |  | determining whether or not a given number is 0-based or 1-based.
2170 |  |  |  |  |
2171 |  |  |  |  | Month, day of month, day of week, and day of year are 1-based. Any
2172 |  |  |  |  | method 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
2174 |  |  |  |  | C<day_of_week_0()> methods.
2175 |  |  |  |  |
2176 |  |  |  |  | The C<day_of_week_0()> method still treats Monday as the first day of
2177 |  |  |  |  | the week.
2178 |  |  |  |  |
2179 |  |  |  |  | All I<time>-related numbers such as hour, minute, and second are
2180 |  |  |  |  | 0-based.
2181 |  |  |  |  |
2182 |  |  |  |  | Years are neither, as they can be both positive or negative, unlike
2183 |  |  |  |  | any other datetime component. There I<is> a year 0.
2184 |  |  |  |  |
2185 |  |  |  |  | There is no C<quarter_0()> method.
2186 |  |  |  |  |
2187 |  |  |  |  | =head2 Error Handling
2188 |  |  |  |  |
2189 |  |  |  |  | Some errors may cause this module to die with an error string. This
2190 |  |  |  |  | can only happen when calling constructor methods, methods that change
2191 |  |  |  |  | the object, such as C<set()>, or methods that take parameters.
2192 |  |  |  |  | Methods that retrieve information about the object, such as C<year()>
2193 |  |  |  |  | or C<epoch()>, will never die.
2194 |  |  |  |  |
2195 |  |  |  |  | =head2 Locales
2196 |  |  |  |  |
2197 |  |  |  |  | All the object methods which return names or abbreviations return data
2198 |  |  |  |  | based on a locale. This is done by setting the locale when
2199 |  |  |  |  | constructing a DateTime object. There is also a C<DefaultLocale()>
2200 |  |  |  |  | class method which may be used to set the default locale for all
2201 |  |  |  |  | DateTime objects created. If this is not set, then "en_US" is used.
2202 |  |  |  |  |
2203 |  |  |  |  | =head2 Floating DateTimes
2204 |  |  |  |  |
2205 |  |  |  |  | The default time zone for new DateTime objects, except where stated
2206 |  |  |  |  | otherwise, is the "floating" time zone. This concept comes from the
2207 |  |  |  |  | iCal standard. A floating datetime is one which is not anchored to
2208 |  |  |  |  | any particular time zone. In addition, floating datetimes do not
2209 |  |  |  |  | include leap seconds, since we cannot apply them without knowing the
2210 |  |  |  |  | datetime's time zone.
2211 |  |  |  |  |
2212 |  |  |  |  | The results of date math and comparison between a floating datetime
2213 |  |  |  |  | and one with a real time zone are not really valid, because one
2214 |  |  |  |  | includes leap seconds and the other does not. Similarly, the results
2215 |  |  |  |  | of datetime math between two floating datetimes and two datetimes with
2216 |  |  |  |  | time zones are not really comparable.
2217 |  |  |  |  |
2218 |  |  |  |  | If you are planning to use any objects with a real time zone, it is
2219 |  |  |  |  | strongly recommended that you B<do not> mix these with floating
2220 |  |  |  |  | datetimes.
2221 |  |  |  |  |
2222 |  |  |  |  | =head2 Math
2223 |  |  |  |  |
2224 |  |  |  |  | If you are going to be using doing date math, please read the section L<How
2225 |  |  |  |  | Datetime Math Works>.
2226 |  |  |  |  |
2227 |  |  |  |  | =head2 Time Zone Warnings
2228 |  |  |  |  |
2229 |  |  |  |  | Determining the local time zone for a system can be slow. If C<$ENV{TZ}> is
2230 |  |  |  |  | not set, it may involve reading a number of files in F</etc> or elsewhere. If
2231 |  |  |  |  | you know that the local time zone won't change while your code is running, and
2232 |  |  |  |  | you need to make many objects for the local time zone, it is strongly
2233 |  |  |  |  | recommended 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 |  |  |  |  |
2241 |  |  |  |  | DateTime itself does not do this internally because local time zones can
2242 |  |  |  |  | change, and there's no good way to determine if it's changed without doing all
2243 |  |  |  |  | the work to look it up.
2244 |  |  |  |  |
2245 |  |  |  |  | Do not try to use named time zones (like "America/Chicago") with dates
2246 |  |  |  |  | very far in the future (thousands of years). The current
2247 |  |  |  |  | implementation of C<DateTime::TimeZone> will use a huge amount of
2248 |  |  |  |  | memory calculating all the DST changes from now until the future
2249 |  |  |  |  | date. Use UTC or the floating time zone and you will be safe.
2250 |  |  |  |  |
2251 |  |  |  |  | =head2 Methods
2252 |  |  |  |  |
2253 |  |  |  |  | =head3 Constructors
2254 |  |  |  |  |
2255 |  |  |  |  | All constructors can die when invalid parameters are given.
2256 |  |  |  |  |
2257 |  |  |  |  | =over 4
2258 |  |  |  |  |
2259 |  |  |  |  | =item * DateTime->new( ... )
2260 |  |  |  |  |
2261 |  |  |  |  | This class method accepts parameters for each date and time component:
2262 |  |  |  |  | "year", "month", "day", "hour", "minute", "second", "nanosecond".
2263 |  |  |  |  | It 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 |  |  |  |  |
2276 |  |  |  |  | DateTime validates the "month", "day", "hour", "minute", and "second",
2277 |  |  |  |  | and "nanosecond" parameters. The valid values for these parameters are:
2278 |  |  |  |  |
2279 |  |  |  |  | =over 8
2280 |  |  |  |  |
2281 |  |  |  |  | =item * month
2282 |  |  |  |  |
2283 |  |  |  |  | An integer from 1-12.
2284 |  |  |  |  |
2285 |  |  |  |  | =item * day
2286 |  |  |  |  |
2287 |  |  |  |  | An integer from 1-31, and it must be within the valid range of days for the
2288 |  |  |  |  | specified month.
2289 |  |  |  |  |
2290 |  |  |  |  | =item * hour
2291 |  |  |  |  |
2292 |  |  |  |  | An integer from 0-23.
2293 |  |  |  |  |
2294 |  |  |  |  | =item * minute
2295 |  |  |  |  |
2296 |  |  |  |  | An integer from 0-59.
2297 |  |  |  |  |
2298 |  |  |  |  | =item * second
2299 |  |  |  |  |
2300 |  |  |  |  | An integer from 0-61 (to allow for leap seconds). Values of 60 or 61 are only
2301 |  |  |  |  | allowed when they match actual leap seconds.
2302 |  |  |  |  |
2303 |  |  |  |  | =item * nanosecond
2304 |  |  |  |  |
2305 |  |  |  |  | An integer >= 0. If this number is greater than 1 billion, it will be
2306 |  |  |  |  | normalized into the second value for the DateTime object.
2307 |  |  |  |  |
2308 |  |  |  |  | =back
2309 |  |  |  |  |
2310 |  |  |  |  | Invalid parameter types (like an array reference) will cause the
2311 |  |  |  |  | constructor to die.
2312 |  |  |  |  |
2313 |  |  |  |  | The value for seconds may be from 0 to 61, to account for leap
2314 |  |  |  |  | seconds. If you give a value greater than 59, DateTime does check to
2315 |  |  |  |  | see that it really matches a valid leap second.
2316 |  |  |  |  |
2317 |  |  |  |  | All 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 |  |  |  |  |
2321 |  |  |  |  | The "locale" parameter should be a string matching one of the valid
2322 |  |  |  |  | locales, or a C<DateTime::Locale> object. See the
2323 |  |  |  |  | L<DateTime::Locale|DateTime::Locale> documentation for details.
2324 |  |  |  |  |
2325 |  |  |  |  | The time_zone parameter can be either a scalar or a
2326 |  |  |  |  | C<DateTime::TimeZone> object. A string will simply be passed to the
2327 |  |  |  |  | C<< DateTime::TimeZone->new >> method as its "name" parameter. This
2328 |  |  |  |  | string may be an Olson DB time zone name ("America/Chicago"), an
2329 |  |  |  |  | offset string ("+0630"), or the words "floating" or "local". See the
2330 |  |  |  |  | C<DateTime::TimeZone> documentation for more details.
2331 |  |  |  |  |
2332 |  |  |  |  | The default time zone is "floating".
2333 |  |  |  |  |
2334 |  |  |  |  | The "formatter" can be either a scalar or an object, but the class
2335 |  |  |  |  | specified by the scalar or the object must implement a
2336 |  |  |  |  | C<format_datetime()> method.
2337 |  |  |  |  |
2338 |  |  |  |  | =back
2339 |  |  |  |  |
2340 |  |  |  |  | =head4 Parsing Dates
2341 |  |  |  |  |
2342 |  |  |  |  | B<This module does not parse dates!> That means there is no
2343 |  |  |  |  | constructor to which you can pass things like "March 3, 1970 12:34".
2344 |  |  |  |  |
2345 |  |  |  |  | Instead, take a look at the various C<DateTime::Format::*> modules on
2346 |  |  |  |  | CPAN. These parse all sorts of different date formats, and you're
2347 |  |  |  |  | bound to find something that can handle your particular needs.
2348 |  |  |  |  |
2349 |  |  |  |  | =head4 Ambiguous Local Times
2350 |  |  |  |  |
2351 |  |  |  |  | Because of Daylight Saving Time, it is possible to specify a local
2352 |  |  |  |  | time that is ambiguous. For example, in the US in 2003, the
2353 |  |  |  |  | transition from to saving to standard time occurred on October 26, at
2354 |  |  |  |  | 02:00:00 local time. The local clock changed from 01:59:59 (saving
2355 |  |  |  |  | time) to 01:00:00 (standard time). This means that the hour from
2356 |  |  |  |  | 01:00:00 through 01:59:59 actually occurs twice, though the UTC time
2357 |  |  |  |  | continues to move forward.
2358 |  |  |  |  |
2359 |  |  |  |  | If you specify an ambiguous time, then the latest UTC time is always
2360 |  |  |  |  | used, in effect always choosing standard time. In this case, you can
2361 |  |  |  |  | simply subtract an hour to the object in order to move to saving time,
2362 |  |  |  |  | for 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 |  |  |  |  |
2382 |  |  |  |  | Alternately, you could create the object with the UTC time zone, and
2383 |  |  |  |  | then call the C<set_time_zone()> method to change the time zone. This
2384 |  |  |  |  | is a good way to ensure that the time is not ambiguous.
2385 |  |  |  |  |
2386 |  |  |  |  | =head4 Invalid Local Times
2387 |  |  |  |  |
2388 |  |  |  |  | Another problem introduced by Daylight Saving Time is that certain
2389 |  |  |  |  | local times just do not exist. For example, in the US in 2003, the
2390 |  |  |  |  | transition from standard to saving time occurred on April 6, at the
2391 |  |  |  |  | change 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
2393 |  |  |  |  | no 02:00:00 through 02:59:59 on April 6!
2394 |  |  |  |  |
2395 |  |  |  |  | Attempting to create an invalid time currently causes a fatal error.
2396 |  |  |  |  | This may change in future version of this module.
2397 |  |  |  |  |
2398 |  |  |  |  | =over 4
2399 |  |  |  |  |
2400 |  |  |  |  | =item * DateTime->from_epoch( epoch => $epoch, ... )
2401 |  |  |  |  |
2402 |  |  |  |  | This class method can be used to construct a new DateTime object from
2403 |  |  |  |  | an epoch time instead of components. Just as with the C<new()>
2404 |  |  |  |  | method, it accepts "time_zone", "locale", and "formatter" parameters.
2405 |  |  |  |  |
2406 |  |  |  |  | If the epoch value is not an integer, the part after the decimal will
2407 |  |  |  |  | be converted to nanoseconds. This is done in order to be compatible
2408 |  |  |  |  | with C<Time::HiRes>. If the floating portion extends past 9 decimal
2409 |  |  |  |  | places, it will be truncated to nine, so that 1.1234567891 will become
2410 |  |  |  |  | 1 second and 123,456,789 nanoseconds.
2411 |  |  |  |  |
2412 |  |  |  |  | By default, the returned object will be in the UTC time zone.
2413 |  |  |  |  |
2414 |  |  |  |  | =item * DateTime->now( ... )
2415 |  |  |  |  |
2416 |  |  |  |  | This class method is equivalent to calling C<from_epoch()> with the
2417 |  |  |  |  | value returned from Perl's C<time()> function. Just as with the
2418 |  |  |  |  | C<new()> method, it accepts "time_zone" and "locale" parameters.
2419 |  |  |  |  |
2420 |  |  |  |  | By default, the returned object will be in the UTC time zone.
2421 |  |  |  |  |
2422 |  |  |  |  | =item * DateTime->today( ... )
2423 |  |  |  |  |
2424 |  |  |  |  | This class method is equivalent to:
2425 |  |  |  |  |
2426 |  |  |  |  | DateTime->now->truncate( to => 'day' );
2427 |  |  |  |  |
2428 |  |  |  |  | =item * DateTime->from_object( object => $object, ... )
2429 |  |  |  |  |
2430 |  |  |  |  | This class method can be used to construct a new DateTime object from
2431 |  |  |  |  | any object that implements the C<utc_rd_values()> method. All
2432 |  |  |  |  | C<DateTime::Calendar> modules must implement this method in order to
2433 |  |  |  |  | provide cross-calendar compatibility. This method accepts a
2434 |  |  |  |  | "locale" and "formatter" parameter
2435 |  |  |  |  |
2436 |  |  |  |  | If the object passed to this method has a C<time_zone()> method, that
2437 |  |  |  |  | is used to set the time zone of the newly created C<DateTime.pm>
2438 |  |  |  |  | object.
2439 |  |  |  |  |
2440 |  |  |  |  | Otherwise, the returned object will be in the floating time zone.
2441 |  |  |  |  |
2442 |  |  |  |  | =item * DateTime->last_day_of_month( ... )
2443 |  |  |  |  |
2444 |  |  |  |  | This constructor takes the same arguments as can be given to the
2445 |  |  |  |  | C<new()> method, except for "day". Additionally, both "year" and
2446 |  |  |  |  | "month" are required.
2447 |  |  |  |  |
2448 |  |  |  |  | =item * DateTime->from_day_of_year( ... )
2449 |  |  |  |  |
2450 |  |  |  |  | This constructor takes the same arguments as can be given to the
2451 |  |  |  |  | C<new()> method, except that it does not accept a "month" or "day"
2452 |  |  |  |  | argument. Instead, it requires both "year" and "day_of_year". The
2453 |  |  |  |  | day of year must be between 1 and 366, and 366 is only allowed for
2454 |  |  |  |  | leap years.
2455 |  |  |  |  |
2456 |  |  |  |  | =item * $dt->clone()
2457 |  |  |  |  |
2458 |  |  |  |  | This object method returns a new object that is replica of the object
2459 |  |  |  |  | upon which the method is called.
2460 |  |  |  |  |
2461 |  |  |  |  | =back
2462 |  |  |  |  |
2463 |  |  |  |  | =head3 "Get" Methods
2464 |  |  |  |  |
2465 |  |  |  |  | This class has many methods for retrieving information about an
2466 |  |  |  |  | object.
2467 |  |  |  |  |
2468 |  |  |  |  | =over 4
2469 |  |  |  |  |
2470 |  |  |  |  | =item * $dt->year()
2471 |  |  |  |  |
2472 |  |  |  |  | Returns the year.
2473 |  |  |  |  |
2474 |  |  |  |  | =item * $dt->ce_year()
2475 |  |  |  |  |
2476 |  |  |  |  | Returns the year according to the BCE/CE numbering system. The year
2477 |  |  |  |  | before year 1 in this system is year -1, aka "1 BCE".
2478 |  |  |  |  |
2479 |  |  |  |  | =item * $dt->era_name()
2480 |  |  |  |  |
2481 |  |  |  |  | Returns the long name of the current era, something like "Before
2482 |  |  |  |  | Christ". See the L<Locales|/Locales> section for more details.
2483 |  |  |  |  |
2484 |  |  |  |  | =item * $dt->era_abbr()
2485 |  |  |  |  |
2486 |  |  |  |  | Returns the abbreviated name of the current era, something like "BC".
2487 |  |  |  |  | See the L<Locales|/Locales> section for more details.
2488 |  |  |  |  |
2489 |  |  |  |  | =item * $dt->christian_era()
2490 |  |  |  |  |
2491 |  |  |  |  | Returns a string, either "BC" or "AD", according to the year.
2492 |  |  |  |  |
2493 |  |  |  |  | =item * $dt->secular_era()
2494 |  |  |  |  |
2495 |  |  |  |  | Returns a string, either "BCE" or "CE", according to the year.
2496 |  |  |  |  |
2497 |  |  |  |  | =item * $dt->year_with_era()
2498 |  |  |  |  |
2499 |  |  |  |  | Returns a string containing the year immediately followed by its era
2500 |  |  |  |  | abbreviation. The year is the absolute value of C<ce_year()>, so that
2501 |  |  |  |  | year 1 is "1AD" and year 0 is "1BC".
2502 |  |  |  |  |
2503 |  |  |  |  | =item * $dt->year_with_christian_era()
2504 |  |  |  |  |
2505 |  |  |  |  | Like C<year_with_era()>, but uses the christian_era() method to get the era
2506 |  |  |  |  | name.
2507 |  |  |  |  |
2508 |  |  |  |  | =item * $dt->year_with_secular_era()
2509 |  |  |  |  |
2510 |  |  |  |  | Like C<year_with_era()>, but uses the secular_era() method to get the
2511 |  |  |  |  | era name.
2512 |  |  |  |  |
2513 |  |  |  |  | =item * $dt->month()
2514 |  |  |  |  |
2515 |  |  |  |  | Returns the month of the year, from 1..12.
2516 |  |  |  |  |
2517 |  |  |  |  | Also available as C<< $dt->mon() >>.
2518 |  |  |  |  |
2519 |  |  |  |  | =item * $dt->month_name()
2520 |  |  |  |  |
2521 |  |  |  |  | Returns the name of the current month. See the
2522 |  |  |  |  | L<Locales|/Locales> section for more details.
2523 |  |  |  |  |
2524 |  |  |  |  | =item * $dt->month_abbr()
2525 |  |  |  |  |
2526 |  |  |  |  | Returns the abbreviated name of the current month. See the
2527 |  |  |  |  | L<Locales|/Locales> section for more details.
2528 |  |  |  |  |
2529 |  |  |  |  | =item * $dt->day()
2530 |  |  |  |  |
2531 |  |  |  |  | Returns the day of the month, from 1..31.
2532 |  |  |  |  |
2533 |  |  |  |  | Also available as C<< $dt->mday() >> and C<< $dt->day_of_month() >>.
2534 |  |  |  |  |
2535 |  |  |  |  | =item * $dt->day_of_week()
2536 |  |  |  |  |
2537 |  |  |  |  | Returns the day of the week as a number, from 1..7, with 1 being
2538 |  |  |  |  | Monday and 7 being Sunday.
2539 |  |  |  |  |
2540 |  |  |  |  | Also available as C<< $dt->wday() >> and C<< $dt->dow() >>.
2541 |  |  |  |  |
2542 |  |  |  |  | =item * $dt->local_day_of_week()
2543 |  |  |  |  |
2544 |  |  |  |  | Returns the day of the week as a number, from 1..7. The day
2545 |  |  |  |  | corresponding to 1 will vary based on the locale.
2546 |  |  |  |  |
2547 |  |  |  |  | =item * $dt->day_name()
2548 |  |  |  |  |
2549 |  |  |  |  | Returns the name of the current day of the week. See the
2550 |  |  |  |  | L<Locales|/Locales> section for more details.
2551 |  |  |  |  |
2552 |  |  |  |  | =item * $dt->day_abbr()
2553 |  |  |  |  |
2554 |  |  |  |  | Returns the abbreviated name of the current day of the week. See the
2555 |  |  |  |  | L<Locales|/Locales> section for more details.
2556 |  |  |  |  |
2557 |  |  |  |  | =item * $dt->day_of_year()
2558 |  |  |  |  |
2559 |  |  |  |  | Returns the day of the year.
2560 |  |  |  |  |
2561 |  |  |  |  | Also available as C<< $dt->doy() >>.
2562 |  |  |  |  |
2563 |  |  |  |  | =item * $dt->quarter()
2564 |  |  |  |  |
2565 |  |  |  |  | Returns the quarter of the year, from 1..4.
2566 |  |  |  |  |
2567 |  |  |  |  | =item * $dt->quarter_name()
2568 |  |  |  |  |
2569 |  |  |  |  | Returns the name of the current quarter. See the
2570 |  |  |  |  | L<Locales|/Locales> section for more details.
2571 |  |  |  |  |
2572 |  |  |  |  | =item * $dt->quarter_abbr()
2573 |  |  |  |  |
2574 |  |  |  |  | Returns the abbreviated name of the current quarter. See the
2575 |  |  |  |  | L<Locales|/Locales> section for more details.
2576 |  |  |  |  |
2577 |  |  |  |  | =item * $dt->day_of_quarter()
2578 |  |  |  |  |
2579 |  |  |  |  | Returns the day of the quarter.
2580 |  |  |  |  |
2581 |  |  |  |  | Also available as C<< $dt->doq() >>.
2582 |  |  |  |  |
2583 |  |  |  |  | =item * $dt->weekday_of_month()
2584 |  |  |  |  |
2585 |  |  |  |  | Returns a number from 1..5 indicating which week day of the month this
2586 |  |  |  |  | is. For example, June 9, 2003 is the second Monday of the month, and
2587 |  |  |  |  | so 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 |  |  |  |  |
2595 |  |  |  |  | Each method returns the year, month, and day, in the order indicated
2596 |  |  |  |  | by the method name. Years are zero-padded to four digits. Months and
2597 |  |  |  |  | days are 0-padded to two digits.
2598 |  |  |  |  |
2599 |  |  |  |  | By default, the values are separated by a dash (-), but this can be
2600 |  |  |  |  | overridden by passing a value to the method.
2601 |  |  |  |  |
2602 |  |  |  |  | The C<< $dt->ymd() >> method is also available as C<< $dt->date() >>.
2603 |  |  |  |  |
2604 |  |  |  |  | =item * $dt->hour()
2605 |  |  |  |  |
2606 |  |  |  |  | Returns the hour of the day, from 0..23.
2607 |  |  |  |  |
2608 |  |  |  |  | =item * $dt->hour_1()
2609 |  |  |  |  |
2610 |  |  |  |  | Returns the hour of the day, from 1..24.
2611 |  |  |  |  |
2612 |  |  |  |  | =item * $dt->hour_12()
2613 |  |  |  |  |
2614 |  |  |  |  | Returns the hour of the day, from 1..12.
2615 |  |  |  |  |
2616 |  |  |  |  | =item * $dt->hour_12_0()
2617 |  |  |  |  |
2618 |  |  |  |  | Returns the hour of the day, from 0..11.
2619 |  |  |  |  |
2620 |  |  |  |  | =item * $dt->am_or_pm()
2621 |  |  |  |  |
2622 |  |  |  |  | Returns the appropriate localized abbreviation, depending on the
2623 |  |  |  |  | current hour.
2624 |  |  |  |  |
2625 |  |  |  |  | =item * $dt->minute()
2626 |  |  |  |  |
2627 |  |  |  |  | Returns the minute of the hour, from 0..59.
2628 |  |  |  |  |
2629 |  |  |  |  | Also available as C<< $dt->min() >>.
2630 |  |  |  |  |
2631 |  |  |  |  | =item * $dt->second()
2632 |  |  |  |  |
2633 |  |  |  |  | Returns the second, from 0..61. The values 60 and 61 are used for
2634 |  |  |  |  | leap seconds.
2635 |  |  |  |  |
2636 |  |  |  |  | Also available as C<< $dt->sec() >>.
2637 |  |  |  |  |
2638 |  |  |  |  | =item * $dt->fractional_second()
2639 |  |  |  |  |
2640 |  |  |  |  | Returns the second, as a real number from 0.0 until 61.999999999
2641 |  |  |  |  |
2642 |  |  |  |  | The values 60 and 61 are used for leap seconds.
2643 |  |  |  |  |
2644 |  |  |  |  | =item * $dt->millisecond()
2645 |  |  |  |  |
2646 |  |  |  |  | Returns the fractional part of the second as milliseconds (1E-3 seconds).
2647 |  |  |  |  |
2648 |  |  |  |  | Half a second is 500 milliseconds.
2649 |  |  |  |  |
2650 |  |  |  |  | =item * $dt->microsecond()
2651 |  |  |  |  |
2652 |  |  |  |  | Returns the fractional part of the second as microseconds (1E-6
2653 |  |  |  |  | seconds). This value will be rounded to an integer.
2654 |  |  |  |  |
2655 |  |  |  |  | Half a second is 500_000 microseconds. This value will be rounded to
2656 |  |  |  |  | an integer.
2657 |  |  |  |  |
2658 |  |  |  |  | =item * $dt->nanosecond()
2659 |  |  |  |  |
2660 |  |  |  |  | Returns the fractional part of the second as nanoseconds (1E-9 seconds).
2661 |  |  |  |  |
2662 |  |  |  |  | Half a second is 500_000_000 nanoseconds.
2663 |  |  |  |  |
2664 |  |  |  |  | =item * $dt->hms( $optional_separator )
2665 |  |  |  |  |
2666 |  |  |  |  | Returns the hour, minute, and second, all zero-padded to two digits.
2667 |  |  |  |  | If no separator is specified, a colon (:) is used by default.
2668 |  |  |  |  |
2669 |  |  |  |  | Also available as C<< $dt->time() >>.
2670 |  |  |  |  |
2671 |  |  |  |  | =item * $dt->datetime()
2672 |  |  |  |  |
2673 |  |  |  |  | This method is equivalent to:
2674 |  |  |  |  |
2675 |  |  |  |  | $dt->ymd('-') . 'T' . $dt->hms(':')
2676 |  |  |  |  |
2677 |  |  |  |  | Also available as C<< $dt->iso8601() >>.
2678 |  |  |  |  |
2679 |  |  |  |  | =item * $dt->is_leap_year()
2680 |  |  |  |  |
2681 |  |  |  |  | This method returns a true or false indicating whether or not the
2682 |  |  |  |  | datetime object is in a leap year.
2683 |  |  |  |  |
2684 |  |  |  |  | =item * $dt->week()
2685 |  |  |  |  |
2686 |  |  |  |  | ($week_year, $week_number) = $dt->week;
2687 |  |  |  |  |
2688 |  |  |  |  | Returns information about the calendar week which contains this
2689 |  |  |  |  | datetime object. The values returned by this method are also available
2690 |  |  |  |  | separately through the week_year and week_number methods.
2691 |  |  |  |  |
2692 |  |  |  |  | The first week of the year is defined by ISO as the one which contains
2693 |  |  |  |  | the fourth day of January, which is equivalent to saying that it's the
2694 |  |  |  |  | first week to overlap the new year by at least four days.
2695 |  |  |  |  |
2696 |  |  |  |  | Typically the week year will be the same as the year that the object
2697 |  |  |  |  | is in, but dates at the very beginning of a calendar year often end up
2698 |  |  |  |  | in the last week of the prior year, and similarly, the final few days
2699 |  |  |  |  | of the year may be placed in the first week of the next year.
2700 |  |  |  |  |
2701 |  |  |  |  | =item * $dt->week_year()
2702 |  |  |  |  |
2703 |  |  |  |  | Returns the year of the week. See C<< $dt->week() >> for details.
2704 |  |  |  |  |
2705 |  |  |  |  | =item * $dt->week_number()
2706 |  |  |  |  |
2707 |  |  |  |  | Returns the week of the year, from 1..53. See C<< $dt->week() >> for details.
2708 |  |  |  |  |
2709 |  |  |  |  | =item * $dt->week_of_month()
2710 |  |  |  |  |
2711 |  |  |  |  | The week of the month, from 0..5. The first week of the month is the
2712 |  |  |  |  | first week that contains a Thursday. This is based on the ICU
2713 |  |  |  |  | definition of week of month, and correlates to the ISO8601 week of
2714 |  |  |  |  | year definition. A day in the week I<before> the week with the first
2715 |  |  |  |  | Thursday will be week 0.
2716 |  |  |  |  |
2717 |  |  |  |  | =item * $dt->jd()
2718 |  |  |  |  |
2719 |  |  |  |  | =item * $dt->mjd()
2720 |  |  |  |  |
2721 |  |  |  |  | These return the Julian Day and Modified Julian Day, respectively.
2722 |  |  |  |  | The value returned is a floating point number. The fractional portion
2723 |  |  |  |  | of the number represents the time portion of the datetime.
2724 |  |  |  |  |
2725 |  |  |  |  | =item * $dt->time_zone()
2726 |  |  |  |  |
2727 |  |  |  |  | This returns the C<DateTime::TimeZone> object for the datetime object.
2728 |  |  |  |  |
2729 |  |  |  |  | =item * $dt->offset()
2730 |  |  |  |  |
2731 |  |  |  |  | This returns the offset from UTC, in seconds, of the datetime object
2732 |  |  |  |  | according to the time zone.
2733 |  |  |  |  |
2734 |  |  |  |  | =item * $dt->is_dst()
2735 |  |  |  |  |
2736 |  |  |  |  | Returns a boolean indicating whether or not the datetime object is
2737 |  |  |  |  | currently in Daylight Saving Time or not.
2738 |  |  |  |  |
2739 |  |  |  |  | =item * $dt->time_zone_long_name()
2740 |  |  |  |  |
2741 |  |  |  |  | This is a shortcut for C<< $dt->time_zone->name >>. It's provided so
2742 |  |  |  |  | that one can use "%{time_zone_long_name}" as a strftime format
2743 |  |  |  |  | specifier.
2744 |  |  |  |  |
2745 |  |  |  |  | =item * $dt->time_zone_short_name()
2746 |  |  |  |  |
2747 |  |  |  |  | This method returns the time zone abbreviation for the current time
2748 |  |  |  |  | zone, such as "PST" or "GMT". These names are B<not> definitive, and
2749 |  |  |  |  | should not be used in any application intended for general use by
2750 |  |  |  |  | users around the world.
2751 |  |  |  |  |
2752 |  |  |  |  | =item * $dt->strftime( $format, ... )
2753 |  |  |  |  |
2754 |  |  |  |  | This method implements functionality similar to the C<strftime()>
2755 |  |  |  |  | method in C. However, if given multiple format strings, then it will
2756 |  |  |  |  | return multiple scalars, one for each format string.
2757 |  |  |  |  |
2758 |  |  |  |  | See the L<strftime Patterns> section for a list of all possible
2759 |  |  |  |  | strftime patterns.
2760 |  |  |  |  |
2761 |  |  |  |  | If you give a pattern that doesn't exist, then it is simply treated as
2762 |  |  |  |  | text.
2763 |  |  |  |  |
2764 |  |  |  |  | =item * $dt->format_cldr( $format, ... )
2765 |  |  |  |  |
2766 |  |  |  |  | This method implements formatting based on the CLDR date patterns. If
2767 |  |  |  |  | given multiple format strings, then it will return multiple scalars,
2768 |  |  |  |  | one for each format string.
2769 |  |  |  |  |
2770 |  |  |  |  | See the L<CLDR Patterns> section for a list of all possible CLDR
2771 |  |  |  |  | patterns.
2772 |  |  |  |  |
2773 |  |  |  |  | If you give a pattern that doesn't exist, then it is simply treated as
2774 |  |  |  |  | text.
2775 |  |  |  |  |
2776 |  |  |  |  | =item * $dt->epoch()
2777 |  |  |  |  |
2778 |  |  |  |  | Return the UTC epoch value for the datetime object. Internally, this
2779 |  |  |  |  | is implemented using C<Time::Local>, which uses the Unix epoch even on
2780 |  |  |  |  | machines with a different epoch (such as MacOS). Datetimes before the
2781 |  |  |  |  | start of the epoch will be returned as a negative number.
2782 |  |  |  |  |
2783 |  |  |  |  | The return value from this method is always an integer.
2784 |  |  |  |  |
2785 |  |  |  |  | Since the epoch does not account for leap seconds, the epoch time for
2786 |  |  |  |  | 1972-12-31T23:59:60 (UTC) is exactly the same as that for
2787 |  |  |  |  | 1973-01-01T00:00:00.
2788 |  |  |  |  |
2789 |  |  |  |  | This module uses C<Time::Local> to calculate the epoch, which may or
2790 |  |  |  |  | may not handle epochs before 1904 or after 2038 (depending on the size
2791 |  |  |  |  | of your system's integers, and whether or not Perl was compiled with
2792 |  |  |  |  | 64-bit int support).
2793 |  |  |  |  |
2794 |  |  |  |  | =item * $dt->hires_epoch()
2795 |  |  |  |  |
2796 |  |  |  |  | Returns the epoch as a floating point number. The floating point
2797 |  |  |  |  | portion of the value represents the nanosecond value of the object.
2798 |  |  |  |  | This method is provided for compatibility with the C<Time::HiRes>
2799 |  |  |  |  | module.
2800 |  |  |  |  |
2801 |  |  |  |  | =item * $dt->is_finite()
2802 |  |  |  |  |
2803 |  |  |  |  | =item * $dt->is_infinite()
2804 |  |  |  |  |
2805 |  |  |  |  | These methods allow you to distinguish normal datetime objects from
2806 |  |  |  |  | infinite ones. Infinite datetime objects are documented in
2807 |  |  |  |  | L<DateTime::Infinite|DateTime::Infinite>.
2808 |  |  |  |  |
2809 |  |  |  |  | =item * $dt->utc_rd_values()
2810 |  |  |  |  |
2811 |  |  |  |  | Returns the current UTC Rata Die days, seconds, and nanoseconds as a
2812 |  |  |  |  | three element list. This exists primarily to allow other calendar
2813 |  |  |  |  | modules to create objects based on the values provided by this object.
2814 |  |  |  |  |
2815 |  |  |  |  | =item * $dt->local_rd_values()
2816 |  |  |  |  |
2817 |  |  |  |  | Returns the current local Rata Die days, seconds, and nanoseconds as a
2818 |  |  |  |  | three element list. This exists for the benefit of other modules
2819 |  |  |  |  | which might want to use this information for date math, such as
2820 |  |  |  |  | C<DateTime::Event::Recurrence>.
2821 |  |  |  |  |
2822 |  |  |  |  | =item * $dt->leap_seconds()
2823 |  |  |  |  |
2824 |  |  |  |  | Returns the number of leap seconds that have happened up to the
2825 |  |  |  |  | datetime represented by the object. For floating datetimes, this
2826 |  |  |  |  | always returns 0.
2827 |  |  |  |  |
2828 |  |  |  |  | =item * $dt->utc_rd_as_seconds()
2829 |  |  |  |  |
2830 |  |  |  |  | Returns the current UTC Rata Die days and seconds purely as seconds.
2831 |  |  |  |  | This number ignores any fractional seconds stored in the object,
2832 |  |  |  |  | as well as leap seconds.
2833 |  |  |  |  |
2834 |  |  |  |  | =item * $dt->locale()
2835 |  |  |  |  |
2836 |  |  |  |  | Returns the current locale object.
2837 |  |  |  |  |
2838 |  |  |  |  | =item * $dt->formatter()
2839 |  |  |  |  |
2840 |  |  |  |  | Returns current formatter object or class. See L<Formatters And
2841 |  |  |  |  | Stringification> for details.
2842 |  |  |  |  |
2843 |  |  |  |  | =back
2844 |  |  |  |  |
2845 |  |  |  |  | =head3 "Set" Methods
2846 |  |  |  |  |
2847 |  |  |  |  | The remaining methods provided by C<DateTime.pm>, except where otherwise
2848 |  |  |  |  | specified, return the object itself, thus making method chaining
2849 |  |  |  |  | possible. 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 |  |  |  |  |
2862 |  |  |  |  | This method can be used to change the local components of a date time,
2863 |  |  |  |  | or its locale. This method accepts any parameter allowed by the
2864 |  |  |  |  | C<new()> method except for "time_zone". Time zones may be set using
2865 |  |  |  |  | the C<set_time_zone()> method.
2866 |  |  |  |  |
2867 |  |  |  |  | This method performs parameters validation just as is done in the
2868 |  |  |  |  | C<new()> method.
2869 |  |  |  |  |
2870 |  |  |  |  | B<Do not use this method to do date math. Use the C<add()> and C<subtract()>
2871 |  |  |  |  | methods 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 |  |  |  |  |
2889 |  |  |  |  | These are shortcuts to calling C<set()> with a single key. They all
2890 |  |  |  |  | take a single parameter.
2891 |  |  |  |  |
2892 |  |  |  |  | =item * $dt->truncate( to => ... )
2893 |  |  |  |  |
2894 |  |  |  |  | This method allows you to reset some of the local time components in
2895 |  |  |  |  | the object to their "zero" values. The "to" parameter is used to
2896 |  |  |  |  | specify which values to truncate, and it may be one of "year",
2897 |  |  |  |  | "month", "week", "day", "hour", "minute", or "second". For example,
2898 |  |  |  |  | if "month" is specified, then the local day becomes 1, and the hour,
2899 |  |  |  |  | minute, and second all become 0.
2900 |  |  |  |  |
2901 |  |  |  |  | If "week" is given, then the datetime is set to the beginning of the
2902 |  |  |  |  | week in which it occurs, and the time components are all set to 0.
2903 |  |  |  |  |
2904 |  |  |  |  | =item * $dt->set_time_zone( $tz )
2905 |  |  |  |  |
2906 |  |  |  |  | This method accepts either a time zone object or a string that can be
2907 |  |  |  |  | passed as the "name" parameter to C<< DateTime::TimeZone->new() >>.
2908 |  |  |  |  | If the new time zone's offset is different from the old time zone,
2909 |  |  |  |  | then the I<local> time is adjusted accordingly.
2910 |  |  |  |  |
2911 |  |  |  |  | For 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 |  |  |  |  |
2928 |  |  |  |  | If the old time zone was a floating time zone, then no adjustments to
2929 |  |  |  |  | the local time are made, except to account for leap seconds. If the
2930 |  |  |  |  | new time zone is floating, then the I<UTC> time is adjusted in order
2931 |  |  |  |  | to leave the local time untouched.
2932 |  |  |  |  |
2933 |  |  |  |  | Fans of Tsai Ming-Liang's films will be happy to know that this does
2934 |  |  |  |  | work:
2935 |  |  |  |  |
2936 |  |  |  |  | my $dt = DateTime->now( time_zone => 'Asia/Taipei' );
2937 |  |  |  |  |
2938 |  |  |  |  | $dt->set_time_zone( 'Europe/Paris' );
2939 |  |  |  |  |
2940 |  |  |  |  | Yes, now we can know "ni3 na4 bian1 ji2dian3?"
2941 |  |  |  |  |
2942 |  |  |  |  | =item * $dt->set_formatter( $formatter )
2943 |  |  |  |  |
2944 |  |  |  |  | Set the formatter for the object. See L<Formatters And
2945 |  |  |  |  | Stringification> for details.
2946 |  |  |  |  |
2947 |  |  |  |  | You can set this to C<undef> to revert to the default formatter.
2948 |  |  |  |  |
2949 |  |  |  |  | =back
2950 |  |  |  |  |
2951 |  |  |  |  | =head3 Math Methods
2952 |  |  |  |  |
2953 |  |  |  |  | Like the set methods, math related methods always return the object
2954 |  |  |  |  | itself, to allow for chaining:
2955 |  |  |  |  |
2956 |  |  |  |  | $dt->add( days => 1 )->subtract( seconds => 1 );
2957 |  |  |  |  |
2958 |  |  |  |  | =over 4
2959 |  |  |  |  |
2960 |  |  |  |  | =item * $dt->duration_class()
2961 |  |  |  |  |
2962 |  |  |  |  | This returns C<DateTime::Duration>, but exists so that a subclass of
2963 |  |  |  |  | C<DateTime.pm> can provide a different value.
2964 |  |  |  |  |
2965 |  |  |  |  | =item * $dt->add_duration( $duration_object )
2966 |  |  |  |  |
2967 |  |  |  |  | This method adds a C<DateTime::Duration> to the current datetime. See
2968 |  |  |  |  | the L<DateTime::Duration|DateTime::Duration> docs for more details.
2969 |  |  |  |  |
2970 |  |  |  |  | =item * $dt->add( DateTime::Duration->new parameters )
2971 |  |  |  |  |
2972 |  |  |  |  | This method is syntactic sugar around the C<add_duration()> method. It
2973 |  |  |  |  | simply creates a new C<DateTime::Duration> object using the parameters
2974 |  |  |  |  | given, and then calls the C<add_duration()> method.
2975 |  |  |  |  |
2976 |  |  |  |  | =item * $dt->subtract_duration( $duration_object )
2977 |  |  |  |  |
2978 |  |  |  |  | When given a C<DateTime::Duration> object, this method simply calls
2979 |  |  |  |  | C<invert()> on that object and passes that new duration to the
2980 |  |  |  |  | C<add_duration> method.
2981 |  |  |  |  |
2982 |  |  |  |  | =item * $dt->subtract( DateTime::Duration->new parameters )
2983 |  |  |  |  |
2984 |  |  |  |  | Like C<add()>, this is syntactic sugar for the C<subtract_duration()>
2985 |  |  |  |  | method.
2986 |  |  |  |  |
2987 |  |  |  |  | =item * $dt->subtract_datetime( $datetime )
2988 |  |  |  |  |
2989 |  |  |  |  | This method returns a new C<DateTime::Duration> object representing
2990 |  |  |  |  | the difference between the two dates. The duration is B<relative> to
2991 |  |  |  |  | the 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 |  |  |  |  |
2998 |  |  |  |  | Note that this duration is not an absolute measure of the amount of
2999 |  |  |  |  | time between the two datetimes, because the length of a month varies,
3000 |  |  |  |  | as well as due to the presence of leap seconds.
3001 |  |  |  |  |
3002 |  |  |  |  | The returned duration may have deltas for months, days, minutes,
3003 |  |  |  |  | seconds, and nanoseconds.
3004 |  |  |  |  |
3005 |  |  |  |  | =item * $dt->delta_md( $datetime )
3006 |  |  |  |  |
3007 |  |  |  |  | =item * $dt->delta_days( $datetime )
3008 |  |  |  |  |
3009 |  |  |  |  | Each of these methods returns a new C<DateTime::Duration> object
3010 |  |  |  |  | representing some portion of the difference between two datetimes.
3011 |  |  |  |  | The C<delta_md()> method returns a duration which contains only the
3012 |  |  |  |  | month and day portions of the duration is represented. The
3013 |  |  |  |  | C<delta_days()> method returns a duration which contains only days.
3014 |  |  |  |  |
3015 |  |  |  |  | The C<delta_md> and C<delta_days> methods truncate the duration so
3016 |  |  |  |  | that any fractional portion of a day is ignored. Both of these
3017 |  |  |  |  | methods operate on the date portion of a datetime only, and so
3018 |  |  |  |  | effectively ignore the time zone.
3019 |  |  |  |  |
3020 |  |  |  |  | Unlike the subtraction methods, B<these methods always return a
3021 |  |  |  |  | positive (or zero) duration>.
3022 |  |  |  |  |
3023 |  |  |  |  | =item * $dt->delta_ms( $datetime )
3024 |  |  |  |  |
3025 |  |  |  |  | Returns a duration which contains only minutes and seconds. Any day
3026 |  |  |  |  | and month differences to minutes are converted to minutes and
3027 |  |  |  |  | seconds. This method also B<always return a positive (or zero)
3028 |  |  |  |  | duration>.
3029 |  |  |  |  |
3030 |  |  |  |  | =item * $dt->subtract_datetime_absolute( $datetime )
3031 |  |  |  |  |
3032 |  |  |  |  | This method returns a new C<DateTime::Duration> object representing
3033 |  |  |  |  | the difference between the two dates in seconds and nanoseconds. This
3034 |  |  |  |  | is the only way to accurately measure the absolute amount of time
3035 |  |  |  |  | between two datetimes, since units larger than a second do not
3036 |  |  |  |  | represent a fixed number of seconds.
3037 |  |  |  |  |
3038 |  |  |  |  | =back
3039 |  |  |  |  |
3040 |  |  |  |  | =head3 Class Methods
3041 |  |  |  |  |
3042 |  |  |  |  | =over 4
3043 |  |  |  |  |
3044 |  |  |  |  | =item * DateTime->DefaultLocale( $locale )
3045 |  |  |  |  |
3046 |  |  |  |  | This can be used to specify the default locale to be used when
3047 |  |  |  |  | creating 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 |  |  |  |  |
3057 |  |  |  |  | Compare two DateTime objects. The semantics are compatible with Perl's
3058 |  |  |  |  | C<sort()> function; it returns -1 if $dt1 < $dt2, 0 if $dt1 == $dt2, 1 if $dt1
3059 |  |  |  |  | > $dt2.
3060 |  |  |  |  |
3061 |  |  |  |  | If one of the two DateTime objects has a floating time zone, it will
3062 |  |  |  |  | first be converted to the time zone of the other object. This is what
3063 |  |  |  |  | you want most of the time, but it can lead to inconsistent results
3064 |  |  |  |  | when you compare a number of DateTime objects, some of which are
3065 |  |  |  |  | floating, and some of which are in other time zones.
3066 |  |  |  |  |
3067 |  |  |  |  | If you want to have consistent results (because you want to sort a
3068 |  |  |  |  | number of objects, for example), you can use the
3069 |  |  |  |  | C<compare_ignore_floating()> method:
3070 |  |  |  |  |
3071 |  |  |  |  | @dates = sort { DateTime->compare_ignore_floating($a, $b) } @dates;
3072 |  |  |  |  |
3073 |  |  |  |  | In this case, objects with a floating time zone will be sorted as if
3074 |  |  |  |  | they were UTC times.
3075 |  |  |  |  |
3076 |  |  |  |  | Since DateTime objects overload comparison operators, this:
3077 |  |  |  |  |
3078 |  |  |  |  | @dates = sort @dates;
3079 |  |  |  |  |
3080 |  |  |  |  | is equivalent to this:
3081 |  |  |  |  |
3082 |  |  |  |  | @dates = sort { DateTime->compare($a, $b) } @dates;
3083 |  |  |  |  |
3084 |  |  |  |  | DateTime objects can be compared to any other calendar class that
3085 |  |  |  |  | implements the C<utc_rd_values()> method.
3086 |  |  |  |  |
3087 |  |  |  |  | =back
3088 |  |  |  |  |
3089 |  |  |  |  | =head2 How Datetime Math Works
3090 |  |  |  |  |
3091 |  |  |  |  | It's important to have some understanding of how datetime math is
3092 |  |  |  |  | implemented in order to effectively use this module and
3093 |  |  |  |  | C<DateTime::Duration>.
3094 |  |  |  |  |
3095 |  |  |  |  | =head3 Making Things Simple
3096 |  |  |  |  |
3097 |  |  |  |  | If you want to simplify your life and not have to think too hard about
3098 |  |  |  |  | the nitty-gritty of datetime math, I have several recommendations:
3099 |  |  |  |  |
3100 |  |  |  |  | =over 4
3101 |  |  |  |  |
3102 |  |  |  |  | =item * use the floating time zone
3103 |  |  |  |  |
3104 |  |  |  |  | If 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 |  |  |  |  |
3109 |  |  |  |  | Math done on two objects in the floating time zone produces very
3110 |  |  |  |  | predictable results.
3111 |  |  |  |  |
3112 |  |  |  |  | Note that in most cases you will want to start by creating an object in a
3113 |  |  |  |  | specific zone and I<then> convert it to the floating time zone. When an object
3114 |  |  |  |  | goes from a real zone to the floating zone, the time for the object remains
3115 |  |  |  |  | the same.
3116 |  |  |  |  |
3117 |  |  |  |  | This means that passing the floating zone to a constructor may not do what you
3118 |  |  |  |  | want.
3119 |  |  |  |  |
3120 |  |  |  |  | my $dt = DateTime->now( time_zone => 'floating' );
3121 |  |  |  |  |
3122 |  |  |  |  | is equivalent to
3123 |  |  |  |  |
3124 |  |  |  |  | my $dt = DateTime->now( time_zone => 'UTC' )->set_time_zone('floating');
3125 |  |  |  |  |
3126 |  |  |  |  | This 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 |  |  |  |  |
3132 |  |  |  |  | If you do care about time zones (particularly DST) or leap seconds,
3133 |  |  |  |  | try to use non-UTC time zones for presentation and user input only.
3134 |  |  |  |  | Convert to UTC immediately and convert back to the local time zone for
3135 |  |  |  |  | presentation:
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 |  |  |  |  |
3147 |  |  |  |  | If you need to do date math on objects with non-UTC time zones, please
3148 |  |  |  |  | read the caveats below carefully. The results C<DateTime.pm> produces are
3149 |  |  |  |  | predictable and correct, and mostly intuitive, but datetime math gets
3150 |  |  |  |  | very ugly when time zones are involved, and there are a few strange
3151 |  |  |  |  | corner cases involving subtraction of two datetimes across a DST
3152 |  |  |  |  | change.
3153 |  |  |  |  |
3154 |  |  |  |  | If you can always use the floating or UTC time zones, you can skip
3155 |  |  |  |  | ahead to L<Leap Seconds and Date Math|Leap Seconds and Date Math>
3156 |  |  |  |  |
3157 |  |  |  |  | =item * date vs datetime math
3158 |  |  |  |  |
3159 |  |  |  |  | If you only care about the date (calendar) portion of a datetime, you
3160 |  |  |  |  | should use either C<delta_md()> or C<delta_days()>, not
3161 |  |  |  |  | C<subtract_datetime()>. This will give predictable, unsurprising
3162 |  |  |  |  | results, free from DST-related complications.
3163 |  |  |  |  |
3164 |  |  |  |  | =item * subtract_datetime() and add_duration()
3165 |  |  |  |  |
3166 |  |  |  |  | You must convert your datetime objects to the UTC time zone before
3167 |  |  |  |  | doing date math if you want to make sure that the following formulas
3168 |  |  |  |  | are always true:
3169 |  |  |  |  |
3170 |  |  |  |  | $dt2 - $dt1 = $dur
3171 |  |  |  |  | $dt1 + $dur = $dt2
3172 |  |  |  |  | $dt2 - $dur = $dt1
3173 |  |  |  |  |
3174 |  |  |  |  | Note that using C<delta_days> ensures that this formula always works,
3175 |  |  |  |  | regardless of the timezone of the objects involved, as does using
3176 |  |  |  |  | C<subtract_datetime_absolute()>. Other methods of subtraction are not
3177 |  |  |  |  | always reversible.
3178 |  |  |  |  |
3179 |  |  |  |  | =back
3180 |  |  |  |  |
3181 |  |  |  |  | =head3 Adding a Duration to a Datetime
3182 |  |  |  |  |
3183 |  |  |  |  | The parts of a duration can be broken down into five parts. These are
3184 |  |  |  |  | months, days, minutes, seconds, and nanoseconds. Adding one month to
3185 |  |  |  |  | a date is different than adding 4 weeks or 28, 29, 30, or 31 days.
3186 |  |  |  |  | Similarly, due to DST and leap seconds, adding a day can be different
3187 |  |  |  |  | than adding 86,400 seconds, and adding a minute is not exactly the
3188 |  |  |  |  | same as 60 seconds.
3189 |  |  |  |  |
3190 |  |  |  |  | We cannot convert between these units, except for seconds and
3191 |  |  |  |  | nanoseconds, because there is no fixed conversion between the two
3192 |  |  |  |  | units, because of things like leap seconds, DST changes, etc.
3193 |  |  |  |  |
3194 |  |  |  |  | C<DateTime.pm> always adds (or subtracts) days, then months, minutes, and then
3195 |  |  |  |  | seconds and nanoseconds. If there are any boundary overflows, these are
3196 |  |  |  |  | normalized at each step. For the days and months the local (not UTC) values
3197 |  |  |  |  | are used. For minutes and seconds, the local values are used. This generally
3198 |  |  |  |  | just works.
3199 |  |  |  |  |
3200 |  |  |  |  | This means that adding one month and one day to February 28, 2003 will
3201 |  |  |  |  | produce 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 |  |  |  |  |
3209 |  |  |  |  | On the other hand, if we add months first, and then separately add
3210 |  |  |  |  | days, we end up with March 29, 2003:
3211 |  |  |  |  |
3212 |  |  |  |  | $dt->add( months => 1 )->add( days => 1 );
3213 |  |  |  |  |
3214 |  |  |  |  | # 2003-03-29
3215 |  |  |  |  |
3216 |  |  |  |  | We 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 |  |  |  |  |
3233 |  |  |  |  | Note that if you converted the datetime object to UTC first you would
3234 |  |  |  |  | get predictable results.
3235 |  |  |  |  |
3236 |  |  |  |  | If you want to know how many seconds a duration object represents, you
3237 |  |  |  |  | have 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 |  |  |  |  |
3244 |  |  |  |  | This returns a duration which only contains seconds and nanoseconds.
3245 |  |  |  |  |
3246 |  |  |  |  | If we were add the duration to a different datetime object we might
3247 |  |  |  |  | get a different number of seconds.
3248 |  |  |  |  |
3249 |  |  |  |  | L<DateTime::Duration> supports three different end-of-month algorithms for
3250 |  |  |  |  | adding months. This comes into play when an addition results in a day past the
3251 |  |  |  |  | end 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 |  |  |  |  |
3262 |  |  |  |  | By default, it uses "wrap" for positive durations and "preserve" for negative
3263 |  |  |  |  | durations. See L<DateTime::Duration> for a detailed explanation of these
3264 |  |  |  |  | algorithms.
3265 |  |  |  |  |
3266 |  |  |  |  | If you need to do lots of work with durations, take a look at Rick
3267 |  |  |  |  | Measham's C<DateTime::Format::Duration> module, which lets you present
3268 |  |  |  |  | information from durations in many useful ways.
3269 |  |  |  |  |
3270 |  |  |  |  | There are other subtract/delta methods in DateTime.pm to generate
3271 |  |  |  |  | different types of durations. These methods are
3272 |  |  |  |  | C<subtract_datetime()>, C<subtract_datetime_absolute()>,
3273 |  |  |  |  | C<delta_md()>, C<delta_days()>, and C<delta_ms()>.
3274 |  |  |  |  |
3275 |  |  |  |  | =head3 Datetime Subtraction
3276 |  |  |  |  |
3277 |  |  |  |  | Date subtraction is done solely based on the two object's local
3278 |  |  |  |  | datetimes, with one exception to handle DST changes. Also, if the two
3279 |  |  |  |  | datetime objects are in different time zones, one of them is converted
3280 |  |  |  |  | to the other's time zone first before subtraction. This is best
3281 |  |  |  |  | explained through examples:
3282 |  |  |  |  |
3283 |  |  |  |  | The 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 |  |  |  |  |
3306 |  |  |  |  | Nice and simple.
3307 |  |  |  |  |
3308 |  |  |  |  | This 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 |  |  |  |  |
3336 |  |  |  |  | Which contradicts the result this one gives, even though they both
3337 |  |  |  |  | make 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 |  |  |  |  |
3365 |  |  |  |  | This last example illustrates the "DST" exception mentioned earlier.
3366 |  |  |  |  | The exception accounts for the fact 2003-04-06 only lasts 23 hours.
3367 |  |  |  |  |
3368 |  |  |  |  | And 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 |  |  |  |  |
3383 |  |  |  |  | This seems obvious until you realize that subtracting 60 minutes from
3384 |  |  |  |  | C<$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 |  |  |  |  |
3389 |  |  |  |  | Date math operations are not always reversible. This is because of
3390 |  |  |  |  | the way that addition operations are ordered. As was discussed
3391 |  |  |  |  | earlier, adding 1 day and 3 minutes in one call to C<add()> is not the
3392 |  |  |  |  | same as first adding 3 minutes and 1 day in two separate calls.
3393 |  |  |  |  |
3394 |  |  |  |  | If we take a duration returned from C<subtract_datetime()> and then
3395 |  |  |  |  | try to add or subtract that duration from one of the datetimes we just
3396 |  |  |  |  | used, 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 |  |  |  |  |
3425 |  |  |  |  | The C<subtract_duration()> operation gives us a (perhaps) unexpected
3426 |  |  |  |  | answer because it first subtracts one day to get 2003-04-05T03:01:00
3427 |  |  |  |  | and then subtracts 3 minutes to get the final result.
3428 |  |  |  |  |
3429 |  |  |  |  | If we explicitly reverse the order we can get the original value of
3430 |  |  |  |  | C<$dt1>. This can be facilitated by C<DateTime::Duration>'s
3431 |  |  |  |  | C<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 |  |  |  |  |
3438 |  |  |  |  | The presence of leap seconds can cause even more anomalies in date
3439 |  |  |  |  | math. 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 |  |  |  |  |
3451 |  |  |  |  | If we do the following:
3452 |  |  |  |  |
3453 |  |  |  |  | $dt->add( months => 1 );
3454 |  |  |  |  |
3455 |  |  |  |  | Then the datetime is now "1973-02-01 00:00:00", because there is no
3456 |  |  |  |  | 23:59:60 on 1973-01-31.
3457 |  |  |  |  |
3458 |  |  |  |  | Leap seconds also force us to distinguish between minutes and seconds
3459 |  |  |  |  | during 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 |  |  |  |  |
3471 |  |  |  |  | we will get different results when adding 1 minute than we get if we
3472 |  |  |  |  | add 60 seconds. This is because in this case, the last minute of the
3473 |  |  |  |  | day, beginning at 23:59:00, actually contains 61 seconds.
3474 |  |  |  |  |
3475 |  |  |  |  | Here 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 |  |  |  |  |
3490 |  |  |  |  | When math crosses a daylight saving boundary, a single day may have
3491 |  |  |  |  | more or less than 24 hours.
3492 |  |  |  |  |
3493 |  |  |  |  | For 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 |  |  |  |  |
3505 |  |  |  |  | then you will produce an I<invalid> local time, and therefore an
3506 |  |  |  |  | exception will be thrown.
3507 |  |  |  |  |
3508 |  |  |  |  | However, 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 |  |  |  |  |
3520 |  |  |  |  | and produces a datetime with the local time of "03:00".
3521 |  |  |  |  |
3522 |  |  |  |  | If all this makes your head hurt, there is a simple alternative. Just
3523 |  |  |  |  | convert your datetime object to the "UTC" time zone before doing date
3524 |  |  |  |  | math on it, and switch it back to the local time zone afterwards.
3525 |  |  |  |  | This avoids the possibility of having date math throw an exception,
3526 |  |  |  |  | and makes sure that 1 day equals 24 hours. Of course, this may not
3527 |  |  |  |  | always be desirable, so caveat user!
3528 |  |  |  |  |
3529 |  |  |  |  | =head2 Overloading
3530 |  |  |  |  |
3531 |  |  |  |  | This module explicitly overloads the addition (+), subtraction (-),
3532 |  |  |  |  | string and numeric comparison operators. This means that the
3533 |  |  |  |  | following 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 |  |  |  |  |
3543 |  |  |  |  | Additionally, the fallback parameter is set to true, so other
3544 |  |  |  |  | derivable operators (+=, -=, etc.) will work properly. Do not expect
3545 |  |  |  |  | increment (++) or decrement (--) to do anything useful.
3546 |  |  |  |  |
3547 |  |  |  |  | The string comparison operators, C<eq> or C<ne>, will use the string
3548 |  |  |  |  | value to compare with non-DateTime objects.
3549 |  |  |  |  |
3550 |  |  |  |  | DateTime objects do not have a numeric value, using C<==> or C<< <=>
3551 |  |  |  |  | >> to compare a DateTime object with a non-DateTime object will result
3552 |  |  |  |  | in an exception. To safely sort mixed DateTime and non-DateTime
3553 |  |  |  |  | objects, use C<sort { $a cmp $b } @dates>.
3554 |  |  |  |  |
3555 |  |  |  |  | The module also overloads stringification using the object's
3556 |  |  |  |  | formatter, defaulting to C<iso8601()> method. See L<Formatters And
3557 |  |  |  |  | Stringification> for details.
3558 |  |  |  |  |
3559 |  |  |  |  | =head2 Formatters And Stringification
3560 |  |  |  |  |
3561 |  |  |  |  | You can optionally specify a "formatter", which is usually a
3562 |  |  |  |  | DateTime::Format::* object/class, to control the stringification of
3563 |  |  |  |  | the DateTime object.
3564 |  |  |  |  |
3565 |  |  |  |  | Any 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 |  |  |  |  |
3570 |  |  |  |  | Or, you can set it afterwards:
3571 |  |  |  |  |
3572 |  |  |  |  | $dt->set_formatter($formatter);
3573 |  |  |  |  | $formatter = $dt->formatter();
3574 |  |  |  |  |
3575 |  |  |  |  | Once you set the formatter, the overloaded stringification method will
3576 |  |  |  |  | use the formatter. If unspecified, the C<iso8601()> method is used.
3577 |  |  |  |  |
3578 |  |  |  |  | A formatter can be handy when you know that in your application you
3579 |  |  |  |  | want to stringify your DateTime objects into a special format all the
3580 |  |  |  |  | time, for example to a different language.
3581 |  |  |  |  |
3582 |  |  |  |  | If you provide a formatter class name or object, it must implement a
3583 |  |  |  |  | C<format_datetime> method. This method will be called with just the
3584 |  |  |  |  | DateTime object as its argument.
3585 |  |  |  |  |
3586 |  |  |  |  | =head2 CLDR Patterns
3587 |  |  |  |  |
3588 |  |  |  |  | The CLDR pattern language is both more powerful and more complex than
3589 |  |  |  |  | strftime. Unlike strftime patterns, you often have to explicitly
3590 |  |  |  |  | escape text that you do not want formatted, as the patterns are simply
3591 |  |  |  |  | letters without any prefix.
3592 |  |  |  |  |
3593 |  |  |  |  | For example, "yyyy-MM-dd" is a valid CLDR pattern. If you want to
3594 |  |  |  |  | include any lower or upper case ASCII characters as-is, you can
3595 |  |  |  |  | surround them with single quotes ('). If you want to include a single
3596 |  |  |  |  | quote, you must escape it as two single quotes ('').
3597 |  |  |  |  |
3598 |  |  |  |  | 'Today is ' EEEE
3599 |  |  |  |  | 'It is now' h 'o''clock' a
3600 |  |  |  |  |
3601 |  |  |  |  | Spaces and any non-letter text will always be passed through as-is.
3602 |  |  |  |  |
3603 |  |  |  |  | Many CLDR patterns which produce numbers will pad the number with
3604 |  |  |  |  | leading zeroes depending on the length of the format specifier. For
3605 |  |  |  |  | example, "h" represents the current hour from 1-12. If you specify
3606 |  |  |  |  | "hh" then the 1-9 will have a leading zero prepended.
3607 |  |  |  |  |
3608 |  |  |  |  | However, CLDR often uses five of a letter to represent the narrow form
3609 |  |  |  |  | of a pattern. This inconsistency is necessary for backwards
3610 |  |  |  |  | compatibility.
3611 |  |  |  |  |
3612 |  |  |  |  | CLDR often distinguishes between the "format" and "stand-alone" forms
3613 |  |  |  |  | of a pattern. The format pattern is used when the thing in question is
3614 |  |  |  |  | being placed into a larger string. The stand-alone form is used when
3615 |  |  |  |  | displaying that item by itself, for example in a calendar.
3616 |  |  |  |  |
3617 |  |  |  |  | It also often provides three sizes for each item, wide (the full
3618 |  |  |  |  | name), abbreviated, and narrow. The narrow form is often just a single
3619 |  |  |  |  | character, for example "T" for "Tuesday", and may not be unique.
3620 |  |  |  |  |
3621 |  |  |  |  | CLDR provides a fairly complex system for localizing time zones that
3622 |  |  |  |  | we ignore entirely. The time zone patterns just use the information
3623 |  |  |  |  | provided by C<DateTime::TimeZone>, and I<do not follow the CLDR spec>.
3624 |  |  |  |  |
3625 |  |  |  |  | The output of a CLDR pattern is always localized, when applicable.
3626 |  |  |  |  |
3627 |  |  |  |  | CLDR provides the following patterns:
3628 |  |  |  |  |
3629 |  |  |  |  | =over 4
3630 |  |  |  |  |
3631 |  |  |  |  | =item * G{1,3}
3632 |  |  |  |  |
3633 |  |  |  |  | The abbreviated era (BC, AD).
3634 |  |  |  |  |
3635 |  |  |  |  | =item * GGGG
3636 |  |  |  |  |
3637 |  |  |  |  | The wide era (Before Christ, Anno Domini).
3638 |  |  |  |  |
3639 |  |  |  |  | =item * GGGGG
3640 |  |  |  |  |
3641 |  |  |  |  | The narrow era, if it exists (and it mostly doesn't).
3642 |  |  |  |  |
3643 |  |  |  |  | =item * y and y{3,}
3644 |  |  |  |  |
3645 |  |  |  |  | The year, zero-prefixed as needed. Negative years will start with a "-",
3646 |  |  |  |  | and this will be included in the length calculation.
3647 |  |  |  |  |
3648 |  |  |  |  | In other, words the "yyyyy" pattern will format year -1234 as "-1234", not
3649 |  |  |  |  | "-01234".
3650 |  |  |  |  |
3651 |  |  |  |  | =item * yy
3652 |  |  |  |  |
3653 |  |  |  |  | This 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 |  |  |  |  |
3658 |  |  |  |  | The week of the year, from C<< $dt->week_year() >>.
3659 |  |  |  |  |
3660 |  |  |  |  | =item * u{1,}
3661 |  |  |  |  |
3662 |  |  |  |  | Same as "y" except that "uu" is not a special case.
3663 |  |  |  |  |
3664 |  |  |  |  | =item * Q{1,2}
3665 |  |  |  |  |
3666 |  |  |  |  | The quarter as a number (1..4).
3667 |  |  |  |  |
3668 |  |  |  |  | =item * QQQ
3669 |  |  |  |  |
3670 |  |  |  |  | The abbreviated format form for the quarter.
3671 |  |  |  |  |
3672 |  |  |  |  | =item * QQQQ
3673 |  |  |  |  |
3674 |  |  |  |  | The wide format form for the quarter.
3675 |  |  |  |  |
3676 |  |  |  |  | =item * q{1,2}
3677 |  |  |  |  |
3678 |  |  |  |  | The quarter as a number (1..4).
3679 |  |  |  |  |
3680 |  |  |  |  | =item * qqq
3681 |  |  |  |  |
3682 |  |  |  |  | The abbreviated stand-alone form for the quarter.
3683 |  |  |  |  |
3684 |  |  |  |  | =item * qqqq
3685 |  |  |  |  |
3686 |  |  |  |  | The wide stand-alone form for the quarter.
3687 |  |  |  |  |
3688 |  |  |  |  | =item * M{1,2]
3689 |  |  |  |  |
3690 |  |  |  |  | The numerical month.
3691 |  |  |  |  |
3692 |  |  |  |  | =item * MMM
3693 |  |  |  |  |
3694 |  |  |  |  | The abbreviated format form for the month.
3695 |  |  |  |  |
3696 |  |  |  |  | =item * MMMM
3697 |  |  |  |  |
3698 |  |  |  |  | The wide format form for the month.
3699 |  |  |  |  |
3700 |  |  |  |  | =item * MMMMM
3701 |  |  |  |  |
3702 |  |  |  |  | The narrow format form for the month.
3703 |  |  |  |  |
3704 |  |  |  |  | =item * L{1,2]
3705 |  |  |  |  |
3706 |  |  |  |  | The numerical month.
3707 |  |  |  |  |
3708 |  |  |  |  | =item * LLL
3709 |  |  |  |  |
3710 |  |  |  |  | The abbreviated stand-alone form for the month.
3711 |  |  |  |  |
3712 |  |  |  |  | =item * LLLL
3713 |  |  |  |  |
3714 |  |  |  |  | The wide stand-alone form for the month.
3715 |  |  |  |  |
3716 |  |  |  |  | =item * LLLLL
3717 |  |  |  |  |
3718 |  |  |  |  | The narrow stand-alone form for the month.
3719 |  |  |  |  |
3720 |  |  |  |  | =item * w{1,2}
3721 |  |  |  |  |
3722 |  |  |  |  | The week of the year, from C<< $dt->week_number() >>.
3723 |  |  |  |  |
3724 |  |  |  |  | =item * W
3725 |  |  |  |  |
3726 |  |  |  |  | The week of the month, from C<< $dt->week_of_month() >>.
3727 |  |  |  |  |
3728 |  |  |  |  | =item * d{1,2}
3729 |  |  |  |  |
3730 |  |  |  |  | The numeric day of of the month.
3731 |  |  |  |  |
3732 |  |  |  |  | =item * D{1,3}
3733 |  |  |  |  |
3734 |  |  |  |  | The numeric day of of the year.
3735 |  |  |  |  |
3736 |  |  |  |  | =item * F
3737 |  |  |  |  |
3738 |  |  |  |  | The day of the week in the month, from C<< $dt->weekday_of_month() >>.
3739 |  |  |  |  |
3740 |  |  |  |  | =item * g{1,}
3741 |  |  |  |  |
3742 |  |  |  |  | The modified Julian day, from C<< $dt->mjd() >>.
3743 |  |  |  |  |
3744 |  |  |  |  | =item * E{1,3} and eee
3745 |  |  |  |  |
3746 |  |  |  |  | The abbreviated format form for the day of the week.
3747 |  |  |  |  |
3748 |  |  |  |  | =item * EEEE and eeee
3749 |  |  |  |  |
3750 |  |  |  |  | The wide format form for the day of the week.
3751 |  |  |  |  |
3752 |  |  |  |  | =item * EEEEE and eeeee
3753 |  |  |  |  |
3754 |  |  |  |  | The narrow format form for the day of the week.
3755 |  |  |  |  |
3756 |  |  |  |  | =item * e{1,2}
3757 |  |  |  |  |
3758 |  |  |  |  | The I<local> numeric day of the week, from 1 to 7. This number depends
3759 |  |  |  |  | on what day is considered the first day of the week, which varies by
3760 |  |  |  |  | locale. For example, in the US, Sunday is the first day of the week,
3761 |  |  |  |  | so this returns 2 for Monday.
3762 |  |  |  |  |
3763 |  |  |  |  | =item * c
3764 |  |  |  |  |
3765 |  |  |  |  | The numeric day of the week from 1 to 7, treating Monday as the first
3766 |  |  |  |  | of the week, regardless of locale.
3767 |  |  |  |  |
3768 |  |  |  |  | =item * ccc
3769 |  |  |  |  |
3770 |  |  |  |  | The abbreviated stand-alone form for the day of the week.
3771 |  |  |  |  |
3772 |  |  |  |  | =item * cccc
3773 |  |  |  |  |
3774 |  |  |  |  | The wide stand-alone form for the day of the week.
3775 |  |  |  |  |
3776 |  |  |  |  | =item * ccccc
3777 |  |  |  |  |
3778 |  |  |  |  | The narrow format form for the day of the week.
3779 |  |  |  |  |
3780 |  |  |  |  | =item * a
3781 |  |  |  |  |
3782 |  |  |  |  | The localized form of AM or PM for the time.
3783 |  |  |  |  |
3784 |  |  |  |  | =item * h{1,2}
3785 |  |  |  |  |
3786 |  |  |  |  | The hour from 1-12.
3787 |  |  |  |  |
3788 |  |  |  |  | =item * H{1,2}
3789 |  |  |  |  |
3790 |  |  |  |  | The hour from 0-23.
3791 |  |  |  |  |
3792 |  |  |  |  | =item * K{1,2}
3793 |  |  |  |  |
3794 |  |  |  |  | The hour from 0-11.
3795 |  |  |  |  |
3796 |  |  |  |  | =item * k{1,2}
3797 |  |  |  |  |
3798 |  |  |  |  | The hour from 1-24.
3799 |  |  |  |  |
3800 |  |  |  |  | =item * j{1,2}
3801 |  |  |  |  |
3802 |  |  |  |  | The hour, in 12 or 24 hour form, based on the preferred form for the
3803 |  |  |  |  | locale. In other words, this is equivalent to either "h{1,2}" or
3804 |  |  |  |  | "H{1,2}".
3805 |  |  |  |  |
3806 |  |  |  |  | =item * m{1,2}
3807 |  |  |  |  |
3808 |  |  |  |  | The minute.
3809 |  |  |  |  |
3810 |  |  |  |  | =item * s{1,2}
3811 |  |  |  |  |
3812 |  |  |  |  | The second.
3813 |  |  |  |  |
3814 |  |  |  |  | =item * S{1,}
3815 |  |  |  |  |
3816 |  |  |  |  | The fractional portion of the seconds, rounded based on the length of
3817 |  |  |  |  | the specifier. This returned I<without> a leading decimal point, but
3818 |  |  |  |  | may have leading or trailing zeroes.
3819 |  |  |  |  |
3820 |  |  |  |  | =item * A{1,}
3821 |  |  |  |  |
3822 |  |  |  |  | The millisecond of the day, based on the current time. In other words,
3823 |  |  |  |  | if it is 12:00:00.00, this returns 43200000.
3824 |  |  |  |  |
3825 |  |  |  |  | =item * z{1,3}
3826 |  |  |  |  |
3827 |  |  |  |  | The time zone short name.
3828 |  |  |  |  |
3829 |  |  |  |  | =item * zzzz
3830 |  |  |  |  |
3831 |  |  |  |  | The time zone long name.
3832 |  |  |  |  |
3833 |  |  |  |  | =item * Z{1,3}
3834 |  |  |  |  |
3835 |  |  |  |  | The time zone offset.
3836 |  |  |  |  |
3837 |  |  |  |  | =item * ZZZZ
3838 |  |  |  |  |
3839 |  |  |  |  | The time zone short name and the offset as one string, so something
3840 |  |  |  |  | like "CDT-0500".
3841 |  |  |  |  |
3842 |  |  |  |  | =item * v{1,3}
3843 |  |  |  |  |
3844 |  |  |  |  | The time zone short name.
3845 |  |  |  |  |
3846 |  |  |  |  | =item * vvvv
3847 |  |  |  |  |
3848 |  |  |  |  | The time zone long name.
3849 |  |  |  |  |
3850 |  |  |  |  | =item * V{1,3}
3851 |  |  |  |  |
3852 |  |  |  |  | The time zone short name.
3853 |  |  |  |  |
3854 |  |  |  |  | =item * VVVV
3855 |  |  |  |  |
3856 |  |  |  |  | The time zone long name.
3857 |  |  |  |  |
3858 |  |  |  |  | =back
3859 |  |  |  |  |
3860 |  |  |  |  | =head2 strftime Patterns
3861 |  |  |  |  |
3862 |  |  |  |  | The following patterns are allowed in the format string given to the
3863 |  |  |  |  | C<< $dt->strftime() >> method:
3864 |  |  |  |  |
3865 |  |  |  |  | =over 4
3866 |  |  |  |  |
3867 |  |  |  |  | =item * %a
3868 |  |  |  |  |
3869 |  |  |  |  | The abbreviated weekday name.
3870 |  |  |  |  |
3871 |  |  |  |  | =item * %A
3872 |  |  |  |  |
3873 |  |  |  |  | The full weekday name.
3874 |  |  |  |  |
3875 |  |  |  |  | =item * %b
3876 |  |  |  |  |
3877 |  |  |  |  | The abbreviated month name.
3878 |  |  |  |  |
3879 |  |  |  |  | =item * %B
3880 |  |  |  |  |
3881 |  |  |  |  | The full month name.
3882 |  |  |  |  |
3883 |  |  |  |  | =item * %c
3884 |  |  |  |  |
3885 |  |  |  |  | The default datetime format for the object's locale.
3886 |  |  |  |  |
3887 |  |  |  |  | =item * %C
3888 |  |  |  |  |
3889 |  |  |  |  | The century number (year/100) as a 2-digit integer.
3890 |  |  |  |  |
3891 |  |  |  |  | =item * %d
3892 |  |  |  |  |
3893 |  |  |  |  | The day of the month as a decimal number (range 01 to 31).
3894 |  |  |  |  |
3895 |  |  |  |  | =item * %D
3896 |  |  |  |  |
3897 |  |  |  |  | Equivalent to %m/%d/%y. This is not a good standard format if you
3898 |  |  |  |  | want folks from both the United States and the rest of the world to
3899 |  |  |  |  | understand the date!
3900 |  |  |  |  |
3901 |  |  |  |  | =item * %e
3902 |  |  |  |  |
3903 |  |  |  |  | Like %d, the day of the month as a decimal number, but a leading zero
3904 |  |  |  |  | is replaced by a space.
3905 |  |  |  |  |
3906 |  |  |  |  | =item * %F
3907 |  |  |  |  |
3908 |  |  |  |  | Equivalent to %Y-%m-%d (the ISO 8601 date format)
3909 |  |  |  |  |
3910 |  |  |  |  | =item * %G
3911 |  |  |  |  |
3912 |  |  |  |  | The ISO 8601 year with century as a decimal number. The 4-digit year
3913 |  |  |  |  | corresponding to the ISO week number (see %V). This has the same
3914 |  |  |  |  | format and value as %Y, except that if the ISO week number belongs to
3915 |  |  |  |  | the previous or next year, that year is used instead. (TZ)
3916 |  |  |  |  |
3917 |  |  |  |  | =item * %g
3918 |  |  |  |  |
3919 |  |  |  |  | Like %G, but without century, i.e., with a 2-digit year (00-99).
3920 |  |  |  |  |
3921 |  |  |  |  | =item * %h
3922 |  |  |  |  |
3923 |  |  |  |  | Equivalent to %b.
3924 |  |  |  |  |
3925 |  |  |  |  | =item * %H
3926 |  |  |  |  |
3927 |  |  |  |  | The hour as a decimal number using a 24-hour clock (range 00 to 23).
3928 |  |  |  |  |
3929 |  |  |  |  | =item * %I
3930 |  |  |  |  |
3931 |  |  |  |  | The hour as a decimal number using a 12-hour clock (range 01 to 12).
3932 |  |  |  |  |
3933 |  |  |  |  | =item * %j
3934 |  |  |  |  |
3935 |  |  |  |  | The day of the year as a decimal number (range 001 to 366).
3936 |  |  |  |  |
3937 |  |  |  |  | =item * %k
3938 |  |  |  |  |
3939 |  |  |  |  | The hour (24-hour clock) as a decimal number (range 0 to 23); single
3940 |  |  |  |  | digits are preceded by a blank. (See also %H.)
3941 |  |  |  |  |
3942 |  |  |  |  | =item * %l
3943 |  |  |  |  |
3944 |  |  |  |  | The hour (12-hour clock) as a decimal number (range 1 to 12); single
3945 |  |  |  |  | digits are preceded by a blank. (See also %I.)
3946 |  |  |  |  |
3947 |  |  |  |  | =item * %m
3948 |  |  |  |  |
3949 |  |  |  |  | The month as a decimal number (range 01 to 12).
3950 |  |  |  |  |
3951 |  |  |  |  | =item * %M
3952 |  |  |  |  |
3953 |  |  |  |  | The minute as a decimal number (range 00 to 59).
3954 |  |  |  |  |
3955 |  |  |  |  | =item * %n
3956 |  |  |  |  |
3957 |  |  |  |  | A newline character.
3958 |  |  |  |  |
3959 |  |  |  |  | =item * %N
3960 |  |  |  |  |
3961 |  |  |  |  | The 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 |  |  |  |  |
3969 |  |  |  |  | Either `AM' or `PM' according to the given time value, or the
3970 |  |  |  |  | corresponding strings for the current locale. Noon is treated as `pm'
3971 |  |  |  |  | and midnight as `am'.
3972 |  |  |  |  |
3973 |  |  |  |  | =item * %P
3974 |  |  |  |  |
3975 |  |  |  |  | Like %p but in lowercase: `am' or `pm' or a corresponding string for
3976 |  |  |  |  | the current locale.
3977 |  |  |  |  |
3978 |  |  |  |  | =item * %r
3979 |  |  |  |  |
3980 |  |  |  |  | The time in a.m. or p.m. notation. In the POSIX locale this is
3981 |  |  |  |  | equivalent to `%I:%M:%S %p'.
3982 |  |  |  |  |
3983 |  |  |  |  | =item * %R
3984 |  |  |  |  |
3985 |  |  |  |  | The time in 24-hour notation (%H:%M). (SU) For a version including the
3986 |  |  |  |  | seconds, see %T below.
3987 |  |  |  |  |
3988 |  |  |  |  | =item * %s
3989 |  |  |  |  |
3990 |  |  |  |  | The number of seconds since the epoch.
3991 |  |  |  |  |
3992 |  |  |  |  | =item * %S
3993 |  |  |  |  |
3994 |  |  |  |  | The second as a decimal number (range 00 to 61).
3995 |  |  |  |  |
3996 |  |  |  |  | =item * %t
3997 |  |  |  |  |
3998 |  |  |  |  | A tab character.
3999 |  |  |  |  |
4000 |  |  |  |  | =item * %T
4001 |  |  |  |  |
4002 |  |  |  |  | The time in 24-hour notation (%H:%M:%S).
4003 |  |  |  |  |
4004 |  |  |  |  | =item * %u
4005 |  |  |  |  |
4006 |  |  |  |  | The day of the week as a decimal, range 1 to 7, Monday being 1. See
4007 |  |  |  |  | also %w.
4008 |  |  |  |  |
4009 |  |  |  |  | =item * %U
4010 |  |  |  |  |
4011 |  |  |  |  | The week number of the current year as a decimal number, range 00 to
4012 |  |  |  |  | 53, starting with the first Sunday as the first day of week 01. See
4013 |  |  |  |  | also %V and %W.
4014 |  |  |  |  |
4015 |  |  |  |  | =item * %V
4016 |  |  |  |  |
4017 |  |  |  |  | The ISO 8601:1988 week number of the current year as a decimal number,
4018 |  |  |  |  | range 01 to 53, where week 1 is the first week that has at least 4
4019 |  |  |  |  | days in the current year, and with Monday as the first day of the
4020 |  |  |  |  | week. See also %U and %W.
4021 |  |  |  |  |
4022 |  |  |  |  | =item * %w
4023 |  |  |  |  |
4024 |  |  |  |  | The day of the week as a decimal, range 0 to 6, Sunday being 0. See
4025 |  |  |  |  | also %u.
4026 |  |  |  |  |
4027 |  |  |  |  | =item * %W
4028 |  |  |  |  |
4029 |  |  |  |  | The week number of the current year as a decimal number, range 00 to
4030 |  |  |  |  | 53, starting with the first Monday as the first day of week 01.
4031 |  |  |  |  |
4032 |  |  |  |  | =item * %x
4033 |  |  |  |  |
4034 |  |  |  |  | The default date format for the object's locale.
4035 |  |  |  |  |
4036 |  |  |  |  | =item * %X
4037 |  |  |  |  |
4038 |  |  |  |  | The default time format for the object's locale.
4039 |  |  |  |  |
4040 |  |  |  |  | =item * %y
4041 |  |  |  |  |
4042 |  |  |  |  | The year as a decimal number without a century (range 00 to 99).
4043 |  |  |  |  |
4044 |  |  |  |  | =item * %Y
4045 |  |  |  |  |
4046 |  |  |  |  | The year as a decimal number including the century.
4047 |  |  |  |  |
4048 |  |  |  |  | =item * %z
4049 |  |  |  |  |
4050 |  |  |  |  | The time-zone as hour offset from UTC. Required to emit
4051 |  |  |  |  | RFC822-conformant dates (using "%a, %d %b %Y %H:%M:%S %z").
4052 |  |  |  |  |
4053 |  |  |  |  | =item * %Z
4054 |  |  |  |  |
4055 |  |  |  |  | The time zone or name or abbreviation.
4056 |  |  |  |  |
4057 |  |  |  |  | =item * %%
4058 |  |  |  |  |
4059 |  |  |  |  | A literal `%' character.
4060 |  |  |  |  |
4061 |  |  |  |  | =item * %{method}
4062 |  |  |  |  |
4063 |  |  |  |  | Any method name may be specified using the format C<%{method}> name
4064 |  |  |  |  | where "method" is a valid C<DateTime.pm> object method.
4065 |  |  |  |  |
4066 |  |  |  |  | =back
4067 |  |  |  |  |
4068 |  |  |  |  | =head2 DateTime.pm and Storable
4069 |  |  |  |  |
4070 |  |  |  |  | DateTime implements Storable hooks in order to reduce the size of a
4071 |  |  |  |  | serialized DateTime object.
4072 |  |  |  |  |
4073 |  |  |  |  | =head1 THE DATETIME PROJECT ECOSYSTEM
4074 |  |  |  |  |
4075 |  |  |  |  | This module is part of a larger ecosystem of modules in the DateTime
4076 |  |  |  |  | family.
4077 |  |  |  |  |
4078 |  |  |  |  | =head2 L<DateTime::Set>
4079 |  |  |  |  |
4080 |  |  |  |  | The L<DateTime::Set> module represents sets (including recurrences) of
4081 |  |  |  |  | datetimes. Many modules return sets or recurrences.
4082 |  |  |  |  |
4083 |  |  |  |  | =head2 Format Modules
4084 |  |  |  |  |
4085 |  |  |  |  | The various format modules exist to parse and format datetimes. For example,
4086 |  |  |  |  | L<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 |  |  |  |  |
4093 |  |  |  |  | Most format modules are suitable for use as a C<formatter> with a DateTime
4094 |  |  |  |  | object.
4095 |  |  |  |  |
4096 |  |  |  |  | All format modules start with C<DateTime::Format::>.
4097 |  |  |  |  |
4098 |  |  |  |  | =head2 Calendar Modules
4099 |  |  |  |  |
4100 |  |  |  |  | There are a number of modules on CPAN that implement non-Gregorian calendars,
4101 |  |  |  |  | such as the Chinese, Mayan, and Julian calendars.
4102 |  |  |  |  |
4103 |  |  |  |  | All calendar modules start with C<DateTime::Calendar::>.
4104 |  |  |  |  |
4105 |  |  |  |  | =head2 Event Modules
4106 |  |  |  |  |
4107 |  |  |  |  | There are a number of modules that calculate the dates for events, such as
4108 |  |  |  |  | Easter, Sunrise, etc.
4109 |  |  |  |  |
4110 |  |  |  |  | All event modules start with C<DateTime::Event::>.
4111 |  |  |  |  |
4112 |  |  |  |  | =head2 Others
4113 |  |  |  |  |
4114 |  |  |  |  | There are many other modules that work with DateTime, including modules in the
4115 |  |  |  |  | C<DateTimeX> namespace, as well as others.
4116 |  |  |  |  |
4117 |  |  |  |  | See the L<datetime wiki|http://datetime.perl.org> and
4118 |  |  |  |  | L<search.cpan.org|http://search.cpan.org/search?query=datetime&mode=dist> for
4119 |  |  |  |  | more details.
4120 |  |  |  |  |
4121 |  |  |  |  | =head1 KNOWN BUGS
4122 |  |  |  |  |
4123 |  |  |  |  | The tests in F<20infinite.t> seem to fail on some machines,
4124 |  |  |  |  | particularly on Win32. This appears to be related to Perl's internal
4125 |  |  |  |  | handling of IEEE infinity and NaN, and seems to be highly
4126 |  |  |  |  | platform/compiler/phase of moon dependent.
4127 |  |  |  |  |
4128 |  |  |  |  | If you don't plan to use infinite datetimes you can probably ignore
4129 |  |  |  |  | this. This will be fixed (perhaps) in future versions.
4130 |  |  |  |  |
4131 |  |  |  |  | =head1 SUPPORT
4132 |  |  |  |  |
4133 |  |  |  |  | Support for this module is provided via the datetime@perl.org email list. See
4134 |  |  |  |  | http://datetime.perl.org/wiki/datetime/page/Mailing_List for details.
4135 |  |  |  |  |
4136 |  |  |  |  | Please submit bugs to the CPAN RT system at
4137 |  |  |  |  | http://rt.cpan.org/NoAuth/Bugs.html?Dist=DateTime or via email at
4138 |  |  |  |  | bug-datetime@rt.cpan.org.
4139 |  |  |  |  |
4140 |  |  |  |  | =head1 DONATIONS
4141 |  |  |  |  |
4142 |  |  |  |  | If you'd like to thank me for the work I've done on this module,
4143 |  |  |  |  | please consider making a "donation" to me via PayPal. I spend a lot of
4144 |  |  |  |  | free time creating free software, and would appreciate any support
4145 |  |  |  |  | you'd care to offer.
4146 |  |  |  |  |
4147 |  |  |  |  | Please note that B<I am not suggesting that you must do this> in order
4148 |  |  |  |  | for me to continue working on this particular software. I will
4149 |  |  |  |  | continue to do so, inasmuch as I have in the past, for as long as it
4150 |  |  |  |  | interests me.
4151 |  |  |  |  |
4152 |  |  |  |  | Similarly, a donation made in this way will probably not make me work
4153 |  |  |  |  | on this software much more, unless I get so many donations that I can
4154 |  |  |  |  | consider working on free software full time, which seems unlikely at
4155 |  |  |  |  | best.
4156 |  |  |  |  |
4157 |  |  |  |  | To donate, log into PayPal and send money to autarch@urth.org or use
4158 |  |  |  |  | the button on this page:
4159 |  |  |  |  | L<http://www.urth.org/~autarch/fs-donation.html>
4160 |  |  |  |  |
4161 |  |  |  |  | =head1 SEE ALSO
4162 |  |  |  |  |
4163 |  |  |  |  | datetime@perl.org mailing list
4164 |  |  |  |  |
4165 |  |  |  |  | http://datetime.perl.org/
4166 |  |  |  |  |
4167 |  |  |  |  | =head1 AUTHOR
4168 |  |  |  |  |
4169 |  |  |  |  | Dave Rolsky <autarch@urth.org>
4170 |  |  |  |  |
4171 |  |  |  |  | =head1 COPYRIGHT AND LICENSE
4172 |  |  |  |  |
4173 |  |  |  |  | This software is Copyright (c) 2012 by Dave Rolsky.
4174 |  |  |  |  |
4175 |  |  |  |  | This 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