diff -Nru libdatetime-perl-1.21/appveyor.yml libdatetime-perl-1.46/appveyor.yml --- libdatetime-perl-1.21/appveyor.yml 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/appveyor.yml 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,17 @@ +--- +skip_tags: true +cache: + - C:\strawberry +install: + - if not exist "C:\strawberry" cinst strawberryperl -y + - set PATH=C:\strawberry\perl\bin;C:\strawberry\perl\site\bin;C:\strawberry\c\bin;%PATH% + - cd %APPVEYOR_BUILD_FOLDER% + - cpanm --installdeps . -n +build_script: + - perl -e 1 +test_script: + - prove -lrv t/ +### __app_cisetup__ +# --- {} + +### __app_cisetup__ diff -Nru libdatetime-perl-1.21/_build/auto_features libdatetime-perl-1.46/_build/auto_features --- libdatetime-perl-1.21/_build/auto_features 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/_build/auto_features 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -do{ my $x = {}; -$x; } \ No newline at end of file diff -Nru libdatetime-perl-1.21/_build/build_params libdatetime-perl-1.46/_build/build_params --- libdatetime-perl-1.21/_build/build_params 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/_build/build_params 1970-01-01 00:00:00.000000000 +0000 @@ -1,156 +0,0 @@ -do{ my $x = [ - { - 'ARGV' => [] - }, - {}, - { - 'PL_files' => undef, - '_added_to_INC' => [ - '/home/autarch/.perlbrew/libs/perl-5.22.0@dev/lib/perl5/x86_64-linux', - '/home/autarch/.perlbrew/libs/perl-5.22.0@dev/lib/perl5' - ], - '_have_c_compiler' => 1, - 'allow_mb_mismatch' => 0, - 'allow_pureperl' => 0, - 'auto_configure_requires' => 1, - 'autosplit' => undef, - 'base_dir' => '/home/autarch/projects/DateTime.pm', - 'bindoc_dirs' => [ - 'blib/script' - ], - 'blib' => 'blib', - 'build_bat' => 0, - 'build_class' => 'Module::Build', - 'build_elements' => [ - 'PL', - 'support', - 'pm', - 'xs', - 'share_dir', - 'pod', - 'script' - ], - 'build_requires' => { - 'ExtUtils::CBuilder' => 0, - 'Module::Build' => '0.28' - }, - 'build_script' => 'Build', - 'bundle_inc' => [], - 'bundle_inc_preload' => [], - 'c_source' => 'c', - 'config' => undef, - 'config_dir' => '_build', - 'configure_requires' => { - 'Module::Build' => '0.28' - }, - 'conflicts' => {}, - 'cpan_client' => 'cpan', - 'create_license' => undef, - 'create_makefile_pl' => undef, - 'create_packlist' => 1, - 'create_readme' => undef, - 'debug' => undef, - 'debugger' => undef, - 'destdir' => undef, - 'dist_abstract' => 'A date and time object for Perl', - 'dist_author' => [ - 'Dave Rolsky ' - ], - 'dist_name' => 'DateTime', - 'dist_suffix' => undef, - 'dist_version' => '1.20', - 'dist_version_from' => undef, - 'dynamic_config' => 1, - 'extra_compiler_flags' => [], - 'extra_linker_flags' => [], - 'extra_manify_args' => undef, - 'get_options' => {}, - 'has_config_data' => undef, - 'html_css' => '', - 'include_dirs' => [], - 'install_base' => '/home/autarch/.perlbrew/libs/perl-5.22.0@dev', - 'install_base_relpaths' => {}, - 'install_path' => {}, - 'install_sets' => {}, - 'installdirs' => 'site', - 'libdoc_dirs' => [ - 'blib/lib', - 'blib/arch' - ], - 'license' => 'artistic_2', - 'magic_number' => undef, - 'mb_version' => '0.4214', - 'meta_add' => {}, - 'meta_merge' => {}, - 'metafile' => 'META.yml', - 'metafile2' => 'META.json', - 'module_name' => 'DateTime', - 'mymetafile' => 'MYMETA.yml', - 'mymetafile2' => 'MYMETA.json', - 'needs_compiler' => 1, - 'orig_dir' => '/home/autarch/projects/DateTime.pm', - 'original_prefix' => {}, - 'perl' => '/home/autarch/perl5/perlbrew/perls/perl-5.22.0/bin/perl', - 'pm_files' => undef, - 'pod_files' => undef, - 'pollute' => undef, - 'prefix' => undef, - 'prefix_relpaths' => {}, - 'prereq_action_types' => [ - 'requires', - 'build_requires', - 'test_requires', - 'conflicts', - 'recommends' - ], - 'program_name' => undef, - 'pureperl_only' => 0, - 'quiet' => undef, - 'recommends' => {}, - 'recurse_into' => [], - 'recursive_test_files' => 1, - 'release_status' => 'stable', - 'requires' => { - 'Carp' => 0, - 'DateTime::Locale' => '0.41', - 'DateTime::TimeZone' => '1.74', - 'POSIX' => 0, - 'Params::Validate' => '1.03', - 'Scalar::Util' => 0, - 'Try::Tiny' => 0, - 'XSLoader' => 0, - 'base' => 0, - 'constant' => 0, - 'integer' => 0, - 'overload' => 0, - 'perl' => '5.008001', - 'strict' => 0, - 'vars' => 0, - 'warnings' => 0, - 'warnings::register' => 0 - }, - 'script_files' => [], - 'scripts' => undef, - 'share_dir' => undef, - 'sign' => undef, - 'tap_harness_args' => {}, - 'test_file_exts' => [ - '.t' - ], - 'test_files' => undef, - 'test_requires' => { - 'ExtUtils::MakeMaker' => 0, - 'File::Spec' => 0, - 'Storable' => 0, - 'Test::Fatal' => 0, - 'Test::More' => '0.96', - 'Test::Warnings' => '0.005', - 'utf8' => 0 - }, - 'use_rcfile' => 1, - 'use_tap_harness' => 0, - 'verbose' => undef, - 'xs_files' => undef - } - ]; -$x; } \ No newline at end of file diff -Nru libdatetime-perl-1.21/_build/cleanup libdatetime-perl-1.46/_build/cleanup --- libdatetime-perl-1.21/_build/cleanup 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/_build/cleanup 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ -do{ my $x = { - 'blib' => 1, - 'blib/arch/auto/DateTime/DateTime.bs' => 1, - 'blib/arch/auto/DateTime/DateTime.so' => 1, - 'lib/DateTime.c' => 1, - 'lib/DateTime.o' => 1 - }; -$x; } \ No newline at end of file diff -Nru libdatetime-perl-1.21/_build/config_data libdatetime-perl-1.46/_build/config_data --- libdatetime-perl-1.21/_build/config_data 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/_build/config_data 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -do{ my $x = {}; -$x; } \ No newline at end of file diff -Nru libdatetime-perl-1.21/_build/features libdatetime-perl-1.46/_build/features --- libdatetime-perl-1.21/_build/features 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/_build/features 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -do{ my $x = {}; -$x; } \ No newline at end of file diff -Nru libdatetime-perl-1.21/_build/magicnum libdatetime-perl-1.46/_build/magicnum --- libdatetime-perl-1.21/_build/magicnum 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/_build/magicnum 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -179351 \ No newline at end of file diff -Nru libdatetime-perl-1.21/_build/notes libdatetime-perl-1.46/_build/notes --- libdatetime-perl-1.21/_build/notes 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/_build/notes 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -do{ my $x = {}; -$x; } \ No newline at end of file diff -Nru libdatetime-perl-1.21/_build/prereqs libdatetime-perl-1.46/_build/prereqs --- libdatetime-perl-1.21/_build/prereqs 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/_build/prereqs 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -do{ my $x = { - 'build_requires' => { - 'ExtUtils::CBuilder' => 0, - 'Module::Build' => '0.28' - }, - 'conflicts' => {}, - 'recommends' => {}, - 'requires' => { - 'Carp' => 0, - 'DateTime::Locale' => '0.41', - 'DateTime::TimeZone' => '1.74', - 'POSIX' => 0, - 'Params::Validate' => '1.03', - 'Scalar::Util' => 0, - 'Try::Tiny' => 0, - 'XSLoader' => 0, - 'base' => 0, - 'constant' => 0, - 'integer' => 0, - 'overload' => 0, - 'perl' => '5.008001', - 'strict' => 0, - 'vars' => 0, - 'warnings' => 0, - 'warnings::register' => 0 - }, - 'test_requires' => { - 'ExtUtils::MakeMaker' => 0, - 'File::Spec' => 0, - 'Storable' => 0, - 'Test::Fatal' => 0, - 'Test::More' => '0.96', - 'Test::Warnings' => '0.005', - 'utf8' => 0 - } - }; -$x; } \ No newline at end of file diff -Nru libdatetime-perl-1.21/_build/runtime_params libdatetime-perl-1.46/_build/runtime_params --- libdatetime-perl-1.21/_build/runtime_params 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/_build/runtime_params 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ -do{ my $x = { - 'install_base' => '/home/autarch/.perlbrew/libs/perl-5.22.0@dev' - }; -$x; } \ No newline at end of file diff -Nru libdatetime-perl-1.21/Build.PL libdatetime-perl-1.46/Build.PL --- libdatetime-perl-1.21/Build.PL 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/Build.PL 1970-01-01 00:00:00.000000000 +0000 @@ -1,89 +0,0 @@ - -# This file was automatically generated by inc::MyModuleBuild v(dev). -use strict; -use warnings; - -use Module::Build 0.28; - - -my %module_build_args = ( - "build_requires" => { - "Module::Build" => "0.28" - }, - "c_source" => "c", - "configure_requires" => { - "Module::Build" => "0.28" - }, - "dist_abstract" => "A date and time object for Perl", - "dist_author" => [ - "Dave Rolsky " - ], - "dist_name" => "DateTime", - "dist_version" => "1.21", - "license" => "artistic_2", - "module_name" => "DateTime", - "recursive_test_files" => 1, - "requires" => { - "Carp" => 0, - "DateTime::Locale" => "0.41", - "DateTime::TimeZone" => "1.74", - "POSIX" => 0, - "Params::Validate" => "1.03", - "Scalar::Util" => 0, - "Try::Tiny" => 0, - "XSLoader" => 0, - "base" => 0, - "constant" => 0, - "integer" => 0, - "overload" => 0, - "perl" => "5.008001", - "strict" => 0, - "vars" => 0, - "warnings" => 0, - "warnings::register" => 0 - }, - "test_requires" => { - "ExtUtils::MakeMaker" => 0, - "File::Spec" => 0, - "Storable" => 0, - "Test::Fatal" => 0, - "Test::More" => "0.96", - "Test::Warnings" => "0.005", - "utf8" => 0 - } -); - - -my %fallback_build_requires = ( - "ExtUtils::MakeMaker" => 0, - "File::Spec" => 0, - "Module::Build" => "0.28", - "Storable" => 0, - "Test::Fatal" => 0, - "Test::More" => "0.96", - "Test::Warnings" => "0.005", - "utf8" => 0 -); - - -unless ( eval { Module::Build->VERSION(0.4004) } ) { - delete $module_build_args{test_requires}; - $module_build_args{build_requires} = \%fallback_build_requires; -} - -my $build = Module::Build->new(%module_build_args); - - -my $skip_xs; -if ( grep { $_ eq '--pp' } @ARGV ) { - $skip_xs = 1; -} -elsif ( ! $build->have_c_compiler() ) { - $skip_xs = 1; -} - -if ($skip_xs) { - $build->build_elements( - [ grep { $_ ne 'xs' } @{ $build->build_elements() } ] ); -} -$build->create_build_script; diff -Nru libdatetime-perl-1.21/c/leap_seconds.h libdatetime-perl-1.46/c/leap_seconds.h --- libdatetime-perl-1.21/c/leap_seconds.h 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/c/leap_seconds.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,139 +0,0 @@ -/* This file is auto-generated by the leap second code generator - (0.03). This code generator comes with the DateTime.pm module - distribution in the tools/ directory - - Generated by ./tools/leap_seconds_header.pl. - - Do not edit this file directly. -*/ - -#define SET_LEAP_SECONDS(utc_rd, ls) \ -{ \ - { \ - if (utc_rd < 720075) { \ - ls = 0; \ - } else if (utc_rd >= 720075 && utc_rd < 720259) { \ - ls = 1; \ - } else if (utc_rd >= 720259 && utc_rd < 720624) { \ - ls = 2; \ - } else if (utc_rd >= 720624 && utc_rd < 720989) { \ - ls = 3; \ - } else if (utc_rd >= 720989 && utc_rd < 721354) { \ - ls = 4; \ - } else if (utc_rd >= 721354 && utc_rd < 721720) { \ - ls = 5; \ - } else if (utc_rd >= 721720 && utc_rd < 722085) { \ - ls = 6; \ - } else if (utc_rd >= 722085 && utc_rd < 722450) { \ - ls = 7; \ - } else if (utc_rd >= 722450 && utc_rd < 722815) { \ - ls = 8; \ - } else if (utc_rd >= 722815 && utc_rd < 723362) { \ - ls = 9; \ - } else if (utc_rd >= 723362 && utc_rd < 723727) { \ - ls = 10; \ - } else if (utc_rd >= 723727 && utc_rd < 724092) { \ - ls = 11; \ - } else if (utc_rd >= 724092 && utc_rd < 724823) { \ - ls = 12; \ - } else if (utc_rd >= 724823 && utc_rd < 725737) { \ - ls = 13; \ - } else if (utc_rd >= 725737 && utc_rd < 726468) { \ - ls = 14; \ - } else if (utc_rd >= 726468 && utc_rd < 726833) { \ - ls = 15; \ - } else if (utc_rd >= 726833 && utc_rd < 727380) { \ - ls = 16; \ - } else if (utc_rd >= 727380 && utc_rd < 727745) { \ - ls = 17; \ - } else if (utc_rd >= 727745 && utc_rd < 728110) { \ - ls = 18; \ - } else if (utc_rd >= 728110 && utc_rd < 728659) { \ - ls = 19; \ - } else if (utc_rd >= 728659 && utc_rd < 729206) { \ - ls = 20; \ - } else if (utc_rd >= 729206 && utc_rd < 729755) { \ - ls = 21; \ - } else if (utc_rd >= 729755 && utc_rd < 732312) { \ - ls = 22; \ - } else if (utc_rd >= 732312 && utc_rd < 733408) { \ - ls = 23; \ - } else if (utc_rd >= 733408 && utc_rd < 734685) { \ - ls = 24; \ - } else if (utc_rd >= 734685 && utc_rd < 735780) { \ - ls = 25; \ - } else { \ - ls = 26; \ - } \ - } \ -} - -#define SET_EXTRA_SECONDS(utc_rd, es) \ -{ \ - { \ - es = 0; \ - switch (utc_rd) { \ - case 720074: es = 1; break; \ - case 720258: es = 1; break; \ - case 720623: es = 1; break; \ - case 720988: es = 1; break; \ - case 721353: es = 1; break; \ - case 721719: es = 1; break; \ - case 722084: es = 1; break; \ - case 722449: es = 1; break; \ - case 722814: es = 1; break; \ - case 723361: es = 1; break; \ - case 723726: es = 1; break; \ - case 724091: es = 1; break; \ - case 724822: es = 1; break; \ - case 725736: es = 1; break; \ - case 726467: es = 1; break; \ - case 726832: es = 1; break; \ - case 727379: es = 1; break; \ - case 727744: es = 1; break; \ - case 728109: es = 1; break; \ - case 728658: es = 1; break; \ - case 729205: es = 1; break; \ - case 729754: es = 1; break; \ - case 732311: es = 1; break; \ - case 733407: es = 1; break; \ - case 734684: es = 1; break; \ - case 735779: es = 1; break; \ - } \ - } \ -} - -#define SET_DAY_LENGTH(utc_rd, dl) \ -{ \ - { \ - dl = 86400; \ - switch (utc_rd) { \ - case 720074: dl = 86400 + 1; break; \ - case 720258: dl = 86400 + 1; break; \ - case 720623: dl = 86400 + 1; break; \ - case 720988: dl = 86400 + 1; break; \ - case 721353: dl = 86400 + 1; break; \ - case 721719: dl = 86400 + 1; break; \ - case 722084: dl = 86400 + 1; break; \ - case 722449: dl = 86400 + 1; break; \ - case 722814: dl = 86400 + 1; break; \ - case 723361: dl = 86400 + 1; break; \ - case 723726: dl = 86400 + 1; break; \ - case 724091: dl = 86400 + 1; break; \ - case 724822: dl = 86400 + 1; break; \ - case 725736: dl = 86400 + 1; break; \ - case 726467: dl = 86400 + 1; break; \ - case 726832: dl = 86400 + 1; break; \ - case 727379: dl = 86400 + 1; break; \ - case 727744: dl = 86400 + 1; break; \ - case 728109: dl = 86400 + 1; break; \ - case 728658: dl = 86400 + 1; break; \ - case 729205: dl = 86400 + 1; break; \ - case 729754: dl = 86400 + 1; break; \ - case 732311: dl = 86400 + 1; break; \ - case 733407: dl = 86400 + 1; break; \ - case 734684: dl = 86400 + 1; break; \ - case 735779: dl = 86400 + 1; break; \ - } \ - } \ -} diff -Nru libdatetime-perl-1.21/c/ppport.h libdatetime-perl-1.46/c/ppport.h --- libdatetime-perl-1.21/c/ppport.h 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/c/ppport.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,7748 +0,0 @@ -#if 0 -<<'SKIP'; -#endif -/* ----------------------------------------------------------------------- - - ppport.h -- Perl/Pollution/Portability Version 3.31 - - Automatically created by Devel::PPPort running under perl 5.010001. - - Do NOT edit this file directly! -- Edit PPPort_pm.PL and the - includes in parts/inc/ instead. - - Use 'perldoc ppport.h' to view the documentation below. - ----------------------------------------------------------------------- - -SKIP - -=pod - -=head1 NAME - -ppport.h - Perl/Pollution/Portability version 3.31 - -=head1 SYNOPSIS - - perl ppport.h [options] [source files] - - Searches current directory for files if no [source files] are given - - --help show short help - - --version show version - - --patch=file write one patch file with changes - --copy=suffix write changed copies with suffix - --diff=program use diff program and options - - --compat-version=version provide compatibility with Perl version - --cplusplus accept C++ comments - - --quiet don't output anything except fatal errors - --nodiag don't show diagnostics - --nohints don't show hints - --nochanges don't suggest changes - --nofilter don't filter input files - - --strip strip all script and doc functionality from - ppport.h - - --list-provided list provided API - --list-unsupported list unsupported API - --api-info=name show Perl API portability information - -=head1 COMPATIBILITY - -This version of F is designed to support operation with Perl -installations back to 5.003, and has been tested up to 5.20. - -=head1 OPTIONS - -=head2 --help - -Display a brief usage summary. - -=head2 --version - -Display the version of F. - -=head2 --patch=I - -If this option is given, a single patch file will be created if -any changes are suggested. This requires a working diff program -to be installed on your system. - -=head2 --copy=I - -If this option is given, a copy of each file will be saved with -the given suffix that contains the suggested changes. This does -not require any external programs. Note that this does not -automagically add a dot between the original filename and the -suffix. If you want the dot, you have to include it in the option -argument. - -If neither C<--patch> or C<--copy> are given, the default is to -simply print the diffs for each file. This requires either -C or a C program to be installed. - -=head2 --diff=I - -Manually set the diff program and options to use. The default -is to use C, when installed, and output unified -context diffs. - -=head2 --compat-version=I - -Tell F to check for compatibility with the given -Perl version. The default is to check for compatibility with Perl -version 5.003. You can use this option to reduce the output -of F if you intend to be backward compatible only -down to a certain Perl version. - -=head2 --cplusplus - -Usually, F will detect C++ style comments and -replace them with C style comments for portability reasons. -Using this option instructs F to leave C++ -comments untouched. - -=head2 --quiet - -Be quiet. Don't print anything except fatal errors. - -=head2 --nodiag - -Don't output any diagnostic messages. Only portability -alerts will be printed. - -=head2 --nohints - -Don't output any hints. Hints often contain useful portability -notes. Warnings will still be displayed. - -=head2 --nochanges - -Don't suggest any changes. Only give diagnostic output and hints -unless these are also deactivated. - -=head2 --nofilter - -Don't filter the list of input files. By default, files not looking -like source code (i.e. not *.xs, *.c, *.cc, *.cpp or *.h) are skipped. - -=head2 --strip - -Strip all script and documentation functionality from F. -This reduces the size of F dramatically and may be useful -if you want to include F in smaller modules without -increasing their distribution size too much. - -The stripped F will have a C<--unstrip> option that allows -you to undo the stripping, but only if an appropriate C -module is installed. - -=head2 --list-provided - -Lists the API elements for which compatibility is provided by -F. Also lists if it must be explicitly requested, -if it has dependencies, and if there are hints or warnings for it. - -=head2 --list-unsupported - -Lists the API elements that are known not to be supported by -F and below which version of Perl they probably -won't be available or work. - -=head2 --api-info=I - -Show portability information for API elements matching I. -If I is surrounded by slashes, it is interpreted as a regular -expression. - -=head1 DESCRIPTION - -In order for a Perl extension (XS) module to be as portable as possible -across differing versions of Perl itself, certain steps need to be taken. - -=over 4 - -=item * - -Including this header is the first major one. This alone will give you -access to a large part of the Perl API that hasn't been available in -earlier Perl releases. Use - - perl ppport.h --list-provided - -to see which API elements are provided by ppport.h. - -=item * - -You should avoid using deprecated parts of the API. For example, using -global Perl variables without the C prefix is deprecated. Also, -some API functions used to have a C prefix. Using this form is -also deprecated. You can safely use the supported API, as F -will provide wrappers for older Perl versions. - -=item * - -If you use one of a few functions or variables that were not present in -earlier versions of Perl, and that can't be provided using a macro, you -have to explicitly request support for these functions by adding one or -more C<#define>s in your source code before the inclusion of F. - -These functions or variables will be marked C in the list shown -by C<--list-provided>. - -Depending on whether you module has a single or multiple files that -use such functions or variables, you want either C or global -variants. - -For a C function or variable (used only in a single source -file), use: - - #define NEED_function - #define NEED_variable - -For a global function or variable (used in multiple source files), -use: - - #define NEED_function_GLOBAL - #define NEED_variable_GLOBAL - -Note that you mustn't have more than one global request for the -same function or variable in your project. - - Function / Variable Static Request Global Request - ----------------------------------------------------------------------------------------- - PL_parser NEED_PL_parser NEED_PL_parser_GLOBAL - PL_signals NEED_PL_signals NEED_PL_signals_GLOBAL - caller_cx() NEED_caller_cx NEED_caller_cx_GLOBAL - eval_pv() NEED_eval_pv NEED_eval_pv_GLOBAL - grok_bin() NEED_grok_bin NEED_grok_bin_GLOBAL - grok_hex() NEED_grok_hex NEED_grok_hex_GLOBAL - grok_number() NEED_grok_number NEED_grok_number_GLOBAL - grok_numeric_radix() NEED_grok_numeric_radix NEED_grok_numeric_radix_GLOBAL - grok_oct() NEED_grok_oct NEED_grok_oct_GLOBAL - load_module() NEED_load_module NEED_load_module_GLOBAL - mg_findext() NEED_mg_findext NEED_mg_findext_GLOBAL - my_snprintf() NEED_my_snprintf NEED_my_snprintf_GLOBAL - my_sprintf() NEED_my_sprintf NEED_my_sprintf_GLOBAL - my_strlcat() NEED_my_strlcat NEED_my_strlcat_GLOBAL - my_strlcpy() NEED_my_strlcpy NEED_my_strlcpy_GLOBAL - newCONSTSUB() NEED_newCONSTSUB NEED_newCONSTSUB_GLOBAL - newRV_noinc() NEED_newRV_noinc NEED_newRV_noinc_GLOBAL - newSV_type() NEED_newSV_type NEED_newSV_type_GLOBAL - newSVpvn_flags() NEED_newSVpvn_flags NEED_newSVpvn_flags_GLOBAL - newSVpvn_share() NEED_newSVpvn_share NEED_newSVpvn_share_GLOBAL - pv_display() NEED_pv_display NEED_pv_display_GLOBAL - pv_escape() NEED_pv_escape NEED_pv_escape_GLOBAL - pv_pretty() NEED_pv_pretty NEED_pv_pretty_GLOBAL - sv_2pv_flags() NEED_sv_2pv_flags NEED_sv_2pv_flags_GLOBAL - sv_2pvbyte() NEED_sv_2pvbyte NEED_sv_2pvbyte_GLOBAL - sv_catpvf_mg() NEED_sv_catpvf_mg NEED_sv_catpvf_mg_GLOBAL - sv_catpvf_mg_nocontext() NEED_sv_catpvf_mg_nocontext NEED_sv_catpvf_mg_nocontext_GLOBAL - sv_pvn_force_flags() NEED_sv_pvn_force_flags NEED_sv_pvn_force_flags_GLOBAL - sv_setpvf_mg() NEED_sv_setpvf_mg NEED_sv_setpvf_mg_GLOBAL - sv_setpvf_mg_nocontext() NEED_sv_setpvf_mg_nocontext NEED_sv_setpvf_mg_nocontext_GLOBAL - sv_unmagicext() NEED_sv_unmagicext NEED_sv_unmagicext_GLOBAL - vload_module() NEED_vload_module NEED_vload_module_GLOBAL - vnewSVpvf() NEED_vnewSVpvf NEED_vnewSVpvf_GLOBAL - warner() NEED_warner NEED_warner_GLOBAL - -To avoid namespace conflicts, you can change the namespace of the -explicitly exported functions / variables using the C -macro. Just C<#define> the macro before including C: - - #define DPPP_NAMESPACE MyOwnNamespace_ - #include "ppport.h" - -The default namespace is C. - -=back - -The good thing is that most of the above can be checked by running -F on your source code. See the next section for -details. - -=head1 EXAMPLES - -To verify whether F is needed for your module, whether you -should make any changes to your code, and whether any special defines -should be used, F can be run as a Perl script to check your -source code. Simply say: - - perl ppport.h - -The result will usually be a list of patches suggesting changes -that should at least be acceptable, if not necessarily the most -efficient solution, or a fix for all possible problems. - -If you know that your XS module uses features only available in -newer Perl releases, if you're aware that it uses C++ comments, -and if you want all suggestions as a single patch file, you could -use something like this: - - perl ppport.h --compat-version=5.6.0 --cplusplus --patch=test.diff - -If you only want your code to be scanned without any suggestions -for changes, use: - - perl ppport.h --nochanges - -You can specify a different C program or options, using -the C<--diff> option: - - perl ppport.h --diff='diff -C 10' - -This would output context diffs with 10 lines of context. - -If you want to create patched copies of your files instead, use: - - perl ppport.h --copy=.new - -To display portability information for the C function, -use: - - perl ppport.h --api-info=newSVpvn - -Since the argument to C<--api-info> can be a regular expression, -you can use - - perl ppport.h --api-info=/_nomg$/ - -to display portability information for all C<_nomg> functions or - - perl ppport.h --api-info=/./ - -to display information for all known API elements. - -=head1 BUGS - -If this version of F is causing failure during -the compilation of this module, please check if newer versions -of either this module or C are available on CPAN -before sending a bug report. - -If F was generated using the latest version of -C and is causing failure of this module, please -file a bug report here: L - -Please include the following information: - -=over 4 - -=item 1. - -The complete output from running "perl -V" - -=item 2. - -This file. - -=item 3. - -The name and version of the module you were trying to build. - -=item 4. - -A full log of the build that failed. - -=item 5. - -Any other information that you think could be relevant. - -=back - -For the latest version of this code, please get the C -module from CPAN. - -=head1 COPYRIGHT - -Version 3.x, Copyright (c) 2004-2013, Marcus Holland-Moritz. - -Version 2.x, Copyright (C) 2001, Paul Marquess. - -Version 1.x, Copyright (C) 1999, Kenneth Albanowski. - -This program is free software; you can redistribute it and/or -modify it under the same terms as Perl itself. - -=head1 SEE ALSO - -See L. - -=cut - -use strict; - -# Disable broken TRIE-optimization -BEGIN { eval '${^RE_TRIE_MAXBUF} = -1' if $] >= 5.009004 && $] <= 5.009005 } - -my $VERSION = 3.31; - -my %opt = ( - quiet => 0, - diag => 1, - hints => 1, - changes => 1, - cplusplus => 0, - filter => 1, - strip => 0, - version => 0, -); - -my($ppport) = $0 =~ /([\w.]+)$/; -my $LF = '(?:\r\n|[\r\n])'; # line feed -my $HS = "[ \t]"; # horizontal whitespace - -# Never use C comments in this file! -my $ccs = '/'.'*'; -my $cce = '*'.'/'; -my $rccs = quotemeta $ccs; -my $rcce = quotemeta $cce; - -eval { - require Getopt::Long; - Getopt::Long::GetOptions(\%opt, qw( - help quiet diag! filter! hints! changes! cplusplus strip version - patch=s copy=s diff=s compat-version=s - list-provided list-unsupported api-info=s - )) or usage(); -}; - -if ($@ and grep /^-/, @ARGV) { - usage() if "@ARGV" =~ /^--?h(?:elp)?$/; - die "Getopt::Long not found. Please don't use any options.\n"; -} - -if ($opt{version}) { - print "This is $0 $VERSION.\n"; - exit 0; -} - -usage() if $opt{help}; -strip() if $opt{strip}; - -if (exists $opt{'compat-version'}) { - my($r,$v,$s) = eval { parse_version($opt{'compat-version'}) }; - if ($@) { - die "Invalid version number format: '$opt{'compat-version'}'\n"; - } - die "Only Perl 5 is supported\n" if $r != 5; - die "Invalid version number: $opt{'compat-version'}\n" if $v >= 1000 || $s >= 1000; - $opt{'compat-version'} = sprintf "%d.%03d%03d", $r, $v, $s; -} -else { - $opt{'compat-version'} = 5; -} - -my %API = map { /^(\w+)\|([^|]*)\|([^|]*)\|(\w*)$/ - ? ( $1 => { - ($2 ? ( base => $2 ) : ()), - ($3 ? ( todo => $3 ) : ()), - (index($4, 'v') >= 0 ? ( varargs => 1 ) : ()), - (index($4, 'p') >= 0 ? ( provided => 1 ) : ()), - (index($4, 'n') >= 0 ? ( nothxarg => 1 ) : ()), - } ) - : die "invalid spec: $_" } qw( -ASCII_TO_NEED||5.007001|n -AvFILLp|5.004050||p -AvFILL||| -BhkDISABLE||5.021008| -BhkENABLE||5.021008| -BhkENTRY_set||5.021008| -BhkENTRY||| -BhkFLAGS||| -CALL_BLOCK_HOOKS||| -CLASS|||n -CPERLscope|5.005000||p -CX_CURPAD_SAVE||| -CX_CURPAD_SV||| -CopFILEAV|5.006000||p -CopFILEGV_set|5.006000||p -CopFILEGV|5.006000||p -CopFILESV|5.006000||p -CopFILE_set|5.006000||p -CopFILE|5.006000||p -CopSTASHPV_set|5.006000||p -CopSTASHPV|5.006000||p -CopSTASH_eq|5.006000||p -CopSTASH_set|5.006000||p -CopSTASH|5.006000||p -CopyD|5.009002|5.004050|p -Copy||| -CvPADLIST||5.008001| -CvSTASH||| -CvWEAKOUTSIDE||| -DEFSV_set|5.010001||p -DEFSV|5.004050||p -END_EXTERN_C|5.005000||p -ENTER||| -ERRSV|5.004050||p -EXTEND||| -EXTERN_C|5.005000||p -F0convert|||n -FREETMPS||| -GIMME_V||5.004000|n -GIMME|||n -GROK_NUMERIC_RADIX|5.007002||p -G_ARRAY||| -G_DISCARD||| -G_EVAL||| -G_METHOD|5.006001||p -G_NOARGS||| -G_SCALAR||| -G_VOID||5.004000| -GetVars||| -GvAV||| -GvCV||| -GvHV||| -GvSVn|5.009003||p -GvSV||| -Gv_AMupdate||5.011000| -HEf_SVKEY|5.003070||p -HeHASH||5.003070| -HeKEY||5.003070| -HeKLEN||5.003070| -HePV||5.004000| -HeSVKEY_force||5.003070| -HeSVKEY_set||5.004000| -HeSVKEY||5.003070| -HeUTF8|5.010001|5.008000|p -HeVAL||5.003070| -HvENAMELEN||5.015004| -HvENAMEUTF8||5.015004| -HvENAME||5.013007| -HvNAMELEN_get|5.009003||p -HvNAMELEN||5.015004| -HvNAMEUTF8||5.015004| -HvNAME_get|5.009003||p -HvNAME||| -INT2PTR|5.006000||p -IN_LOCALE_COMPILETIME|5.007002||p -IN_LOCALE_RUNTIME|5.007002||p -IN_LOCALE|5.007002||p -IN_PERL_COMPILETIME|5.008001||p -IS_NUMBER_GREATER_THAN_UV_MAX|5.007002||p -IS_NUMBER_INFINITY|5.007002||p -IS_NUMBER_IN_UV|5.007002||p -IS_NUMBER_NAN|5.007003||p -IS_NUMBER_NEG|5.007002||p -IS_NUMBER_NOT_INT|5.007002||p -IVSIZE|5.006000||p -IVTYPE|5.006000||p -IVdf|5.006000||p -LEAVE||| -LINKLIST||5.013006| -LVRET||| -MARK||| -MULTICALL||5.021008| -MUTABLE_PTR|5.010001||p -MUTABLE_SV|5.010001||p -MY_CXT_CLONE|5.009002||p -MY_CXT_INIT|5.007003||p -MY_CXT|5.007003||p -MoveD|5.009002|5.004050|p -Move||| -NATIVE_TO_NEED||5.007001|n -NOOP|5.005000||p -NUM2PTR|5.006000||p -NVTYPE|5.006000||p -NVef|5.006001||p -NVff|5.006001||p -NVgf|5.006001||p -Newxc|5.009003||p -Newxz|5.009003||p -Newx|5.009003||p -Nullav||| -Nullch||| -Nullcv||| -Nullhv||| -Nullsv||| -OP_CLASS||5.013007| -OP_DESC||5.007003| -OP_NAME||5.007003| -OP_TYPE_IS_OR_WAS||5.019010| -OP_TYPE_IS||5.019007| -ORIGMARK||| -OpHAS_SIBLING||5.021007| -OpSIBLING_set||5.021007| -OpSIBLING||5.021007| -PAD_BASE_SV||| -PAD_CLONE_VARS||| -PAD_COMPNAME_FLAGS||| -PAD_COMPNAME_GEN_set||| -PAD_COMPNAME_GEN||| -PAD_COMPNAME_OURSTASH||| -PAD_COMPNAME_PV||| -PAD_COMPNAME_TYPE||| -PAD_RESTORE_LOCAL||| -PAD_SAVE_LOCAL||| -PAD_SAVE_SETNULLPAD||| -PAD_SETSV||| -PAD_SET_CUR_NOSAVE||| -PAD_SET_CUR||| -PAD_SVl||| -PAD_SV||| -PERLIO_FUNCS_CAST|5.009003||p -PERLIO_FUNCS_DECL|5.009003||p -PERL_ABS|5.008001||p -PERL_BCDVERSION|5.021008||p -PERL_GCC_BRACE_GROUPS_FORBIDDEN|5.008001||p -PERL_HASH|5.003070||p -PERL_INT_MAX|5.003070||p -PERL_INT_MIN|5.003070||p -PERL_LONG_MAX|5.003070||p -PERL_LONG_MIN|5.003070||p -PERL_MAGIC_arylen|5.007002||p -PERL_MAGIC_backref|5.007002||p -PERL_MAGIC_bm|5.007002||p -PERL_MAGIC_collxfrm|5.007002||p -PERL_MAGIC_dbfile|5.007002||p -PERL_MAGIC_dbline|5.007002||p -PERL_MAGIC_defelem|5.007002||p -PERL_MAGIC_envelem|5.007002||p -PERL_MAGIC_env|5.007002||p -PERL_MAGIC_ext|5.007002||p -PERL_MAGIC_fm|5.007002||p -PERL_MAGIC_glob|5.021008||p -PERL_MAGIC_isaelem|5.007002||p -PERL_MAGIC_isa|5.007002||p -PERL_MAGIC_mutex|5.021008||p -PERL_MAGIC_nkeys|5.007002||p -PERL_MAGIC_overload_elem|5.021008||p -PERL_MAGIC_overload_table|5.007002||p -PERL_MAGIC_overload|5.021008||p -PERL_MAGIC_pos|5.007002||p -PERL_MAGIC_qr|5.007002||p -PERL_MAGIC_regdata|5.007002||p -PERL_MAGIC_regdatum|5.007002||p -PERL_MAGIC_regex_global|5.007002||p -PERL_MAGIC_shared_scalar|5.007003||p -PERL_MAGIC_shared|5.007003||p -PERL_MAGIC_sigelem|5.007002||p -PERL_MAGIC_sig|5.007002||p -PERL_MAGIC_substr|5.007002||p -PERL_MAGIC_sv|5.007002||p -PERL_MAGIC_taint|5.007002||p -PERL_MAGIC_tiedelem|5.007002||p -PERL_MAGIC_tiedscalar|5.007002||p -PERL_MAGIC_tied|5.007002||p -PERL_MAGIC_utf8|5.008001||p -PERL_MAGIC_uvar_elem|5.007003||p -PERL_MAGIC_uvar|5.007002||p -PERL_MAGIC_vec|5.007002||p -PERL_MAGIC_vstring|5.008001||p -PERL_PV_ESCAPE_ALL|5.009004||p -PERL_PV_ESCAPE_FIRSTCHAR|5.009004||p -PERL_PV_ESCAPE_NOBACKSLASH|5.009004||p -PERL_PV_ESCAPE_NOCLEAR|5.009004||p -PERL_PV_ESCAPE_QUOTE|5.009004||p -PERL_PV_ESCAPE_RE|5.009005||p -PERL_PV_ESCAPE_UNI_DETECT|5.009004||p -PERL_PV_ESCAPE_UNI|5.009004||p -PERL_PV_PRETTY_DUMP|5.009004||p -PERL_PV_PRETTY_ELLIPSES|5.010000||p -PERL_PV_PRETTY_LTGT|5.009004||p -PERL_PV_PRETTY_NOCLEAR|5.010000||p -PERL_PV_PRETTY_QUOTE|5.009004||p -PERL_PV_PRETTY_REGPROP|5.009004||p -PERL_QUAD_MAX|5.003070||p -PERL_QUAD_MIN|5.003070||p -PERL_REVISION|5.006000||p -PERL_SCAN_ALLOW_UNDERSCORES|5.007003||p -PERL_SCAN_DISALLOW_PREFIX|5.007003||p -PERL_SCAN_GREATER_THAN_UV_MAX|5.007003||p -PERL_SCAN_SILENT_ILLDIGIT|5.008001||p -PERL_SHORT_MAX|5.003070||p -PERL_SHORT_MIN|5.003070||p -PERL_SIGNALS_UNSAFE_FLAG|5.008001||p -PERL_SUBVERSION|5.006000||p -PERL_SYS_INIT3||5.006000| -PERL_SYS_INIT||| -PERL_SYS_TERM||5.021008| -PERL_UCHAR_MAX|5.003070||p -PERL_UCHAR_MIN|5.003070||p -PERL_UINT_MAX|5.003070||p -PERL_UINT_MIN|5.003070||p -PERL_ULONG_MAX|5.003070||p -PERL_ULONG_MIN|5.003070||p -PERL_UNUSED_ARG|5.009003||p -PERL_UNUSED_CONTEXT|5.009004||p -PERL_UNUSED_DECL|5.007002||p -PERL_UNUSED_VAR|5.007002||p -PERL_UQUAD_MAX|5.003070||p -PERL_UQUAD_MIN|5.003070||p -PERL_USE_GCC_BRACE_GROUPS|5.009004||p -PERL_USHORT_MAX|5.003070||p -PERL_USHORT_MIN|5.003070||p -PERL_VERSION|5.006000||p -PL_DBsignal|5.005000||p -PL_DBsingle|||pn -PL_DBsub|||pn -PL_DBtrace|||pn -PL_Sv|5.005000||p -PL_bufend|5.021008||p -PL_bufptr|5.021008||p -PL_check||5.006000| -PL_compiling|5.004050||p -PL_comppad_name||5.017004| -PL_comppad||5.008001| -PL_copline|5.021008||p -PL_curcop|5.004050||p -PL_curpad||5.005000| -PL_curstash|5.004050||p -PL_debstash|5.004050||p -PL_defgv|5.004050||p -PL_diehook|5.004050||p -PL_dirty|5.004050||p -PL_dowarn|||pn -PL_errgv|5.004050||p -PL_error_count|5.021008||p -PL_expect|5.021008||p -PL_hexdigit|5.005000||p -PL_hints|5.005000||p -PL_in_my_stash|5.021008||p -PL_in_my|5.021008||p -PL_keyword_plugin||5.011002| -PL_last_in_gv|||n -PL_laststatval|5.005000||p -PL_lex_state|5.021008||p -PL_lex_stuff|5.021008||p -PL_linestr|5.021008||p -PL_modglobal||5.005000|n -PL_na|5.004050||pn -PL_no_modify|5.006000||p -PL_ofsgv|||n -PL_opfreehook||5.011000|n -PL_parser|5.009005||p -PL_peepp||5.007003|n -PL_perl_destruct_level|5.004050||p -PL_perldb|5.004050||p -PL_ppaddr|5.006000||p -PL_rpeepp||5.013005|n -PL_rsfp_filters|5.021008||p -PL_rsfp|5.021008||p -PL_rs|||n -PL_signals|5.008001||p -PL_stack_base|5.004050||p -PL_stack_sp|5.004050||p -PL_statcache|5.005000||p -PL_stdingv|5.004050||p -PL_sv_arenaroot|5.004050||p -PL_sv_no|5.004050||pn -PL_sv_undef|5.004050||pn -PL_sv_yes|5.004050||pn -PL_tainted|5.004050||p -PL_tainting|5.004050||p -PL_tokenbuf|5.021008||p -POP_MULTICALL||5.021008| -POPi|||n -POPl|||n -POPn|||n -POPpbytex||5.007001|n -POPpx||5.005030|n -POPp|||n -POPs|||n -PTR2IV|5.006000||p -PTR2NV|5.006000||p -PTR2UV|5.006000||p -PTR2nat|5.009003||p -PTR2ul|5.007001||p -PTRV|5.006000||p -PUSHMARK||| -PUSH_MULTICALL||5.021008| -PUSHi||| -PUSHmortal|5.009002||p -PUSHn||| -PUSHp||| -PUSHs||| -PUSHu|5.004000||p -PUTBACK||| -PadARRAY||5.021008| -PadMAX||5.021008| -PadlistARRAY||5.021008| -PadlistMAX||5.021008| -PadlistNAMESARRAY||5.021008| -PadlistNAMESMAX||5.021008| -PadlistNAMES||5.021008| -PadlistREFCNT||5.017004| -PadnameIsOUR||| -PadnameIsSTATE||| -PadnameLEN||5.021008| -PadnameOURSTASH||| -PadnameOUTER||| -PadnamePV||5.021008| -PadnameREFCNT_dec||5.021008| -PadnameREFCNT||5.021008| -PadnameSV||5.021008| -PadnameTYPE||| -PadnameUTF8||5.021007| -PadnamelistARRAY||5.021008| -PadnamelistMAX||5.021008| -PadnamelistREFCNT_dec||5.021008| -PadnamelistREFCNT||5.021008| -PerlIO_clearerr||5.007003| -PerlIO_close||5.007003| -PerlIO_context_layers||5.009004| -PerlIO_eof||5.007003| -PerlIO_error||5.007003| -PerlIO_fileno||5.007003| -PerlIO_fill||5.007003| -PerlIO_flush||5.007003| -PerlIO_get_base||5.007003| -PerlIO_get_bufsiz||5.007003| -PerlIO_get_cnt||5.007003| -PerlIO_get_ptr||5.007003| -PerlIO_read||5.007003| -PerlIO_restore_errno||| -PerlIO_save_errno||| -PerlIO_seek||5.007003| -PerlIO_set_cnt||5.007003| -PerlIO_set_ptrcnt||5.007003| -PerlIO_setlinebuf||5.007003| -PerlIO_stderr||5.007003| -PerlIO_stdin||5.007003| -PerlIO_stdout||5.007003| -PerlIO_tell||5.007003| -PerlIO_unread||5.007003| -PerlIO_write||5.007003| -Perl_signbit||5.009005|n -PoisonFree|5.009004||p -PoisonNew|5.009004||p -PoisonWith|5.009004||p -Poison|5.008000||p -READ_XDIGIT||5.017006| -RETVAL|||n -Renewc||| -Renew||| -SAVECLEARSV||| -SAVECOMPPAD||| -SAVEPADSV||| -SAVETMPS||| -SAVE_DEFSV|5.004050||p -SPAGAIN||| -SP||| -START_EXTERN_C|5.005000||p -START_MY_CXT|5.007003||p -STMT_END|||p -STMT_START|||p -STR_WITH_LEN|5.009003||p -ST||| -SV_CONST_RETURN|5.009003||p -SV_COW_DROP_PV|5.008001||p -SV_COW_SHARED_HASH_KEYS|5.009005||p -SV_GMAGIC|5.007002||p -SV_HAS_TRAILING_NUL|5.009004||p -SV_IMMEDIATE_UNREF|5.007001||p -SV_MUTABLE_RETURN|5.009003||p -SV_NOSTEAL|5.009002||p -SV_SMAGIC|5.009003||p -SV_UTF8_NO_ENCODING|5.008001||p -SVfARG|5.009005||p -SVf_UTF8|5.006000||p -SVf|5.006000||p -SVt_INVLIST||5.019002| -SVt_IV||| -SVt_NULL||| -SVt_NV||| -SVt_PVAV||| -SVt_PVCV||| -SVt_PVFM||| -SVt_PVGV||| -SVt_PVHV||| -SVt_PVIO||| -SVt_PVIV||| -SVt_PVLV||| -SVt_PVMG||| -SVt_PVNV||| -SVt_PV||| -SVt_REGEXP||5.011000| -Safefree||| -Slab_Alloc||| -Slab_Free||| -Slab_to_ro||| -Slab_to_rw||| -StructCopy||| -SvCUR_set||| -SvCUR||| -SvEND||| -SvGAMAGIC||5.006001| -SvGETMAGIC|5.004050||p -SvGROW||| -SvIOK_UV||5.006000| -SvIOK_notUV||5.006000| -SvIOK_off||| -SvIOK_only_UV||5.006000| -SvIOK_only||| -SvIOK_on||| -SvIOKp||| -SvIOK||| -SvIVX||| -SvIV_nomg|5.009001||p -SvIV_set||| -SvIVx||| -SvIV||| -SvIsCOW_shared_hash||5.008003| -SvIsCOW||5.008003| -SvLEN_set||| -SvLEN||| -SvLOCK||5.007003| -SvMAGIC_set|5.009003||p -SvNIOK_off||| -SvNIOKp||| -SvNIOK||| -SvNOK_off||| -SvNOK_only||| -SvNOK_on||| -SvNOKp||| -SvNOK||| -SvNVX||| -SvNV_nomg||5.013002| -SvNV_set||| -SvNVx||| -SvNV||| -SvOK||| -SvOOK_offset||5.011000| -SvOOK||| -SvPOK_off||| -SvPOK_only_UTF8||5.006000| -SvPOK_only||| -SvPOK_on||| -SvPOKp||| -SvPOK||| -SvPVX_const|5.009003||p -SvPVX_mutable|5.009003||p -SvPVX||| -SvPV_const|5.009003||p -SvPV_flags_const_nolen|5.009003||p -SvPV_flags_const|5.009003||p -SvPV_flags_mutable|5.009003||p -SvPV_flags|5.007002||p -SvPV_force_flags_mutable|5.009003||p -SvPV_force_flags_nolen|5.009003||p -SvPV_force_flags|5.007002||p -SvPV_force_mutable|5.009003||p -SvPV_force_nolen|5.009003||p -SvPV_force_nomg_nolen|5.009003||p -SvPV_force_nomg|5.007002||p -SvPV_force|||p -SvPV_mutable|5.009003||p -SvPV_nolen_const|5.009003||p -SvPV_nolen|5.006000||p -SvPV_nomg_const_nolen|5.009003||p -SvPV_nomg_const|5.009003||p -SvPV_nomg_nolen|5.013007||p -SvPV_nomg|5.007002||p -SvPV_renew|5.009003||p -SvPV_set||| -SvPVbyte_force||5.009002| -SvPVbyte_nolen||5.006000| -SvPVbytex_force||5.006000| -SvPVbytex||5.006000| -SvPVbyte|5.006000||p -SvPVutf8_force||5.006000| -SvPVutf8_nolen||5.006000| -SvPVutf8x_force||5.006000| -SvPVutf8x||5.006000| -SvPVutf8||5.006000| -SvPVx||| -SvPV||| -SvREFCNT_dec_NN||5.017007| -SvREFCNT_dec||| -SvREFCNT_inc_NN|5.009004||p -SvREFCNT_inc_simple_NN|5.009004||p -SvREFCNT_inc_simple_void_NN|5.009004||p -SvREFCNT_inc_simple_void|5.009004||p -SvREFCNT_inc_simple|5.009004||p -SvREFCNT_inc_void_NN|5.009004||p -SvREFCNT_inc_void|5.009004||p -SvREFCNT_inc|||p -SvREFCNT||| -SvROK_off||| -SvROK_on||| -SvROK||| -SvRV_set|5.009003||p -SvRV||| -SvRXOK||5.009005| -SvRX||5.009005| -SvSETMAGIC||| -SvSHARED_HASH|5.009003||p -SvSHARE||5.007003| -SvSTASH_set|5.009003||p -SvSTASH||| -SvSetMagicSV_nosteal||5.004000| -SvSetMagicSV||5.004000| -SvSetSV_nosteal||5.004000| -SvSetSV||| -SvTAINTED_off||5.004000| -SvTAINTED_on||5.004000| -SvTAINTED||5.004000| -SvTAINT||| -SvTHINKFIRST||| -SvTRUE_nomg||5.013006| -SvTRUE||| -SvTYPE||| -SvUNLOCK||5.007003| -SvUOK|5.007001|5.006000|p -SvUPGRADE||| -SvUTF8_off||5.006000| -SvUTF8_on||5.006000| -SvUTF8||5.006000| -SvUVXx|5.004000||p -SvUVX|5.004000||p -SvUV_nomg|5.009001||p -SvUV_set|5.009003||p -SvUVx|5.004000||p -SvUV|5.004000||p -SvVOK||5.008001| -SvVSTRING_mg|5.009004||p -THIS|||n -UNDERBAR|5.009002||p -UTF8_MAXBYTES|5.009002||p -UVSIZE|5.006000||p -UVTYPE|5.006000||p -UVXf|5.007001||p -UVof|5.006000||p -UVuf|5.006000||p -UVxf|5.006000||p -WARN_ALL|5.006000||p -WARN_AMBIGUOUS|5.006000||p -WARN_ASSERTIONS|5.021008||p -WARN_BAREWORD|5.006000||p -WARN_CLOSED|5.006000||p -WARN_CLOSURE|5.006000||p -WARN_DEBUGGING|5.006000||p -WARN_DEPRECATED|5.006000||p -WARN_DIGIT|5.006000||p -WARN_EXEC|5.006000||p -WARN_EXITING|5.006000||p -WARN_GLOB|5.006000||p -WARN_INPLACE|5.006000||p -WARN_INTERNAL|5.006000||p -WARN_IO|5.006000||p -WARN_LAYER|5.008000||p -WARN_MALLOC|5.006000||p -WARN_MISC|5.006000||p -WARN_NEWLINE|5.006000||p -WARN_NUMERIC|5.006000||p -WARN_ONCE|5.006000||p -WARN_OVERFLOW|5.006000||p -WARN_PACK|5.006000||p -WARN_PARENTHESIS|5.006000||p -WARN_PIPE|5.006000||p -WARN_PORTABLE|5.006000||p -WARN_PRECEDENCE|5.006000||p -WARN_PRINTF|5.006000||p -WARN_PROTOTYPE|5.006000||p -WARN_QW|5.006000||p -WARN_RECURSION|5.006000||p -WARN_REDEFINE|5.006000||p -WARN_REGEXP|5.006000||p -WARN_RESERVED|5.006000||p -WARN_SEMICOLON|5.006000||p -WARN_SEVERE|5.006000||p -WARN_SIGNAL|5.006000||p -WARN_SUBSTR|5.006000||p -WARN_SYNTAX|5.006000||p -WARN_TAINT|5.006000||p -WARN_THREADS|5.008000||p -WARN_UNINITIALIZED|5.006000||p -WARN_UNOPENED|5.006000||p -WARN_UNPACK|5.006000||p -WARN_UNTIE|5.006000||p -WARN_UTF8|5.006000||p -WARN_VOID|5.006000||p -WIDEST_UTYPE|5.015004||p -XCPT_CATCH|5.009002||p -XCPT_RETHROW|5.009002||p -XCPT_TRY_END|5.009002||p -XCPT_TRY_START|5.009002||p -XPUSHi||| -XPUSHmortal|5.009002||p -XPUSHn||| -XPUSHp||| -XPUSHs||| -XPUSHu|5.004000||p -XSPROTO|5.010000||p -XSRETURN_EMPTY||| -XSRETURN_IV||| -XSRETURN_NO||| -XSRETURN_NV||| -XSRETURN_PV||| -XSRETURN_UNDEF||| -XSRETURN_UV|5.008001||p -XSRETURN_YES||| -XSRETURN|||p -XST_mIV||| -XST_mNO||| -XST_mNV||| -XST_mPV||| -XST_mUNDEF||| -XST_mUV|5.008001||p -XST_mYES||| -XS_APIVERSION_BOOTCHECK||5.021008| -XS_EXTERNAL||5.021008| -XS_INTERNAL||5.021008| -XS_VERSION_BOOTCHECK||5.021008| -XS_VERSION||| -XSprePUSH|5.006000||p -XS||| -XopDISABLE||5.021008| -XopENABLE||5.021008| -XopENTRYCUSTOM||5.021008| -XopENTRY_set||5.021008| -XopENTRY||5.021008| -XopFLAGS||5.013007| -ZeroD|5.009002||p -Zero||| -_aMY_CXT|5.007003||p -_add_range_to_invlist||| -_append_range_to_invlist||| -_core_swash_init||| -_get_encoding||| -_get_regclass_nonbitmap_data||| -_get_swash_invlist||| -_invlist_array_init|||n -_invlist_contains_cp|||n -_invlist_contents||| -_invlist_dump||| -_invlist_intersection_maybe_complement_2nd||| -_invlist_intersection||| -_invlist_invert||| -_invlist_len|||n -_invlist_populate_swatch|||n -_invlist_search|||n -_invlist_subtract||| -_invlist_union_maybe_complement_2nd||| -_invlist_union||| -_is_cur_LC_category_utf8||| -_is_in_locale_category||5.021001| -_is_uni_FOO||5.017008| -_is_uni_perl_idcont||5.017008| -_is_uni_perl_idstart||5.017007| -_is_utf8_FOO||5.017008| -_is_utf8_char_slow||5.021001|n -_is_utf8_idcont||5.021001| -_is_utf8_idstart||5.021001| -_is_utf8_mark||5.017008| -_is_utf8_perl_idcont||5.017008| -_is_utf8_perl_idstart||5.017007| -_is_utf8_xidcont||5.021001| -_is_utf8_xidstart||5.021001| -_load_PL_utf8_foldclosures||| -_make_exactf_invlist||| -_new_invlist_C_array||| -_new_invlist||| -_pMY_CXT|5.007003||p -_setup_canned_invlist||| -_swash_inversion_hash||| -_swash_to_invlist||| -_to_fold_latin1||| -_to_uni_fold_flags||5.014000| -_to_upper_title_latin1||| -_to_utf8_fold_flags||5.019009| -_to_utf8_lower_flags||5.019009| -_to_utf8_title_flags||5.019009| -_to_utf8_upper_flags||5.019009| -_warn_problematic_locale|||n -aMY_CXT_|5.007003||p -aMY_CXT|5.007003||p -aTHXR_|5.021008||p -aTHXR|5.021008||p -aTHX_|5.006000||p -aTHX|5.006000||p -aassign_common_vars||| -add_above_Latin1_folds||| -add_cp_to_invlist||| -add_data|||n -add_multi_match||| -add_utf16_textfilter||| -adjust_size_and_find_bucket|||n -advance_one_SB||| -advance_one_WB||| -alloc_maybe_populate_EXACT||| -alloccopstash||| -allocmy||| -amagic_call||| -amagic_cmp_locale||| -amagic_cmp||| -amagic_deref_call||5.013007| -amagic_i_ncmp||| -amagic_is_enabled||| -amagic_ncmp||| -anonymise_cv_maybe||| -any_dup||| -ao||| -append_utf8_from_native_byte||5.019004|n -apply_attrs_my||| -apply_attrs_string||5.006001| -apply_attrs||| -apply||| -assert_uft8_cache_coherent||| -assignment_type||| -atfork_lock||5.007003|n -atfork_unlock||5.007003|n -av_arylen_p||5.009003| -av_clear||| -av_create_and_push||5.009005| -av_create_and_unshift_one||5.009005| -av_delete||5.006000| -av_exists||5.006000| -av_extend_guts||| -av_extend||| -av_fetch||| -av_fill||| -av_iter_p||5.011000| -av_len||| -av_make||| -av_pop||| -av_push||| -av_reify||| -av_shift||| -av_store||| -av_tindex||5.017009| -av_top_index||5.017009| -av_undef||| -av_unshift||| -ax|||n -backup_one_SB||| -backup_one_WB||| -bad_type_gv||| -bad_type_pv||| -bind_match||| -block_end||5.004000| -block_gimme||5.004000| -block_start||5.004000| -blockhook_register||5.013003| -boolSV|5.004000||p -boot_core_PerlIO||| -boot_core_UNIVERSAL||| -boot_core_mro||| -bytes_cmp_utf8||5.013007| -bytes_from_utf8||5.007001| -bytes_to_utf8||5.006001| -call_argv|5.006000||p -call_atexit||5.006000| -call_list||5.004000| -call_method|5.006000||p -call_pv|5.006000||p -call_sv|5.006000||p -caller_cx|5.013005|5.006000|p -calloc||5.007002|n -cando||| -cast_i32||5.006000|n -cast_iv||5.006000|n -cast_ulong||5.006000|n -cast_uv||5.006000|n -check_locale_boundary_crossing||| -check_type_and_open||| -check_uni||| -check_utf8_print||| -checkcomma||| -ckWARN|5.006000||p -ck_entersub_args_core||| -ck_entersub_args_list||5.013006| -ck_entersub_args_proto_or_list||5.013006| -ck_entersub_args_proto||5.013006| -ck_warner_d||5.011001|v -ck_warner||5.011001|v -ckwarn_common||| -ckwarn_d||5.009003| -ckwarn||5.009003| -clear_placeholders||| -clear_special_blocks||| -clone_params_del|||n -clone_params_new|||n -closest_cop||| -cntrl_to_mnemonic|||n -compute_EXACTish|||n -construct_ahocorasick_from_trie||| -cop_fetch_label||5.015001| -cop_free||| -cop_hints_2hv||5.013007| -cop_hints_fetch_pvn||5.013007| -cop_hints_fetch_pvs||5.013007| -cop_hints_fetch_pv||5.013007| -cop_hints_fetch_sv||5.013007| -cop_store_label||5.015001| -cophh_2hv||5.013007| -cophh_copy||5.013007| -cophh_delete_pvn||5.013007| -cophh_delete_pvs||5.013007| -cophh_delete_pv||5.013007| -cophh_delete_sv||5.013007| -cophh_fetch_pvn||5.013007| -cophh_fetch_pvs||5.013007| -cophh_fetch_pv||5.013007| -cophh_fetch_sv||5.013007| -cophh_free||5.013007| -cophh_new_empty||5.021008| -cophh_store_pvn||5.013007| -cophh_store_pvs||5.013007| -cophh_store_pv||5.013007| -cophh_store_sv||5.013007| -core_prototype||| -coresub_op||| -could_it_be_a_POSIX_class|||n -cr_textfilter||| -create_eval_scope||| -croak_memory_wrap||5.019003|n -croak_no_mem|||n -croak_no_modify||5.013003|n -croak_nocontext|||vn -croak_popstack|||n -croak_sv||5.013001| -croak_xs_usage||5.010001|n -croak|||v -csighandler||5.009003|n -current_re_engine||| -curse||| -custom_op_desc||5.007003| -custom_op_get_field||| -custom_op_name||5.007003| -custom_op_register||5.013007| -custom_op_xop||5.013007| -cv_ckproto_len_flags||| -cv_clone_into||| -cv_clone||| -cv_const_sv_or_av|||n -cv_const_sv||5.003070|n -cv_dump||| -cv_forget_slab||| -cv_get_call_checker||5.013006| -cv_name||5.021005| -cv_set_call_checker_flags||5.021004| -cv_set_call_checker||5.013006| -cv_undef_flags||| -cv_undef||| -cvgv_from_hek||| -cvgv_set||| -cvstash_set||| -cx_dump||5.005000| -cx_dup||| -cxinc||| -dAXMARK|5.009003||p -dAX|5.007002||p -dITEMS|5.007002||p -dMARK||| -dMULTICALL||5.009003| -dMY_CXT_SV|5.007003||p -dMY_CXT|5.007003||p -dNOOP|5.006000||p -dORIGMARK||| -dSP||| -dTHR|5.004050||p -dTHXR|5.021008||p -dTHXa|5.006000||p -dTHXoa|5.006000||p -dTHX|5.006000||p -dUNDERBAR|5.009002||p -dVAR|5.009003||p -dXCPT|5.009002||p -dXSARGS||| -dXSI32||| -dXSTARG|5.006000||p -deb_curcv||| -deb_nocontext|||vn -deb_stack_all||| -deb_stack_n||| -debop||5.005000| -debprofdump||5.005000| -debprof||| -debstackptrs||5.007003| -debstack||5.007003| -debug_start_match||| -deb||5.007003|v -defelem_target||| -del_sv||| -delete_eval_scope||| -delimcpy||5.004000|n -deprecate_commaless_var_list||| -despatch_signals||5.007001| -destroy_matcher||| -die_nocontext|||vn -die_sv||5.013001| -die_unwind||| -die|||v -dirp_dup||| -div128||| -djSP||| -do_aexec5||| -do_aexec||| -do_aspawn||| -do_binmode||5.004050| -do_chomp||| -do_close||| -do_delete_local||| -do_dump_pad||| -do_eof||| -do_exec3||| -do_execfree||| -do_exec||| -do_gv_dump||5.006000| -do_gvgv_dump||5.006000| -do_hv_dump||5.006000| -do_ipcctl||| -do_ipcget||| -do_join||| -do_magic_dump||5.006000| -do_msgrcv||| -do_msgsnd||| -do_ncmp||| -do_oddball||| -do_op_dump||5.006000| -do_open6||| -do_open9||5.006000| -do_open_raw||| -do_openn||5.007001| -do_open||5.003070| -do_pmop_dump||5.006000| -do_print||| -do_readline||| -do_seek||| -do_semop||| -do_shmio||| -do_smartmatch||| -do_spawn_nowait||| -do_spawn||| -do_sprintf||| -do_sv_dump||5.006000| -do_sysseek||| -do_tell||| -do_trans_complex_utf8||| -do_trans_complex||| -do_trans_count_utf8||| -do_trans_count||| -do_trans_simple_utf8||| -do_trans_simple||| -do_trans||| -do_vecget||| -do_vecset||| -do_vop||| -docatch||| -doeval||| -dofile||| -dofindlabel||| -doform||| -doing_taint||5.008001|n -dooneliner||| -doopen_pm||| -doparseform||| -dopoptoeval||| -dopoptogiven||| -dopoptolabel||| -dopoptoloop||| -dopoptosub_at||| -dopoptowhen||| -doref||5.009003| -dounwind||| -dowantarray||| -drand48_init_r|||n -drand48_r|||n -dump_all_perl||| -dump_all||5.006000| -dump_c_backtrace||| -dump_eval||5.006000| -dump_exec_pos||| -dump_form||5.006000| -dump_indent||5.006000|v -dump_mstats||| -dump_packsubs_perl||| -dump_packsubs||5.006000| -dump_sub_perl||| -dump_sub||5.006000| -dump_sv_child||| -dump_trie_interim_list||| -dump_trie_interim_table||| -dump_trie||| -dump_vindent||5.006000| -dumpuntil||| -dup_attrlist||| -emulate_cop_io||| -eval_pv|5.006000||p -eval_sv|5.006000||p -exec_failed||| -expect_number||| -fbm_compile||5.005000| -fbm_instr||5.005000| -feature_is_enabled||| -filter_add||| -filter_del||| -filter_gets||| -filter_read||| -finalize_optree||| -finalize_op||| -find_and_forget_pmops||| -find_array_subscript||| -find_beginning||| -find_byclass||| -find_default_stash||| -find_hash_subscript||| -find_in_my_stash||| -find_lexical_cv||| -find_runcv_where||| -find_runcv||5.008001| -find_rundefsv2||| -find_rundefsvoffset||5.009002| -find_rundefsv||5.013002| -find_script||| -find_uninit_var||| -first_symbol|||n -fixup_errno_string||| -foldEQ_latin1||5.013008|n -foldEQ_locale||5.013002|n -foldEQ_utf8_flags||5.013010| -foldEQ_utf8||5.013002| -foldEQ||5.013002|n -fold_constants||| -forbid_setid||| -force_ident_maybe_lex||| -force_ident||| -force_list||| -force_next||| -force_strict_version||| -force_version||| -force_word||| -forget_pmop||| -form_nocontext|||vn -form_short_octal_warning||| -form||5.004000|v -fp_dup||| -fprintf_nocontext|||vn -free_c_backtrace||| -free_global_struct||| -free_tied_hv_pool||| -free_tmps||| -gen_constant_list||| -get_ANYOF_cp_list_for_ssc||| -get_and_check_backslash_N_name||| -get_aux_mg||| -get_av|5.006000||p -get_c_backtrace_dump||| -get_c_backtrace||| -get_context||5.006000|n -get_cvn_flags|5.009005||p -get_cvs|5.011000||p -get_cv|5.006000||p -get_db_sub||| -get_debug_opts||| -get_hash_seed||| -get_hv|5.006000||p -get_invlist_iter_addr|||n -get_invlist_offset_addr|||n -get_invlist_previous_index_addr|||n -get_mstats||| -get_no_modify||| -get_num||| -get_op_descs||5.005000| -get_op_names||5.005000| -get_opargs||| -get_ppaddr||5.006000| -get_re_arg||| -get_sv|5.006000||p -get_vtbl||5.005030| -getcwd_sv||5.007002| -getenv_len||| -glob_2number||| -glob_assign_glob||| -gp_dup||| -gp_free||| -gp_ref||| -grok_atoUV|||n -grok_bin|5.007003||p -grok_bslash_N||| -grok_bslash_c||| -grok_bslash_o||| -grok_bslash_x||| -grok_hex|5.007003||p -grok_infnan||5.021004| -grok_number_flags||5.021002| -grok_number|5.007002||p -grok_numeric_radix|5.007002||p -grok_oct|5.007003||p -group_end||| -gv_AVadd||| -gv_HVadd||| -gv_IOadd||| -gv_SVadd||| -gv_add_by_type||5.011000| -gv_autoload4||5.004000| -gv_autoload_pvn||5.015004| -gv_autoload_pv||5.015004| -gv_autoload_sv||5.015004| -gv_check||| -gv_const_sv||5.009003| -gv_dump||5.006000| -gv_efullname3||5.003070| -gv_efullname4||5.006001| -gv_efullname||| -gv_fetchfile_flags||5.009005| -gv_fetchfile||| -gv_fetchmeth_autoload||5.007003| -gv_fetchmeth_internal||| -gv_fetchmeth_pv_autoload||5.015004| -gv_fetchmeth_pvn_autoload||5.015004| -gv_fetchmeth_pvn||5.015004| -gv_fetchmeth_pv||5.015004| -gv_fetchmeth_sv_autoload||5.015004| -gv_fetchmeth_sv||5.015004| -gv_fetchmethod_autoload||5.004000| -gv_fetchmethod_pv_flags||5.015004| -gv_fetchmethod_pvn_flags||5.015004| -gv_fetchmethod_sv_flags||5.015004| -gv_fetchmethod||| -gv_fetchmeth||| -gv_fetchpvn_flags|5.009002||p -gv_fetchpvs|5.009004||p -gv_fetchpv||| -gv_fetchsv|5.009002||p -gv_fullname3||5.003070| -gv_fullname4||5.006001| -gv_fullname||| -gv_handler||5.007001| -gv_init_pvn||5.015004| -gv_init_pv||5.015004| -gv_init_svtype||| -gv_init_sv||5.015004| -gv_init||| -gv_is_in_main||| -gv_magicalize_isa||| -gv_magicalize||| -gv_name_set||5.009004| -gv_override||| -gv_setref||| -gv_stashpvn_internal||| -gv_stashpvn|5.003070||p -gv_stashpvs|5.009003||p -gv_stashpv||| -gv_stashsvpvn_cached||| -gv_stashsv||| -gv_try_downgrade||| -handle_regex_sets||| -he_dup||| -hek_dup||| -hfree_next_entry||| -hfreeentries||| -hsplit||| -hv_assert||| -hv_auxinit_internal|||n -hv_auxinit||| -hv_backreferences_p||| -hv_clear_placeholders||5.009001| -hv_clear||| -hv_common_key_len||5.010000| -hv_common||5.010000| -hv_copy_hints_hv||5.009004| -hv_delayfree_ent||5.004000| -hv_delete_common||| -hv_delete_ent||5.003070| -hv_delete||| -hv_eiter_p||5.009003| -hv_eiter_set||5.009003| -hv_ename_add||| -hv_ename_delete||| -hv_exists_ent||5.003070| -hv_exists||| -hv_fetch_ent||5.003070| -hv_fetchs|5.009003||p -hv_fetch||| -hv_fill||5.013002| -hv_free_ent_ret||| -hv_free_ent||5.004000| -hv_iterinit||| -hv_iterkeysv||5.003070| -hv_iterkey||| -hv_iternext_flags||5.008000| -hv_iternextsv||| -hv_iternext||| -hv_iterval||| -hv_kill_backrefs||| -hv_ksplit||5.003070| -hv_magic_check|||n -hv_magic||| -hv_name_set||5.009003| -hv_notallowed||| -hv_placeholders_get||5.009003| -hv_placeholders_p||| -hv_placeholders_set||5.009003| -hv_rand_set||5.018000| -hv_riter_p||5.009003| -hv_riter_set||5.009003| -hv_scalar||5.009001| -hv_store_ent||5.003070| -hv_store_flags||5.008000| -hv_stores|5.009004||p -hv_store||| -hv_undef_flags||| -hv_undef||| -ibcmp_locale||5.004000| -ibcmp_utf8||5.007003| -ibcmp||| -incline||| -incpush_if_exists||| -incpush_use_sep||| -incpush||| -ingroup||| -init_argv_symbols||| -init_constants||| -init_dbargs||| -init_debugger||| -init_global_struct||| -init_i18nl10n||5.006000| -init_i18nl14n||5.006000| -init_ids||| -init_interp||| -init_main_stash||| -init_perllib||| -init_postdump_symbols||| -init_predump_symbols||| -init_stacks||5.005000| -init_tm||5.007002| -inplace_aassign||| -instr|||n -intro_my||5.004000| -intuit_method||| -intuit_more||| -invert||| -invlist_array|||n -invlist_clone||| -invlist_extend||| -invlist_highest|||n -invlist_is_iterating|||n -invlist_iterfinish|||n -invlist_iterinit|||n -invlist_iternext|||n -invlist_max|||n -invlist_previous_index|||n -invlist_set_len||| -invlist_set_previous_index|||n -invlist_trim|||n -invoke_exception_hook||| -io_close||| -isALNUMC|5.006000||p -isALNUM_lazy||5.021001| -isALPHANUMERIC||5.017008| -isALPHA||| -isASCII|5.006000||p -isBLANK|5.006001||p -isCNTRL|5.006000||p -isDIGIT||| -isFOO_lc||| -isFOO_utf8_lc||| -isGCB|||n -isGRAPH|5.006000||p -isGV_with_GP|5.009004||p -isIDCONT||5.017008| -isIDFIRST_lazy||5.021001| -isIDFIRST||| -isLOWER||| -isOCTAL||5.013005| -isPRINT|5.004000||p -isPSXSPC|5.006001||p -isPUNCT|5.006000||p -isSB||| -isSPACE||| -isUPPER||| -isUTF8_CHAR||5.021001| -isWB||| -isWORDCHAR||5.013006| -isXDIGIT|5.006000||p -is_an_int||| -is_ascii_string||5.011000| -is_handle_constructor|||n -is_invariant_string||5.021007|n -is_lvalue_sub||5.007001| -is_safe_syscall||5.019004| -is_ssc_worth_it|||n -is_uni_alnum_lc||5.006000| -is_uni_alnumc_lc||5.017007| -is_uni_alnumc||5.017007| -is_uni_alnum||5.006000| -is_uni_alpha_lc||5.006000| -is_uni_alpha||5.006000| -is_uni_ascii_lc||5.006000| -is_uni_ascii||5.006000| -is_uni_blank_lc||5.017002| -is_uni_blank||5.017002| -is_uni_cntrl_lc||5.006000| -is_uni_cntrl||5.006000| -is_uni_digit_lc||5.006000| -is_uni_digit||5.006000| -is_uni_graph_lc||5.006000| -is_uni_graph||5.006000| -is_uni_idfirst_lc||5.006000| -is_uni_idfirst||5.006000| -is_uni_lower_lc||5.006000| -is_uni_lower||5.006000| -is_uni_print_lc||5.006000| -is_uni_print||5.006000| -is_uni_punct_lc||5.006000| -is_uni_punct||5.006000| -is_uni_space_lc||5.006000| -is_uni_space||5.006000| -is_uni_upper_lc||5.006000| -is_uni_upper||5.006000| -is_uni_xdigit_lc||5.006000| -is_uni_xdigit||5.006000| -is_utf8_alnumc||5.017007| -is_utf8_alnum||5.006000| -is_utf8_alpha||5.006000| -is_utf8_ascii||5.006000| -is_utf8_blank||5.017002| -is_utf8_char_buf||5.015008|n -is_utf8_char||5.006000|n -is_utf8_cntrl||5.006000| -is_utf8_common||| -is_utf8_digit||5.006000| -is_utf8_graph||5.006000| -is_utf8_idcont||5.008000| -is_utf8_idfirst||5.006000| -is_utf8_lower||5.006000| -is_utf8_mark||5.006000| -is_utf8_perl_space||5.011001| -is_utf8_perl_word||5.011001| -is_utf8_posix_digit||5.011001| -is_utf8_print||5.006000| -is_utf8_punct||5.006000| -is_utf8_space||5.006000| -is_utf8_string_loclen||5.009003|n -is_utf8_string_loc||5.008001|n -is_utf8_string||5.006001|n -is_utf8_upper||5.006000| -is_utf8_xdigit||5.006000| -is_utf8_xidcont||5.013010| -is_utf8_xidfirst||5.013010| -isa_lookup||| -isinfnansv||| -isinfnan||5.021004|n -items|||n -ix|||n -jmaybe||| -join_exact||| -keyword_plugin_standard||| -keyword||| -leave_common||| -leave_scope||| -lex_bufutf8||5.011002| -lex_discard_to||5.011002| -lex_grow_linestr||5.011002| -lex_next_chunk||5.011002| -lex_peek_unichar||5.011002| -lex_read_space||5.011002| -lex_read_to||5.011002| -lex_read_unichar||5.011002| -lex_start||5.009005| -lex_stuff_pvn||5.011002| -lex_stuff_pvs||5.013005| -lex_stuff_pv||5.013006| -lex_stuff_sv||5.011002| -lex_unstuff||5.011002| -listkids||| -list||| -load_module_nocontext|||vn -load_module|5.006000||pv -localize||| -looks_like_bool||| -looks_like_number||| -lop||| -mPUSHi|5.009002||p -mPUSHn|5.009002||p -mPUSHp|5.009002||p -mPUSHs|5.010001||p -mPUSHu|5.009002||p -mXPUSHi|5.009002||p -mXPUSHn|5.009002||p -mXPUSHp|5.009002||p -mXPUSHs|5.010001||p -mXPUSHu|5.009002||p -magic_clear_all_env||| -magic_cleararylen_p||| -magic_clearenv||| -magic_clearhints||| -magic_clearhint||| -magic_clearisa||| -magic_clearpack||| -magic_clearsig||| -magic_copycallchecker||| -magic_dump||5.006000| -magic_existspack||| -magic_freearylen_p||| -magic_freeovrld||| -magic_getarylen||| -magic_getdebugvar||| -magic_getdefelem||| -magic_getnkeys||| -magic_getpack||| -magic_getpos||| -magic_getsig||| -magic_getsubstr||| -magic_gettaint||| -magic_getuvar||| -magic_getvec||| -magic_get||| -magic_killbackrefs||| -magic_methcall1||| -magic_methcall|||v -magic_methpack||| -magic_nextpack||| -magic_regdata_cnt||| -magic_regdatum_get||| -magic_regdatum_set||| -magic_scalarpack||| -magic_set_all_env||| -magic_setarylen||| -magic_setcollxfrm||| -magic_setdbline||| -magic_setdebugvar||| -magic_setdefelem||| -magic_setenv||| -magic_sethint||| -magic_setisa||| -magic_setlvref||| -magic_setmglob||| -magic_setnkeys||| -magic_setpack||| -magic_setpos||| -magic_setregexp||| -magic_setsig||| -magic_setsubstr||| -magic_settaint||| -magic_setutf8||| -magic_setuvar||| -magic_setvec||| -magic_set||| -magic_sizepack||| -magic_wipepack||| -make_matcher||| -make_trie||| -malloc_good_size|||n -malloced_size|||n -malloc||5.007002|n -markstack_grow||5.021001| -matcher_matches_sv||| -maybe_multimagic_gv||| -mayberelocate||| -measure_struct||| -memEQs|5.009005||p -memEQ|5.004000||p -memNEs|5.009005||p -memNE|5.004000||p -mem_collxfrm||| -mem_log_common|||n -mess_alloc||| -mess_nocontext|||vn -mess_sv||5.013001| -mess||5.006000|v -mfree||5.007002|n -mg_clear||| -mg_copy||| -mg_dup||| -mg_find_mglob||| -mg_findext|5.013008||pn -mg_find|||n -mg_free_type||5.013006| -mg_free||| -mg_get||| -mg_length||5.005000| -mg_localize||| -mg_magical|||n -mg_set||| -mg_size||5.005000| -mini_mktime||5.007002|n -minus_v||| -missingterm||| -mode_from_discipline||| -modkids||| -more_bodies||| -more_sv||| -moreswitches||| -move_proto_attr||| -mro_clean_isarev||| -mro_gather_and_rename||| -mro_get_from_name||5.010001| -mro_get_linear_isa_dfs||| -mro_get_linear_isa||5.009005| -mro_get_private_data||5.010001| -mro_isa_changed_in||| -mro_meta_dup||| -mro_meta_init||| -mro_method_changed_in||5.009005| -mro_package_moved||| -mro_register||5.010001| -mro_set_mro||5.010001| -mro_set_private_data||5.010001| -mul128||| -mulexp10|||n -multideref_stringify||| -my_atof2||5.007002| -my_atof||5.006000| -my_attrs||| -my_bcopy|||n -my_bytes_to_utf8|||n -my_bzero|||n -my_chsize||| -my_clearenv||| -my_cxt_index||| -my_cxt_init||| -my_dirfd||5.009005|n -my_exit_jump||| -my_exit||| -my_failure_exit||5.004000| -my_fflush_all||5.006000| -my_fork||5.007003|n -my_kid||| -my_lstat_flags||| -my_lstat||5.021008| -my_memcmp|||n -my_memset|||n -my_pclose||5.003070| -my_popen_list||5.007001| -my_popen||5.003070| -my_setenv||| -my_setlocale||| -my_snprintf|5.009004||pvn -my_socketpair||5.007003|n -my_sprintf|5.009003||pvn -my_stat_flags||| -my_stat||5.021008| -my_strerror||5.021001| -my_strftime||5.007002| -my_strlcat|5.009004||pn -my_strlcpy|5.009004||pn -my_unexec||| -my_vsnprintf||5.009004|n -need_utf8|||n -newANONATTRSUB||5.006000| -newANONHASH||| -newANONLIST||| -newANONSUB||| -newASSIGNOP||| -newATTRSUB_x||| -newATTRSUB||5.006000| -newAVREF||| -newAV||| -newBINOP||| -newCONDOP||| -newCONSTSUB_flags||5.015006| -newCONSTSUB|5.004050||p -newCVREF||| -newDEFSVOP||5.021006| -newFORM||| -newFOROP||5.013007| -newGIVENOP||5.009003| -newGIVWHENOP||| -newGP||| -newGVOP||| -newGVREF||| -newGVgen_flags||5.015004| -newGVgen||| -newHVREF||| -newHVhv||5.005000| -newHV||| -newIO||| -newLISTOP||| -newLOGOP||| -newLOOPEX||| -newLOOPOP||| -newMETHOP_internal||| -newMETHOP_named||5.021005| -newMETHOP||5.021005| -newMYSUB||5.017004| -newNULLLIST||| -newOP||| -newPADNAMELIST||5.021007|n -newPADNAMEouter||5.021007|n -newPADNAMEpvn||5.021007|n -newPADOP||| -newPMOP||| -newPROG||| -newPVOP||| -newRANGE||| -newRV_inc|5.004000||p -newRV_noinc|5.004000||p -newRV||| -newSLICEOP||| -newSTATEOP||| -newSTUB||| -newSUB||| -newSVOP||| -newSVREF||| -newSV_type|5.009005||p -newSVavdefelem||| -newSVhek||5.009003| -newSViv||| -newSVnv||| -newSVpadname||5.017004| -newSVpv_share||5.013006| -newSVpvf_nocontext|||vn -newSVpvf||5.004000|v -newSVpvn_flags|5.010001||p -newSVpvn_share|5.007001||p -newSVpvn_utf8|5.010001||p -newSVpvn|5.004050||p -newSVpvs_flags|5.010001||p -newSVpvs_share|5.009003||p -newSVpvs|5.009003||p -newSVpv||| -newSVrv||| -newSVsv||| -newSVuv|5.006000||p -newSV||| -newUNOP_AUX||5.021007| -newUNOP||| -newWHENOP||5.009003| -newWHILEOP||5.013007| -newXS_deffile||| -newXS_flags||5.009004| -newXS_len_flags||| -newXSproto||5.006000| -newXS||5.006000| -new_collate||5.006000| -new_constant||| -new_ctype||5.006000| -new_he||| -new_logop||| -new_numeric||5.006000| -new_stackinfo||5.005000| -new_version||5.009000| -new_warnings_bitfield||| -next_symbol||| -nextargv||| -nextchar||| -ninstr|||n -no_bareword_allowed||| -no_fh_allowed||| -no_op||| -noperl_die|||vn -not_a_number||| -not_incrementable||| -nothreadhook||5.008000| -nuke_stacks||| -num_overflow|||n -oopsAV||| -oopsHV||| -op_append_elem||5.013006| -op_append_list||5.013006| -op_clear||| -op_contextualize||5.013006| -op_convert_list||5.021006| -op_dump||5.006000| -op_free||| -op_integerize||| -op_linklist||5.013006| -op_lvalue_flags||| -op_lvalue||5.013007| -op_null||5.007002| -op_parent||5.021002|n -op_prepend_elem||5.013006| -op_refcnt_dec||| -op_refcnt_inc||| -op_refcnt_lock||5.009002| -op_refcnt_unlock||5.009002| -op_relocate_sv||| -op_scope||5.013007| -op_sibling_splice||5.021002|n -op_std_init||| -op_unscope||| -open_script||| -openn_cleanup||| -openn_setup||| -opmethod_stash||| -opslab_force_free||| -opslab_free_nopad||| -opslab_free||| -pMY_CXT_|5.007003||p -pMY_CXT|5.007003||p -pTHX_|5.006000||p -pTHX|5.006000||p -packWARN|5.007003||p -pack_cat||5.007003| -pack_rec||| -package_version||| -package||| -packlist||5.008001| -pad_add_anon||5.008001| -pad_add_name_pvn||5.015001| -pad_add_name_pvs||5.015001| -pad_add_name_pv||5.015001| -pad_add_name_sv||5.015001| -pad_add_weakref||| -pad_alloc_name||| -pad_alloc||| -pad_block_start||| -pad_check_dup||| -pad_compname_type||5.009003| -pad_findlex||| -pad_findmy_pvn||5.015001| -pad_findmy_pvs||5.015001| -pad_findmy_pv||5.015001| -pad_findmy_sv||5.015001| -pad_fixup_inner_anons||| -pad_free||| -pad_leavemy||| -pad_new||5.008001| -pad_push||| -pad_reset||| -pad_setsv||| -pad_sv||| -pad_swipe||| -pad_tidy||5.008001| -padlist_dup||| -padlist_store||| -padname_dup||| -padname_free||| -padnamelist_dup||| -padnamelist_fetch||5.021007|n -padnamelist_free||| -padnamelist_store||5.021007| -parse_arithexpr||5.013008| -parse_barestmt||5.013007| -parse_block||5.013007| -parse_body||| -parse_fullexpr||5.013008| -parse_fullstmt||5.013005| -parse_gv_stash_name||| -parse_ident||| -parse_label||5.013007| -parse_listexpr||5.013008| -parse_lparen_question_flags||| -parse_stmtseq||5.013006| -parse_subsignature||| -parse_termexpr||5.013008| -parse_unicode_opts||| -parser_dup||| -parser_free_nexttoke_ops||| -parser_free||| -path_is_searchable|||n -peep||| -pending_ident||| -perl_alloc_using|||n -perl_alloc|||n -perl_clone_using|||n -perl_clone|||n -perl_construct|||n -perl_destruct||5.007003|n -perl_free|||n -perl_parse||5.006000|n -perl_run|||n -pidgone||| -pm_description||| -pmop_dump||5.006000| -pmruntime||| -pmtrans||| -pop_scope||| -populate_ANYOF_from_invlist||| -populate_isa|||v -pregcomp||5.009005| -pregexec||| -pregfree2||5.011000| -pregfree||| -prescan_version||5.011004| -printbuf||| -printf_nocontext|||vn -process_special_blocks||| -ptr_hash|||n -ptr_table_clear||5.009005| -ptr_table_fetch||5.009005| -ptr_table_find|||n -ptr_table_free||5.009005| -ptr_table_new||5.009005| -ptr_table_split||5.009005| -ptr_table_store||5.009005| -push_scope||| -put_charclass_bitmap_innards||| -put_code_point||| -put_range||| -pv_display|5.006000||p -pv_escape|5.009004||p -pv_pretty|5.009004||p -pv_uni_display||5.007003| -qerror||| -qsortsvu||| -quadmath_format_needed|||n -quadmath_format_single|||n -re_compile||5.009005| -re_croak2||| -re_dup_guts||| -re_intuit_start||5.019001| -re_intuit_string||5.006000| -re_op_compile||| -realloc||5.007002|n -reentrant_free||5.021008| -reentrant_init||5.021008| -reentrant_retry||5.021008|vn -reentrant_size||5.021008| -ref_array_or_hash||| -refcounted_he_chain_2hv||| -refcounted_he_fetch_pvn||| -refcounted_he_fetch_pvs||| -refcounted_he_fetch_pv||| -refcounted_he_fetch_sv||| -refcounted_he_free||| -refcounted_he_inc||| -refcounted_he_new_pvn||| -refcounted_he_new_pvs||| -refcounted_he_new_pv||| -refcounted_he_new_sv||| -refcounted_he_value||| -refkids||| -refto||| -ref||5.021008| -reg2Lanode||| -reg_check_named_buff_matched|||n -reg_named_buff_all||5.009005| -reg_named_buff_exists||5.009005| -reg_named_buff_fetch||5.009005| -reg_named_buff_firstkey||5.009005| -reg_named_buff_iter||| -reg_named_buff_nextkey||5.009005| -reg_named_buff_scalar||5.009005| -reg_named_buff||| -reg_node||| -reg_numbered_buff_fetch||| -reg_numbered_buff_length||| -reg_numbered_buff_store||| -reg_qr_package||| -reg_recode||| -reg_scan_name||| -reg_skipcomment|||n -reg_temp_copy||| -reganode||| -regatom||| -regbranch||| -regclass_swash||5.009004| -regclass||| -regcppop||| -regcppush||| -regcurly|||n -regdump_extflags||| -regdump_intflags||| -regdump||5.005000| -regdupe_internal||| -regexec_flags||5.005000| -regfree_internal||5.009005| -reghop3|||n -reghop4|||n -reghopmaybe3|||n -reginclass||| -reginitcolors||5.006000| -reginsert||| -regmatch||| -regnext||5.005000| -regnode_guts||| -regpatws|||n -regpiece||| -regpposixcc||| -regprop||| -regrepeat||| -regtail_study||| -regtail||| -regtry||| -reg||| -repeatcpy|||n -report_evil_fh||| -report_redefined_cv||| -report_uninit||| -report_wrongway_fh||| -require_pv||5.006000| -require_tie_mod||| -restore_magic||| -rninstr|||n -rpeep||| -rsignal_restore||| -rsignal_save||| -rsignal_state||5.004000| -rsignal||5.004000| -run_body||| -run_user_filter||| -runops_debug||5.005000| -runops_standard||5.005000| -rv2cv_op_cv||5.013006| -rvpv_dup||| -rxres_free||| -rxres_restore||| -rxres_save||| -safesyscalloc||5.006000|n -safesysfree||5.006000|n -safesysmalloc||5.006000|n -safesysrealloc||5.006000|n -same_dirent||| -save_I16||5.004000| -save_I32||| -save_I8||5.006000| -save_adelete||5.011000| -save_aelem_flags||5.011000| -save_aelem||5.004050| -save_aliased_sv||| -save_alloc||5.006000| -save_aptr||| -save_ary||| -save_bool||5.008001| -save_clearsv||| -save_delete||| -save_destructor_x||5.006000| -save_destructor||5.006000| -save_freeop||| -save_freepv||| -save_freesv||| -save_generic_pvref||5.006001| -save_generic_svref||5.005030| -save_gp||5.004000| -save_hash||| -save_hdelete||5.011000| -save_hek_flags|||n -save_helem_flags||5.011000| -save_helem||5.004050| -save_hints||5.010001| -save_hptr||| -save_int||| -save_item||| -save_iv||5.005000| -save_lines||| -save_list||| -save_long||| -save_magic_flags||| -save_mortalizesv||5.007001| -save_nogv||| -save_op||5.005000| -save_padsv_and_mortalize||5.010001| -save_pptr||| -save_pushi32ptr||5.010001| -save_pushptri32ptr||| -save_pushptrptr||5.010001| -save_pushptr||5.010001| -save_re_context||5.006000| -save_scalar_at||| -save_scalar||| -save_set_svflags||5.009000| -save_shared_pvref||5.007003| -save_sptr||| -save_strlen||| -save_svref||| -save_vptr||5.006000| -savepvn||| -savepvs||5.009003| -savepv||| -savesharedpvn||5.009005| -savesharedpvs||5.013006| -savesharedpv||5.007003| -savesharedsvpv||5.013006| -savestack_grow_cnt||5.008001| -savestack_grow||| -savesvpv||5.009002| -sawparens||| -scalar_mod_type|||n -scalarboolean||| -scalarkids||| -scalarseq||| -scalarvoid||| -scalar||| -scan_bin||5.006000| -scan_commit||| -scan_const||| -scan_formline||| -scan_heredoc||| -scan_hex||| -scan_ident||| -scan_inputsymbol||| -scan_num||5.007001| -scan_oct||| -scan_pat||| -scan_str||| -scan_subst||| -scan_trans||| -scan_version||5.009001| -scan_vstring||5.009005| -scan_word||| -search_const||| -seed||5.008001| -sequence_num||| -set_ANYOF_arg||| -set_caret_X||| -set_context||5.006000|n -set_numeric_local||5.006000| -set_numeric_radix||5.006000| -set_numeric_standard||5.006000| -set_padlist|||n -setdefout||| -share_hek_flags||| -share_hek||5.004000| -should_warn_nl|||n -si_dup||| -sighandler|||n -simplify_sort||| -skipspace_flags||| -softref2xv||| -sortcv_stacked||| -sortcv_xsub||| -sortcv||| -sortsv_flags||5.009003| -sortsv||5.007003| -space_join_names_mortal||| -ss_dup||| -ssc_add_range||| -ssc_and||| -ssc_anything||| -ssc_clear_locale|||n -ssc_cp_and||| -ssc_finalize||| -ssc_init||| -ssc_intersection||| -ssc_is_anything|||n -ssc_is_cp_posixl_init|||n -ssc_or||| -ssc_union||| -stack_grow||| -start_glob||| -start_subparse||5.004000| -stdize_locale||| -strEQ||| -strGE||| -strGT||| -strLE||| -strLT||| -strNE||| -str_to_version||5.006000| -strip_return||| -strnEQ||| -strnNE||| -study_chunk||| -sub_crush_depth||| -sublex_done||| -sublex_push||| -sublex_start||| -sv_2bool_flags||5.013006| -sv_2bool||| -sv_2cv||| -sv_2io||| -sv_2iuv_common||| -sv_2iuv_non_preserve||| -sv_2iv_flags||5.009001| -sv_2iv||| -sv_2mortal||| -sv_2num||| -sv_2nv_flags||5.013001| -sv_2pv_flags|5.007002||p -sv_2pv_nolen|5.006000||p -sv_2pvbyte_nolen|5.006000||p -sv_2pvbyte|5.006000||p -sv_2pvutf8_nolen||5.006000| -sv_2pvutf8||5.006000| -sv_2pv||| -sv_2uv_flags||5.009001| -sv_2uv|5.004000||p -sv_add_arena||| -sv_add_backref||| -sv_backoff|||n -sv_bless||| -sv_buf_to_ro||| -sv_buf_to_rw||| -sv_cat_decode||5.008001| -sv_catpv_flags||5.013006| -sv_catpv_mg|5.004050||p -sv_catpv_nomg||5.013006| -sv_catpvf_mg_nocontext|||pvn -sv_catpvf_mg|5.006000|5.004000|pv -sv_catpvf_nocontext|||vn -sv_catpvf||5.004000|v -sv_catpvn_flags||5.007002| -sv_catpvn_mg|5.004050||p -sv_catpvn_nomg|5.007002||p -sv_catpvn||| -sv_catpvs_flags||5.013006| -sv_catpvs_mg||5.013006| -sv_catpvs_nomg||5.013006| -sv_catpvs|5.009003||p -sv_catpv||| -sv_catsv_flags||5.007002| -sv_catsv_mg|5.004050||p -sv_catsv_nomg|5.007002||p -sv_catsv||| -sv_chop||| -sv_clean_all||| -sv_clean_objs||| -sv_clear||| -sv_cmp_flags||5.013006| -sv_cmp_locale_flags||5.013006| -sv_cmp_locale||5.004000| -sv_cmp||| -sv_collxfrm_flags||5.013006| -sv_collxfrm||| -sv_copypv_flags||5.017002| -sv_copypv_nomg||5.017002| -sv_copypv||| -sv_dec_nomg||5.013002| -sv_dec||| -sv_del_backref||| -sv_derived_from_pvn||5.015004| -sv_derived_from_pv||5.015004| -sv_derived_from_sv||5.015004| -sv_derived_from||5.004000| -sv_destroyable||5.010000| -sv_display||| -sv_does_pvn||5.015004| -sv_does_pv||5.015004| -sv_does_sv||5.015004| -sv_does||5.009004| -sv_dump||| -sv_dup_common||| -sv_dup_inc_multiple||| -sv_dup_inc||| -sv_dup||| -sv_eq_flags||5.013006| -sv_eq||| -sv_exp_grow||| -sv_force_normal_flags||5.007001| -sv_force_normal||5.006000| -sv_free2||| -sv_free_arenas||| -sv_free||| -sv_get_backrefs||5.021008|n -sv_gets||5.003070| -sv_grow||| -sv_i_ncmp||| -sv_inc_nomg||5.013002| -sv_inc||| -sv_insert_flags||5.010001| -sv_insert||| -sv_isa||| -sv_isobject||| -sv_iv||5.005000| -sv_kill_backrefs||| -sv_len_utf8_nomg||| -sv_len_utf8||5.006000| -sv_len||| -sv_magic_portable|5.021008|5.004000|p -sv_magicext_mglob||| -sv_magicext||5.007003| -sv_magic||| -sv_mortalcopy_flags||| -sv_mortalcopy||| -sv_ncmp||| -sv_newmortal||| -sv_newref||| -sv_nolocking||5.007003| -sv_nosharing||5.007003| -sv_nounlocking||| -sv_nv||5.005000| -sv_only_taint_gmagic|||n -sv_or_pv_pos_u2b||| -sv_peek||5.005000| -sv_pos_b2u_flags||5.019003| -sv_pos_b2u_midway||| -sv_pos_b2u||5.006000| -sv_pos_u2b_cached||| -sv_pos_u2b_flags||5.011005| -sv_pos_u2b_forwards|||n -sv_pos_u2b_midway|||n -sv_pos_u2b||5.006000| -sv_pvbyten_force||5.006000| -sv_pvbyten||5.006000| -sv_pvbyte||5.006000| -sv_pvn_force_flags|5.007002||p -sv_pvn_force||| -sv_pvn_nomg|5.007003|5.005000|p -sv_pvn||5.005000| -sv_pvutf8n_force||5.006000| -sv_pvutf8n||5.006000| -sv_pvutf8||5.006000| -sv_pv||5.006000| -sv_recode_to_utf8||5.007003| -sv_reftype||| -sv_ref||| -sv_release_COW||| -sv_replace||| -sv_report_used||| -sv_resetpvn||| -sv_reset||| -sv_rvweaken||5.006000| -sv_sethek||| -sv_setiv_mg|5.004050||p -sv_setiv||| -sv_setnv_mg|5.006000||p -sv_setnv||| -sv_setpv_mg|5.004050||p -sv_setpvf_mg_nocontext|||pvn -sv_setpvf_mg|5.006000|5.004000|pv -sv_setpvf_nocontext|||vn -sv_setpvf||5.004000|v -sv_setpviv_mg||5.008001| -sv_setpviv||5.008001| -sv_setpvn_mg|5.004050||p -sv_setpvn||| -sv_setpvs_mg||5.013006| -sv_setpvs|5.009004||p -sv_setpv||| -sv_setref_iv||| -sv_setref_nv||| -sv_setref_pvn||| -sv_setref_pvs||5.021008| -sv_setref_pv||| -sv_setref_uv||5.007001| -sv_setsv_cow||| -sv_setsv_flags||5.007002| -sv_setsv_mg|5.004050||p -sv_setsv_nomg|5.007002||p -sv_setsv||| -sv_setuv_mg|5.004050||p -sv_setuv|5.004000||p -sv_tainted||5.004000| -sv_taint||5.004000| -sv_true||5.005000| -sv_unglob||| -sv_uni_display||5.007003| -sv_unmagicext|5.013008||p -sv_unmagic||| -sv_unref_flags||5.007001| -sv_unref||| -sv_untaint||5.004000| -sv_upgrade||| -sv_usepvn_flags||5.009004| -sv_usepvn_mg|5.004050||p -sv_usepvn||| -sv_utf8_decode||5.006000| -sv_utf8_downgrade||5.006000| -sv_utf8_encode||5.006000| -sv_utf8_upgrade_flags_grow||5.011000| -sv_utf8_upgrade_flags||5.007002| -sv_utf8_upgrade_nomg||5.007002| -sv_utf8_upgrade||5.007001| -sv_uv|5.005000||p -sv_vcatpvf_mg|5.006000|5.004000|p -sv_vcatpvfn_flags||5.017002| -sv_vcatpvfn||5.004000| -sv_vcatpvf|5.006000|5.004000|p -sv_vsetpvf_mg|5.006000|5.004000|p -sv_vsetpvfn||5.004000| -sv_vsetpvf|5.006000|5.004000|p -svtype||| -swallow_bom||| -swash_fetch||5.007002| -swash_init||5.006000| -swash_scan_list_line||| -swatch_get||| -sync_locale||5.021004| -sys_init3||5.010000|n -sys_init||5.010000|n -sys_intern_clear||| -sys_intern_dup||| -sys_intern_init||| -sys_term||5.010000|n -taint_env||| -taint_proper||| -tied_method|||v -tmps_grow_p||| -toFOLD_uni||5.007003| -toFOLD_utf8||5.019001| -toFOLD||5.019001| -toLOWER_L1||5.019001| -toLOWER_LC||5.004000| -toLOWER_uni||5.007003| -toLOWER_utf8||5.015007| -toLOWER||| -toTITLE_uni||5.007003| -toTITLE_utf8||5.015007| -toTITLE||5.019001| -toUPPER_uni||5.007003| -toUPPER_utf8||5.015007| -toUPPER||| -to_byte_substr||| -to_lower_latin1|||n -to_uni_fold||5.007003| -to_uni_lower_lc||5.006000| -to_uni_lower||5.007003| -to_uni_title_lc||5.006000| -to_uni_title||5.007003| -to_uni_upper_lc||5.006000| -to_uni_upper||5.007003| -to_utf8_case||5.007003| -to_utf8_fold||5.015007| -to_utf8_lower||5.015007| -to_utf8_substr||| -to_utf8_title||5.015007| -to_utf8_upper||5.015007| -tokenize_use||| -tokeq||| -tokereport||| -too_few_arguments_pv||| -too_many_arguments_pv||| -translate_substr_offsets|||n -try_amagic_bin||| -try_amagic_un||| -uiv_2buf|||n -unlnk||| -unpack_rec||| -unpack_str||5.007003| -unpackstring||5.008001| -unreferenced_to_tmp_stack||| -unshare_hek_or_pvn||| -unshare_hek||| -unsharepvn||5.003070| -unwind_handler_stack||| -update_debugger_info||| -upg_version||5.009005| -usage||| -utf16_textfilter||| -utf16_to_utf8_reversed||5.006001| -utf16_to_utf8||5.006001| -utf8_distance||5.006000| -utf8_hop||5.006000|n -utf8_length||5.007001| -utf8_mg_len_cache_update||| -utf8_mg_pos_cache_update||| -utf8_to_bytes||5.006001| -utf8_to_uvchr_buf||5.015009| -utf8_to_uvchr||5.007001| -utf8_to_uvuni_buf||5.015009| -utf8_to_uvuni||5.007001| -utf8n_to_uvchr||5.007001| -utf8n_to_uvuni||5.007001| -utilize||| -uvchr_to_utf8_flags||5.007003| -uvchr_to_utf8||5.007001| -uvoffuni_to_utf8_flags||5.019004| -uvuni_to_utf8_flags||5.007003| -uvuni_to_utf8||5.007001| -valid_utf8_to_uvchr||5.015009| -valid_utf8_to_uvuni||5.015009| -validate_proto||| -validate_suid||| -varname||| -vcmp||5.009000| -vcroak||5.006000| -vdeb||5.007003| -vform||5.006000| -visit||| -vivify_defelem||| -vivify_ref||| -vload_module|5.006000||p -vmess||5.006000| -vnewSVpvf|5.006000|5.004000|p -vnormal||5.009002| -vnumify||5.009000| -vstringify||5.009000| -vverify||5.009003| -vwarner||5.006000| -vwarn||5.006000| -wait4pid||| -warn_nocontext|||vn -warn_sv||5.013001| -warner_nocontext|||vn -warner|5.006000|5.004000|pv -warn|||v -was_lvalue_sub||| -watch||| -whichsig_pvn||5.015004| -whichsig_pv||5.015004| -whichsig_sv||5.015004| -whichsig||| -win32_croak_not_implemented|||n -with_queued_errors||| -wrap_op_checker||5.015008| -write_to_stderr||| -xs_boot_epilog||| -xs_handshake|||vn -xs_version_bootcheck||| -yyerror_pvn||| -yyerror_pv||| -yyerror||| -yylex||| -yyparse||| -yyunlex||| -yywarn||| -); - -if (exists $opt{'list-unsupported'}) { - my $f; - for $f (sort { lc $a cmp lc $b } keys %API) { - next unless $API{$f}{todo}; - print "$f ", '.'x(40-length($f)), " ", format_version($API{$f}{todo}), "\n"; - } - exit 0; -} - -# Scan for possible replacement candidates - -my(%replace, %need, %hints, %warnings, %depends); -my $replace = 0; -my($hint, $define, $function); - -sub find_api -{ - my $code = shift; - $code =~ s{ - / (?: \*[^*]*\*+(?:[^$ccs][^*]*\*+)* / | /[^\r\n]*) - | "[^"\\]*(?:\\.[^"\\]*)*" - | '[^'\\]*(?:\\.[^'\\]*)*' }{}egsx; - grep { exists $API{$_} } $code =~ /(\w+)/mg; -} - -while () { - if ($hint) { - my $h = $hint->[0] eq 'Hint' ? \%hints : \%warnings; - if (m{^\s*\*\s(.*?)\s*$}) { - for (@{$hint->[1]}) { - $h->{$_} ||= ''; # suppress warning with older perls - $h->{$_} .= "$1\n"; - } - } - else { undef $hint } - } - - $hint = [$1, [split /,?\s+/, $2]] - if m{^\s*$rccs\s+(Hint|Warning):\s+(\w+(?:,?\s+\w+)*)\s*$}; - - if ($define) { - if ($define->[1] =~ /\\$/) { - $define->[1] .= $_; - } - else { - if (exists $API{$define->[0]} && $define->[1] !~ /^DPPP_\(/) { - my @n = find_api($define->[1]); - push @{$depends{$define->[0]}}, @n if @n - } - undef $define; - } - } - - $define = [$1, $2] if m{^\s*#\s*define\s+(\w+)(?:\([^)]*\))?\s+(.*)}; - - if ($function) { - if (/^}/) { - if (exists $API{$function->[0]}) { - my @n = find_api($function->[1]); - push @{$depends{$function->[0]}}, @n if @n - } - undef $function; - } - else { - $function->[1] .= $_; - } - } - - $function = [$1, ''] if m{^DPPP_\(my_(\w+)\)}; - - $replace = $1 if m{^\s*$rccs\s+Replace:\s+(\d+)\s+$rcce\s*$}; - $replace{$2} = $1 if $replace and m{^\s*#\s*define\s+(\w+)(?:\([^)]*\))?\s+(\w+)}; - $replace{$2} = $1 if m{^\s*#\s*define\s+(\w+)(?:\([^)]*\))?\s+(\w+).*$rccs\s+Replace\s+$rcce}; - $replace{$1} = $2 if m{^\s*$rccs\s+Replace (\w+) with (\w+)\s+$rcce\s*$}; - - if (m{^\s*$rccs\s+(\w+(\s*,\s*\w+)*)\s+depends\s+on\s+(\w+(\s*,\s*\w+)*)\s+$rcce\s*$}) { - my @deps = map { s/\s+//g; $_ } split /,/, $3; - my $d; - for $d (map { s/\s+//g; $_ } split /,/, $1) { - push @{$depends{$d}}, @deps; - } - } - - $need{$1} = 1 if m{^#if\s+defined\(NEED_(\w+)(?:_GLOBAL)?\)}; -} - -for (values %depends) { - my %s; - $_ = [sort grep !$s{$_}++, @$_]; -} - -if (exists $opt{'api-info'}) { - my $f; - my $count = 0; - my $match = $opt{'api-info'} =~ m!^/(.*)/$! ? $1 : "^\Q$opt{'api-info'}\E\$"; - for $f (sort { lc $a cmp lc $b } keys %API) { - next unless $f =~ /$match/; - print "\n=== $f ===\n\n"; - my $info = 0; - if ($API{$f}{base} || $API{$f}{todo}) { - my $base = format_version($API{$f}{base} || $API{$f}{todo}); - print "Supported at least starting from perl-$base.\n"; - $info++; - } - if ($API{$f}{provided}) { - my $todo = $API{$f}{todo} ? format_version($API{$f}{todo}) : "5.003"; - print "Support by $ppport provided back to perl-$todo.\n"; - print "Support needs to be explicitly requested by NEED_$f.\n" if exists $need{$f}; - print "Depends on: ", join(', ', @{$depends{$f}}), ".\n" if exists $depends{$f}; - print "\n$hints{$f}" if exists $hints{$f}; - print "\nWARNING:\n$warnings{$f}" if exists $warnings{$f}; - $info++; - } - print "No portability information available.\n" unless $info; - $count++; - } - $count or print "Found no API matching '$opt{'api-info'}'."; - print "\n"; - exit 0; -} - -if (exists $opt{'list-provided'}) { - my $f; - for $f (sort { lc $a cmp lc $b } keys %API) { - next unless $API{$f}{provided}; - my @flags; - push @flags, 'explicit' if exists $need{$f}; - push @flags, 'depend' if exists $depends{$f}; - push @flags, 'hint' if exists $hints{$f}; - push @flags, 'warning' if exists $warnings{$f}; - my $flags = @flags ? ' ['.join(', ', @flags).']' : ''; - print "$f$flags\n"; - } - exit 0; -} - -my @files; -my @srcext = qw( .xs .c .h .cc .cpp -c.inc -xs.inc ); -my $srcext = join '|', map { quotemeta $_ } @srcext; - -if (@ARGV) { - my %seen; - for (@ARGV) { - if (-e) { - if (-f) { - push @files, $_ unless $seen{$_}++; - } - else { warn "'$_' is not a file.\n" } - } - else { - my @new = grep { -f } glob $_ - or warn "'$_' does not exist.\n"; - push @files, grep { !$seen{$_}++ } @new; - } - } -} -else { - eval { - require File::Find; - File::Find::find(sub { - $File::Find::name =~ /($srcext)$/i - and push @files, $File::Find::name; - }, '.'); - }; - if ($@) { - @files = map { glob "*$_" } @srcext; - } -} - -if (!@ARGV || $opt{filter}) { - my(@in, @out); - my %xsc = map { /(.*)\.xs$/ ? ("$1.c" => 1, "$1.cc" => 1) : () } @files; - for (@files) { - my $out = exists $xsc{$_} || /\b\Q$ppport\E$/i || !/($srcext)$/i; - push @{ $out ? \@out : \@in }, $_; - } - if (@ARGV && @out) { - warning("Skipping the following files (use --nofilter to avoid this):\n| ", join "\n| ", @out); - } - @files = @in; -} - -die "No input files given!\n" unless @files; - -my(%files, %global, %revreplace); -%revreplace = reverse %replace; -my $filename; -my $patch_opened = 0; - -for $filename (@files) { - unless (open IN, "<$filename") { - warn "Unable to read from $filename: $!\n"; - next; - } - - info("Scanning $filename ..."); - - my $c = do { local $/; }; - close IN; - - my %file = (orig => $c, changes => 0); - - # Temporarily remove C/XS comments and strings from the code - my @ccom; - - $c =~ s{ - ( ^$HS*\#$HS*include\b[^\r\n]+\b(?:\Q$ppport\E|XSUB\.h)\b[^\r\n]* - | ^$HS*\#$HS*(?:define|elif|if(?:def)?)\b[^\r\n]* ) - | ( ^$HS*\#[^\r\n]* - | "[^"\\]*(?:\\.[^"\\]*)*" - | '[^'\\]*(?:\\.[^'\\]*)*' - | / (?: \*[^*]*\*+(?:[^$ccs][^*]*\*+)* / | /[^\r\n]* ) ) - }{ defined $2 and push @ccom, $2; - defined $1 ? $1 : "$ccs$#ccom$cce" }mgsex; - - $file{ccom} = \@ccom; - $file{code} = $c; - $file{has_inc_ppport} = $c =~ /^$HS*#$HS*include[^\r\n]+\b\Q$ppport\E\b/m; - - my $func; - - for $func (keys %API) { - my $match = $func; - $match .= "|$revreplace{$func}" if exists $revreplace{$func}; - if ($c =~ /\b(?:Perl_)?($match)\b/) { - $file{uses_replace}{$1}++ if exists $revreplace{$func} && $1 eq $revreplace{$func}; - $file{uses_Perl}{$func}++ if $c =~ /\bPerl_$func\b/; - if (exists $API{$func}{provided}) { - $file{uses_provided}{$func}++; - if (!exists $API{$func}{base} || $API{$func}{base} > $opt{'compat-version'}) { - $file{uses}{$func}++; - my @deps = rec_depend($func); - if (@deps) { - $file{uses_deps}{$func} = \@deps; - for (@deps) { - $file{uses}{$_} = 0 unless exists $file{uses}{$_}; - } - } - for ($func, @deps) { - $file{needs}{$_} = 'static' if exists $need{$_}; - } - } - } - if (exists $API{$func}{todo} && $API{$func}{todo} > $opt{'compat-version'}) { - if ($c =~ /\b$func\b/) { - $file{uses_todo}{$func}++; - } - } - } - } - - while ($c =~ /^$HS*#$HS*define$HS+(NEED_(\w+?)(_GLOBAL)?)\b/mg) { - if (exists $need{$2}) { - $file{defined $3 ? 'needed_global' : 'needed_static'}{$2}++; - } - else { warning("Possibly wrong #define $1 in $filename") } - } - - for (qw(uses needs uses_todo needed_global needed_static)) { - for $func (keys %{$file{$_}}) { - push @{$global{$_}{$func}}, $filename; - } - } - - $files{$filename} = \%file; -} - -# Globally resolve NEED_'s -my $need; -for $need (keys %{$global{needs}}) { - if (@{$global{needs}{$need}} > 1) { - my @targets = @{$global{needs}{$need}}; - my @t = grep $files{$_}{needed_global}{$need}, @targets; - @targets = @t if @t; - @t = grep /\.xs$/i, @targets; - @targets = @t if @t; - my $target = shift @targets; - $files{$target}{needs}{$need} = 'global'; - for (@{$global{needs}{$need}}) { - $files{$_}{needs}{$need} = 'extern' if $_ ne $target; - } - } -} - -for $filename (@files) { - exists $files{$filename} or next; - - info("=== Analyzing $filename ==="); - - my %file = %{$files{$filename}}; - my $func; - my $c = $file{code}; - my $warnings = 0; - - for $func (sort keys %{$file{uses_Perl}}) { - if ($API{$func}{varargs}) { - unless ($API{$func}{nothxarg}) { - my $changes = ($c =~ s{\b(Perl_$func\s*\(\s*)(?!aTHX_?)(\)|[^\s)]*\))} - { $1 . ($2 eq ')' ? 'aTHX' : 'aTHX_ ') . $2 }ge); - if ($changes) { - warning("Doesn't pass interpreter argument aTHX to Perl_$func"); - $file{changes} += $changes; - } - } - } - else { - warning("Uses Perl_$func instead of $func"); - $file{changes} += ($c =~ s{\bPerl_$func(\s*)\((\s*aTHX_?)?\s*} - {$func$1(}g); - } - } - - for $func (sort keys %{$file{uses_replace}}) { - warning("Uses $func instead of $replace{$func}"); - $file{changes} += ($c =~ s/\b$func\b/$replace{$func}/g); - } - - for $func (sort keys %{$file{uses_provided}}) { - if ($file{uses}{$func}) { - if (exists $file{uses_deps}{$func}) { - diag("Uses $func, which depends on ", join(', ', @{$file{uses_deps}{$func}})); - } - else { - diag("Uses $func"); - } - } - $warnings += hint($func); - } - - unless ($opt{quiet}) { - for $func (sort keys %{$file{uses_todo}}) { - print "*** WARNING: Uses $func, which may not be portable below perl ", - format_version($API{$func}{todo}), ", even with '$ppport'\n"; - $warnings++; - } - } - - for $func (sort keys %{$file{needed_static}}) { - my $message = ''; - if (not exists $file{uses}{$func}) { - $message = "No need to define NEED_$func if $func is never used"; - } - elsif (exists $file{needs}{$func} && $file{needs}{$func} ne 'static') { - $message = "No need to define NEED_$func when already needed globally"; - } - if ($message) { - diag($message); - $file{changes} += ($c =~ s/^$HS*#$HS*define$HS+NEED_$func\b.*$LF//mg); - } - } - - for $func (sort keys %{$file{needed_global}}) { - my $message = ''; - if (not exists $global{uses}{$func}) { - $message = "No need to define NEED_${func}_GLOBAL if $func is never used"; - } - elsif (exists $file{needs}{$func}) { - if ($file{needs}{$func} eq 'extern') { - $message = "No need to define NEED_${func}_GLOBAL when already needed globally"; - } - elsif ($file{needs}{$func} eq 'static') { - $message = "No need to define NEED_${func}_GLOBAL when only used in this file"; - } - } - if ($message) { - diag($message); - $file{changes} += ($c =~ s/^$HS*#$HS*define$HS+NEED_${func}_GLOBAL\b.*$LF//mg); - } - } - - $file{needs_inc_ppport} = keys %{$file{uses}}; - - if ($file{needs_inc_ppport}) { - my $pp = ''; - - for $func (sort keys %{$file{needs}}) { - my $type = $file{needs}{$func}; - next if $type eq 'extern'; - my $suffix = $type eq 'global' ? '_GLOBAL' : ''; - unless (exists $file{"needed_$type"}{$func}) { - if ($type eq 'global') { - diag("Files [@{$global{needs}{$func}}] need $func, adding global request"); - } - else { - diag("File needs $func, adding static request"); - } - $pp .= "#define NEED_$func$suffix\n"; - } - } - - if ($pp && ($c =~ s/^(?=$HS*#$HS*define$HS+NEED_\w+)/$pp/m)) { - $pp = ''; - $file{changes}++; - } - - unless ($file{has_inc_ppport}) { - diag("Needs to include '$ppport'"); - $pp .= qq(#include "$ppport"\n) - } - - if ($pp) { - $file{changes} += ($c =~ s/^($HS*#$HS*define$HS+NEED_\w+.*?)^/$1$pp/ms) - || ($c =~ s/^(?=$HS*#$HS*include.*\Q$ppport\E)/$pp/m) - || ($c =~ s/^($HS*#$HS*include.*XSUB.*\s*?)^/$1$pp/m) - || ($c =~ s/^/$pp/); - } - } - else { - if ($file{has_inc_ppport}) { - diag("No need to include '$ppport'"); - $file{changes} += ($c =~ s/^$HS*?#$HS*include.*\Q$ppport\E.*?$LF//m); - } - } - - # put back in our C comments - my $ix; - my $cppc = 0; - my @ccom = @{$file{ccom}}; - for $ix (0 .. $#ccom) { - if (!$opt{cplusplus} && $ccom[$ix] =~ s!^//!!) { - $cppc++; - $file{changes} += $c =~ s/$rccs$ix$rcce/$ccs$ccom[$ix] $cce/; - } - else { - $c =~ s/$rccs$ix$rcce/$ccom[$ix]/; - } - } - - if ($cppc) { - my $s = $cppc != 1 ? 's' : ''; - warning("Uses $cppc C++ style comment$s, which is not portable"); - } - - my $s = $warnings != 1 ? 's' : ''; - my $warn = $warnings ? " ($warnings warning$s)" : ''; - info("Analysis completed$warn"); - - if ($file{changes}) { - if (exists $opt{copy}) { - my $newfile = "$filename$opt{copy}"; - if (-e $newfile) { - error("'$newfile' already exists, refusing to write copy of '$filename'"); - } - else { - local *F; - if (open F, ">$newfile") { - info("Writing copy of '$filename' with changes to '$newfile'"); - print F $c; - close F; - } - else { - error("Cannot open '$newfile' for writing: $!"); - } - } - } - elsif (exists $opt{patch} || $opt{changes}) { - if (exists $opt{patch}) { - unless ($patch_opened) { - if (open PATCH, ">$opt{patch}") { - $patch_opened = 1; - } - else { - error("Cannot open '$opt{patch}' for writing: $!"); - delete $opt{patch}; - $opt{changes} = 1; - goto fallback; - } - } - mydiff(\*PATCH, $filename, $c); - } - else { -fallback: - info("Suggested changes:"); - mydiff(\*STDOUT, $filename, $c); - } - } - else { - my $s = $file{changes} == 1 ? '' : 's'; - info("$file{changes} potentially required change$s detected"); - } - } - else { - info("Looks good"); - } -} - -close PATCH if $patch_opened; - -exit 0; - - -sub try_use { eval "use @_;"; return $@ eq '' } - -sub mydiff -{ - local *F = shift; - my($file, $str) = @_; - my $diff; - - if (exists $opt{diff}) { - $diff = run_diff($opt{diff}, $file, $str); - } - - if (!defined $diff and try_use('Text::Diff')) { - $diff = Text::Diff::diff($file, \$str, { STYLE => 'Unified' }); - $diff = <
$tmp") { - print F $str; - close F; - - if (open F, "$prog $file $tmp |") { - while () { - s/\Q$tmp\E/$file.patched/; - $diff .= $_; - } - close F; - unlink $tmp; - return $diff; - } - - unlink $tmp; - } - else { - error("Cannot open '$tmp' for writing: $!"); - } - - return undef; -} - -sub rec_depend -{ - my($func, $seen) = @_; - return () unless exists $depends{$func}; - $seen = {%{$seen||{}}}; - return () if $seen->{$func}++; - my %s; - grep !$s{$_}++, map { ($_, rec_depend($_, $seen)) } @{$depends{$func}}; -} - -sub parse_version -{ - my $ver = shift; - - if ($ver =~ /^(\d+)\.(\d+)\.(\d+)$/) { - return ($1, $2, $3); - } - elsif ($ver !~ /^\d+\.[\d_]+$/) { - die "cannot parse version '$ver'\n"; - } - - $ver =~ s/_//g; - $ver =~ s/$/000000/; - - my($r,$v,$s) = $ver =~ /(\d+)\.(\d{3})(\d{3})/; - - $v = int $v; - $s = int $s; - - if ($r < 5 || ($r == 5 && $v < 6)) { - if ($s % 10) { - die "cannot parse version '$ver'\n"; - } - } - - return ($r, $v, $s); -} - -sub format_version -{ - my $ver = shift; - - $ver =~ s/$/000000/; - my($r,$v,$s) = $ver =~ /(\d+)\.(\d{3})(\d{3})/; - - $v = int $v; - $s = int $s; - - if ($r < 5 || ($r == 5 && $v < 6)) { - if ($s % 10) { - die "invalid version '$ver'\n"; - } - $s /= 10; - - $ver = sprintf "%d.%03d", $r, $v; - $s > 0 and $ver .= sprintf "_%02d", $s; - - return $ver; - } - - return sprintf "%d.%d.%d", $r, $v, $s; -} - -sub info -{ - $opt{quiet} and return; - print @_, "\n"; -} - -sub diag -{ - $opt{quiet} and return; - $opt{diag} and print @_, "\n"; -} - -sub warning -{ - $opt{quiet} and return; - print "*** ", @_, "\n"; -} - -sub error -{ - print "*** ERROR: ", @_, "\n"; -} - -my %given_hints; -my %given_warnings; -sub hint -{ - $opt{quiet} and return; - my $func = shift; - my $rv = 0; - if (exists $warnings{$func} && !$given_warnings{$func}++) { - my $warn = $warnings{$func}; - $warn =~ s!^!*** !mg; - print "*** WARNING: $func\n", $warn; - $rv++; - } - if ($opt{hints} && exists $hints{$func} && !$given_hints{$func}++) { - my $hint = $hints{$func}; - $hint =~ s/^/ /mg; - print " --- hint for $func ---\n", $hint; - } - $rv; -} - -sub usage -{ - my($usage) = do { local(@ARGV,$/)=($0); <> } =~ /^=head\d$HS+SYNOPSIS\s*^(.*?)\s*^=/ms; - my %M = ( 'I' => '*' ); - $usage =~ s/^\s*perl\s+\S+/$^X $0/; - $usage =~ s/([A-Z])<([^>]+)>/$M{$1}$2$M{$1}/g; - - print < }; - my($copy) = $self =~ /^=head\d\s+COPYRIGHT\s*^(.*?)^=\w+/ms; - $copy =~ s/^(?=\S+)/ /gms; - $self =~ s/^$HS+Do NOT edit.*?(?=^-)/$copy/ms; - $self =~ s/^SKIP.*(?=^__DATA__)/SKIP -if (\@ARGV && \$ARGV[0] eq '--unstrip') { - eval { require Devel::PPPort }; - \$@ and die "Cannot require Devel::PPPort, please install.\\n"; - if (eval \$Devel::PPPort::VERSION < $VERSION) { - die "$0 was originally generated with Devel::PPPort $VERSION.\\n" - . "Your Devel::PPPort is only version \$Devel::PPPort::VERSION.\\n" - . "Please install a newer version, or --unstrip will not work.\\n"; - } - Devel::PPPort::WriteFile(\$0); - exit 0; -} -print <$0" or die "cannot strip $0: $!\n"; - print OUT "$pl$c\n"; - - exit 0; -} - -__DATA__ -*/ - -#ifndef _P_P_PORTABILITY_H_ -#define _P_P_PORTABILITY_H_ - -#ifndef DPPP_NAMESPACE -# define DPPP_NAMESPACE DPPP_ -#endif - -#define DPPP_CAT2(x,y) CAT2(x,y) -#define DPPP_(name) DPPP_CAT2(DPPP_NAMESPACE, name) - -#ifndef PERL_REVISION -# if !defined(__PATCHLEVEL_H_INCLUDED__) && !(defined(PATCHLEVEL) && defined(SUBVERSION)) -# define PERL_PATCHLEVEL_H_IMPLICIT -# include -# endif -# if !(defined(PERL_VERSION) || (defined(SUBVERSION) && defined(PATCHLEVEL))) -# include -# endif -# ifndef PERL_REVISION -# define PERL_REVISION (5) - /* Replace: 1 */ -# define PERL_VERSION PATCHLEVEL -# define PERL_SUBVERSION SUBVERSION - /* Replace PERL_PATCHLEVEL with PERL_VERSION */ - /* Replace: 0 */ -# endif -#endif - -#define _dpppDEC2BCD(dec) ((((dec)/100)<<8)|((((dec)%100)/10)<<4)|((dec)%10)) -#define PERL_BCDVERSION ((_dpppDEC2BCD(PERL_REVISION)<<24)|(_dpppDEC2BCD(PERL_VERSION)<<12)|_dpppDEC2BCD(PERL_SUBVERSION)) - -/* It is very unlikely that anyone will try to use this with Perl 6 - (or greater), but who knows. - */ -#if PERL_REVISION != 5 -# error ppport.h only works with Perl version 5 -#endif /* PERL_REVISION != 5 */ -#ifndef dTHR -# define dTHR dNOOP -#endif -#ifndef dTHX -# define dTHX dNOOP -#endif - -#ifndef dTHXa -# define dTHXa(x) dNOOP -#endif -#ifndef pTHX -# define pTHX void -#endif - -#ifndef pTHX_ -# define pTHX_ -#endif - -#ifndef aTHX -# define aTHX -#endif - -#ifndef aTHX_ -# define aTHX_ -#endif - -#if (PERL_BCDVERSION < 0x5006000) -# ifdef USE_THREADS -# define aTHXR thr -# define aTHXR_ thr, -# else -# define aTHXR -# define aTHXR_ -# endif -# define dTHXR dTHR -#else -# define aTHXR aTHX -# define aTHXR_ aTHX_ -# define dTHXR dTHX -#endif -#ifndef dTHXoa -# define dTHXoa(x) dTHXa(x) -#endif - -#ifdef I_LIMITS -# include -#endif - -#ifndef PERL_UCHAR_MIN -# define PERL_UCHAR_MIN ((unsigned char)0) -#endif - -#ifndef PERL_UCHAR_MAX -# ifdef UCHAR_MAX -# define PERL_UCHAR_MAX ((unsigned char)UCHAR_MAX) -# else -# ifdef MAXUCHAR -# define PERL_UCHAR_MAX ((unsigned char)MAXUCHAR) -# else -# define PERL_UCHAR_MAX ((unsigned char)~(unsigned)0) -# endif -# endif -#endif - -#ifndef PERL_USHORT_MIN -# define PERL_USHORT_MIN ((unsigned short)0) -#endif - -#ifndef PERL_USHORT_MAX -# ifdef USHORT_MAX -# define PERL_USHORT_MAX ((unsigned short)USHORT_MAX) -# else -# ifdef MAXUSHORT -# define PERL_USHORT_MAX ((unsigned short)MAXUSHORT) -# else -# ifdef USHRT_MAX -# define PERL_USHORT_MAX ((unsigned short)USHRT_MAX) -# else -# define PERL_USHORT_MAX ((unsigned short)~(unsigned)0) -# endif -# endif -# endif -#endif - -#ifndef PERL_SHORT_MAX -# ifdef SHORT_MAX -# define PERL_SHORT_MAX ((short)SHORT_MAX) -# else -# ifdef MAXSHORT /* Often used in */ -# define PERL_SHORT_MAX ((short)MAXSHORT) -# else -# ifdef SHRT_MAX -# define PERL_SHORT_MAX ((short)SHRT_MAX) -# else -# define PERL_SHORT_MAX ((short) (PERL_USHORT_MAX >> 1)) -# endif -# endif -# endif -#endif - -#ifndef PERL_SHORT_MIN -# ifdef SHORT_MIN -# define PERL_SHORT_MIN ((short)SHORT_MIN) -# else -# ifdef MINSHORT -# define PERL_SHORT_MIN ((short)MINSHORT) -# else -# ifdef SHRT_MIN -# define PERL_SHORT_MIN ((short)SHRT_MIN) -# else -# define PERL_SHORT_MIN (-PERL_SHORT_MAX - ((3 & -1) == 3)) -# endif -# endif -# endif -#endif - -#ifndef PERL_UINT_MAX -# ifdef UINT_MAX -# define PERL_UINT_MAX ((unsigned int)UINT_MAX) -# else -# ifdef MAXUINT -# define PERL_UINT_MAX ((unsigned int)MAXUINT) -# else -# define PERL_UINT_MAX (~(unsigned int)0) -# endif -# endif -#endif - -#ifndef PERL_UINT_MIN -# define PERL_UINT_MIN ((unsigned int)0) -#endif - -#ifndef PERL_INT_MAX -# ifdef INT_MAX -# define PERL_INT_MAX ((int)INT_MAX) -# else -# ifdef MAXINT /* Often used in */ -# define PERL_INT_MAX ((int)MAXINT) -# else -# define PERL_INT_MAX ((int)(PERL_UINT_MAX >> 1)) -# endif -# endif -#endif - -#ifndef PERL_INT_MIN -# ifdef INT_MIN -# define PERL_INT_MIN ((int)INT_MIN) -# else -# ifdef MININT -# define PERL_INT_MIN ((int)MININT) -# else -# define PERL_INT_MIN (-PERL_INT_MAX - ((3 & -1) == 3)) -# endif -# endif -#endif - -#ifndef PERL_ULONG_MAX -# ifdef ULONG_MAX -# define PERL_ULONG_MAX ((unsigned long)ULONG_MAX) -# else -# ifdef MAXULONG -# define PERL_ULONG_MAX ((unsigned long)MAXULONG) -# else -# define PERL_ULONG_MAX (~(unsigned long)0) -# endif -# endif -#endif - -#ifndef PERL_ULONG_MIN -# define PERL_ULONG_MIN ((unsigned long)0L) -#endif - -#ifndef PERL_LONG_MAX -# ifdef LONG_MAX -# define PERL_LONG_MAX ((long)LONG_MAX) -# else -# ifdef MAXLONG -# define PERL_LONG_MAX ((long)MAXLONG) -# else -# define PERL_LONG_MAX ((long) (PERL_ULONG_MAX >> 1)) -# endif -# endif -#endif - -#ifndef PERL_LONG_MIN -# ifdef LONG_MIN -# define PERL_LONG_MIN ((long)LONG_MIN) -# else -# ifdef MINLONG -# define PERL_LONG_MIN ((long)MINLONG) -# else -# define PERL_LONG_MIN (-PERL_LONG_MAX - ((3 & -1) == 3)) -# endif -# endif -#endif - -#if defined(HAS_QUAD) && (defined(convex) || defined(uts)) -# ifndef PERL_UQUAD_MAX -# ifdef ULONGLONG_MAX -# define PERL_UQUAD_MAX ((unsigned long long)ULONGLONG_MAX) -# else -# ifdef MAXULONGLONG -# define PERL_UQUAD_MAX ((unsigned long long)MAXULONGLONG) -# else -# define PERL_UQUAD_MAX (~(unsigned long long)0) -# endif -# endif -# endif - -# ifndef PERL_UQUAD_MIN -# define PERL_UQUAD_MIN ((unsigned long long)0L) -# endif - -# ifndef PERL_QUAD_MAX -# ifdef LONGLONG_MAX -# define PERL_QUAD_MAX ((long long)LONGLONG_MAX) -# else -# ifdef MAXLONGLONG -# define PERL_QUAD_MAX ((long long)MAXLONGLONG) -# else -# define PERL_QUAD_MAX ((long long) (PERL_UQUAD_MAX >> 1)) -# endif -# endif -# endif - -# ifndef PERL_QUAD_MIN -# ifdef LONGLONG_MIN -# define PERL_QUAD_MIN ((long long)LONGLONG_MIN) -# else -# ifdef MINLONGLONG -# define PERL_QUAD_MIN ((long long)MINLONGLONG) -# else -# define PERL_QUAD_MIN (-PERL_QUAD_MAX - ((3 & -1) == 3)) -# endif -# endif -# endif -#endif - -/* This is based on code from 5.003 perl.h */ -#ifdef HAS_QUAD -# ifdef cray -#ifndef IVTYPE -# define IVTYPE int -#endif - -#ifndef IV_MIN -# define IV_MIN PERL_INT_MIN -#endif - -#ifndef IV_MAX -# define IV_MAX PERL_INT_MAX -#endif - -#ifndef UV_MIN -# define UV_MIN PERL_UINT_MIN -#endif - -#ifndef UV_MAX -# define UV_MAX PERL_UINT_MAX -#endif - -# ifdef INTSIZE -#ifndef IVSIZE -# define IVSIZE INTSIZE -#endif - -# endif -# else -# if defined(convex) || defined(uts) -#ifndef IVTYPE -# define IVTYPE long long -#endif - -#ifndef IV_MIN -# define IV_MIN PERL_QUAD_MIN -#endif - -#ifndef IV_MAX -# define IV_MAX PERL_QUAD_MAX -#endif - -#ifndef UV_MIN -# define UV_MIN PERL_UQUAD_MIN -#endif - -#ifndef UV_MAX -# define UV_MAX PERL_UQUAD_MAX -#endif - -# ifdef LONGLONGSIZE -#ifndef IVSIZE -# define IVSIZE LONGLONGSIZE -#endif - -# endif -# else -#ifndef IVTYPE -# define IVTYPE long -#endif - -#ifndef IV_MIN -# define IV_MIN PERL_LONG_MIN -#endif - -#ifndef IV_MAX -# define IV_MAX PERL_LONG_MAX -#endif - -#ifndef UV_MIN -# define UV_MIN PERL_ULONG_MIN -#endif - -#ifndef UV_MAX -# define UV_MAX PERL_ULONG_MAX -#endif - -# ifdef LONGSIZE -#ifndef IVSIZE -# define IVSIZE LONGSIZE -#endif - -# endif -# endif -# endif -#ifndef IVSIZE -# define IVSIZE 8 -#endif - -#ifndef LONGSIZE -# define LONGSIZE 8 -#endif - -#ifndef PERL_QUAD_MIN -# define PERL_QUAD_MIN IV_MIN -#endif - -#ifndef PERL_QUAD_MAX -# define PERL_QUAD_MAX IV_MAX -#endif - -#ifndef PERL_UQUAD_MIN -# define PERL_UQUAD_MIN UV_MIN -#endif - -#ifndef PERL_UQUAD_MAX -# define PERL_UQUAD_MAX UV_MAX -#endif - -#else -#ifndef IVTYPE -# define IVTYPE long -#endif - -#ifndef LONGSIZE -# define LONGSIZE 4 -#endif - -#ifndef IV_MIN -# define IV_MIN PERL_LONG_MIN -#endif - -#ifndef IV_MAX -# define IV_MAX PERL_LONG_MAX -#endif - -#ifndef UV_MIN -# define UV_MIN PERL_ULONG_MIN -#endif - -#ifndef UV_MAX -# define UV_MAX PERL_ULONG_MAX -#endif - -#endif - -#ifndef IVSIZE -# ifdef LONGSIZE -# define IVSIZE LONGSIZE -# else -# define IVSIZE 4 /* A bold guess, but the best we can make. */ -# endif -#endif -#ifndef UVTYPE -# define UVTYPE unsigned IVTYPE -#endif - -#ifndef UVSIZE -# define UVSIZE IVSIZE -#endif -#ifndef sv_setuv -# define sv_setuv(sv, uv) \ - STMT_START { \ - UV TeMpUv = uv; \ - if (TeMpUv <= IV_MAX) \ - sv_setiv(sv, TeMpUv); \ - else \ - sv_setnv(sv, (double)TeMpUv); \ - } STMT_END -#endif -#ifndef newSVuv -# define newSVuv(uv) ((uv) <= IV_MAX ? newSViv((IV)uv) : newSVnv((NV)uv)) -#endif -#ifndef sv_2uv -# define sv_2uv(sv) ((PL_Sv = (sv)), (UV) (SvNOK(PL_Sv) ? SvNV(PL_Sv) : sv_2nv(PL_Sv))) -#endif - -#ifndef SvUVX -# define SvUVX(sv) ((UV)SvIVX(sv)) -#endif - -#ifndef SvUVXx -# define SvUVXx(sv) SvUVX(sv) -#endif - -#ifndef SvUV -# define SvUV(sv) (SvIOK(sv) ? SvUVX(sv) : sv_2uv(sv)) -#endif - -#ifndef SvUVx -# define SvUVx(sv) ((PL_Sv = (sv)), SvUV(PL_Sv)) -#endif - -/* Hint: sv_uv - * Always use the SvUVx() macro instead of sv_uv(). - */ -#ifndef sv_uv -# define sv_uv(sv) SvUVx(sv) -#endif - -#if !defined(SvUOK) && defined(SvIOK_UV) -# define SvUOK(sv) SvIOK_UV(sv) -#endif -#ifndef XST_mUV -# define XST_mUV(i,v) (ST(i) = sv_2mortal(newSVuv(v)) ) -#endif - -#ifndef XSRETURN_UV -# define XSRETURN_UV(v) STMT_START { XST_mUV(0,v); XSRETURN(1); } STMT_END -#endif -#ifndef PUSHu -# define PUSHu(u) STMT_START { sv_setuv(TARG, (UV)(u)); PUSHTARG; } STMT_END -#endif - -#ifndef XPUSHu -# define XPUSHu(u) STMT_START { sv_setuv(TARG, (UV)(u)); XPUSHTARG; } STMT_END -#endif - -#ifdef HAS_MEMCMP -#ifndef memNE -# define memNE(s1,s2,l) (memcmp(s1,s2,l)) -#endif - -#ifndef memEQ -# define memEQ(s1,s2,l) (!memcmp(s1,s2,l)) -#endif - -#else -#ifndef memNE -# define memNE(s1,s2,l) (bcmp(s1,s2,l)) -#endif - -#ifndef memEQ -# define memEQ(s1,s2,l) (!bcmp(s1,s2,l)) -#endif - -#endif -#ifndef memEQs -# define memEQs(s1, l, s2) \ - (sizeof(s2)-1 == l && memEQ(s1, (s2 ""), (sizeof(s2)-1))) -#endif - -#ifndef memNEs -# define memNEs(s1, l, s2) !memEQs(s1, l, s2) -#endif -#ifndef MoveD -# define MoveD(s,d,n,t) memmove((char*)(d),(char*)(s), (n) * sizeof(t)) -#endif - -#ifndef CopyD -# define CopyD(s,d,n,t) memcpy((char*)(d),(char*)(s), (n) * sizeof(t)) -#endif - -#ifdef HAS_MEMSET -#ifndef ZeroD -# define ZeroD(d,n,t) memzero((char*)(d), (n) * sizeof(t)) -#endif - -#else -#ifndef ZeroD -# define ZeroD(d,n,t) ((void)memzero((char*)(d), (n) * sizeof(t)), d) -#endif - -#endif -#ifndef PoisonWith -# define PoisonWith(d,n,t,b) (void)memset((char*)(d), (U8)(b), (n) * sizeof(t)) -#endif - -#ifndef PoisonNew -# define PoisonNew(d,n,t) PoisonWith(d,n,t,0xAB) -#endif - -#ifndef PoisonFree -# define PoisonFree(d,n,t) PoisonWith(d,n,t,0xEF) -#endif - -#ifndef Poison -# define Poison(d,n,t) PoisonFree(d,n,t) -#endif -#ifndef Newx -# define Newx(v,n,t) New(0,v,n,t) -#endif - -#ifndef Newxc -# define Newxc(v,n,t,c) Newc(0,v,n,t,c) -#endif - -#ifndef Newxz -# define Newxz(v,n,t) Newz(0,v,n,t) -#endif - -#ifndef PERL_UNUSED_DECL -# ifdef HASATTRIBUTE -# if (defined(__GNUC__) && defined(__cplusplus)) || defined(__INTEL_COMPILER) -# define PERL_UNUSED_DECL -# else -# define PERL_UNUSED_DECL __attribute__((unused)) -# endif -# else -# define PERL_UNUSED_DECL -# endif -#endif - -#ifndef PERL_UNUSED_ARG -# if defined(lint) && defined(S_SPLINT_S) /* www.splint.org */ -# include -# define PERL_UNUSED_ARG(x) NOTE(ARGUNUSED(x)) -# else -# define PERL_UNUSED_ARG(x) ((void)x) -# endif -#endif - -#ifndef PERL_UNUSED_VAR -# define PERL_UNUSED_VAR(x) ((void)x) -#endif - -#ifndef PERL_UNUSED_CONTEXT -# ifdef USE_ITHREADS -# define PERL_UNUSED_CONTEXT PERL_UNUSED_ARG(my_perl) -# else -# define PERL_UNUSED_CONTEXT -# endif -#endif -#ifndef NOOP -# define NOOP /*EMPTY*/(void)0 -#endif - -#ifndef dNOOP -# define dNOOP extern int /*@unused@*/ Perl___notused PERL_UNUSED_DECL -#endif - -#ifndef NVTYPE -# if defined(USE_LONG_DOUBLE) && defined(HAS_LONG_DOUBLE) -# define NVTYPE long double -# else -# define NVTYPE double -# endif -typedef NVTYPE NV; -#endif - -#ifndef INT2PTR -# if (IVSIZE == PTRSIZE) && (UVSIZE == PTRSIZE) -# define PTRV UV -# define INT2PTR(any,d) (any)(d) -# else -# if PTRSIZE == LONGSIZE -# define PTRV unsigned long -# else -# define PTRV unsigned -# endif -# define INT2PTR(any,d) (any)(PTRV)(d) -# endif -#endif - -#ifndef PTR2ul -# if PTRSIZE == LONGSIZE -# define PTR2ul(p) (unsigned long)(p) -# else -# define PTR2ul(p) INT2PTR(unsigned long,p) -# endif -#endif -#ifndef PTR2nat -# define PTR2nat(p) (PTRV)(p) -#endif - -#ifndef NUM2PTR -# define NUM2PTR(any,d) (any)PTR2nat(d) -#endif - -#ifndef PTR2IV -# define PTR2IV(p) INT2PTR(IV,p) -#endif - -#ifndef PTR2UV -# define PTR2UV(p) INT2PTR(UV,p) -#endif - -#ifndef PTR2NV -# define PTR2NV(p) NUM2PTR(NV,p) -#endif - -#undef START_EXTERN_C -#undef END_EXTERN_C -#undef EXTERN_C -#ifdef __cplusplus -# define START_EXTERN_C extern "C" { -# define END_EXTERN_C } -# define EXTERN_C extern "C" -#else -# define START_EXTERN_C -# define END_EXTERN_C -# define EXTERN_C extern -#endif - -#if defined(PERL_GCC_PEDANTIC) -# ifndef PERL_GCC_BRACE_GROUPS_FORBIDDEN -# define PERL_GCC_BRACE_GROUPS_FORBIDDEN -# endif -#endif - -#if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN) && !defined(__cplusplus) -# ifndef PERL_USE_GCC_BRACE_GROUPS -# define PERL_USE_GCC_BRACE_GROUPS -# endif -#endif - -#undef STMT_START -#undef STMT_END -#ifdef PERL_USE_GCC_BRACE_GROUPS -# define STMT_START (void)( /* gcc supports ``({ STATEMENTS; })'' */ -# define STMT_END ) -#else -# if defined(VOIDFLAGS) && (VOIDFLAGS) && (defined(sun) || defined(__sun__)) && !defined(__GNUC__) -# define STMT_START if (1) -# define STMT_END else (void)0 -# else -# define STMT_START do -# define STMT_END while (0) -# endif -#endif -#ifndef boolSV -# define boolSV(b) ((b) ? &PL_sv_yes : &PL_sv_no) -#endif - -/* DEFSV appears first in 5.004_56 */ -#ifndef DEFSV -# define DEFSV GvSV(PL_defgv) -#endif - -#ifndef SAVE_DEFSV -# define SAVE_DEFSV SAVESPTR(GvSV(PL_defgv)) -#endif - -#ifndef DEFSV_set -# define DEFSV_set(sv) (DEFSV = (sv)) -#endif - -/* Older perls (<=5.003) lack AvFILLp */ -#ifndef AvFILLp -# define AvFILLp AvFILL -#endif -#ifndef ERRSV -# define ERRSV get_sv("@",FALSE) -#endif - -/* Hint: gv_stashpvn - * This function's backport doesn't support the length parameter, but - * rather ignores it. Portability can only be ensured if the length - * parameter is used for speed reasons, but the length can always be - * correctly computed from the string argument. - */ -#ifndef gv_stashpvn -# define gv_stashpvn(str,len,create) gv_stashpv(str,create) -#endif - -/* Replace: 1 */ -#ifndef get_cv -# define get_cv perl_get_cv -#endif - -#ifndef get_sv -# define get_sv perl_get_sv -#endif - -#ifndef get_av -# define get_av perl_get_av -#endif - -#ifndef get_hv -# define get_hv perl_get_hv -#endif - -/* Replace: 0 */ -#ifndef dUNDERBAR -# define dUNDERBAR dNOOP -#endif - -#ifndef UNDERBAR -# define UNDERBAR DEFSV -#endif -#ifndef dAX -# define dAX I32 ax = MARK - PL_stack_base + 1 -#endif - -#ifndef dITEMS -# define dITEMS I32 items = SP - MARK -#endif -#ifndef dXSTARG -# define dXSTARG SV * targ = sv_newmortal() -#endif -#ifndef dAXMARK -# define dAXMARK I32 ax = POPMARK; \ - register SV ** const mark = PL_stack_base + ax++ -#endif -#ifndef XSprePUSH -# define XSprePUSH (sp = PL_stack_base + ax - 1) -#endif - -#if (PERL_BCDVERSION < 0x5005000) -# undef XSRETURN -# define XSRETURN(off) \ - STMT_START { \ - PL_stack_sp = PL_stack_base + ax + ((off) - 1); \ - return; \ - } STMT_END -#endif -#ifndef XSPROTO -# define XSPROTO(name) void name(pTHX_ CV* cv) -#endif - -#ifndef SVfARG -# define SVfARG(p) ((void*)(p)) -#endif -#ifndef PERL_ABS -# define PERL_ABS(x) ((x) < 0 ? -(x) : (x)) -#endif -#ifndef dVAR -# define dVAR dNOOP -#endif -#ifndef SVf -# define SVf "_" -#endif -#ifndef UTF8_MAXBYTES -# define UTF8_MAXBYTES UTF8_MAXLEN -#endif -#ifndef CPERLscope -# define CPERLscope(x) x -#endif -#ifndef PERL_HASH -# define PERL_HASH(hash,str,len) \ - STMT_START { \ - const char *s_PeRlHaSh = str; \ - I32 i_PeRlHaSh = len; \ - U32 hash_PeRlHaSh = 0; \ - while (i_PeRlHaSh--) \ - hash_PeRlHaSh = hash_PeRlHaSh * 33 + *s_PeRlHaSh++; \ - (hash) = hash_PeRlHaSh; \ - } STMT_END -#endif - -#ifndef PERLIO_FUNCS_DECL -# ifdef PERLIO_FUNCS_CONST -# define PERLIO_FUNCS_DECL(funcs) const PerlIO_funcs funcs -# define PERLIO_FUNCS_CAST(funcs) (PerlIO_funcs*)(funcs) -# else -# define PERLIO_FUNCS_DECL(funcs) PerlIO_funcs funcs -# define PERLIO_FUNCS_CAST(funcs) (funcs) -# endif -#endif - -/* provide these typedefs for older perls */ -#if (PERL_BCDVERSION < 0x5009003) - -# ifdef ARGSproto -typedef OP* (CPERLscope(*Perl_ppaddr_t))(ARGSproto); -# else -typedef OP* (CPERLscope(*Perl_ppaddr_t))(pTHX); -# endif - -typedef OP* (CPERLscope(*Perl_check_t)) (pTHX_ OP*); - -#endif -#ifndef isPSXSPC -# define isPSXSPC(c) (isSPACE(c) || (c) == '\v') -#endif - -#ifndef isBLANK -# define isBLANK(c) ((c) == ' ' || (c) == '\t') -#endif - -#ifdef EBCDIC -#ifndef isALNUMC -# define isALNUMC(c) isalnum(c) -#endif - -#ifndef isASCII -# define isASCII(c) isascii(c) -#endif - -#ifndef isCNTRL -# define isCNTRL(c) iscntrl(c) -#endif - -#ifndef isGRAPH -# define isGRAPH(c) isgraph(c) -#endif - -#ifndef isPRINT -# define isPRINT(c) isprint(c) -#endif - -#ifndef isPUNCT -# define isPUNCT(c) ispunct(c) -#endif - -#ifndef isXDIGIT -# define isXDIGIT(c) isxdigit(c) -#endif - -#else -# if (PERL_BCDVERSION < 0x5010000) -/* Hint: isPRINT - * The implementation in older perl versions includes all of the - * isSPACE() characters, which is wrong. The version provided by - * Devel::PPPort always overrides a present buggy version. - */ -# undef isPRINT -# endif - -#ifdef HAS_QUAD -# ifdef U64TYPE -# define WIDEST_UTYPE U64TYPE -# else -# define WIDEST_UTYPE Quad_t -# endif -#else -# define WIDEST_UTYPE U32 -#endif -#ifndef isALNUMC -# define isALNUMC(c) (isALPHA(c) || isDIGIT(c)) -#endif - -#ifndef isASCII -# define isASCII(c) ((WIDEST_UTYPE) (c) <= 127) -#endif - -#ifndef isCNTRL -# define isCNTRL(c) ((WIDEST_UTYPE) (c) < ' ' || (c) == 127) -#endif - -#ifndef isGRAPH -# define isGRAPH(c) (isALNUM(c) || isPUNCT(c)) -#endif - -#ifndef isPRINT -# define isPRINT(c) (((c) >= 32 && (c) < 127)) -#endif - -#ifndef isPUNCT -# define isPUNCT(c) (((c) >= 33 && (c) <= 47) || ((c) >= 58 && (c) <= 64) || ((c) >= 91 && (c) <= 96) || ((c) >= 123 && (c) <= 126)) -#endif - -#ifndef isXDIGIT -# define isXDIGIT(c) (isDIGIT(c) || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F')) -#endif - -#endif - -/* Until we figure out how to support this in older perls... */ -#if (PERL_BCDVERSION >= 0x5008000) -#ifndef HeUTF8 -# define HeUTF8(he) ((HeKLEN(he) == HEf_SVKEY) ? \ - SvUTF8(HeKEY_sv(he)) : \ - (U32)HeKUTF8(he)) -#endif - -#endif - -#ifndef PERL_SIGNALS_UNSAFE_FLAG - -#define PERL_SIGNALS_UNSAFE_FLAG 0x0001 - -#if (PERL_BCDVERSION < 0x5008000) -# define D_PPP_PERL_SIGNALS_INIT PERL_SIGNALS_UNSAFE_FLAG -#else -# define D_PPP_PERL_SIGNALS_INIT 0 -#endif - -#if defined(NEED_PL_signals) -static U32 DPPP_(my_PL_signals) = D_PPP_PERL_SIGNALS_INIT; -#elif defined(NEED_PL_signals_GLOBAL) -U32 DPPP_(my_PL_signals) = D_PPP_PERL_SIGNALS_INIT; -#else -extern U32 DPPP_(my_PL_signals); -#endif -#define PL_signals DPPP_(my_PL_signals) - -#endif - -/* Hint: PL_ppaddr - * Calling an op via PL_ppaddr requires passing a context argument - * for threaded builds. Since the context argument is different for - * 5.005 perls, you can use aTHXR (supplied by ppport.h), which will - * automatically be defined as the correct argument. - */ - -#if (PERL_BCDVERSION <= 0x5005005) -/* Replace: 1 */ -# define PL_ppaddr ppaddr -# define PL_no_modify no_modify -/* Replace: 0 */ -#endif - -#if (PERL_BCDVERSION <= 0x5004005) -/* Replace: 1 */ -# define PL_DBsignal DBsignal -# define PL_DBsingle DBsingle -# define PL_DBsub DBsub -# define PL_DBtrace DBtrace -# define PL_Sv Sv -# define PL_bufend bufend -# define PL_bufptr bufptr -# define PL_compiling compiling -# define PL_copline copline -# define PL_curcop curcop -# define PL_curstash curstash -# define PL_debstash debstash -# define PL_defgv defgv -# define PL_diehook diehook -# define PL_dirty dirty -# define PL_dowarn dowarn -# define PL_errgv errgv -# define PL_error_count error_count -# define PL_expect expect -# define PL_hexdigit hexdigit -# define PL_hints hints -# define PL_in_my in_my -# define PL_laststatval laststatval -# define PL_lex_state lex_state -# define PL_lex_stuff lex_stuff -# define PL_linestr linestr -# define PL_na na -# define PL_perl_destruct_level perl_destruct_level -# define PL_perldb perldb -# define PL_rsfp_filters rsfp_filters -# define PL_rsfp rsfp -# define PL_stack_base stack_base -# define PL_stack_sp stack_sp -# define PL_statcache statcache -# define PL_stdingv stdingv -# define PL_sv_arenaroot sv_arenaroot -# define PL_sv_no sv_no -# define PL_sv_undef sv_undef -# define PL_sv_yes sv_yes -# define PL_tainted tainted -# define PL_tainting tainting -# define PL_tokenbuf tokenbuf -/* Replace: 0 */ -#endif - -/* Warning: PL_parser - * For perl versions earlier than 5.9.5, this is an always - * non-NULL dummy. Also, it cannot be dereferenced. Don't - * use it if you can avoid is and unless you absolutely know - * what you're doing. - * If you always check that PL_parser is non-NULL, you can - * define DPPP_PL_parser_NO_DUMMY to avoid the creation of - * a dummy parser structure. - */ - -#if (PERL_BCDVERSION >= 0x5009005) -# ifdef DPPP_PL_parser_NO_DUMMY -# define D_PPP_my_PL_parser_var(var) ((PL_parser ? PL_parser : \ - (croak("panic: PL_parser == NULL in %s:%d", \ - __FILE__, __LINE__), (yy_parser *) NULL))->var) -# else -# ifdef DPPP_PL_parser_NO_DUMMY_WARNING -# define D_PPP_parser_dummy_warning(var) -# else -# define D_PPP_parser_dummy_warning(var) \ - warn("warning: dummy PL_" #var " used in %s:%d", __FILE__, __LINE__), -# endif -# define D_PPP_my_PL_parser_var(var) ((PL_parser ? PL_parser : \ - (D_PPP_parser_dummy_warning(var) &DPPP_(dummy_PL_parser)))->var) -#if defined(NEED_PL_parser) -static yy_parser DPPP_(dummy_PL_parser); -#elif defined(NEED_PL_parser_GLOBAL) -yy_parser DPPP_(dummy_PL_parser); -#else -extern yy_parser DPPP_(dummy_PL_parser); -#endif - -# endif - -/* PL_expect, PL_copline, PL_rsfp, PL_rsfp_filters, PL_linestr, PL_bufptr, PL_bufend, PL_lex_state, PL_lex_stuff, PL_tokenbuf depends on PL_parser */ -/* Warning: PL_expect, PL_copline, PL_rsfp, PL_rsfp_filters, PL_linestr, PL_bufptr, PL_bufend, PL_lex_state, PL_lex_stuff, PL_tokenbuf - * Do not use this variable unless you know exactly what you're - * doint. It is internal to the perl parser and may change or even - * be removed in the future. As of perl 5.9.5, you have to check - * for (PL_parser != NULL) for this variable to have any effect. - * An always non-NULL PL_parser dummy is provided for earlier - * perl versions. - * If PL_parser is NULL when you try to access this variable, a - * dummy is being accessed instead and a warning is issued unless - * you define DPPP_PL_parser_NO_DUMMY_WARNING. - * If DPPP_PL_parser_NO_DUMMY is defined, the code trying to access - * this variable will croak with a panic message. - */ - -# define PL_expect D_PPP_my_PL_parser_var(expect) -# define PL_copline D_PPP_my_PL_parser_var(copline) -# define PL_rsfp D_PPP_my_PL_parser_var(rsfp) -# define PL_rsfp_filters D_PPP_my_PL_parser_var(rsfp_filters) -# define PL_linestr D_PPP_my_PL_parser_var(linestr) -# define PL_bufptr D_PPP_my_PL_parser_var(bufptr) -# define PL_bufend D_PPP_my_PL_parser_var(bufend) -# define PL_lex_state D_PPP_my_PL_parser_var(lex_state) -# define PL_lex_stuff D_PPP_my_PL_parser_var(lex_stuff) -# define PL_tokenbuf D_PPP_my_PL_parser_var(tokenbuf) -# define PL_in_my D_PPP_my_PL_parser_var(in_my) -# define PL_in_my_stash D_PPP_my_PL_parser_var(in_my_stash) -# define PL_error_count D_PPP_my_PL_parser_var(error_count) - - -#else - -/* ensure that PL_parser != NULL and cannot be dereferenced */ -# define PL_parser ((void *) 1) - -#endif -#ifndef mPUSHs -# define mPUSHs(s) PUSHs(sv_2mortal(s)) -#endif - -#ifndef PUSHmortal -# define PUSHmortal PUSHs(sv_newmortal()) -#endif - -#ifndef mPUSHp -# define mPUSHp(p,l) sv_setpvn(PUSHmortal, (p), (l)) -#endif - -#ifndef mPUSHn -# define mPUSHn(n) sv_setnv(PUSHmortal, (NV)(n)) -#endif - -#ifndef mPUSHi -# define mPUSHi(i) sv_setiv(PUSHmortal, (IV)(i)) -#endif - -#ifndef mPUSHu -# define mPUSHu(u) sv_setuv(PUSHmortal, (UV)(u)) -#endif -#ifndef mXPUSHs -# define mXPUSHs(s) XPUSHs(sv_2mortal(s)) -#endif - -#ifndef XPUSHmortal -# define XPUSHmortal XPUSHs(sv_newmortal()) -#endif - -#ifndef mXPUSHp -# define mXPUSHp(p,l) STMT_START { EXTEND(sp,1); sv_setpvn(PUSHmortal, (p), (l)); } STMT_END -#endif - -#ifndef mXPUSHn -# define mXPUSHn(n) STMT_START { EXTEND(sp,1); sv_setnv(PUSHmortal, (NV)(n)); } STMT_END -#endif - -#ifndef mXPUSHi -# define mXPUSHi(i) STMT_START { EXTEND(sp,1); sv_setiv(PUSHmortal, (IV)(i)); } STMT_END -#endif - -#ifndef mXPUSHu -# define mXPUSHu(u) STMT_START { EXTEND(sp,1); sv_setuv(PUSHmortal, (UV)(u)); } STMT_END -#endif - -/* Replace: 1 */ -#ifndef call_sv -# define call_sv perl_call_sv -#endif - -#ifndef call_pv -# define call_pv perl_call_pv -#endif - -#ifndef call_argv -# define call_argv perl_call_argv -#endif - -#ifndef call_method -# define call_method perl_call_method -#endif -#ifndef eval_sv -# define eval_sv perl_eval_sv -#endif - -/* Replace: 0 */ -#ifndef PERL_LOADMOD_DENY -# define PERL_LOADMOD_DENY 0x1 -#endif - -#ifndef PERL_LOADMOD_NOIMPORT -# define PERL_LOADMOD_NOIMPORT 0x2 -#endif - -#ifndef PERL_LOADMOD_IMPORT_OPS -# define PERL_LOADMOD_IMPORT_OPS 0x4 -#endif - -#ifndef G_METHOD -# define G_METHOD 64 -# ifdef call_sv -# undef call_sv -# endif -# if (PERL_BCDVERSION < 0x5006000) -# define call_sv(sv, flags) ((flags) & G_METHOD ? perl_call_method((char *) SvPV_nolen_const(sv), \ - (flags) & ~G_METHOD) : perl_call_sv(sv, flags)) -# else -# define call_sv(sv, flags) ((flags) & G_METHOD ? Perl_call_method(aTHX_ (char *) SvPV_nolen_const(sv), \ - (flags) & ~G_METHOD) : Perl_call_sv(aTHX_ sv, flags)) -# endif -#endif - -/* Replace perl_eval_pv with eval_pv */ - -#ifndef eval_pv -#if defined(NEED_eval_pv) -static SV* DPPP_(my_eval_pv)(char *p, I32 croak_on_error); -static -#else -extern SV* DPPP_(my_eval_pv)(char *p, I32 croak_on_error); -#endif - -#ifdef eval_pv -# undef eval_pv -#endif -#define eval_pv(a,b) DPPP_(my_eval_pv)(aTHX_ a,b) -#define Perl_eval_pv DPPP_(my_eval_pv) - -#if defined(NEED_eval_pv) || defined(NEED_eval_pv_GLOBAL) - -SV* -DPPP_(my_eval_pv)(char *p, I32 croak_on_error) -{ - dSP; - SV* sv = newSVpv(p, 0); - - PUSHMARK(sp); - eval_sv(sv, G_SCALAR); - SvREFCNT_dec(sv); - - SPAGAIN; - sv = POPs; - PUTBACK; - - if (croak_on_error && SvTRUE(GvSV(errgv))) - croak(SvPVx(GvSV(errgv), na)); - - return sv; -} - -#endif -#endif - -#ifndef vload_module -#if defined(NEED_vload_module) -static void DPPP_(my_vload_module)(U32 flags, SV *name, SV *ver, va_list *args); -static -#else -extern void DPPP_(my_vload_module)(U32 flags, SV *name, SV *ver, va_list *args); -#endif - -#ifdef vload_module -# undef vload_module -#endif -#define vload_module(a,b,c,d) DPPP_(my_vload_module)(aTHX_ a,b,c,d) -#define Perl_vload_module DPPP_(my_vload_module) - -#if defined(NEED_vload_module) || defined(NEED_vload_module_GLOBAL) - -void -DPPP_(my_vload_module)(U32 flags, SV *name, SV *ver, va_list *args) -{ - dTHR; - dVAR; - OP *veop, *imop; - - OP * const modname = newSVOP(OP_CONST, 0, name); - /* 5.005 has a somewhat hacky force_normal that doesn't croak on - SvREADONLY() if PL_compling is true. Current perls take care in - ck_require() to correctly turn off SvREADONLY before calling - force_normal_flags(). This seems a better fix than fudging PL_compling - */ - SvREADONLY_off(((SVOP*)modname)->op_sv); - modname->op_private |= OPpCONST_BARE; - if (ver) { - veop = newSVOP(OP_CONST, 0, ver); - } - else - veop = NULL; - if (flags & PERL_LOADMOD_NOIMPORT) { - imop = sawparens(newNULLLIST()); - } - else if (flags & PERL_LOADMOD_IMPORT_OPS) { - imop = va_arg(*args, OP*); - } - else { - SV *sv; - imop = NULL; - sv = va_arg(*args, SV*); - while (sv) { - imop = append_elem(OP_LIST, imop, newSVOP(OP_CONST, 0, sv)); - sv = va_arg(*args, SV*); - } - } - { - const line_t ocopline = PL_copline; - COP * const ocurcop = PL_curcop; - const int oexpect = PL_expect; - -#if (PERL_BCDVERSION >= 0x5004000) - utilize(!(flags & PERL_LOADMOD_DENY), start_subparse(FALSE, 0), - veop, modname, imop); -#elif (PERL_BCDVERSION > 0x5003000) - utilize(!(flags & PERL_LOADMOD_DENY), start_subparse(), - veop, modname, imop); -#else - utilize(!(flags & PERL_LOADMOD_DENY), start_subparse(), - modname, imop); -#endif - PL_expect = oexpect; - PL_copline = ocopline; - PL_curcop = ocurcop; - } -} - -#endif -#endif - -#ifndef load_module -#if defined(NEED_load_module) -static void DPPP_(my_load_module)(U32 flags, SV *name, SV *ver, ...); -static -#else -extern void DPPP_(my_load_module)(U32 flags, SV *name, SV *ver, ...); -#endif - -#ifdef load_module -# undef load_module -#endif -#define load_module DPPP_(my_load_module) -#define Perl_load_module DPPP_(my_load_module) - -#if defined(NEED_load_module) || defined(NEED_load_module_GLOBAL) - -void -DPPP_(my_load_module)(U32 flags, SV *name, SV *ver, ...) -{ - va_list args; - va_start(args, ver); - vload_module(flags, name, ver, &args); - va_end(args); -} - -#endif -#endif -#ifndef newRV_inc -# define newRV_inc(sv) newRV(sv) /* Replace */ -#endif - -#ifndef newRV_noinc -#if defined(NEED_newRV_noinc) -static SV * DPPP_(my_newRV_noinc)(SV *sv); -static -#else -extern SV * DPPP_(my_newRV_noinc)(SV *sv); -#endif - -#ifdef newRV_noinc -# undef newRV_noinc -#endif -#define newRV_noinc(a) DPPP_(my_newRV_noinc)(aTHX_ a) -#define Perl_newRV_noinc DPPP_(my_newRV_noinc) - -#if defined(NEED_newRV_noinc) || defined(NEED_newRV_noinc_GLOBAL) -SV * -DPPP_(my_newRV_noinc)(SV *sv) -{ - SV *rv = (SV *)newRV(sv); - SvREFCNT_dec(sv); - return rv; -} -#endif -#endif - -/* Hint: newCONSTSUB - * Returns a CV* as of perl-5.7.1. This return value is not supported - * by Devel::PPPort. - */ - -/* newCONSTSUB from IO.xs is in the core starting with 5.004_63 */ -#if (PERL_BCDVERSION < 0x5004063) && (PERL_BCDVERSION != 0x5004005) -#if defined(NEED_newCONSTSUB) -static void DPPP_(my_newCONSTSUB)(HV *stash, const char *name, SV *sv); -static -#else -extern void DPPP_(my_newCONSTSUB)(HV *stash, const char *name, SV *sv); -#endif - -#ifdef newCONSTSUB -# undef newCONSTSUB -#endif -#define newCONSTSUB(a,b,c) DPPP_(my_newCONSTSUB)(aTHX_ a,b,c) -#define Perl_newCONSTSUB DPPP_(my_newCONSTSUB) - -#if defined(NEED_newCONSTSUB) || defined(NEED_newCONSTSUB_GLOBAL) - -/* This is just a trick to avoid a dependency of newCONSTSUB on PL_parser */ -/* (There's no PL_parser in perl < 5.005, so this is completely safe) */ -#define D_PPP_PL_copline PL_copline - -void -DPPP_(my_newCONSTSUB)(HV *stash, const char *name, SV *sv) -{ - U32 oldhints = PL_hints; - HV *old_cop_stash = PL_curcop->cop_stash; - HV *old_curstash = PL_curstash; - line_t oldline = PL_curcop->cop_line; - PL_curcop->cop_line = D_PPP_PL_copline; - - PL_hints &= ~HINT_BLOCK_SCOPE; - if (stash) - PL_curstash = PL_curcop->cop_stash = stash; - - newSUB( - -#if (PERL_BCDVERSION < 0x5003022) - start_subparse(), -#elif (PERL_BCDVERSION == 0x5003022) - start_subparse(0), -#else /* 5.003_23 onwards */ - start_subparse(FALSE, 0), -#endif - - newSVOP(OP_CONST, 0, newSVpv((char *) name, 0)), - newSVOP(OP_CONST, 0, &PL_sv_no), /* SvPV(&PL_sv_no) == "" -- GMB */ - newSTATEOP(0, Nullch, newSVOP(OP_CONST, 0, sv)) - ); - - PL_hints = oldhints; - PL_curcop->cop_stash = old_cop_stash; - PL_curstash = old_curstash; - PL_curcop->cop_line = oldline; -} -#endif -#endif - -/* - * Boilerplate macros for initializing and accessing interpreter-local - * data from C. All statics in extensions should be reworked to use - * this, if you want to make the extension thread-safe. See ext/re/re.xs - * for an example of the use of these macros. - * - * Code that uses these macros is responsible for the following: - * 1. #define MY_CXT_KEY to a unique string, e.g. "DynaLoader_guts" - * 2. Declare a typedef named my_cxt_t that is a structure that contains - * all the data that needs to be interpreter-local. - * 3. Use the START_MY_CXT macro after the declaration of my_cxt_t. - * 4. Use the MY_CXT_INIT macro such that it is called exactly once - * (typically put in the BOOT: section). - * 5. Use the members of the my_cxt_t structure everywhere as - * MY_CXT.member. - * 6. Use the dMY_CXT macro (a declaration) in all the functions that - * access MY_CXT. - */ - -#if defined(MULTIPLICITY) || defined(PERL_OBJECT) || \ - defined(PERL_CAPI) || defined(PERL_IMPLICIT_CONTEXT) - -#ifndef START_MY_CXT - -/* This must appear in all extensions that define a my_cxt_t structure, - * right after the definition (i.e. at file scope). The non-threads - * case below uses it to declare the data as static. */ -#define START_MY_CXT - -#if (PERL_BCDVERSION < 0x5004068) -/* Fetches the SV that keeps the per-interpreter data. */ -#define dMY_CXT_SV \ - SV *my_cxt_sv = get_sv(MY_CXT_KEY, FALSE) -#else /* >= perl5.004_68 */ -#define dMY_CXT_SV \ - SV *my_cxt_sv = *hv_fetch(PL_modglobal, MY_CXT_KEY, \ - sizeof(MY_CXT_KEY)-1, TRUE) -#endif /* < perl5.004_68 */ - -/* This declaration should be used within all functions that use the - * interpreter-local data. */ -#define dMY_CXT \ - dMY_CXT_SV; \ - my_cxt_t *my_cxtp = INT2PTR(my_cxt_t*,SvUV(my_cxt_sv)) - -/* Creates and zeroes the per-interpreter data. - * (We allocate my_cxtp in a Perl SV so that it will be released when - * the interpreter goes away.) */ -#define MY_CXT_INIT \ - dMY_CXT_SV; \ - /* newSV() allocates one more than needed */ \ - my_cxt_t *my_cxtp = (my_cxt_t*)SvPVX(newSV(sizeof(my_cxt_t)-1));\ - Zero(my_cxtp, 1, my_cxt_t); \ - sv_setuv(my_cxt_sv, PTR2UV(my_cxtp)) - -/* This macro must be used to access members of the my_cxt_t structure. - * e.g. MYCXT.some_data */ -#define MY_CXT (*my_cxtp) - -/* Judicious use of these macros can reduce the number of times dMY_CXT - * is used. Use is similar to pTHX, aTHX etc. */ -#define pMY_CXT my_cxt_t *my_cxtp -#define pMY_CXT_ pMY_CXT, -#define _pMY_CXT ,pMY_CXT -#define aMY_CXT my_cxtp -#define aMY_CXT_ aMY_CXT, -#define _aMY_CXT ,aMY_CXT - -#endif /* START_MY_CXT */ - -#ifndef MY_CXT_CLONE -/* Clones the per-interpreter data. */ -#define MY_CXT_CLONE \ - dMY_CXT_SV; \ - my_cxt_t *my_cxtp = (my_cxt_t*)SvPVX(newSV(sizeof(my_cxt_t)-1));\ - Copy(INT2PTR(my_cxt_t*, SvUV(my_cxt_sv)), my_cxtp, 1, my_cxt_t);\ - sv_setuv(my_cxt_sv, PTR2UV(my_cxtp)) -#endif - -#else /* single interpreter */ - -#ifndef START_MY_CXT - -#define START_MY_CXT static my_cxt_t my_cxt; -#define dMY_CXT_SV dNOOP -#define dMY_CXT dNOOP -#define MY_CXT_INIT NOOP -#define MY_CXT my_cxt - -#define pMY_CXT void -#define pMY_CXT_ -#define _pMY_CXT -#define aMY_CXT -#define aMY_CXT_ -#define _aMY_CXT - -#endif /* START_MY_CXT */ - -#ifndef MY_CXT_CLONE -#define MY_CXT_CLONE NOOP -#endif - -#endif - -#ifndef IVdf -# if IVSIZE == LONGSIZE -# define IVdf "ld" -# define UVuf "lu" -# define UVof "lo" -# define UVxf "lx" -# define UVXf "lX" -# elif IVSIZE == INTSIZE -# define IVdf "d" -# define UVuf "u" -# define UVof "o" -# define UVxf "x" -# define UVXf "X" -# else -# error "cannot define IV/UV formats" -# endif -#endif - -#ifndef NVef -# if defined(USE_LONG_DOUBLE) && defined(HAS_LONG_DOUBLE) && \ - defined(PERL_PRIfldbl) && (PERL_BCDVERSION != 0x5006000) - /* Not very likely, but let's try anyway. */ -# define NVef PERL_PRIeldbl -# define NVff PERL_PRIfldbl -# define NVgf PERL_PRIgldbl -# else -# define NVef "e" -# define NVff "f" -# define NVgf "g" -# endif -#endif - -#ifndef SvREFCNT_inc -# ifdef PERL_USE_GCC_BRACE_GROUPS -# define SvREFCNT_inc(sv) \ - ({ \ - SV * const _sv = (SV*)(sv); \ - if (_sv) \ - (SvREFCNT(_sv))++; \ - _sv; \ - }) -# else -# define SvREFCNT_inc(sv) \ - ((PL_Sv=(SV*)(sv)) ? (++(SvREFCNT(PL_Sv)),PL_Sv) : NULL) -# endif -#endif - -#ifndef SvREFCNT_inc_simple -# ifdef PERL_USE_GCC_BRACE_GROUPS -# define SvREFCNT_inc_simple(sv) \ - ({ \ - if (sv) \ - (SvREFCNT(sv))++; \ - (SV *)(sv); \ - }) -# else -# define SvREFCNT_inc_simple(sv) \ - ((sv) ? (SvREFCNT(sv)++,(SV*)(sv)) : NULL) -# endif -#endif - -#ifndef SvREFCNT_inc_NN -# ifdef PERL_USE_GCC_BRACE_GROUPS -# define SvREFCNT_inc_NN(sv) \ - ({ \ - SV * const _sv = (SV*)(sv); \ - SvREFCNT(_sv)++; \ - _sv; \ - }) -# else -# define SvREFCNT_inc_NN(sv) \ - (PL_Sv=(SV*)(sv),++(SvREFCNT(PL_Sv)),PL_Sv) -# endif -#endif - -#ifndef SvREFCNT_inc_void -# ifdef PERL_USE_GCC_BRACE_GROUPS -# define SvREFCNT_inc_void(sv) \ - ({ \ - SV * const _sv = (SV*)(sv); \ - if (_sv) \ - (void)(SvREFCNT(_sv)++); \ - }) -# else -# define SvREFCNT_inc_void(sv) \ - (void)((PL_Sv=(SV*)(sv)) ? ++(SvREFCNT(PL_Sv)) : 0) -# endif -#endif -#ifndef SvREFCNT_inc_simple_void -# define SvREFCNT_inc_simple_void(sv) STMT_START { if (sv) SvREFCNT(sv)++; } STMT_END -#endif - -#ifndef SvREFCNT_inc_simple_NN -# define SvREFCNT_inc_simple_NN(sv) (++SvREFCNT(sv), (SV*)(sv)) -#endif - -#ifndef SvREFCNT_inc_void_NN -# define SvREFCNT_inc_void_NN(sv) (void)(++SvREFCNT((SV*)(sv))) -#endif - -#ifndef SvREFCNT_inc_simple_void_NN -# define SvREFCNT_inc_simple_void_NN(sv) (void)(++SvREFCNT((SV*)(sv))) -#endif - -#ifndef newSV_type - -#if defined(NEED_newSV_type) -static SV* DPPP_(my_newSV_type)(pTHX_ svtype const t); -static -#else -extern SV* DPPP_(my_newSV_type)(pTHX_ svtype const t); -#endif - -#ifdef newSV_type -# undef newSV_type -#endif -#define newSV_type(a) DPPP_(my_newSV_type)(aTHX_ a) -#define Perl_newSV_type DPPP_(my_newSV_type) - -#if defined(NEED_newSV_type) || defined(NEED_newSV_type_GLOBAL) - -SV* -DPPP_(my_newSV_type)(pTHX_ svtype const t) -{ - SV* const sv = newSV(0); - sv_upgrade(sv, t); - return sv; -} - -#endif - -#endif - -#if (PERL_BCDVERSION < 0x5006000) -# define D_PPP_CONSTPV_ARG(x) ((char *) (x)) -#else -# define D_PPP_CONSTPV_ARG(x) (x) -#endif -#ifndef newSVpvn -# define newSVpvn(data,len) ((data) \ - ? ((len) ? newSVpv((data), (len)) : newSVpv("", 0)) \ - : newSV(0)) -#endif -#ifndef newSVpvn_utf8 -# define newSVpvn_utf8(s, len, u) newSVpvn_flags((s), (len), (u) ? SVf_UTF8 : 0) -#endif -#ifndef SVf_UTF8 -# define SVf_UTF8 0 -#endif - -#ifndef newSVpvn_flags - -#if defined(NEED_newSVpvn_flags) -static SV * DPPP_(my_newSVpvn_flags)(pTHX_ const char *s, STRLEN len, U32 flags); -static -#else -extern SV * DPPP_(my_newSVpvn_flags)(pTHX_ const char *s, STRLEN len, U32 flags); -#endif - -#ifdef newSVpvn_flags -# undef newSVpvn_flags -#endif -#define newSVpvn_flags(a,b,c) DPPP_(my_newSVpvn_flags)(aTHX_ a,b,c) -#define Perl_newSVpvn_flags DPPP_(my_newSVpvn_flags) - -#if defined(NEED_newSVpvn_flags) || defined(NEED_newSVpvn_flags_GLOBAL) - -SV * -DPPP_(my_newSVpvn_flags)(pTHX_ const char *s, STRLEN len, U32 flags) -{ - SV *sv = newSVpvn(D_PPP_CONSTPV_ARG(s), len); - SvFLAGS(sv) |= (flags & SVf_UTF8); - return (flags & SVs_TEMP) ? sv_2mortal(sv) : sv; -} - -#endif - -#endif - -/* Backwards compatibility stuff... :-( */ -#if !defined(NEED_sv_2pv_flags) && defined(NEED_sv_2pv_nolen) -# define NEED_sv_2pv_flags -#endif -#if !defined(NEED_sv_2pv_flags_GLOBAL) && defined(NEED_sv_2pv_nolen_GLOBAL) -# define NEED_sv_2pv_flags_GLOBAL -#endif - -/* Hint: sv_2pv_nolen - * Use the SvPV_nolen() or SvPV_nolen_const() macros instead of sv_2pv_nolen(). - */ -#ifndef sv_2pv_nolen -# define sv_2pv_nolen(sv) SvPV_nolen(sv) -#endif - -#ifdef SvPVbyte - -/* Hint: SvPVbyte - * Does not work in perl-5.6.1, ppport.h implements a version - * borrowed from perl-5.7.3. - */ - -#if (PERL_BCDVERSION < 0x5007000) - -#if defined(NEED_sv_2pvbyte) -static char * DPPP_(my_sv_2pvbyte)(pTHX_ SV *sv, STRLEN *lp); -static -#else -extern char * DPPP_(my_sv_2pvbyte)(pTHX_ SV *sv, STRLEN *lp); -#endif - -#ifdef sv_2pvbyte -# undef sv_2pvbyte -#endif -#define sv_2pvbyte(a,b) DPPP_(my_sv_2pvbyte)(aTHX_ a,b) -#define Perl_sv_2pvbyte DPPP_(my_sv_2pvbyte) - -#if defined(NEED_sv_2pvbyte) || defined(NEED_sv_2pvbyte_GLOBAL) - -char * -DPPP_(my_sv_2pvbyte)(pTHX_ SV *sv, STRLEN *lp) -{ - sv_utf8_downgrade(sv,0); - return SvPV(sv,*lp); -} - -#endif - -/* Hint: sv_2pvbyte - * Use the SvPVbyte() macro instead of sv_2pvbyte(). - */ - -#undef SvPVbyte - -#define SvPVbyte(sv, lp) \ - ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8)) == (SVf_POK) \ - ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pvbyte(sv, &lp)) - -#endif - -#else - -# define SvPVbyte SvPV -# define sv_2pvbyte sv_2pv - -#endif -#ifndef sv_2pvbyte_nolen -# define sv_2pvbyte_nolen(sv) sv_2pv_nolen(sv) -#endif - -/* Hint: sv_pvn - * Always use the SvPV() macro instead of sv_pvn(). - */ - -/* Hint: sv_pvn_force - * Always use the SvPV_force() macro instead of sv_pvn_force(). - */ - -/* If these are undefined, they're not handled by the core anyway */ -#ifndef SV_IMMEDIATE_UNREF -# define SV_IMMEDIATE_UNREF 0 -#endif - -#ifndef SV_GMAGIC -# define SV_GMAGIC 0 -#endif - -#ifndef SV_COW_DROP_PV -# define SV_COW_DROP_PV 0 -#endif - -#ifndef SV_UTF8_NO_ENCODING -# define SV_UTF8_NO_ENCODING 0 -#endif - -#ifndef SV_NOSTEAL -# define SV_NOSTEAL 0 -#endif - -#ifndef SV_CONST_RETURN -# define SV_CONST_RETURN 0 -#endif - -#ifndef SV_MUTABLE_RETURN -# define SV_MUTABLE_RETURN 0 -#endif - -#ifndef SV_SMAGIC -# define SV_SMAGIC 0 -#endif - -#ifndef SV_HAS_TRAILING_NUL -# define SV_HAS_TRAILING_NUL 0 -#endif - -#ifndef SV_COW_SHARED_HASH_KEYS -# define SV_COW_SHARED_HASH_KEYS 0 -#endif - -#if (PERL_BCDVERSION < 0x5007002) - -#if defined(NEED_sv_2pv_flags) -static char * DPPP_(my_sv_2pv_flags)(pTHX_ SV *sv, STRLEN *lp, I32 flags); -static -#else -extern char * DPPP_(my_sv_2pv_flags)(pTHX_ SV *sv, STRLEN *lp, I32 flags); -#endif - -#ifdef sv_2pv_flags -# undef sv_2pv_flags -#endif -#define sv_2pv_flags(a,b,c) DPPP_(my_sv_2pv_flags)(aTHX_ a,b,c) -#define Perl_sv_2pv_flags DPPP_(my_sv_2pv_flags) - -#if defined(NEED_sv_2pv_flags) || defined(NEED_sv_2pv_flags_GLOBAL) - -char * -DPPP_(my_sv_2pv_flags)(pTHX_ SV *sv, STRLEN *lp, I32 flags) -{ - STRLEN n_a = (STRLEN) flags; - return sv_2pv(sv, lp ? lp : &n_a); -} - -#endif - -#if defined(NEED_sv_pvn_force_flags) -static char * DPPP_(my_sv_pvn_force_flags)(pTHX_ SV *sv, STRLEN *lp, I32 flags); -static -#else -extern char * DPPP_(my_sv_pvn_force_flags)(pTHX_ SV *sv, STRLEN *lp, I32 flags); -#endif - -#ifdef sv_pvn_force_flags -# undef sv_pvn_force_flags -#endif -#define sv_pvn_force_flags(a,b,c) DPPP_(my_sv_pvn_force_flags)(aTHX_ a,b,c) -#define Perl_sv_pvn_force_flags DPPP_(my_sv_pvn_force_flags) - -#if defined(NEED_sv_pvn_force_flags) || defined(NEED_sv_pvn_force_flags_GLOBAL) - -char * -DPPP_(my_sv_pvn_force_flags)(pTHX_ SV *sv, STRLEN *lp, I32 flags) -{ - STRLEN n_a = (STRLEN) flags; - return sv_pvn_force(sv, lp ? lp : &n_a); -} - -#endif - -#endif - -#if (PERL_BCDVERSION < 0x5008008) || ( (PERL_BCDVERSION >= 0x5009000) && (PERL_BCDVERSION < 0x5009003) ) -# define DPPP_SVPV_NOLEN_LP_ARG &PL_na -#else -# define DPPP_SVPV_NOLEN_LP_ARG 0 -#endif -#ifndef SvPV_const -# define SvPV_const(sv, lp) SvPV_flags_const(sv, lp, SV_GMAGIC) -#endif - -#ifndef SvPV_mutable -# define SvPV_mutable(sv, lp) SvPV_flags_mutable(sv, lp, SV_GMAGIC) -#endif -#ifndef SvPV_flags -# define SvPV_flags(sv, lp, flags) \ - ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ - ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pv_flags(sv, &lp, flags)) -#endif -#ifndef SvPV_flags_const -# define SvPV_flags_const(sv, lp, flags) \ - ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ - ? ((lp = SvCUR(sv)), SvPVX_const(sv)) : \ - (const char*) sv_2pv_flags(sv, &lp, flags|SV_CONST_RETURN)) -#endif -#ifndef SvPV_flags_const_nolen -# define SvPV_flags_const_nolen(sv, flags) \ - ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ - ? SvPVX_const(sv) : \ - (const char*) sv_2pv_flags(sv, DPPP_SVPV_NOLEN_LP_ARG, flags|SV_CONST_RETURN)) -#endif -#ifndef SvPV_flags_mutable -# define SvPV_flags_mutable(sv, lp, flags) \ - ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ - ? ((lp = SvCUR(sv)), SvPVX_mutable(sv)) : \ - sv_2pv_flags(sv, &lp, flags|SV_MUTABLE_RETURN)) -#endif -#ifndef SvPV_force -# define SvPV_force(sv, lp) SvPV_force_flags(sv, lp, SV_GMAGIC) -#endif - -#ifndef SvPV_force_nolen -# define SvPV_force_nolen(sv) SvPV_force_flags_nolen(sv, SV_GMAGIC) -#endif - -#ifndef SvPV_force_mutable -# define SvPV_force_mutable(sv, lp) SvPV_force_flags_mutable(sv, lp, SV_GMAGIC) -#endif - -#ifndef SvPV_force_nomg -# define SvPV_force_nomg(sv, lp) SvPV_force_flags(sv, lp, 0) -#endif - -#ifndef SvPV_force_nomg_nolen -# define SvPV_force_nomg_nolen(sv) SvPV_force_flags_nolen(sv, 0) -#endif -#ifndef SvPV_force_flags -# define SvPV_force_flags(sv, lp, flags) \ - ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST)) == SVf_POK \ - ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_pvn_force_flags(sv, &lp, flags)) -#endif -#ifndef SvPV_force_flags_nolen -# define SvPV_force_flags_nolen(sv, flags) \ - ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST)) == SVf_POK \ - ? SvPVX(sv) : sv_pvn_force_flags(sv, DPPP_SVPV_NOLEN_LP_ARG, flags)) -#endif -#ifndef SvPV_force_flags_mutable -# define SvPV_force_flags_mutable(sv, lp, flags) \ - ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST)) == SVf_POK \ - ? ((lp = SvCUR(sv)), SvPVX_mutable(sv)) \ - : sv_pvn_force_flags(sv, &lp, flags|SV_MUTABLE_RETURN)) -#endif -#ifndef SvPV_nolen -# define SvPV_nolen(sv) \ - ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ - ? SvPVX(sv) : sv_2pv_flags(sv, DPPP_SVPV_NOLEN_LP_ARG, SV_GMAGIC)) -#endif -#ifndef SvPV_nolen_const -# define SvPV_nolen_const(sv) \ - ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ - ? SvPVX_const(sv) : sv_2pv_flags(sv, DPPP_SVPV_NOLEN_LP_ARG, SV_GMAGIC|SV_CONST_RETURN)) -#endif -#ifndef SvPV_nomg -# define SvPV_nomg(sv, lp) SvPV_flags(sv, lp, 0) -#endif - -#ifndef SvPV_nomg_const -# define SvPV_nomg_const(sv, lp) SvPV_flags_const(sv, lp, 0) -#endif - -#ifndef SvPV_nomg_const_nolen -# define SvPV_nomg_const_nolen(sv) SvPV_flags_const_nolen(sv, 0) -#endif - -#ifndef SvPV_nomg_nolen -# define SvPV_nomg_nolen(sv) ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ - ? SvPVX(sv) : sv_2pv_flags(sv, DPPP_SVPV_NOLEN_LP_ARG, 0)) -#endif -#ifndef SvPV_renew -# define SvPV_renew(sv,n) STMT_START { SvLEN_set(sv, n); \ - SvPV_set((sv), (char *) saferealloc( \ - (Malloc_t)SvPVX(sv), (MEM_SIZE)((n)))); \ - } STMT_END -#endif -#ifndef SvMAGIC_set -# define SvMAGIC_set(sv, val) \ - STMT_START { assert(SvTYPE(sv) >= SVt_PVMG); \ - (((XPVMG*) SvANY(sv))->xmg_magic = (val)); } STMT_END -#endif - -#if (PERL_BCDVERSION < 0x5009003) -#ifndef SvPVX_const -# define SvPVX_const(sv) ((const char*) (0 + SvPVX(sv))) -#endif - -#ifndef SvPVX_mutable -# define SvPVX_mutable(sv) (0 + SvPVX(sv)) -#endif -#ifndef SvRV_set -# define SvRV_set(sv, val) \ - STMT_START { assert(SvTYPE(sv) >= SVt_RV); \ - (((XRV*) SvANY(sv))->xrv_rv = (val)); } STMT_END -#endif - -#else -#ifndef SvPVX_const -# define SvPVX_const(sv) ((const char*)((sv)->sv_u.svu_pv)) -#endif - -#ifndef SvPVX_mutable -# define SvPVX_mutable(sv) ((sv)->sv_u.svu_pv) -#endif -#ifndef SvRV_set -# define SvRV_set(sv, val) \ - STMT_START { assert(SvTYPE(sv) >= SVt_RV); \ - ((sv)->sv_u.svu_rv = (val)); } STMT_END -#endif - -#endif -#ifndef SvSTASH_set -# define SvSTASH_set(sv, val) \ - STMT_START { assert(SvTYPE(sv) >= SVt_PVMG); \ - (((XPVMG*) SvANY(sv))->xmg_stash = (val)); } STMT_END -#endif - -#if (PERL_BCDVERSION < 0x5004000) -#ifndef SvUV_set -# define SvUV_set(sv, val) \ - STMT_START { assert(SvTYPE(sv) == SVt_IV || SvTYPE(sv) >= SVt_PVIV); \ - (((XPVIV*) SvANY(sv))->xiv_iv = (IV) (val)); } STMT_END -#endif - -#else -#ifndef SvUV_set -# define SvUV_set(sv, val) \ - STMT_START { assert(SvTYPE(sv) == SVt_IV || SvTYPE(sv) >= SVt_PVIV); \ - (((XPVUV*) SvANY(sv))->xuv_uv = (val)); } STMT_END -#endif - -#endif - -#if (PERL_BCDVERSION >= 0x5004000) && !defined(vnewSVpvf) -#if defined(NEED_vnewSVpvf) -static SV * DPPP_(my_vnewSVpvf)(pTHX_ const char *pat, va_list *args); -static -#else -extern SV * DPPP_(my_vnewSVpvf)(pTHX_ const char *pat, va_list *args); -#endif - -#ifdef vnewSVpvf -# undef vnewSVpvf -#endif -#define vnewSVpvf(a,b) DPPP_(my_vnewSVpvf)(aTHX_ a,b) -#define Perl_vnewSVpvf DPPP_(my_vnewSVpvf) - -#if defined(NEED_vnewSVpvf) || defined(NEED_vnewSVpvf_GLOBAL) - -SV * -DPPP_(my_vnewSVpvf)(pTHX_ const char *pat, va_list *args) -{ - register SV *sv = newSV(0); - sv_vsetpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*)); - return sv; -} - -#endif -#endif - -#if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_vcatpvf) -# define sv_vcatpvf(sv, pat, args) sv_vcatpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*)) -#endif - -#if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_vsetpvf) -# define sv_vsetpvf(sv, pat, args) sv_vsetpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*)) -#endif - -#if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_catpvf_mg) -#if defined(NEED_sv_catpvf_mg) -static void DPPP_(my_sv_catpvf_mg)(pTHX_ SV *sv, const char *pat, ...); -static -#else -extern void DPPP_(my_sv_catpvf_mg)(pTHX_ SV *sv, const char *pat, ...); -#endif - -#define Perl_sv_catpvf_mg DPPP_(my_sv_catpvf_mg) - -#if defined(NEED_sv_catpvf_mg) || defined(NEED_sv_catpvf_mg_GLOBAL) - -void -DPPP_(my_sv_catpvf_mg)(pTHX_ SV *sv, const char *pat, ...) -{ - va_list args; - va_start(args, pat); - sv_vcatpvfn(sv, pat, strlen(pat), &args, Null(SV**), 0, Null(bool*)); - SvSETMAGIC(sv); - va_end(args); -} - -#endif -#endif - -#ifdef PERL_IMPLICIT_CONTEXT -#if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_catpvf_mg_nocontext) -#if defined(NEED_sv_catpvf_mg_nocontext) -static void DPPP_(my_sv_catpvf_mg_nocontext)(SV *sv, const char *pat, ...); -static -#else -extern void DPPP_(my_sv_catpvf_mg_nocontext)(SV *sv, const char *pat, ...); -#endif - -#define sv_catpvf_mg_nocontext DPPP_(my_sv_catpvf_mg_nocontext) -#define Perl_sv_catpvf_mg_nocontext DPPP_(my_sv_catpvf_mg_nocontext) - -#if defined(NEED_sv_catpvf_mg_nocontext) || defined(NEED_sv_catpvf_mg_nocontext_GLOBAL) - -void -DPPP_(my_sv_catpvf_mg_nocontext)(SV *sv, const char *pat, ...) -{ - dTHX; - va_list args; - va_start(args, pat); - sv_vcatpvfn(sv, pat, strlen(pat), &args, Null(SV**), 0, Null(bool*)); - SvSETMAGIC(sv); - va_end(args); -} - -#endif -#endif -#endif - -/* sv_catpvf_mg depends on sv_catpvf_mg_nocontext */ -#ifndef sv_catpvf_mg -# ifdef PERL_IMPLICIT_CONTEXT -# define sv_catpvf_mg Perl_sv_catpvf_mg_nocontext -# else -# define sv_catpvf_mg Perl_sv_catpvf_mg -# endif -#endif - -#if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_vcatpvf_mg) -# define sv_vcatpvf_mg(sv, pat, args) \ - STMT_START { \ - sv_vcatpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*)); \ - SvSETMAGIC(sv); \ - } STMT_END -#endif - -#if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_setpvf_mg) -#if defined(NEED_sv_setpvf_mg) -static void DPPP_(my_sv_setpvf_mg)(pTHX_ SV *sv, const char *pat, ...); -static -#else -extern void DPPP_(my_sv_setpvf_mg)(pTHX_ SV *sv, const char *pat, ...); -#endif - -#define Perl_sv_setpvf_mg DPPP_(my_sv_setpvf_mg) - -#if defined(NEED_sv_setpvf_mg) || defined(NEED_sv_setpvf_mg_GLOBAL) - -void -DPPP_(my_sv_setpvf_mg)(pTHX_ SV *sv, const char *pat, ...) -{ - va_list args; - va_start(args, pat); - sv_vsetpvfn(sv, pat, strlen(pat), &args, Null(SV**), 0, Null(bool*)); - SvSETMAGIC(sv); - va_end(args); -} - -#endif -#endif - -#ifdef PERL_IMPLICIT_CONTEXT -#if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_setpvf_mg_nocontext) -#if defined(NEED_sv_setpvf_mg_nocontext) -static void DPPP_(my_sv_setpvf_mg_nocontext)(SV *sv, const char *pat, ...); -static -#else -extern void DPPP_(my_sv_setpvf_mg_nocontext)(SV *sv, const char *pat, ...); -#endif - -#define sv_setpvf_mg_nocontext DPPP_(my_sv_setpvf_mg_nocontext) -#define Perl_sv_setpvf_mg_nocontext DPPP_(my_sv_setpvf_mg_nocontext) - -#if defined(NEED_sv_setpvf_mg_nocontext) || defined(NEED_sv_setpvf_mg_nocontext_GLOBAL) - -void -DPPP_(my_sv_setpvf_mg_nocontext)(SV *sv, const char *pat, ...) -{ - dTHX; - va_list args; - va_start(args, pat); - sv_vsetpvfn(sv, pat, strlen(pat), &args, Null(SV**), 0, Null(bool*)); - SvSETMAGIC(sv); - va_end(args); -} - -#endif -#endif -#endif - -/* sv_setpvf_mg depends on sv_setpvf_mg_nocontext */ -#ifndef sv_setpvf_mg -# ifdef PERL_IMPLICIT_CONTEXT -# define sv_setpvf_mg Perl_sv_setpvf_mg_nocontext -# else -# define sv_setpvf_mg Perl_sv_setpvf_mg -# endif -#endif - -#if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_vsetpvf_mg) -# define sv_vsetpvf_mg(sv, pat, args) \ - STMT_START { \ - sv_vsetpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*)); \ - SvSETMAGIC(sv); \ - } STMT_END -#endif - -/* Hint: newSVpvn_share - * The SVs created by this function only mimic the behaviour of - * shared PVs without really being shared. Only use if you know - * what you're doing. - */ - -#ifndef newSVpvn_share - -#if defined(NEED_newSVpvn_share) -static SV * DPPP_(my_newSVpvn_share)(pTHX_ const char *src, I32 len, U32 hash); -static -#else -extern SV * DPPP_(my_newSVpvn_share)(pTHX_ const char *src, I32 len, U32 hash); -#endif - -#ifdef newSVpvn_share -# undef newSVpvn_share -#endif -#define newSVpvn_share(a,b,c) DPPP_(my_newSVpvn_share)(aTHX_ a,b,c) -#define Perl_newSVpvn_share DPPP_(my_newSVpvn_share) - -#if defined(NEED_newSVpvn_share) || defined(NEED_newSVpvn_share_GLOBAL) - -SV * -DPPP_(my_newSVpvn_share)(pTHX_ const char *src, I32 len, U32 hash) -{ - SV *sv; - if (len < 0) - len = -len; - if (!hash) - PERL_HASH(hash, (char*) src, len); - sv = newSVpvn((char *) src, len); - sv_upgrade(sv, SVt_PVIV); - SvIVX(sv) = hash; - SvREADONLY_on(sv); - SvPOK_on(sv); - return sv; -} - -#endif - -#endif -#ifndef SvSHARED_HASH -# define SvSHARED_HASH(sv) (0 + SvUVX(sv)) -#endif -#ifndef HvNAME_get -# define HvNAME_get(hv) HvNAME(hv) -#endif -#ifndef HvNAMELEN_get -# define HvNAMELEN_get(hv) (HvNAME_get(hv) ? (I32)strlen(HvNAME_get(hv)) : 0) -#endif -#ifndef GvSVn -# define GvSVn(gv) GvSV(gv) -#endif - -#ifndef isGV_with_GP -# define isGV_with_GP(gv) isGV(gv) -#endif - -#ifndef gv_fetchpvn_flags -# define gv_fetchpvn_flags(name, len, flags, svt) gv_fetchpv(name, flags, svt) -#endif - -#ifndef gv_fetchsv -# define gv_fetchsv(name, flags, svt) gv_fetchpv(SvPV_nolen_const(name), flags, svt) -#endif -#ifndef get_cvn_flags -# define get_cvn_flags(name, namelen, flags) get_cv(name, flags) -#endif -#ifndef WARN_ALL -# define WARN_ALL 0 -#endif - -#ifndef WARN_CLOSURE -# define WARN_CLOSURE 1 -#endif - -#ifndef WARN_DEPRECATED -# define WARN_DEPRECATED 2 -#endif - -#ifndef WARN_EXITING -# define WARN_EXITING 3 -#endif - -#ifndef WARN_GLOB -# define WARN_GLOB 4 -#endif - -#ifndef WARN_IO -# define WARN_IO 5 -#endif - -#ifndef WARN_CLOSED -# define WARN_CLOSED 6 -#endif - -#ifndef WARN_EXEC -# define WARN_EXEC 7 -#endif - -#ifndef WARN_LAYER -# define WARN_LAYER 8 -#endif - -#ifndef WARN_NEWLINE -# define WARN_NEWLINE 9 -#endif - -#ifndef WARN_PIPE -# define WARN_PIPE 10 -#endif - -#ifndef WARN_UNOPENED -# define WARN_UNOPENED 11 -#endif - -#ifndef WARN_MISC -# define WARN_MISC 12 -#endif - -#ifndef WARN_NUMERIC -# define WARN_NUMERIC 13 -#endif - -#ifndef WARN_ONCE -# define WARN_ONCE 14 -#endif - -#ifndef WARN_OVERFLOW -# define WARN_OVERFLOW 15 -#endif - -#ifndef WARN_PACK -# define WARN_PACK 16 -#endif - -#ifndef WARN_PORTABLE -# define WARN_PORTABLE 17 -#endif - -#ifndef WARN_RECURSION -# define WARN_RECURSION 18 -#endif - -#ifndef WARN_REDEFINE -# define WARN_REDEFINE 19 -#endif - -#ifndef WARN_REGEXP -# define WARN_REGEXP 20 -#endif - -#ifndef WARN_SEVERE -# define WARN_SEVERE 21 -#endif - -#ifndef WARN_DEBUGGING -# define WARN_DEBUGGING 22 -#endif - -#ifndef WARN_INPLACE -# define WARN_INPLACE 23 -#endif - -#ifndef WARN_INTERNAL -# define WARN_INTERNAL 24 -#endif - -#ifndef WARN_MALLOC -# define WARN_MALLOC 25 -#endif - -#ifndef WARN_SIGNAL -# define WARN_SIGNAL 26 -#endif - -#ifndef WARN_SUBSTR -# define WARN_SUBSTR 27 -#endif - -#ifndef WARN_SYNTAX -# define WARN_SYNTAX 28 -#endif - -#ifndef WARN_AMBIGUOUS -# define WARN_AMBIGUOUS 29 -#endif - -#ifndef WARN_BAREWORD -# define WARN_BAREWORD 30 -#endif - -#ifndef WARN_DIGIT -# define WARN_DIGIT 31 -#endif - -#ifndef WARN_PARENTHESIS -# define WARN_PARENTHESIS 32 -#endif - -#ifndef WARN_PRECEDENCE -# define WARN_PRECEDENCE 33 -#endif - -#ifndef WARN_PRINTF -# define WARN_PRINTF 34 -#endif - -#ifndef WARN_PROTOTYPE -# define WARN_PROTOTYPE 35 -#endif - -#ifndef WARN_QW -# define WARN_QW 36 -#endif - -#ifndef WARN_RESERVED -# define WARN_RESERVED 37 -#endif - -#ifndef WARN_SEMICOLON -# define WARN_SEMICOLON 38 -#endif - -#ifndef WARN_TAINT -# define WARN_TAINT 39 -#endif - -#ifndef WARN_THREADS -# define WARN_THREADS 40 -#endif - -#ifndef WARN_UNINITIALIZED -# define WARN_UNINITIALIZED 41 -#endif - -#ifndef WARN_UNPACK -# define WARN_UNPACK 42 -#endif - -#ifndef WARN_UNTIE -# define WARN_UNTIE 43 -#endif - -#ifndef WARN_UTF8 -# define WARN_UTF8 44 -#endif - -#ifndef WARN_VOID -# define WARN_VOID 45 -#endif - -#ifndef WARN_ASSERTIONS -# define WARN_ASSERTIONS 46 -#endif -#ifndef packWARN -# define packWARN(a) (a) -#endif - -#ifndef ckWARN -# ifdef G_WARN_ON -# define ckWARN(a) (PL_dowarn & G_WARN_ON) -# else -# define ckWARN(a) PL_dowarn -# endif -#endif - -#if (PERL_BCDVERSION >= 0x5004000) && !defined(warner) -#if defined(NEED_warner) -static void DPPP_(my_warner)(U32 err, const char *pat, ...); -static -#else -extern void DPPP_(my_warner)(U32 err, const char *pat, ...); -#endif - -#define Perl_warner DPPP_(my_warner) - -#if defined(NEED_warner) || defined(NEED_warner_GLOBAL) - -void -DPPP_(my_warner)(U32 err, const char *pat, ...) -{ - SV *sv; - va_list args; - - PERL_UNUSED_ARG(err); - - va_start(args, pat); - sv = vnewSVpvf(pat, &args); - va_end(args); - sv_2mortal(sv); - warn("%s", SvPV_nolen(sv)); -} - -#define warner Perl_warner - -#define Perl_warner_nocontext Perl_warner - -#endif -#endif - -/* concatenating with "" ensures that only literal strings are accepted as argument - * note that STR_WITH_LEN() can't be used as argument to macros or functions that - * under some configurations might be macros - */ -#ifndef STR_WITH_LEN -# define STR_WITH_LEN(s) (s ""), (sizeof(s)-1) -#endif -#ifndef newSVpvs -# define newSVpvs(str) newSVpvn(str "", sizeof(str) - 1) -#endif - -#ifndef newSVpvs_flags -# define newSVpvs_flags(str, flags) newSVpvn_flags(str "", sizeof(str) - 1, flags) -#endif - -#ifndef newSVpvs_share -# define newSVpvs_share(str) newSVpvn_share(str "", sizeof(str) - 1, 0) -#endif - -#ifndef sv_catpvs -# define sv_catpvs(sv, str) sv_catpvn(sv, str "", sizeof(str) - 1) -#endif - -#ifndef sv_setpvs -# define sv_setpvs(sv, str) sv_setpvn(sv, str "", sizeof(str) - 1) -#endif - -#ifndef hv_fetchs -# define hv_fetchs(hv, key, lval) hv_fetch(hv, key "", sizeof(key) - 1, lval) -#endif - -#ifndef hv_stores -# define hv_stores(hv, key, val) hv_store(hv, key "", sizeof(key) - 1, val, 0) -#endif -#ifndef gv_fetchpvs -# define gv_fetchpvs(name, flags, svt) gv_fetchpvn_flags(name "", sizeof(name) - 1, flags, svt) -#endif - -#ifndef gv_stashpvs -# define gv_stashpvs(name, flags) gv_stashpvn(name "", sizeof(name) - 1, flags) -#endif -#ifndef get_cvs -# define get_cvs(name, flags) get_cvn_flags(name "", sizeof(name)-1, flags) -#endif -#ifndef SvGETMAGIC -# define SvGETMAGIC(x) STMT_START { if (SvGMAGICAL(x)) mg_get(x); } STMT_END -#endif - -/* Some random bits for sv_unmagicext. These should probably be pulled in for - real and organized at some point */ -#ifndef HEf_SVKEY -# define HEf_SVKEY -2 -#endif - -#if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN) -# define MUTABLE_PTR(p) ({ void *_p = (p); _p; }) -#else -# define MUTABLE_PTR(p) ((void *) (p)) -#endif - -#define MUTABLE_SV(p) ((SV *)MUTABLE_PTR(p)) - -/* end of random bits */ -#ifndef PERL_MAGIC_sv -# define PERL_MAGIC_sv '\0' -#endif - -#ifndef PERL_MAGIC_overload -# define PERL_MAGIC_overload 'A' -#endif - -#ifndef PERL_MAGIC_overload_elem -# define PERL_MAGIC_overload_elem 'a' -#endif - -#ifndef PERL_MAGIC_overload_table -# define PERL_MAGIC_overload_table 'c' -#endif - -#ifndef PERL_MAGIC_bm -# define PERL_MAGIC_bm 'B' -#endif - -#ifndef PERL_MAGIC_regdata -# define PERL_MAGIC_regdata 'D' -#endif - -#ifndef PERL_MAGIC_regdatum -# define PERL_MAGIC_regdatum 'd' -#endif - -#ifndef PERL_MAGIC_env -# define PERL_MAGIC_env 'E' -#endif - -#ifndef PERL_MAGIC_envelem -# define PERL_MAGIC_envelem 'e' -#endif - -#ifndef PERL_MAGIC_fm -# define PERL_MAGIC_fm 'f' -#endif - -#ifndef PERL_MAGIC_regex_global -# define PERL_MAGIC_regex_global 'g' -#endif - -#ifndef PERL_MAGIC_isa -# define PERL_MAGIC_isa 'I' -#endif - -#ifndef PERL_MAGIC_isaelem -# define PERL_MAGIC_isaelem 'i' -#endif - -#ifndef PERL_MAGIC_nkeys -# define PERL_MAGIC_nkeys 'k' -#endif - -#ifndef PERL_MAGIC_dbfile -# define PERL_MAGIC_dbfile 'L' -#endif - -#ifndef PERL_MAGIC_dbline -# define PERL_MAGIC_dbline 'l' -#endif - -#ifndef PERL_MAGIC_mutex -# define PERL_MAGIC_mutex 'm' -#endif - -#ifndef PERL_MAGIC_shared -# define PERL_MAGIC_shared 'N' -#endif - -#ifndef PERL_MAGIC_shared_scalar -# define PERL_MAGIC_shared_scalar 'n' -#endif - -#ifndef PERL_MAGIC_collxfrm -# define PERL_MAGIC_collxfrm 'o' -#endif - -#ifndef PERL_MAGIC_tied -# define PERL_MAGIC_tied 'P' -#endif - -#ifndef PERL_MAGIC_tiedelem -# define PERL_MAGIC_tiedelem 'p' -#endif - -#ifndef PERL_MAGIC_tiedscalar -# define PERL_MAGIC_tiedscalar 'q' -#endif - -#ifndef PERL_MAGIC_qr -# define PERL_MAGIC_qr 'r' -#endif - -#ifndef PERL_MAGIC_sig -# define PERL_MAGIC_sig 'S' -#endif - -#ifndef PERL_MAGIC_sigelem -# define PERL_MAGIC_sigelem 's' -#endif - -#ifndef PERL_MAGIC_taint -# define PERL_MAGIC_taint 't' -#endif - -#ifndef PERL_MAGIC_uvar -# define PERL_MAGIC_uvar 'U' -#endif - -#ifndef PERL_MAGIC_uvar_elem -# define PERL_MAGIC_uvar_elem 'u' -#endif - -#ifndef PERL_MAGIC_vstring -# define PERL_MAGIC_vstring 'V' -#endif - -#ifndef PERL_MAGIC_vec -# define PERL_MAGIC_vec 'v' -#endif - -#ifndef PERL_MAGIC_utf8 -# define PERL_MAGIC_utf8 'w' -#endif - -#ifndef PERL_MAGIC_substr -# define PERL_MAGIC_substr 'x' -#endif - -#ifndef PERL_MAGIC_defelem -# define PERL_MAGIC_defelem 'y' -#endif - -#ifndef PERL_MAGIC_glob -# define PERL_MAGIC_glob '*' -#endif - -#ifndef PERL_MAGIC_arylen -# define PERL_MAGIC_arylen '#' -#endif - -#ifndef PERL_MAGIC_pos -# define PERL_MAGIC_pos '.' -#endif - -#ifndef PERL_MAGIC_backref -# define PERL_MAGIC_backref '<' -#endif - -#ifndef PERL_MAGIC_ext -# define PERL_MAGIC_ext '~' -#endif - -/* That's the best we can do... */ -#ifndef sv_catpvn_nomg -# define sv_catpvn_nomg sv_catpvn -#endif - -#ifndef sv_catsv_nomg -# define sv_catsv_nomg sv_catsv -#endif - -#ifndef sv_setsv_nomg -# define sv_setsv_nomg sv_setsv -#endif - -#ifndef sv_pvn_nomg -# define sv_pvn_nomg sv_pvn -#endif - -#ifndef SvIV_nomg -# define SvIV_nomg SvIV -#endif - -#ifndef SvUV_nomg -# define SvUV_nomg SvUV -#endif - -#ifndef sv_catpv_mg -# define sv_catpv_mg(sv, ptr) \ - STMT_START { \ - SV *TeMpSv = sv; \ - sv_catpv(TeMpSv,ptr); \ - SvSETMAGIC(TeMpSv); \ - } STMT_END -#endif - -#ifndef sv_catpvn_mg -# define sv_catpvn_mg(sv, ptr, len) \ - STMT_START { \ - SV *TeMpSv = sv; \ - sv_catpvn(TeMpSv,ptr,len); \ - SvSETMAGIC(TeMpSv); \ - } STMT_END -#endif - -#ifndef sv_catsv_mg -# define sv_catsv_mg(dsv, ssv) \ - STMT_START { \ - SV *TeMpSv = dsv; \ - sv_catsv(TeMpSv,ssv); \ - SvSETMAGIC(TeMpSv); \ - } STMT_END -#endif - -#ifndef sv_setiv_mg -# define sv_setiv_mg(sv, i) \ - STMT_START { \ - SV *TeMpSv = sv; \ - sv_setiv(TeMpSv,i); \ - SvSETMAGIC(TeMpSv); \ - } STMT_END -#endif - -#ifndef sv_setnv_mg -# define sv_setnv_mg(sv, num) \ - STMT_START { \ - SV *TeMpSv = sv; \ - sv_setnv(TeMpSv,num); \ - SvSETMAGIC(TeMpSv); \ - } STMT_END -#endif - -#ifndef sv_setpv_mg -# define sv_setpv_mg(sv, ptr) \ - STMT_START { \ - SV *TeMpSv = sv; \ - sv_setpv(TeMpSv,ptr); \ - SvSETMAGIC(TeMpSv); \ - } STMT_END -#endif - -#ifndef sv_setpvn_mg -# define sv_setpvn_mg(sv, ptr, len) \ - STMT_START { \ - SV *TeMpSv = sv; \ - sv_setpvn(TeMpSv,ptr,len); \ - SvSETMAGIC(TeMpSv); \ - } STMT_END -#endif - -#ifndef sv_setsv_mg -# define sv_setsv_mg(dsv, ssv) \ - STMT_START { \ - SV *TeMpSv = dsv; \ - sv_setsv(TeMpSv,ssv); \ - SvSETMAGIC(TeMpSv); \ - } STMT_END -#endif - -#ifndef sv_setuv_mg -# define sv_setuv_mg(sv, i) \ - STMT_START { \ - SV *TeMpSv = sv; \ - sv_setuv(TeMpSv,i); \ - SvSETMAGIC(TeMpSv); \ - } STMT_END -#endif - -#ifndef sv_usepvn_mg -# define sv_usepvn_mg(sv, ptr, len) \ - STMT_START { \ - SV *TeMpSv = sv; \ - sv_usepvn(TeMpSv,ptr,len); \ - SvSETMAGIC(TeMpSv); \ - } STMT_END -#endif -#ifndef SvVSTRING_mg -# define SvVSTRING_mg(sv) (SvMAGICAL(sv) ? mg_find(sv, PERL_MAGIC_vstring) : NULL) -#endif - -/* Hint: sv_magic_portable - * This is a compatibility function that is only available with - * Devel::PPPort. It is NOT in the perl core. - * Its purpose is to mimic the 5.8.0 behaviour of sv_magic() when - * it is being passed a name pointer with namlen == 0. In that - * case, perl 5.8.0 and later store the pointer, not a copy of it. - * The compatibility can be provided back to perl 5.004. With - * earlier versions, the code will not compile. - */ - -#if (PERL_BCDVERSION < 0x5004000) - - /* code that uses sv_magic_portable will not compile */ - -#elif (PERL_BCDVERSION < 0x5008000) - -# define sv_magic_portable(sv, obj, how, name, namlen) \ - STMT_START { \ - SV *SvMp_sv = (sv); \ - char *SvMp_name = (char *) (name); \ - I32 SvMp_namlen = (namlen); \ - if (SvMp_name && SvMp_namlen == 0) \ - { \ - MAGIC *mg; \ - sv_magic(SvMp_sv, obj, how, 0, 0); \ - mg = SvMAGIC(SvMp_sv); \ - mg->mg_len = -42; /* XXX: this is the tricky part */ \ - mg->mg_ptr = SvMp_name; \ - } \ - else \ - { \ - sv_magic(SvMp_sv, obj, how, SvMp_name, SvMp_namlen); \ - } \ - } STMT_END - -#else - -# define sv_magic_portable(a, b, c, d, e) sv_magic(a, b, c, d, e) - -#endif - -#if !defined(mg_findext) -#if defined(NEED_mg_findext) -static MAGIC * DPPP_(my_mg_findext)(SV * sv, int type, const MGVTBL *vtbl); -static -#else -extern MAGIC * DPPP_(my_mg_findext)(SV * sv, int type, const MGVTBL *vtbl); -#endif - -#define mg_findext DPPP_(my_mg_findext) -#define Perl_mg_findext DPPP_(my_mg_findext) - -#if defined(NEED_mg_findext) || defined(NEED_mg_findext_GLOBAL) - -MAGIC * -DPPP_(my_mg_findext)(SV * sv, int type, const MGVTBL *vtbl) { - if (sv) { - MAGIC *mg; - -#ifdef AvPAD_NAMELIST - assert(!(SvTYPE(sv) == SVt_PVAV && AvPAD_NAMELIST(sv))); -#endif - - for (mg = SvMAGIC (sv); mg; mg = mg->mg_moremagic) { - if (mg->mg_type == type && mg->mg_virtual == vtbl) - return mg; - } - } - - return NULL; -} - -#endif -#endif - -#if !defined(sv_unmagicext) -#if defined(NEED_sv_unmagicext) -static int DPPP_(my_sv_unmagicext)(pTHX_ SV * const sv, const int type, MGVTBL * vtbl); -static -#else -extern int DPPP_(my_sv_unmagicext)(pTHX_ SV * const sv, const int type, MGVTBL * vtbl); -#endif - -#ifdef sv_unmagicext -# undef sv_unmagicext -#endif -#define sv_unmagicext(a,b,c) DPPP_(my_sv_unmagicext)(aTHX_ a,b,c) -#define Perl_sv_unmagicext DPPP_(my_sv_unmagicext) - -#if defined(NEED_sv_unmagicext) || defined(NEED_sv_unmagicext_GLOBAL) - -int -DPPP_(my_sv_unmagicext)(pTHX_ SV *const sv, const int type, MGVTBL *vtbl) -{ - MAGIC* mg; - MAGIC** mgp; - - if (SvTYPE(sv) < SVt_PVMG || !SvMAGIC(sv)) - return 0; - mgp = &(SvMAGIC(sv)); - for (mg = *mgp; mg; mg = *mgp) { - const MGVTBL* const virt = mg->mg_virtual; - if (mg->mg_type == type && virt == vtbl) { - *mgp = mg->mg_moremagic; - if (virt && virt->svt_free) - virt->svt_free(aTHX_ sv, mg); - if (mg->mg_ptr && mg->mg_type != PERL_MAGIC_regex_global) { - if (mg->mg_len > 0) - Safefree(mg->mg_ptr); - else if (mg->mg_len == HEf_SVKEY) /* Questionable on older perls... */ - SvREFCNT_dec(MUTABLE_SV(mg->mg_ptr)); - else if (mg->mg_type == PERL_MAGIC_utf8) - Safefree(mg->mg_ptr); - } - if (mg->mg_flags & MGf_REFCOUNTED) - SvREFCNT_dec(mg->mg_obj); - Safefree(mg); - } - else - mgp = &mg->mg_moremagic; - } - if (SvMAGIC(sv)) { - if (SvMAGICAL(sv)) /* if we're under save_magic, wait for restore_magic; */ - mg_magical(sv); /* else fix the flags now */ - } - else { - SvMAGICAL_off(sv); - SvFLAGS(sv) |= (SvFLAGS(sv) & (SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT; - } - return 0; -} - -#endif -#endif - -#ifdef USE_ITHREADS -#ifndef CopFILE -# define CopFILE(c) ((c)->cop_file) -#endif - -#ifndef CopFILEGV -# define CopFILEGV(c) (CopFILE(c) ? gv_fetchfile(CopFILE(c)) : Nullgv) -#endif - -#ifndef CopFILE_set -# define CopFILE_set(c,pv) ((c)->cop_file = savepv(pv)) -#endif - -#ifndef CopFILESV -# define CopFILESV(c) (CopFILE(c) ? GvSV(gv_fetchfile(CopFILE(c))) : Nullsv) -#endif - -#ifndef CopFILEAV -# define CopFILEAV(c) (CopFILE(c) ? GvAV(gv_fetchfile(CopFILE(c))) : Nullav) -#endif - -#ifndef CopSTASHPV -# define CopSTASHPV(c) ((c)->cop_stashpv) -#endif - -#ifndef CopSTASHPV_set -# define CopSTASHPV_set(c,pv) ((c)->cop_stashpv = ((pv) ? savepv(pv) : Nullch)) -#endif - -#ifndef CopSTASH -# define CopSTASH(c) (CopSTASHPV(c) ? gv_stashpv(CopSTASHPV(c),GV_ADD) : Nullhv) -#endif - -#ifndef CopSTASH_set -# define CopSTASH_set(c,hv) CopSTASHPV_set(c, (hv) ? HvNAME(hv) : Nullch) -#endif - -#ifndef CopSTASH_eq -# define CopSTASH_eq(c,hv) ((hv) && (CopSTASHPV(c) == HvNAME(hv) \ - || (CopSTASHPV(c) && HvNAME(hv) \ - && strEQ(CopSTASHPV(c), HvNAME(hv))))) -#endif - -#else -#ifndef CopFILEGV -# define CopFILEGV(c) ((c)->cop_filegv) -#endif - -#ifndef CopFILEGV_set -# define CopFILEGV_set(c,gv) ((c)->cop_filegv = (GV*)SvREFCNT_inc(gv)) -#endif - -#ifndef CopFILE_set -# define CopFILE_set(c,pv) CopFILEGV_set((c), gv_fetchfile(pv)) -#endif - -#ifndef CopFILESV -# define CopFILESV(c) (CopFILEGV(c) ? GvSV(CopFILEGV(c)) : Nullsv) -#endif - -#ifndef CopFILEAV -# define CopFILEAV(c) (CopFILEGV(c) ? GvAV(CopFILEGV(c)) : Nullav) -#endif - -#ifndef CopFILE -# define CopFILE(c) (CopFILESV(c) ? SvPVX(CopFILESV(c)) : Nullch) -#endif - -#ifndef CopSTASH -# define CopSTASH(c) ((c)->cop_stash) -#endif - -#ifndef CopSTASH_set -# define CopSTASH_set(c,hv) ((c)->cop_stash = (hv)) -#endif - -#ifndef CopSTASHPV -# define CopSTASHPV(c) (CopSTASH(c) ? HvNAME(CopSTASH(c)) : Nullch) -#endif - -#ifndef CopSTASHPV_set -# define CopSTASHPV_set(c,pv) CopSTASH_set((c), gv_stashpv(pv,GV_ADD)) -#endif - -#ifndef CopSTASH_eq -# define CopSTASH_eq(c,hv) (CopSTASH(c) == (hv)) -#endif - -#endif /* USE_ITHREADS */ - -#if (PERL_BCDVERSION >= 0x5006000) -#ifndef caller_cx - -# if defined(NEED_caller_cx) || defined(NEED_caller_cx_GLOBAL) -static I32 -DPPP_dopoptosub_at(const PERL_CONTEXT *cxstk, I32 startingblock) -{ - I32 i; - - for (i = startingblock; i >= 0; i--) { - register const PERL_CONTEXT * const cx = &cxstk[i]; - switch (CxTYPE(cx)) { - default: - continue; - case CXt_EVAL: - case CXt_SUB: - case CXt_FORMAT: - return i; - } - } - return i; -} -# endif - -# if defined(NEED_caller_cx) -static const PERL_CONTEXT * DPPP_(my_caller_cx)(pTHX_ I32 count, const PERL_CONTEXT **dbcxp); -static -#else -extern const PERL_CONTEXT * DPPP_(my_caller_cx)(pTHX_ I32 count, const PERL_CONTEXT **dbcxp); -#endif - -#ifdef caller_cx -# undef caller_cx -#endif -#define caller_cx(a,b) DPPP_(my_caller_cx)(aTHX_ a,b) -#define Perl_caller_cx DPPP_(my_caller_cx) - -#if defined(NEED_caller_cx) || defined(NEED_caller_cx_GLOBAL) - -const PERL_CONTEXT * -DPPP_(my_caller_cx)(pTHX_ I32 count, const PERL_CONTEXT **dbcxp) -{ - register I32 cxix = DPPP_dopoptosub_at(cxstack, cxstack_ix); - register const PERL_CONTEXT *cx; - register const PERL_CONTEXT *ccstack = cxstack; - const PERL_SI *top_si = PL_curstackinfo; - - for (;;) { - /* we may be in a higher stacklevel, so dig down deeper */ - while (cxix < 0 && top_si->si_type != PERLSI_MAIN) { - top_si = top_si->si_prev; - ccstack = top_si->si_cxstack; - cxix = DPPP_dopoptosub_at(ccstack, top_si->si_cxix); - } - if (cxix < 0) - return NULL; - /* caller() should not report the automatic calls to &DB::sub */ - if (PL_DBsub && GvCV(PL_DBsub) && cxix >= 0 && - ccstack[cxix].blk_sub.cv == GvCV(PL_DBsub)) - count++; - if (!count--) - break; - cxix = DPPP_dopoptosub_at(ccstack, cxix - 1); - } - - cx = &ccstack[cxix]; - if (dbcxp) *dbcxp = cx; - - if (CxTYPE(cx) == CXt_SUB || CxTYPE(cx) == CXt_FORMAT) { - const I32 dbcxix = DPPP_dopoptosub_at(ccstack, cxix - 1); - /* We expect that ccstack[dbcxix] is CXt_SUB, anyway, the - field below is defined for any cx. */ - /* caller() should not report the automatic calls to &DB::sub */ - if (PL_DBsub && GvCV(PL_DBsub) && dbcxix >= 0 && ccstack[dbcxix].blk_sub.cv == GvCV(PL_DBsub)) - cx = &ccstack[dbcxix]; - } - - return cx; -} - -# endif -#endif /* caller_cx */ -#endif /* 5.6.0 */ -#ifndef IN_PERL_COMPILETIME -# define IN_PERL_COMPILETIME (PL_curcop == &PL_compiling) -#endif - -#ifndef IN_LOCALE_RUNTIME -# define IN_LOCALE_RUNTIME (PL_curcop->op_private & HINT_LOCALE) -#endif - -#ifndef IN_LOCALE_COMPILETIME -# define IN_LOCALE_COMPILETIME (PL_hints & HINT_LOCALE) -#endif - -#ifndef IN_LOCALE -# define IN_LOCALE (IN_PERL_COMPILETIME ? IN_LOCALE_COMPILETIME : IN_LOCALE_RUNTIME) -#endif -#ifndef IS_NUMBER_IN_UV -# define IS_NUMBER_IN_UV 0x01 -#endif - -#ifndef IS_NUMBER_GREATER_THAN_UV_MAX -# define IS_NUMBER_GREATER_THAN_UV_MAX 0x02 -#endif - -#ifndef IS_NUMBER_NOT_INT -# define IS_NUMBER_NOT_INT 0x04 -#endif - -#ifndef IS_NUMBER_NEG -# define IS_NUMBER_NEG 0x08 -#endif - -#ifndef IS_NUMBER_INFINITY -# define IS_NUMBER_INFINITY 0x10 -#endif - -#ifndef IS_NUMBER_NAN -# define IS_NUMBER_NAN 0x20 -#endif -#ifndef GROK_NUMERIC_RADIX -# define GROK_NUMERIC_RADIX(sp, send) grok_numeric_radix(sp, send) -#endif -#ifndef PERL_SCAN_GREATER_THAN_UV_MAX -# define PERL_SCAN_GREATER_THAN_UV_MAX 0x02 -#endif - -#ifndef PERL_SCAN_SILENT_ILLDIGIT -# define PERL_SCAN_SILENT_ILLDIGIT 0x04 -#endif - -#ifndef PERL_SCAN_ALLOW_UNDERSCORES -# define PERL_SCAN_ALLOW_UNDERSCORES 0x01 -#endif - -#ifndef PERL_SCAN_DISALLOW_PREFIX -# define PERL_SCAN_DISALLOW_PREFIX 0x02 -#endif - -#ifndef grok_numeric_radix -#if defined(NEED_grok_numeric_radix) -static bool DPPP_(my_grok_numeric_radix)(pTHX_ const char ** sp, const char * send); -static -#else -extern bool DPPP_(my_grok_numeric_radix)(pTHX_ const char ** sp, const char * send); -#endif - -#ifdef grok_numeric_radix -# undef grok_numeric_radix -#endif -#define grok_numeric_radix(a,b) DPPP_(my_grok_numeric_radix)(aTHX_ a,b) -#define Perl_grok_numeric_radix DPPP_(my_grok_numeric_radix) - -#if defined(NEED_grok_numeric_radix) || defined(NEED_grok_numeric_radix_GLOBAL) -bool -DPPP_(my_grok_numeric_radix)(pTHX_ const char **sp, const char *send) -{ -#ifdef USE_LOCALE_NUMERIC -#ifdef PL_numeric_radix_sv - if (PL_numeric_radix_sv && IN_LOCALE) { - STRLEN len; - char* radix = SvPV(PL_numeric_radix_sv, len); - if (*sp + len <= send && memEQ(*sp, radix, len)) { - *sp += len; - return TRUE; - } - } -#else - /* older perls don't have PL_numeric_radix_sv so the radix - * must manually be requested from locale.h - */ -#include - dTHR; /* needed for older threaded perls */ - struct lconv *lc = localeconv(); - char *radix = lc->decimal_point; - if (radix && IN_LOCALE) { - STRLEN len = strlen(radix); - if (*sp + len <= send && memEQ(*sp, radix, len)) { - *sp += len; - return TRUE; - } - } -#endif -#endif /* USE_LOCALE_NUMERIC */ - /* always try "." if numeric radix didn't match because - * we may have data from different locales mixed */ - if (*sp < send && **sp == '.') { - ++*sp; - return TRUE; - } - return FALSE; -} -#endif -#endif - -#ifndef grok_number -#if defined(NEED_grok_number) -static int DPPP_(my_grok_number)(pTHX_ const char * pv, STRLEN len, UV * valuep); -static -#else -extern int DPPP_(my_grok_number)(pTHX_ const char * pv, STRLEN len, UV * valuep); -#endif - -#ifdef grok_number -# undef grok_number -#endif -#define grok_number(a,b,c) DPPP_(my_grok_number)(aTHX_ a,b,c) -#define Perl_grok_number DPPP_(my_grok_number) - -#if defined(NEED_grok_number) || defined(NEED_grok_number_GLOBAL) -int -DPPP_(my_grok_number)(pTHX_ const char *pv, STRLEN len, UV *valuep) -{ - const char *s = pv; - const char *send = pv + len; - const UV max_div_10 = UV_MAX / 10; - const char max_mod_10 = UV_MAX % 10; - int numtype = 0; - int sawinf = 0; - int sawnan = 0; - - while (s < send && isSPACE(*s)) - s++; - if (s == send) { - return 0; - } else if (*s == '-') { - s++; - numtype = IS_NUMBER_NEG; - } - else if (*s == '+') - s++; - - if (s == send) - return 0; - - /* next must be digit or the radix separator or beginning of infinity */ - if (isDIGIT(*s)) { - /* UVs are at least 32 bits, so the first 9 decimal digits cannot - overflow. */ - UV value = *s - '0'; - /* This construction seems to be more optimiser friendly. - (without it gcc does the isDIGIT test and the *s - '0' separately) - With it gcc on arm is managing 6 instructions (6 cycles) per digit. - In theory the optimiser could deduce how far to unroll the loop - before checking for overflow. */ - if (++s < send) { - int digit = *s - '0'; - if (digit >= 0 && digit <= 9) { - value = value * 10 + digit; - if (++s < send) { - digit = *s - '0'; - if (digit >= 0 && digit <= 9) { - value = value * 10 + digit; - if (++s < send) { - digit = *s - '0'; - if (digit >= 0 && digit <= 9) { - value = value * 10 + digit; - if (++s < send) { - digit = *s - '0'; - if (digit >= 0 && digit <= 9) { - value = value * 10 + digit; - if (++s < send) { - digit = *s - '0'; - if (digit >= 0 && digit <= 9) { - value = value * 10 + digit; - if (++s < send) { - digit = *s - '0'; - if (digit >= 0 && digit <= 9) { - value = value * 10 + digit; - if (++s < send) { - digit = *s - '0'; - if (digit >= 0 && digit <= 9) { - value = value * 10 + digit; - if (++s < send) { - digit = *s - '0'; - if (digit >= 0 && digit <= 9) { - value = value * 10 + digit; - if (++s < send) { - /* Now got 9 digits, so need to check - each time for overflow. */ - digit = *s - '0'; - while (digit >= 0 && digit <= 9 - && (value < max_div_10 - || (value == max_div_10 - && digit <= max_mod_10))) { - value = value * 10 + digit; - if (++s < send) - digit = *s - '0'; - else - break; - } - if (digit >= 0 && digit <= 9 - && (s < send)) { - /* value overflowed. - skip the remaining digits, don't - worry about setting *valuep. */ - do { - s++; - } while (s < send && isDIGIT(*s)); - numtype |= - IS_NUMBER_GREATER_THAN_UV_MAX; - goto skip_value; - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - numtype |= IS_NUMBER_IN_UV; - if (valuep) - *valuep = value; - - skip_value: - if (GROK_NUMERIC_RADIX(&s, send)) { - numtype |= IS_NUMBER_NOT_INT; - while (s < send && isDIGIT(*s)) /* optional digits after the radix */ - s++; - } - } - else if (GROK_NUMERIC_RADIX(&s, send)) { - numtype |= IS_NUMBER_NOT_INT | IS_NUMBER_IN_UV; /* valuep assigned below */ - /* no digits before the radix means we need digits after it */ - if (s < send && isDIGIT(*s)) { - do { - s++; - } while (s < send && isDIGIT(*s)); - if (valuep) { - /* integer approximation is valid - it's 0. */ - *valuep = 0; - } - } - else - return 0; - } else if (*s == 'I' || *s == 'i') { - s++; if (s == send || (*s != 'N' && *s != 'n')) return 0; - s++; if (s == send || (*s != 'F' && *s != 'f')) return 0; - s++; if (s < send && (*s == 'I' || *s == 'i')) { - s++; if (s == send || (*s != 'N' && *s != 'n')) return 0; - s++; if (s == send || (*s != 'I' && *s != 'i')) return 0; - s++; if (s == send || (*s != 'T' && *s != 't')) return 0; - s++; if (s == send || (*s != 'Y' && *s != 'y')) return 0; - s++; - } - sawinf = 1; - } else if (*s == 'N' || *s == 'n') { - /* XXX TODO: There are signaling NaNs and quiet NaNs. */ - s++; if (s == send || (*s != 'A' && *s != 'a')) return 0; - s++; if (s == send || (*s != 'N' && *s != 'n')) return 0; - s++; - sawnan = 1; - } else - return 0; - - if (sawinf) { - numtype &= IS_NUMBER_NEG; /* Keep track of sign */ - numtype |= IS_NUMBER_INFINITY | IS_NUMBER_NOT_INT; - } else if (sawnan) { - numtype &= IS_NUMBER_NEG; /* Keep track of sign */ - numtype |= IS_NUMBER_NAN | IS_NUMBER_NOT_INT; - } else if (s < send) { - /* we can have an optional exponent part */ - if (*s == 'e' || *s == 'E') { - /* The only flag we keep is sign. Blow away any "it's UV" */ - numtype &= IS_NUMBER_NEG; - numtype |= IS_NUMBER_NOT_INT; - s++; - if (s < send && (*s == '-' || *s == '+')) - s++; - if (s < send && isDIGIT(*s)) { - do { - s++; - } while (s < send && isDIGIT(*s)); - } - else - return 0; - } - } - while (s < send && isSPACE(*s)) - s++; - if (s >= send) - return numtype; - if (len == 10 && memEQ(pv, "0 but true", 10)) { - if (valuep) - *valuep = 0; - return IS_NUMBER_IN_UV; - } - return 0; -} -#endif -#endif - -/* - * The grok_* routines have been modified to use warn() instead of - * Perl_warner(). Also, 'hexdigit' was the former name of PL_hexdigit, - * which is why the stack variable has been renamed to 'xdigit'. - */ - -#ifndef grok_bin -#if defined(NEED_grok_bin) -static UV DPPP_(my_grok_bin)(pTHX_ const char * start, STRLEN * len_p, I32 * flags, NV * result); -static -#else -extern UV DPPP_(my_grok_bin)(pTHX_ const char * start, STRLEN * len_p, I32 * flags, NV * result); -#endif - -#ifdef grok_bin -# undef grok_bin -#endif -#define grok_bin(a,b,c,d) DPPP_(my_grok_bin)(aTHX_ a,b,c,d) -#define Perl_grok_bin DPPP_(my_grok_bin) - -#if defined(NEED_grok_bin) || defined(NEED_grok_bin_GLOBAL) -UV -DPPP_(my_grok_bin)(pTHX_ const char *start, STRLEN *len_p, I32 *flags, NV *result) -{ - const char *s = start; - STRLEN len = *len_p; - UV value = 0; - NV value_nv = 0; - - const UV max_div_2 = UV_MAX / 2; - bool allow_underscores = *flags & PERL_SCAN_ALLOW_UNDERSCORES; - bool overflowed = FALSE; - - if (!(*flags & PERL_SCAN_DISALLOW_PREFIX)) { - /* strip off leading b or 0b. - for compatibility silently suffer "b" and "0b" as valid binary - numbers. */ - if (len >= 1) { - if (s[0] == 'b') { - s++; - len--; - } - else if (len >= 2 && s[0] == '0' && s[1] == 'b') { - s+=2; - len-=2; - } - } - } - - for (; len-- && *s; s++) { - char bit = *s; - if (bit == '0' || bit == '1') { - /* Write it in this wonky order with a goto to attempt to get the - compiler to make the common case integer-only loop pretty tight. - With gcc seems to be much straighter code than old scan_bin. */ - redo: - if (!overflowed) { - if (value <= max_div_2) { - value = (value << 1) | (bit - '0'); - continue; - } - /* Bah. We're just overflowed. */ - warn("Integer overflow in binary number"); - overflowed = TRUE; - value_nv = (NV) value; - } - value_nv *= 2.0; - /* If an NV has not enough bits in its mantissa to - * represent a UV this summing of small low-order numbers - * is a waste of time (because the NV cannot preserve - * the low-order bits anyway): we could just remember when - * did we overflow and in the end just multiply value_nv by the - * right amount. */ - value_nv += (NV)(bit - '0'); - continue; - } - if (bit == '_' && len && allow_underscores && (bit = s[1]) - && (bit == '0' || bit == '1')) - { - --len; - ++s; - goto redo; - } - if (!(*flags & PERL_SCAN_SILENT_ILLDIGIT)) - warn("Illegal binary digit '%c' ignored", *s); - break; - } - - if ( ( overflowed && value_nv > 4294967295.0) -#if UVSIZE > 4 - || (!overflowed && value > 0xffffffff ) -#endif - ) { - warn("Binary number > 0b11111111111111111111111111111111 non-portable"); - } - *len_p = s - start; - if (!overflowed) { - *flags = 0; - return value; - } - *flags = PERL_SCAN_GREATER_THAN_UV_MAX; - if (result) - *result = value_nv; - return UV_MAX; -} -#endif -#endif - -#ifndef grok_hex -#if defined(NEED_grok_hex) -static UV DPPP_(my_grok_hex)(pTHX_ const char * start, STRLEN * len_p, I32 * flags, NV * result); -static -#else -extern UV DPPP_(my_grok_hex)(pTHX_ const char * start, STRLEN * len_p, I32 * flags, NV * result); -#endif - -#ifdef grok_hex -# undef grok_hex -#endif -#define grok_hex(a,b,c,d) DPPP_(my_grok_hex)(aTHX_ a,b,c,d) -#define Perl_grok_hex DPPP_(my_grok_hex) - -#if defined(NEED_grok_hex) || defined(NEED_grok_hex_GLOBAL) -UV -DPPP_(my_grok_hex)(pTHX_ const char *start, STRLEN *len_p, I32 *flags, NV *result) -{ - const char *s = start; - STRLEN len = *len_p; - UV value = 0; - NV value_nv = 0; - - const UV max_div_16 = UV_MAX / 16; - bool allow_underscores = *flags & PERL_SCAN_ALLOW_UNDERSCORES; - bool overflowed = FALSE; - const char *xdigit; - - if (!(*flags & PERL_SCAN_DISALLOW_PREFIX)) { - /* strip off leading x or 0x. - for compatibility silently suffer "x" and "0x" as valid hex numbers. - */ - if (len >= 1) { - if (s[0] == 'x') { - s++; - len--; - } - else if (len >= 2 && s[0] == '0' && s[1] == 'x') { - s+=2; - len-=2; - } - } - } - - for (; len-- && *s; s++) { - xdigit = strchr((char *) PL_hexdigit, *s); - if (xdigit) { - /* Write it in this wonky order with a goto to attempt to get the - compiler to make the common case integer-only loop pretty tight. - With gcc seems to be much straighter code than old scan_hex. */ - redo: - if (!overflowed) { - if (value <= max_div_16) { - value = (value << 4) | ((xdigit - PL_hexdigit) & 15); - continue; - } - warn("Integer overflow in hexadecimal number"); - overflowed = TRUE; - value_nv = (NV) value; - } - value_nv *= 16.0; - /* If an NV has not enough bits in its mantissa to - * represent a UV this summing of small low-order numbers - * is a waste of time (because the NV cannot preserve - * the low-order bits anyway): we could just remember when - * did we overflow and in the end just multiply value_nv by the - * right amount of 16-tuples. */ - value_nv += (NV)((xdigit - PL_hexdigit) & 15); - continue; - } - if (*s == '_' && len && allow_underscores && s[1] - && (xdigit = strchr((char *) PL_hexdigit, s[1]))) - { - --len; - ++s; - goto redo; - } - if (!(*flags & PERL_SCAN_SILENT_ILLDIGIT)) - warn("Illegal hexadecimal digit '%c' ignored", *s); - break; - } - - if ( ( overflowed && value_nv > 4294967295.0) -#if UVSIZE > 4 - || (!overflowed && value > 0xffffffff ) -#endif - ) { - warn("Hexadecimal number > 0xffffffff non-portable"); - } - *len_p = s - start; - if (!overflowed) { - *flags = 0; - return value; - } - *flags = PERL_SCAN_GREATER_THAN_UV_MAX; - if (result) - *result = value_nv; - return UV_MAX; -} -#endif -#endif - -#ifndef grok_oct -#if defined(NEED_grok_oct) -static UV DPPP_(my_grok_oct)(pTHX_ const char * start, STRLEN * len_p, I32 * flags, NV * result); -static -#else -extern UV DPPP_(my_grok_oct)(pTHX_ const char * start, STRLEN * len_p, I32 * flags, NV * result); -#endif - -#ifdef grok_oct -# undef grok_oct -#endif -#define grok_oct(a,b,c,d) DPPP_(my_grok_oct)(aTHX_ a,b,c,d) -#define Perl_grok_oct DPPP_(my_grok_oct) - -#if defined(NEED_grok_oct) || defined(NEED_grok_oct_GLOBAL) -UV -DPPP_(my_grok_oct)(pTHX_ const char *start, STRLEN *len_p, I32 *flags, NV *result) -{ - const char *s = start; - STRLEN len = *len_p; - UV value = 0; - NV value_nv = 0; - - const UV max_div_8 = UV_MAX / 8; - bool allow_underscores = *flags & PERL_SCAN_ALLOW_UNDERSCORES; - bool overflowed = FALSE; - - for (; len-- && *s; s++) { - /* gcc 2.95 optimiser not smart enough to figure that this subtraction - out front allows slicker code. */ - int digit = *s - '0'; - if (digit >= 0 && digit <= 7) { - /* Write it in this wonky order with a goto to attempt to get the - compiler to make the common case integer-only loop pretty tight. - */ - redo: - if (!overflowed) { - if (value <= max_div_8) { - value = (value << 3) | digit; - continue; - } - /* Bah. We're just overflowed. */ - warn("Integer overflow in octal number"); - overflowed = TRUE; - value_nv = (NV) value; - } - value_nv *= 8.0; - /* If an NV has not enough bits in its mantissa to - * represent a UV this summing of small low-order numbers - * is a waste of time (because the NV cannot preserve - * the low-order bits anyway): we could just remember when - * did we overflow and in the end just multiply value_nv by the - * right amount of 8-tuples. */ - value_nv += (NV)digit; - continue; - } - if (digit == ('_' - '0') && len && allow_underscores - && (digit = s[1] - '0') && (digit >= 0 && digit <= 7)) - { - --len; - ++s; - goto redo; - } - /* Allow \octal to work the DWIM way (that is, stop scanning - * as soon as non-octal characters are seen, complain only iff - * someone seems to want to use the digits eight and nine). */ - if (digit == 8 || digit == 9) { - if (!(*flags & PERL_SCAN_SILENT_ILLDIGIT)) - warn("Illegal octal digit '%c' ignored", *s); - } - break; - } - - if ( ( overflowed && value_nv > 4294967295.0) -#if UVSIZE > 4 - || (!overflowed && value > 0xffffffff ) -#endif - ) { - warn("Octal number > 037777777777 non-portable"); - } - *len_p = s - start; - if (!overflowed) { - *flags = 0; - return value; - } - *flags = PERL_SCAN_GREATER_THAN_UV_MAX; - if (result) - *result = value_nv; - return UV_MAX; -} -#endif -#endif - -#if !defined(my_snprintf) -#if defined(NEED_my_snprintf) -static int DPPP_(my_my_snprintf)(char * buffer, const Size_t len, const char * format, ...); -static -#else -extern int DPPP_(my_my_snprintf)(char * buffer, const Size_t len, const char * format, ...); -#endif - -#define my_snprintf DPPP_(my_my_snprintf) -#define Perl_my_snprintf DPPP_(my_my_snprintf) - -#if defined(NEED_my_snprintf) || defined(NEED_my_snprintf_GLOBAL) - -int -DPPP_(my_my_snprintf)(char *buffer, const Size_t len, const char *format, ...) -{ - dTHX; - int retval; - va_list ap; - va_start(ap, format); -#ifdef HAS_VSNPRINTF - retval = vsnprintf(buffer, len, format, ap); -#else - retval = vsprintf(buffer, format, ap); -#endif - va_end(ap); - if (retval < 0 || (len > 0 && (Size_t)retval >= len)) - Perl_croak(aTHX_ "panic: my_snprintf buffer overflow"); - return retval; -} - -#endif -#endif - -#if !defined(my_sprintf) -#if defined(NEED_my_sprintf) -static int DPPP_(my_my_sprintf)(char * buffer, const char * pat, ...); -static -#else -extern int DPPP_(my_my_sprintf)(char * buffer, const char * pat, ...); -#endif - -#define my_sprintf DPPP_(my_my_sprintf) -#define Perl_my_sprintf DPPP_(my_my_sprintf) - -#if defined(NEED_my_sprintf) || defined(NEED_my_sprintf_GLOBAL) - -int -DPPP_(my_my_sprintf)(char *buffer, const char* pat, ...) -{ - va_list args; - va_start(args, pat); - vsprintf(buffer, pat, args); - va_end(args); - return strlen(buffer); -} - -#endif -#endif - -#ifdef NO_XSLOCKS -# ifdef dJMPENV -# define dXCPT dJMPENV; int rEtV = 0 -# define XCPT_TRY_START JMPENV_PUSH(rEtV); if (rEtV == 0) -# define XCPT_TRY_END JMPENV_POP; -# define XCPT_CATCH if (rEtV != 0) -# define XCPT_RETHROW JMPENV_JUMP(rEtV) -# else -# define dXCPT Sigjmp_buf oldTOP; int rEtV = 0 -# define XCPT_TRY_START Copy(top_env, oldTOP, 1, Sigjmp_buf); rEtV = Sigsetjmp(top_env, 1); if (rEtV == 0) -# define XCPT_TRY_END Copy(oldTOP, top_env, 1, Sigjmp_buf); -# define XCPT_CATCH if (rEtV != 0) -# define XCPT_RETHROW Siglongjmp(top_env, rEtV) -# endif -#endif - -#if !defined(my_strlcat) -#if defined(NEED_my_strlcat) -static Size_t DPPP_(my_my_strlcat)(char * dst, const char * src, Size_t size); -static -#else -extern Size_t DPPP_(my_my_strlcat)(char * dst, const char * src, Size_t size); -#endif - -#define my_strlcat DPPP_(my_my_strlcat) -#define Perl_my_strlcat DPPP_(my_my_strlcat) - -#if defined(NEED_my_strlcat) || defined(NEED_my_strlcat_GLOBAL) - -Size_t -DPPP_(my_my_strlcat)(char *dst, const char *src, Size_t size) -{ - Size_t used, length, copy; - - used = strlen(dst); - length = strlen(src); - if (size > 0 && used < size - 1) { - copy = (length >= size - used) ? size - used - 1 : length; - memcpy(dst + used, src, copy); - dst[used + copy] = '\0'; - } - return used + length; -} -#endif -#endif - -#if !defined(my_strlcpy) -#if defined(NEED_my_strlcpy) -static Size_t DPPP_(my_my_strlcpy)(char * dst, const char * src, Size_t size); -static -#else -extern Size_t DPPP_(my_my_strlcpy)(char * dst, const char * src, Size_t size); -#endif - -#define my_strlcpy DPPP_(my_my_strlcpy) -#define Perl_my_strlcpy DPPP_(my_my_strlcpy) - -#if defined(NEED_my_strlcpy) || defined(NEED_my_strlcpy_GLOBAL) - -Size_t -DPPP_(my_my_strlcpy)(char *dst, const char *src, Size_t size) -{ - Size_t length, copy; - - length = strlen(src); - if (size > 0) { - copy = (length >= size) ? size - 1 : length; - memcpy(dst, src, copy); - dst[copy] = '\0'; - } - return length; -} - -#endif -#endif -#ifndef PERL_PV_ESCAPE_QUOTE -# define PERL_PV_ESCAPE_QUOTE 0x0001 -#endif - -#ifndef PERL_PV_PRETTY_QUOTE -# define PERL_PV_PRETTY_QUOTE PERL_PV_ESCAPE_QUOTE -#endif - -#ifndef PERL_PV_PRETTY_ELLIPSES -# define PERL_PV_PRETTY_ELLIPSES 0x0002 -#endif - -#ifndef PERL_PV_PRETTY_LTGT -# define PERL_PV_PRETTY_LTGT 0x0004 -#endif - -#ifndef PERL_PV_ESCAPE_FIRSTCHAR -# define PERL_PV_ESCAPE_FIRSTCHAR 0x0008 -#endif - -#ifndef PERL_PV_ESCAPE_UNI -# define PERL_PV_ESCAPE_UNI 0x0100 -#endif - -#ifndef PERL_PV_ESCAPE_UNI_DETECT -# define PERL_PV_ESCAPE_UNI_DETECT 0x0200 -#endif - -#ifndef PERL_PV_ESCAPE_ALL -# define PERL_PV_ESCAPE_ALL 0x1000 -#endif - -#ifndef PERL_PV_ESCAPE_NOBACKSLASH -# define PERL_PV_ESCAPE_NOBACKSLASH 0x2000 -#endif - -#ifndef PERL_PV_ESCAPE_NOCLEAR -# define PERL_PV_ESCAPE_NOCLEAR 0x4000 -#endif - -#ifndef PERL_PV_ESCAPE_RE -# define PERL_PV_ESCAPE_RE 0x8000 -#endif - -#ifndef PERL_PV_PRETTY_NOCLEAR -# define PERL_PV_PRETTY_NOCLEAR PERL_PV_ESCAPE_NOCLEAR -#endif -#ifndef PERL_PV_PRETTY_DUMP -# define PERL_PV_PRETTY_DUMP PERL_PV_PRETTY_ELLIPSES|PERL_PV_PRETTY_QUOTE -#endif - -#ifndef PERL_PV_PRETTY_REGPROP -# define PERL_PV_PRETTY_REGPROP PERL_PV_PRETTY_ELLIPSES|PERL_PV_PRETTY_LTGT|PERL_PV_ESCAPE_RE -#endif - -/* Hint: pv_escape - * Note that unicode functionality is only backported to - * those perl versions that support it. For older perl - * versions, the implementation will fall back to bytes. - */ - -#ifndef pv_escape -#if defined(NEED_pv_escape) -static char * DPPP_(my_pv_escape)(pTHX_ SV * dsv, char const * const str, const STRLEN count, const STRLEN max, STRLEN * const escaped, const U32 flags); -static -#else -extern char * DPPP_(my_pv_escape)(pTHX_ SV * dsv, char const * const str, const STRLEN count, const STRLEN max, STRLEN * const escaped, const U32 flags); -#endif - -#ifdef pv_escape -# undef pv_escape -#endif -#define pv_escape(a,b,c,d,e,f) DPPP_(my_pv_escape)(aTHX_ a,b,c,d,e,f) -#define Perl_pv_escape DPPP_(my_pv_escape) - -#if defined(NEED_pv_escape) || defined(NEED_pv_escape_GLOBAL) - -char * -DPPP_(my_pv_escape)(pTHX_ SV *dsv, char const * const str, - const STRLEN count, const STRLEN max, - STRLEN * const escaped, const U32 flags) -{ - const char esc = flags & PERL_PV_ESCAPE_RE ? '%' : '\\'; - const char dq = flags & PERL_PV_ESCAPE_QUOTE ? '"' : esc; - char octbuf[32] = "%123456789ABCDF"; - STRLEN wrote = 0; - STRLEN chsize = 0; - STRLEN readsize = 1; -#if defined(is_utf8_string) && defined(utf8_to_uvchr) - bool isuni = flags & PERL_PV_ESCAPE_UNI ? 1 : 0; -#endif - const char *pv = str; - const char * const end = pv + count; - octbuf[0] = esc; - - if (!(flags & PERL_PV_ESCAPE_NOCLEAR)) - sv_setpvs(dsv, ""); - -#if defined(is_utf8_string) && defined(utf8_to_uvchr) - if ((flags & PERL_PV_ESCAPE_UNI_DETECT) && is_utf8_string((U8*)pv, count)) - isuni = 1; -#endif - - for (; pv < end && (!max || wrote < max) ; pv += readsize) { - const UV u = -#if defined(is_utf8_string) && defined(utf8_to_uvchr) - isuni ? utf8_to_uvchr((U8*)pv, &readsize) : -#endif - (U8)*pv; - const U8 c = (U8)u & 0xFF; - - if (u > 255 || (flags & PERL_PV_ESCAPE_ALL)) { - if (flags & PERL_PV_ESCAPE_FIRSTCHAR) - chsize = my_snprintf(octbuf, sizeof octbuf, - "%" UVxf, u); - else - chsize = my_snprintf(octbuf, sizeof octbuf, - "%cx{%" UVxf "}", esc, u); - } else if (flags & PERL_PV_ESCAPE_NOBACKSLASH) { - chsize = 1; - } else { - if (c == dq || c == esc || !isPRINT(c)) { - chsize = 2; - switch (c) { - case '\\' : /* fallthrough */ - case '%' : if (c == esc) - octbuf[1] = esc; - else - chsize = 1; - break; - case '\v' : octbuf[1] = 'v'; break; - case '\t' : octbuf[1] = 't'; break; - case '\r' : octbuf[1] = 'r'; break; - case '\n' : octbuf[1] = 'n'; break; - case '\f' : octbuf[1] = 'f'; break; - case '"' : if (dq == '"') - octbuf[1] = '"'; - else - chsize = 1; - break; - default: chsize = my_snprintf(octbuf, sizeof octbuf, - pv < end && isDIGIT((U8)*(pv+readsize)) - ? "%c%03o" : "%c%o", esc, c); - } - } else { - chsize = 1; - } - } - if (max && wrote + chsize > max) { - break; - } else if (chsize > 1) { - sv_catpvn(dsv, octbuf, chsize); - wrote += chsize; - } else { - char tmp[2]; - my_snprintf(tmp, sizeof tmp, "%c", c); - sv_catpvn(dsv, tmp, 1); - wrote++; - } - if (flags & PERL_PV_ESCAPE_FIRSTCHAR) - break; - } - if (escaped != NULL) - *escaped= pv - str; - return SvPVX(dsv); -} - -#endif -#endif - -#ifndef pv_pretty -#if defined(NEED_pv_pretty) -static char * DPPP_(my_pv_pretty)(pTHX_ SV * dsv, char const * const str, const STRLEN count, const STRLEN max, char const * const start_color, char const * const end_color, const U32 flags); -static -#else -extern char * DPPP_(my_pv_pretty)(pTHX_ SV * dsv, char const * const str, const STRLEN count, const STRLEN max, char const * const start_color, char const * const end_color, const U32 flags); -#endif - -#ifdef pv_pretty -# undef pv_pretty -#endif -#define pv_pretty(a,b,c,d,e,f,g) DPPP_(my_pv_pretty)(aTHX_ a,b,c,d,e,f,g) -#define Perl_pv_pretty DPPP_(my_pv_pretty) - -#if defined(NEED_pv_pretty) || defined(NEED_pv_pretty_GLOBAL) - -char * -DPPP_(my_pv_pretty)(pTHX_ SV *dsv, char const * const str, const STRLEN count, - const STRLEN max, char const * const start_color, char const * const end_color, - const U32 flags) -{ - const U8 dq = (flags & PERL_PV_PRETTY_QUOTE) ? '"' : '%'; - STRLEN escaped; - - if (!(flags & PERL_PV_PRETTY_NOCLEAR)) - sv_setpvs(dsv, ""); - - if (dq == '"') - sv_catpvs(dsv, "\""); - else if (flags & PERL_PV_PRETTY_LTGT) - sv_catpvs(dsv, "<"); - - if (start_color != NULL) - sv_catpv(dsv, D_PPP_CONSTPV_ARG(start_color)); - - pv_escape(dsv, str, count, max, &escaped, flags | PERL_PV_ESCAPE_NOCLEAR); - - if (end_color != NULL) - sv_catpv(dsv, D_PPP_CONSTPV_ARG(end_color)); - - if (dq == '"') - sv_catpvs(dsv, "\""); - else if (flags & PERL_PV_PRETTY_LTGT) - sv_catpvs(dsv, ">"); - - if ((flags & PERL_PV_PRETTY_ELLIPSES) && escaped < count) - sv_catpvs(dsv, "..."); - - return SvPVX(dsv); -} - -#endif -#endif - -#ifndef pv_display -#if defined(NEED_pv_display) -static char * DPPP_(my_pv_display)(pTHX_ SV * dsv, const char * pv, STRLEN cur, STRLEN len, STRLEN pvlim); -static -#else -extern char * DPPP_(my_pv_display)(pTHX_ SV * dsv, const char * pv, STRLEN cur, STRLEN len, STRLEN pvlim); -#endif - -#ifdef pv_display -# undef pv_display -#endif -#define pv_display(a,b,c,d,e) DPPP_(my_pv_display)(aTHX_ a,b,c,d,e) -#define Perl_pv_display DPPP_(my_pv_display) - -#if defined(NEED_pv_display) || defined(NEED_pv_display_GLOBAL) - -char * -DPPP_(my_pv_display)(pTHX_ SV *dsv, const char *pv, STRLEN cur, STRLEN len, STRLEN pvlim) -{ - pv_pretty(dsv, pv, cur, pvlim, NULL, NULL, PERL_PV_PRETTY_DUMP); - if (len > cur && pv[cur] == '\0') - sv_catpvs(dsv, "\\0"); - return SvPVX(dsv); -} - -#endif -#endif - -#endif /* _P_P_PORTABILITY_H_ */ - -/* End of File ppport.h */ diff -Nru libdatetime-perl-1.21/Changes libdatetime-perl-1.46/Changes --- libdatetime-perl-1.21/Changes 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/Changes 2018-02-11 23:36:51.000000000 +0000 @@ -1,3 +1,221 @@ +1.46 2018-02-11 + +- Fixed the formatting for the CLDR "S" symbol. It could in some cases round + _up_ to 1 instead of truncating a value. For example, the "SSS" symbol would + format 999,999,999 nanoseconds as "1.000". Fixed by Gianni Ceccarelli. PR + #71. + + +1.45 2017-12-26 + +- Added month_length(), quarter_length() and year_length() + methods. Implemented by Dan Stewart. PR #70. + + +1.44 2017-08-20 + +- Added a stringify() method. This does exactly the same thing as + stringification overloading does. GH #58. + +- Added an is_last_day_of_month() method to indicate whether or not an object + falls on the last day of its month. GH #60. + + +1.43 2017-05-29 + +- Added a small optimization for boolification overloading. Rather than + relying on a fallback to stringification, we now return true directly, which + is a little faster in cases like "if ($might_be_dt) { ... }". + +- The datetime() method now accepts a single argument to use as the separate + between the date and time portion. This defaults to "T". + + +1.42 2016-12-25 + +- The DateTime::Duration->add and ->subtract methods now accept + DateTime::Duration objects. This used to work by accident, but this is now + done intentionally (with docs and tests). Reported by Petr Pisar. GitHub + #50. + + +1.41 2016-11-16 + +- The DateTime->add and ->subtract methods now accept DateTime::Duration + objects. This used to work by accident, but this is now done intentionally + (with docs and tests). Based on PR #45 from Sam Kington. + + +1.40 2016-11-12 + +- Switched from RT to the GitHub issue tracker. + + +1.39 2016-09-17 + +- Bump minimum required Perl to 5.8.4 from 5.8.1. Looking at CPAN Testers, + this distro hasn't actually passed with earlier Perl versions since + 1.35. I'm not explicitly testing with anything earlier than 5.8.8 + + +1.38 2016-09-16 + +- This release includes changes from past trial releases to switch from + Params::Validate and Params::ValidationCompiler. Relevant release notes from + those trial releases are repeated here for clarity. + +- Replaced Params::Validate with Params::ValidationCompiler and Specio. In my + benchmarks this makes constructing a new DateTime object about 14% + faster. However, it slows down module load time by about 100 milliseconds + (1/10 of a second) on my desktop system with a primed cache (so really + measuring compile time, not disk load time). + +- When you pass a locale to $dt->set you will now get a warning suggesting you + should use $dt->set_locale instead. The previous trial releases didn't allow + locale to be passed at all, which broke a lot of modules. I've sent PRs, but + for now the parameter should be allowed (but discouraged). Reported by + Slaven Rezić. RT #115420. + +- Removed the long-deprecated DateTime->DefaultLanguage method. Use + DefaultLocale instead. + +- Removed the long-deprecated "language" constructor parameter. Use "locale" + instead. + + +1.37 2016-08-14 (TRIAL RELEASE) + +- Require the latest Params::ValidationCompiler (0.11). + + +1.36 2016-08-06 + +- Require namespace::autoclean 0.19. + + +1.35 2016-08-05 + +- Use namespace::autoclean in all packages which import anything. Without + cleaning the namespace, DateTime ends up with "methods" like try and catch + (from Try::Tiny), which can lead to very confusing bugs. Reported by Mischa + Schwieger. RT #115983. + + +1.34 2016-07-06 + +- Added the leap second coming on December 31, 2016. + + +1.33 2016-06-29 + +- Fixed the $dt->set docs to say that you cannot pass a locale (even though + you can but you'll get a warning) and added more docs for $dt->set_locale. + +- Require DateTime::Locale 1.05. + +- Require DateTime::TimeZone 2.00. + + +1.32 2016-06-28 + +- This release *does not* include any of the changes in the 1.29-1.30 TRIAL + releases. + +- When you pass a locale to $dt->set you will now get a warning suggesting you + should use $dt->set_locale instead. If you have DateTime::Format::Mail + installed you should upgrade to 0.0403 or later, since that module will + trigger this warning. + +- Added support for $dt->truncate( to => 'quarter' ). Implemented by Michael + Conrad. GitHub #17. + + +1.31 2016-06-18 (TRIAL RELEASE) + +- When you pass a locale to $dt->set you will now get a warning suggesting you + should use $dt->set_locale instead. The previous trial releases didn't allow + locale to be passed at all, which broke a lot of modules. I've sent PRs, but + for now the parameter should be allowed (but discouraged). Reported by + Slaven Rezić. RT #115420. + + +1.30 2016-06-18 (TRIAL RELEASE) + +- Require the latest version of Params::ValidationCompiler (0.06). Tests failed + with 0.01. + + +1.29 2016-06-17 (TRIAL RELEASE) + +- Replaced Params::Validate with Params::ValidationCompiler and Specio. In my + benchmarks this makes constructing a new DateTime object about 14% + faster. However, it slows down module load time by about 100 milliseconds + (1/10 of a second) on my desktop system with a primed cache (so really + measuring compile time, not disk load time). + + +1.28 2016-05-21 + +- Fixed handling of some floating point epochs. Because DateTime treated the + epoch like a string instead of a number, certain epochs with a non-integer + value ended up treated like integers (Perl is weird). Patch by Christian + Hansen. GitHub #15. This also addresses the problem that GitHub #6 brought + up. Addresses RT #96452, reported by Slaven Rezić. + + +1.27 2016-05-13 + +- Added an environment variable PERL_DATETIME_DEFAULT_TZ to globally set the + default time zone. Using this is very dangerous! Be careful!. Patch by + Ovid. GitHub #14. + + +1.26 2016-03-21 + +- Switched from Module::Build to ExtUtils::MakeMaker. Implementation by Karen + Etheridge. GitHub #13. + + +1.25 2016-03-06 + +- DateTime->from_object would die if given a DateTime::Infinite object. Now it + returns another DateTime::Infinite object. Reported by Greg Oschwald. RT + #112712. + + +1.24 2016-02-29 + +- The last release partially broke $dt->time. If you passed a value to use as + unit separator, this was ignored. Reported by Sergiy Zuban. RT #112585. + + +1.23 2016-02-28 + +- Make all DateTime::Infinite objects return the system's representation of + positive or negative infinity for any method which returns a number of + string representation (year(), month(), ymd(), iso8601(), etc.). Previously + some of these methods could return "Nan", "-Inf--Inf--Inf", and other + confusing outputs. Reported by Greg Oschwald. RT #110341. + + +1.22 2016-02-21 (TRIAL RELEASE) + +- Fixed several issues with the handling of non-integer values passed to + from_epoch(). + + This method was simply broken for negative values, which would end up being + incremented by a full second, so for example -0.5 became 0.5. + + The method did not accept all valid float values. Specifically, it did not + accept values in scientific notation. + + Finally, this method now rounds all non-integer values to the nearest + millisecond. This matches the precision we can expect from Perl itself (53 + bits) in most cases. + + Patch by Christian Hansen. GitHub #11. + + 1.21 2015-09-30 - Make all tests pass with both the current DateTime::Locale and the upcoming @@ -20,7 +238,7 @@ - The 30future-tz.t could fail if run at certain very specific times. This should now be much less likely, unless a time zone being tested implements a DST change at noon (which would even more insane than DST already is by a - huge factor). Reported by Karen Etheridge and diagnosed by Slaven Rezic. RT + huge factor). Reported by Karen Etheridge and diagnosed by Slaven Rezić. RT #102925. @@ -76,7 +294,7 @@ 1.11 2014-08-31 - The latest historical changes in DateTime::TimeZone 1.74 caused some tests - to fail. Reported by Slaven Rezic. RT #98483. + to fail. Reported by Slaven Rezić. RT #98483. - This release of DateTime.pm now requires the DateTime::TimeZone 1.74. diff -Nru libdatetime-perl-1.21/CONTRIBUTING.md libdatetime-perl-1.46/CONTRIBUTING.md --- libdatetime-perl-1.21/CONTRIBUTING.md 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/CONTRIBUTING.md 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,137 @@ +# CONTRIBUTING + +Thank you for considering contributing to this distribution. This file +contains instructions that will help you work with the source code. + +Please note that if you have any questions or difficulties, you can reach the +maintainer(s) through the bug queue described later in this document +(preferred), or by emailing the releaser directly. You are not required to +follow any of the steps in this document to submit a patch or bug report; +these are just recommendations, intended to help you (and help us help you +faster). + +This distribution has a TODO file in the repository; you may want to check +there to see if your issue or patch idea is mentioned. + + +The distribution is managed with +[Dist::Zilla](https://metacpan.org/release/Dist-Zilla). + +However, you can still compile and test the code with the `Makefile.PL` or +`Build.PL` in the repository: + + perl Makefile.PL + make + make test + +or + perl Build.PL + ./Build + ./Build test + +As well as: + + $ prove -bvr t + +or + + $ perl -Mblib t/some_test_file.t + +You may need to satisfy some dependencies. The easiest way to satisfy +dependencies is to install the last release. This is available at +https://metacpan.org/release/DateTime + +If you use cpanminus, you can do it without downloading the tarball first: + + $ cpanm --reinstall --installdeps --with-recommends DateTime + +Dist::Zilla is a very powerful authoring tool, but requires a number of +author-specific plugins. If you would like to use it for contributing, install +it from CPAN, then run one of the following commands, depending on your CPAN +client: + + $ cpan `dzil authordeps --missing` + +or + + $ dzil authordeps --missing | cpanm + +They may also be additional requirements not needed by the dzil build which +are needed for tests or other development: + + $ cpan `dzil listdeps --author --missing` + +or + + $ dzil listdeps --author --missing | cpanm + +Or, you can use the 'dzil stale' command to install all requirements at once: + + $ cpan Dist::Zilla::App::Command::stale + $ cpan `dzil stale --all` + +or + + $ cpanm Dist::Zilla::App::Command::stale + $ dzil stale --all | cpanm + +You can also do this via cpanm directly: + + $ cpanm --reinstall --installdeps --with-develop --with-recommends DateTime + +Once installed, here are some dzil commands you might try: + + $ dzil build + $ dzil test + $ dzil test --release + $ dzil xtest + $ dzil listdeps --json + $ dzil build --notgz + +You can learn more about Dist::Zilla at http://dzil.org/. + +The code for this distribution is [hosted at GitHub](https://github.com/houseabsolute/DateTime.pm). + +You can submit code changes by forking the repository, pushing your code +changes to your clone, and then submitting a pull request. Detailed +instructions for doing that is available here: + +https://help.github.com/articles/creating-a-pull-request + +If you have found a bug, but do not have an accompanying patch to fix it, you +can submit an issue report [via the web](https://github.com/houseabsolute/DateTime.pm/issues) +). + + +There is a mailing list available for users of this distribution, +datetime@perl.org + +## Travis + +All pull requests for this distribution will be automatically tested by +[Travis](https://travis-ci.org/) and the build status will be reported on the +pull request page. If your build fails, please take a look at the output. + +## TidyAll + +This distribution uses +[Code::TidyAll](https://metacpan.org/release/Code-TidyAll) to enforce a +uniform coding style. This is tested as part of the author testing suite. You +can install and run tidyall by running the following commands: + + $ cpanm Code::TidyAll + $ tidyall -a + +Please run this before committing your changes and address any issues it +brings up. + +## Contributor Names + +If you send a patch or pull request, your name and email address will be +included in the documentation as a contributor (using the attribution on the +commit or patch), unless you specifically request for it not to be. If you +wish to be listed under a different name or address, you should submit a pull +request to the .mailmap file to contain the correct mapping. + +This file was generated via Dist::Zilla::Plugin::GenerateFile::FromShareDir 0.013 from a +template file originating in Dist-Zilla-PluginBundle-DROLSKY-0.89. diff -Nru libdatetime-perl-1.21/cpanfile libdatetime-perl-1.46/cpanfile --- libdatetime-perl-1.21/cpanfile 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/cpanfile 2018-02-11 23:36:51.000000000 +0000 @@ -1,26 +1,31 @@ requires "Carp" => "0"; -requires "DateTime::Locale" => "0.41"; -requires "DateTime::TimeZone" => "1.74"; +requires "DateTime::Locale" => "1.06"; +requires "DateTime::TimeZone" => "2.02"; +requires "Dist::CheckConflicts" => "0.02"; requires "POSIX" => "0"; -requires "Params::Validate" => "1.03"; +requires "Params::ValidationCompiler" => "0.26"; requires "Scalar::Util" => "0"; +requires "Specio" => "0.18"; +requires "Specio::Declare" => "0"; +requires "Specio::Exporter" => "0"; +requires "Specio::Library::Builtins" => "0"; +requires "Specio::Library::Numeric" => "0"; +requires "Specio::Library::String" => "0"; requires "Try::Tiny" => "0"; requires "XSLoader" => "0"; requires "base" => "0"; -requires "constant" => "0"; requires "integer" => "0"; +requires "namespace::autoclean" => "0.19"; requires "overload" => "0"; -requires "perl" => "5.008001"; +requires "parent" => "0"; +requires "perl" => "5.008004"; requires "strict" => "0"; -requires "vars" => "0"; requires "warnings" => "0"; requires "warnings::register" => "0"; -on 'build' => sub { - requires "Module::Build" => "0.28"; -}; - on 'test' => sub { + requires "CPAN::Meta::Check" => "0.011"; + requires "CPAN::Meta::Requirements" => "0"; requires "ExtUtils::MakeMaker" => "0"; requires "File::Spec" => "0"; requires "Storable" => "0"; @@ -35,25 +40,44 @@ }; on 'configure' => sub { - requires "Module::Build" => "0.28"; + requires "Dist::CheckConflicts" => "0.02"; + requires "ExtUtils::MakeMaker" => "0"; +}; + +on 'configure' => sub { + suggests "JSON::PP" => "2.27300"; }; on 'develop' => sub { - requires "Code::TidyAll" => "0.24"; + requires "Code::TidyAll" => "0.56"; + requires "Code::TidyAll::Plugin::SortLines::Naturally" => "0.000003"; + requires "Code::TidyAll::Plugin::Test::Vars" => "0.02"; + requires "Cwd" => "0"; + requires "Devel::PPPort" => "3.23"; requires "Module::Implementation" => "0"; - requires "Perl::Critic" => "1.123"; - requires "Perl::Tidy" => "20140711"; + requires "Parallel::ForkManager" => "1.19"; + requires "Perl::Critic" => "1.126"; + requires "Perl::Tidy" => "20160302"; requires "Pod::Coverage::TrustPod" => "0"; + requires "Pod::Wordlist" => "0"; + requires "Storable" => "0"; requires "Test::CPAN::Changes" => "0.19"; - requires "Test::Code::TidyAll" => "0.24"; + requires "Test::CPAN::Meta::JSON" => "0.16"; + requires "Test::CleanNamespaces" => "0.15"; + requires "Test::Code::TidyAll" => "0.50"; + requires "Test::DependentModules" => "0"; requires "Test::EOL" => "0"; + requires "Test::Fatal" => "0"; requires "Test::Mojibake" => "0"; - requires "Test::More" => "0.88"; + requires "Test::More" => "0.96"; requires "Test::NoTabs" => "0"; requires "Test::Pod" => "1.41"; requires "Test::Pod::Coverage" => "1.08"; - requires "Test::Pod::LinkCheck" => "0"; + requires "Test::Portability::Files" => "0"; requires "Test::Spelling" => "0.12"; - requires "Test::Version" => "1"; + requires "Test::Vars" => "0.009"; + requires "Test::Version" => "2.05"; + requires "Test::Warnings" => "0.005"; requires "autodie" => "0"; + requires "utf8" => "0"; }; diff -Nru libdatetime-perl-1.21/DateTime.xs libdatetime-perl-1.46/DateTime.xs --- libdatetime-perl-1.21/DateTime.xs 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/DateTime.xs 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,312 @@ +#include "EXTERN.h" +#include "perl.h" +#include "XSUB.h" +#define NEED_sv_2pv_flags +#include "ppport.h" + +#include + +/* This file is generated by tools/leap_seconds_header.pl */ +#include "leap_seconds.h" + +/* This is a temporary hack until a better solution can be found to + get the finite() function on Win32 */ +#ifndef WIN32 +# include +# ifndef isfinite +# ifdef finite +# define finite isfinite +# endif +# endif +#endif + +#define DAYS_PER_400_YEARS 146097 +#define DAYS_PER_4_YEARS 1461 +#define MARCH_1 306 + +#define SECONDS_PER_DAY 86400 + +const int PREVIOUS_MONTH_DOY[12] = { 0, + 31, + 59, + 90, + 120, + 151, + 181, + 212, + 243, + 273, + 304, + 334 }; + +const int PREVIOUS_MONTH_DOLY[12] = { 0, + 31, + 60, + 91, + 121, + 152, + 182, + 213, + 244, + 274, + 305, + 335 }; + + +IV +_real_is_leap_year(IV y) { + /* See http://www.perlmonks.org/?node_id=274247 for where this silliness + comes from */ + return (y % 4) ? 0 : (y % 100) ? 1 : (y % 400) ? 0 : 1; +} + + +MODULE = DateTime PACKAGE = DateTime + +PROTOTYPES: ENABLE + +void +_rd2ymd(self, d, extra = 0) + IV d; + IV extra; + + PREINIT: + IV y, m; + IV c; + IV quarter; + IV yadj = 0; + IV dow, doy, doq; + IV rd_days; + + PPCODE: + rd_days = d; + + d += MARCH_1; + + if (d <= 0) { + yadj = -1 * (((-1 * d) / DAYS_PER_400_YEARS) + 1); + d -= yadj * DAYS_PER_400_YEARS; + } + + /* c is century */ + c = ((d * 4) - 1) / DAYS_PER_400_YEARS; + d -= c * DAYS_PER_400_YEARS / 4; + y = ((d * 4) - 1) / DAYS_PER_4_YEARS; + d -= y * DAYS_PER_4_YEARS / 4; + m = ((d * 12) + 1093) / 367; + d -= ((m * 367) - 1094) / 12; + y += (c * 100) + (yadj * 400); + + if (m > 12) { + ++y; + m -= 12; + } + + EXTEND(SP, extra ? 7 : 3); + mPUSHi(y); + mPUSHi(m); + mPUSHi(d); + + if (extra) { + quarter = ( ( 1.0 / 3.1 ) * m ) + 1; + + dow = rd_days % 7; + if ( dow <= 0 ) { + dow += 7; + } + + mPUSHi(dow); + + if (_real_is_leap_year(y)) { + doy = PREVIOUS_MONTH_DOLY[m - 1] + d; + doq = doy - PREVIOUS_MONTH_DOLY[ (3 * quarter) - 3 ]; + } else { + doy = PREVIOUS_MONTH_DOY[m - 1] + d; + doq = doy - PREVIOUS_MONTH_DOY[ (3 * quarter ) - 3 ]; + } + + mPUSHi(doy); + mPUSHi(quarter); + mPUSHi(doq); + } + +void +_ymd2rd(self, y, m, d) + IV y; + IV m; + IV d; + + PREINIT: + IV adj; + + PPCODE: + if (m <= 2) { + adj = (14 - m) / 12; + y -= adj; + m += 12 * adj; + } else if (m > 14) { + adj = (m - 3) / 12; + y += adj; + m -= 12 * adj; + } + + if (y < 0) { + adj = (399 - y) / 400; + d -= DAYS_PER_400_YEARS * adj; + y += 400 * adj; + } + + d += (m * 367 - 1094) / + 12 + y % 100 * DAYS_PER_4_YEARS / + 4 + (y / 100 * 36524 + y / 400) - MARCH_1; + + EXTEND(SP, 1); + mPUSHi(d); + +void +_seconds_as_components(self, secs, utc_secs = 0, secs_modifier = 0) + IV secs; + IV utc_secs; + IV secs_modifier; + + PREINIT: + IV h, m, s; + + PPCODE: + secs -= secs_modifier; + + h = secs / 3600; + secs -= h * 3600; + + m = secs / 60; + + s = secs - (m * 60); + + if (utc_secs >= SECONDS_PER_DAY) { + if (utc_secs >= SECONDS_PER_DAY + 1) { + /* If we just use %d and the IV, we get a warning that IV is + not an int. */ + croak("Invalid UTC RD seconds value: %s", SvPV_nolen(newSViv(utc_secs))); + } + + s += (utc_secs - SECONDS_PER_DAY) + 60; + m = 59; + h--; + + if (h < 0) { + h = 23; + } + } + + EXTEND(SP, 3); + mPUSHi(h); + mPUSHi(m); + mPUSHi(s); + +#ifdef isfinite +void +_normalize_tai_seconds(self, days, secs) + SV* days; + SV* secs; + + PPCODE: + if (isfinite(SvNV(days)) && isfinite(SvNV(secs))) { + IV d = SvIV(days); + IV s = SvIV(secs); + IV adj; + + if (s < 0) { + adj = (s - (SECONDS_PER_DAY - 1)) / SECONDS_PER_DAY; + } else { + adj = s / SECONDS_PER_DAY; + } + + d += adj; + s -= adj * SECONDS_PER_DAY; + + sv_setiv(days, (IV) d); + sv_setiv(secs, (IV) s); + } + +void +_normalize_leap_seconds(self, days, secs) + SV* days; + SV* secs; + + PPCODE: + if (isfinite(SvNV(days)) && isfinite(SvNV(secs))) { + IV d = SvIV(days); + IV s = SvIV(secs); + IV day_length; + + while (s < 0) { + SET_DAY_LENGTH(d - 1, day_length); + + s += day_length; + d--; + } + + SET_DAY_LENGTH(d, day_length); + + while (s > day_length - 1) { + s -= day_length; + d++; + SET_DAY_LENGTH(d, day_length); + } + + sv_setiv(days, (IV) d); + sv_setiv(secs, (IV) s); + } + +#endif /* ifdef isfinite */ + +void +_time_as_seconds(self, h, m, s) + IV h; + IV m; + IV s; + + PPCODE: + EXTEND(SP, 1); + mPUSHi(h * 3600 + m * 60 + s); + +void +_is_leap_year(self, y) + IV y; + + PPCODE: + EXTEND(SP, 1); + mPUSHi(_real_is_leap_year(y)); + +void +_day_length(self, utc_rd) + IV utc_rd; + + PPCODE: + IV day_length; + SET_DAY_LENGTH(utc_rd, day_length); + + EXTEND(SP, 1); + mPUSHi(day_length); + +void +_day_has_leap_second(self, utc_rd) + IV utc_rd; + + PPCODE: + IV day_length; + SET_DAY_LENGTH(utc_rd, day_length); + + EXTEND(SP, 1); + mPUSHi(day_length > 86400 ? 1 : 0); + +void +_accumulated_leap_seconds(self, utc_rd) + IV utc_rd; + + PPCODE: + IV leap_seconds; + SET_LEAP_SECONDS(utc_rd, leap_seconds); + + EXTEND(SP, 1); + mPUSHi(leap_seconds); diff -Nru libdatetime-perl-1.21/debian/changelog libdatetime-perl-1.46/debian/changelog --- libdatetime-perl-1.21/debian/changelog 2015-12-18 20:30:02.000000000 +0000 +++ libdatetime-perl-1.46/debian/changelog 2021-03-21 18:33:01.000000000 +0000 @@ -1,8 +1,146 @@ -libdatetime-perl (2:1.21-1build1) xenial; urgency=medium +libdatetime-perl (2:1.46-1~16.04.sav0) xenial; urgency=medium - * No-change rebuild for perl 5.22.1. + * Backport to Xenial - -- Mathieu Trudel-Lapierre Fri, 18 Dec 2015 15:30:00 -0500 + -- Rob Savoury Sun, 21 Mar 2021 11:33:01 -0700 + +libdatetime-perl (2:1.46-1) unstable; urgency=medium + + * Import upstream version 1.46. + * Update years of packaging copyright. + + -- gregor herrmann Wed, 14 Feb 2018 20:05:46 +0100 + +libdatetime-perl (2:1.45-1) unstable; urgency=medium + + [ Alex Muntada ] + * Remove inactive pkg-perl members from Uploaders. + + [ gregor herrmann ] + * Import upstream version 1.45. + * Update years of packaging copyright. + * Make (build) dependency on libparams-validationcompiler-perl + versioned. + * Declare compliance with Debian Policy 4.1.3. + * Let cme fix a versioned alternative build dependency. + * Update debian/tests/pkg-perl/syntax-skip. + Drop one fail, update error messages for another. + + -- gregor herrmann Wed, 03 Jan 2018 21:11:11 +0100 + +libdatetime-perl (2:1.44-1) unstable; urgency=medium + + * New upstream version 1.44 + * Declare compliance with Debian Policy 4.1.0 + * Bump debhelper compatibility version to 10 + + -- Nick Morrott Sat, 26 Aug 2017 03:02:11 +0100 + +libdatetime-perl (2:1.43-1) unstable; urgency=medium + + * Import upstream version 1.43. + * Update years of upstream and packaging copyright. + * Declare compliance with Debian Policy 4.0.0. + + -- gregor herrmann Wed, 02 Aug 2017 21:12:12 -0400 + +libdatetime-perl (2:1.42-1) unstable; urgency=medium + + * Import upstream version 1.42. + + -- gregor herrmann Mon, 26 Dec 2016 03:54:31 +0100 + +libdatetime-perl (2:1.41-1) unstable; urgency=medium + + * Import upstream version 1.41 + * Refresh d/u/metadata + * Add Datetime/Duration.pm to d/t/p/syntax-skip + + -- Nick Morrott Thu, 17 Nov 2016 21:23:42 +0000 + +libdatetime-perl (2:1.39-1) unstable; urgency=medium + + [ gregor herrmann ] + * Remove Antonio Radici from Uploaders. Thanks for your work! + * Remove Iulian Udrea from Uploaders. Thanks for your work! + * Remove Jonathan Yu from Uploaders. Thanks for your work! + * Remove Ryan Niebur from Uploaders. Thanks for your work! + + [ Nick Morrott ] + * Import upstream version 1.39 + * Refresh (build-) dependencies + + -- Nick Morrott Tue, 11 Oct 2016 03:30:09 +0100 + +libdatetime-perl (2:1.36-1) unstable; urgency=medium + + * Import upstream version 1.36 + * Refresh (build-) dependencies + + -- Nick Morrott Tue, 09 Aug 2016 01:11:13 +0100 + +libdatetime-perl (2:1.35-1) unstable; urgency=medium + + [ Salvatore Bonaccorso ] + * debian/control: Remove Franck Joncourt from Uploaders. + Thanks to Tobias Frost (Closes: #831295) + + [ Nick Morrott ] + * Import upstream version 1.35 + * Refresh (build-) dependencies + * Add myself to Uploaders + * Add DateTime.pm to d/t/p/syntax-skip + + -- Nick Morrott Sat, 06 Aug 2016 20:35:51 +0100 + +libdatetime-perl (2:1.34-1) unstable; urgency=medium + + * Import upstream version 1.34. + * Add missing epoch to libdatetime-locale-perl (build) dependency. + + -- gregor herrmann Thu, 07 Jul 2016 19:14:58 +0200 + +libdatetime-perl (2:1.33-1) unstable; urgency=medium + + * debian/upstream/metadata: use HTTPS for GitHub URLs. + * Import upstream version 1.33. + * Update debian/upstream/metadata (GitHub URLs). + * Update (build) dependencies. + * Ignore a file for autopkgtest's syntax test. + + -- gregor herrmann Fri, 01 Jul 2016 18:07:52 +0200 + +libdatetime-perl (2:1.27-1) unstable; urgency=medium + + * debian/copyright: change Copyright-Format 1.0 URL to HTTPS. + * debian/upstream/metadata: change GitHub/CPAN URL(s) to HTTPS. + * Import upstream version 1.27. + * Update years of packaging copyright. + + -- gregor herrmann Sat, 21 May 2016 17:33:44 +0200 + +libdatetime-perl (2:1.26-1) unstable; urgency=medium + + * Team upload. + + [ Salvatore Bonaccorso ] + * debian/control: Use HTTPS transport protocol for Vcs-Git URI + + [ Lucas Kanashiro ] + * Import upstream version 1.26 + * Update debian/upstream/metadata + * Update years of upstream copyright + * Update Debian packaging copyright + * Declare compliance with Debian policy 3.9.8 + * debian/control: update build and runtime dependencies + * debian/rules: export DEB_BUILD_MAINT_OPTIONS = hardening=+bindnow + * debian/copyright: remove c/ppport.h, does not exist anymore + + [ gregor herrmann ] + * debian/copyright: add new ppport.h. + * Install new CONTRIBUTING document. + + -- Lucas Kanashiro Wed, 11 May 2016 13:38:41 -0300 libdatetime-perl (2:1.21-1) unstable; urgency=medium diff -Nru libdatetime-perl-1.21/debian/compat libdatetime-perl-1.46/debian/compat --- libdatetime-perl-1.21/debian/compat 2015-10-17 19:36:55.000000000 +0000 +++ libdatetime-perl-1.46/debian/compat 2018-02-14 19:05:46.000000000 +0000 @@ -1 +1 @@ -9 +10 diff -Nru libdatetime-perl-1.21/debian/control libdatetime-perl-1.46/debian/control --- libdatetime-perl-1.21/debian/control 2015-10-17 19:36:55.000000000 +0000 +++ libdatetime-perl-1.46/debian/control 2018-02-14 19:05:46.000000000 +0000 @@ -1,32 +1,31 @@ Source: libdatetime-perl Maintainer: Debian Perl Group -Uploaders: Antonio Radici , - gregor herrmann , - Ryan Niebur , - Iulian Udrea , - Jonathan Yu , +Uploaders: gregor herrmann , Ansgar Burchardt , - Franck Joncourt , - Alessandro Ghedini , - Xavier Guimard + Xavier Guimard , + Nick Morrott Section: perl +Testsuite: autopkgtest-pkg-perl Priority: optional # don't build-depend on libdatetime-format-strptime-perl which depends # on libdatetime-perl again -Build-Depends: debhelper (>= 9.20120312), - libdatetime-locale-perl, - libdatetime-timezone-perl (>= 1:1.74), - libmodule-build-perl, - libparams-validate-perl (>= 1.03), +Build-Depends: debhelper (>= 10), + libcpan-meta-check-perl (>= 0.011), + libdatetime-locale-perl (>= 1:1.06), + libdatetime-timezone-perl (>= 1:2.02), + libdist-checkconflicts-perl, + libnamespace-autoclean-perl (>= 0.19), + libparams-validationcompiler-perl (>= 0.26), + libspecio-perl, + libtest-cleannamespaces-perl, libtest-fatal-perl, libtest-warnings-perl, libtry-tiny-perl, perl, - perl (>= 5.13.4) | libtest-simple-perl (>= 0.96) -Standards-Version: 3.9.6 + perl (>= 5.15.7) | libcpan-meta-requirements-perl (>= 2.113640) +Standards-Version: 4.1.3 Vcs-Browser: https://anonscm.debian.org/cgit/pkg-perl/packages/libdatetime-perl.git -Vcs-Git: git://anonscm.debian.org/pkg-perl/packages/libdatetime-perl.git -Testsuite: autopkgtest-pkg-perl +Vcs-Git: https://anonscm.debian.org/git/pkg-perl/packages/libdatetime-perl.git Homepage: http://datetime.perl.org/ Package: libdatetime-perl @@ -34,10 +33,13 @@ Depends: ${misc:Depends}, ${perl:Depends}, ${shlibs:Depends}, - libdatetime-locale-perl, - libdatetime-timezone-perl (>= 1:1.74), - libparams-validate-perl (>= 1.03), + libdatetime-locale-perl (>= 1:1.06), + libdatetime-timezone-perl (>= 1:2.02), + libnamespace-autoclean-perl (>= 0.19), + libparams-validationcompiler-perl (>= 0.26), + libspecio-perl, libtry-tiny-perl +Breaks: libdatetime-format-mail-perl (<< 0.4020++) Description: module for manipulating dates, times and timestamps DateTime is a Perl module which aims to provide a complete, correct, and easy to use date/time object implementation. It provides an easy way to manipulate @@ -49,4 +51,3 @@ time zone information, and more importantly, daylight saving time rules, can be handled transparently, simply by setting the correct time zone. This is done by using the DateTime::TimeZone module. - diff -Nru libdatetime-perl-1.21/debian/copyright libdatetime-perl-1.46/debian/copyright --- libdatetime-perl-1.21/debian/copyright 2015-10-17 19:36:55.000000000 +0000 +++ libdatetime-perl-1.46/debian/copyright 2018-02-14 19:05:46.000000000 +0000 @@ -1,13 +1,13 @@ -Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: DateTime Source: https://metacpan.org/release/DateTime Upstream-Contact: Dave Rolsky Files: * -Copyright: 2015, Dave Rolsky +Copyright: 2003-2018, Dave Rolsky License: Artistic-2.0 -Files: c/ppport.h +Files: ppport.h Copyright: 2004-2013, Marcus Holland-Moritz 2001, Paul Marquess (Version 2.x) 1999, Kenneth Albanowski (Version 1.x) @@ -16,7 +16,7 @@ Files: debian/* Copyright: 2003-2008, Piotr Roszatycki 2009, Gunnar Wolf - 2009-2015, gregor herrmann + 2009-2018, gregor herrmann 2009, Damyan Ivanov 2009, Antonio Radici 2009, Ryan Niebur @@ -24,6 +24,7 @@ 2010, Franck Joncourt 2010-2011, Nicholas Bamber 2012-2013, Xavier Guimard + 2016, Lucas Kanashiro License: Artistic or GPL-1+ License: Artistic-2.0 diff -Nru libdatetime-perl-1.21/debian/libdatetime-perl.docs libdatetime-perl-1.46/debian/libdatetime-perl.docs --- libdatetime-perl-1.21/debian/libdatetime-perl.docs 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/debian/libdatetime-perl.docs 2018-02-14 19:05:46.000000000 +0000 @@ -0,0 +1 @@ +CONTRIBUTING.md diff -Nru libdatetime-perl-1.21/debian/rules libdatetime-perl-1.46/debian/rules --- libdatetime-perl-1.21/debian/rules 2015-10-17 19:36:55.000000000 +0000 +++ libdatetime-perl-1.46/debian/rules 2018-02-14 19:05:46.000000000 +0000 @@ -1,4 +1,6 @@ #!/usr/bin/make -f +export DEB_BUILD_MAINT_OPTIONS = hardening=+bindnow + %: dh $@ diff -Nru libdatetime-perl-1.21/debian/tests/pkg-perl/syntax-skip libdatetime-perl-1.46/debian/tests/pkg-perl/syntax-skip --- libdatetime-perl-1.21/debian/tests/pkg-perl/syntax-skip 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/debian/tests/pkg-perl/syntax-skip 2018-02-14 19:05:46.000000000 +0000 @@ -0,0 +1,17 @@ +# String found where operator expected at /usr/lib/x86_64-linux-gnu/perl5/5.26/DateTime.pm line 2062, near "carp 'You passed a locale to the set() method.'" +# (Do you need to predeclare carp?) +# syntax error at /usr/lib/x86_64-linux-gnu/perl5/5.26/DateTime.pm line 2062, near "carp 'You passed a locale to the set() method.'" +# +# -and- +# +# Type of arg 1 to Try::Tiny::catch must be block or sub {} (not reference constructor) at /usr/lib/x86_64-linux-gnu/perl5/5.26/DateTime.pm line 2173, near "};" +# Type of arg 1 to Try::Tiny::try must be block or sub {} (not reference constructor) at /usr/lib/x86_64-linux-gnu/perl5/5.26/DateTime.pm line 2173, near "};" +# Type of arg 1 to Try::Tiny::catch must be block or sub {} (not reference constructor) at /usr/lib/x86_64-linux-gnu/perl5/5.26/DateTime.pm line 2237, near "};" +# Type of arg 1 to Try::Tiny::try must be block or sub {} (not reference constructor) at /usr/lib/x86_64-linux-gnu/perl5/5.26/DateTime.pm line 2237, near "};" +# +# See https://rt.cpan.org/Public/Bug/Display.html?id=115983 +DateTime.pm + +# needs Dist::CheckConflicts, but this doesn't make lots of sense at runtime +# alternatively we could just not install DateTime/Conflicts.pm ... +DateTime/Conflicts.pm diff -Nru libdatetime-perl-1.21/debian/upstream/metadata libdatetime-perl-1.46/debian/upstream/metadata --- libdatetime-perl-1.21/debian/upstream/metadata 2015-10-17 19:36:55.000000000 +0000 +++ libdatetime-perl-1.46/debian/upstream/metadata 2018-02-14 19:05:46.000000000 +0000 @@ -1,8 +1,8 @@ --- Archive: CPAN -Bug-Database: http://rt.cpan.org/NoAuth/Bugs.html?Dist=DateTime -Bug-Submit: bug-datetime@rt.cpan.org +Bug-Database: https://github.com/houseabsolute/DateTime.pm/issues +Bug-Submit: https://github.com/houseabsolute/DateTime.pm/issues/new Contact: Dave Rolsky Name: DateTime -Repository: git://git.urth.org/DateTime.pm.git -Repository-Browse: http://git.urth.org/DateTime.pm.git +Repository: https://github.com/houseabsolute/DateTime.pm.git +Repository-Browse: https://github.com/houseabsolute/DateTime.pm diff -Nru libdatetime-perl-1.21/dist.ini libdatetime-perl-1.46/dist.ini --- libdatetime-perl-1.21/dist.ini 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/dist.ini 2018-02-11 23:36:51.000000000 +0000 @@ -2,22 +2,19 @@ author = Dave Rolsky license = Artistic_2_0 copyright_holder = Dave Rolsky - -[GatherDir] -exclude_filename = cpanfile -exclude_filename = LICENSE -exclude_filename = Build.PL -exclude_filename = README.md +copyright_year = 2003 [PruneCruft] [@DROLSKY] dist = DateTime -exclude_files = Build.PL +exclude_files = leap_seconds.h next_release_width = 6 +pod_coverage_skip = DateTime::Conflicts pod_coverage_skip = DateTime::Helpers pod_coverage_skip = DateTime::PP pod_coverage_skip = DateTime::PPExtra +pod_coverage_trustme = DateTime => qr/^[A-Z_]+$/ pod_coverage_trustme = DateTime => qr/0$/ pod_coverage_trustme = DateTime => qr/^STORABLE/ pod_coverage_trustme = DateTime => qr/^utc_year$/ @@ -33,29 +30,43 @@ pod_coverage_trustme = DateTime => qr/^mon$/ pod_coverage_trustme = DateTime => qr/^sec$/ pod_coverage_trustme = DateTime => qr/^wday$/ -pod_coverage_trustme = DateTime::Infinite => qr/^STORABLE/ -pod_coverage_trustme = DateTime::Infinite => qr/^set/ -pod_coverage_trustme = DateTime::Infinite => qr/^is(?:in)?finite/ -pod_coverage_trustme = DateTime::Infinite => qr/^truncate/ +pod_coverage_trustme = DateTime::Duration => qr/^[A-Z_]+$/ +pod_coverage_trustme = DateTime::Infinite => qr/^.+$/ ; deprecated methods pod_coverage_trustme = DateTime => qr/^DefaultLanguage$/ pod_coverage_trustme = DateTime => qr/^era$/ pod_coverage_trustme = DateTime => qr/^language$/ stopwords_file = .stopwords --remove = Git::GatherDir --remove = MakeMaker +Test::CleanNamespaces.skip = DateTime::Conflicts +use_github_issues = 1 -remove = Test::Compile -remove = Test::Pod::No404s -remove = Test::Synopsis +[lib] +lib = inc + +[=LeapSecondsHeader] + +[CopyFilesFromBuild] +copy = leap_seconds.h + +[MetaResources] +x_MailingList = datetime@perl.org + [Prereqs / DevelopRequires] autodie = 0 ; Working around an issue with older Params::Validate releases under Perl 5.10 ; that causes failures with Travis. I'm not sure _what_ the issue is though. Module::Implementation = 0 -; authordep Dist::Zilla::Plugin::ModuleBuild::XSOrPP -[=inc::MyModuleBuild] - [PurePerlTests] +:version = 0.06 env_var = PERL_DATETIME_PP + +[Conflicts] +:version = 0.18 +DateTime::Format::Mail = 0.402 + +[Test::CheckBreaks] +conflicts_module = DateTime::Conflicts diff -Nru libdatetime-perl-1.21/inc/LeapSecondsHeader.pm libdatetime-perl-1.46/inc/LeapSecondsHeader.pm --- libdatetime-perl-1.21/inc/LeapSecondsHeader.pm 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/inc/LeapSecondsHeader.pm 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,212 @@ +package LeapSecondsHeader; + +use strict; +use warnings; +use autodie; + +my $VERSION = 0.04; + +use Dist::Zilla::File::InMemory; + +use Moose; + +has _leap_second_data => ( + is => 'ro', + isa => 'HashRef', + lazy => 1, + builder => '_build_leap_second_data', +); + +with 'Dist::Zilla::Role::FileGatherer'; + +sub gather_files { + my $self = shift; + + $self->add_file( + Dist::Zilla::File::InMemory->new( + name => 'leap_seconds.h', + encoding => 'bytes', + content => $self->_header, + ), + ); +} + +my $x = 1; +my %months = map { $_ => $x++ } + qw( Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec ); + +sub _build_leap_second_data { + my $self = shift; + + open my $fh, '<', 'leaptab.txt'; + + my @leap_seconds; + my @rd; + my %rd_length; + + my $value = -1; + while (<$fh>) { + my ( $year, $mon, $day, $leap_seconds ) = split /\s+/; + + $mon =~ s/\W//; + + $leap_seconds =~ s/^([+-])//; + my $mult = $1 eq '+' ? 1 : -1; + + my $utc_epoch = _ymd2rd( $year, $months{$mon}, $day ); + + $value += $leap_seconds * $mult; + + push @leap_seconds, $value; + push @rd, $utc_epoch; + + $rd_length{ $utc_epoch - 1 } = $leap_seconds; + } + + close $fh; + + push @leap_seconds, ++$value; + + return { + leap_seconds => \@leap_seconds, + rd => \@rd, + rd_length => \%rd_length, + }; +} + +sub _header { + my $self = shift; + + my ( $leap_seconds, $rd, $rd_length ) + = @{ $self->_leap_second_data }{qw( leap_seconds rd rd_length )}; + + my $set_leap_seconds = <<"EOF"; + +#define SET_LEAP_SECONDS(utc_rd, ls) \\ +{ \\ + { \\ + if (utc_rd < $rd->[0]) { \\ + ls = $leap_seconds->[0]; \\ +EOF + + for ( my $x = 1; $x < @{$rd}; $x++ ) { + my $condition + = $x == @{$rd} + ? "utc_rd < $rd->[$x]" + : "utc_rd >= $rd->[$x - 1] && utc_rd < $rd->[$x]"; + + $set_leap_seconds .= <<"EOF" + } else if ($condition) { \\ + ls = $leap_seconds->[$x]; \\ +EOF + } + + $set_leap_seconds .= <<"EOF"; + } else { \\ + ls = $leap_seconds->[-1]; \\ + } \\ + } \\ +} +EOF + + my $set_extra_seconds = <<"EOF"; + +#define SET_EXTRA_SECONDS(utc_rd, es) \\ +{ \\ + { \\ + es = 0; \\ + switch (utc_rd) { \\ +EOF + + my $set_day_length = <<"EOF"; + +#define SET_DAY_LENGTH(utc_rd, dl) \\ +{ \\ + { \\ + dl = 86400; \\ + switch (utc_rd) { \\ +EOF + + foreach my $utc_rd ( sort keys %{$rd_length} ) { + $set_extra_seconds .= <<"EOF"; + case $utc_rd: es = $rd_length->{$utc_rd}; break; \\ +EOF + + $set_day_length .= <<"EOF"; + case $utc_rd: dl = 86400 + $rd_length->{$utc_rd}; break; \\ +EOF + } + + $set_extra_seconds .= <<"EOF"; + } \\ + } \\ +} +EOF + + $set_day_length .= <<"EOF"; + } \\ + } \\ +} +EOF + + my $generator = ref $self; + + my $header = <<"EOF"; +/* + +This file is auto-generated by the leap second code generator ($VERSION). This +code generator comes with the DateTime.pm module distribution in the tools/ +directory + +Generated $generator. + +Do not edit this file directly. + +*/ +EOF + + return join q{}, ( + $header, + $set_leap_seconds, + $set_extra_seconds, + $set_day_length, + ); +} + +# from lib/DateTimePP.pm +sub _ymd2rd { + use integer; + my ( $y, $m, $d ) = @_; + my $adj; + + # make month in range 3..14 (treat Jan & Feb as months 13..14 of + # prev year) + if ( $m <= 2 ) { + $y -= ( $adj = ( 14 - $m ) / 12 ); + $m += 12 * $adj; + } + elsif ( $m > 14 ) { + $y += ( $adj = ( $m - 3 ) / 12 ); + $m -= 12 * $adj; + } + + # make year positive (oh, for a use integer 'sane_div'!) + if ( $y < 0 ) { + $d -= 146097 * ( $adj = ( 399 - $y ) / 400 ); + $y += 400 * $adj; + } + + # add: day of month, days of previous 0-11 month period that began + # w/March, days of previous 0-399 year period that began w/March + # of a 400-multiple year), days of any 400-year periods before + # that, and 306 days to adjust from Mar 1, year 0-relative to Jan + # 1, year 1-relative (whew) + + $d + += ( $m * 367 - 1094 ) / 12 + + $y % 100 * 1461 / 4 + + ( $y / 100 * 36524 + $y / 400 ) + - 306; +} + +1; diff -Nru libdatetime-perl-1.21/inc/MyModuleBuild.pm libdatetime-perl-1.46/inc/MyModuleBuild.pm --- libdatetime-perl-1.21/inc/MyModuleBuild.pm 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/inc/MyModuleBuild.pm 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -package inc::MyModuleBuild; - -use strict; -use warnings; - -use Moose; - -extends 'Dist::Zilla::Plugin::ModuleBuild::XSOrPP'; - -around module_build_args => sub { - my $orig = shift; - my $self = shift; - - my $args = $self->$orig(@_); - - $args->{c_source} = 'c'; - - return $args; -}; - -no Moose; - -__PACKAGE__->meta()->make_immutable(); - -1; diff -Nru libdatetime-perl-1.21/INSTALL libdatetime-perl-1.46/INSTALL --- libdatetime-perl-1.21/INSTALL 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/INSTALL 2018-02-11 23:36:51.000000000 +0000 @@ -8,10 +8,10 @@ % cpanm DateTime -If you are installing into a system-wide directory, you may need to pass the -"-S" flag to cpanm, which uses sudo to install the module: - - % cpanm -S DateTime +If it does not have permission to install modules to the current perl, cpanm +will automatically set up and install to a local::lib in your home directory. +See the local::lib documentation (https://metacpan.org/pod/local::lib) for +details on enabling it in your environment. ## Installing with the CPAN shell @@ -24,16 +24,16 @@ As a last resort, you can manually install it. Download the tarball, untar it, then build it: - % perl Build.PL - % ./Build && ./Build test + % perl Makefile.PL + % make && make test Then install it: - % ./Build install - -If you are installing into a system-wide directory, you may need to run: + % make install - % sudo ./Build install +If your perl is system-managed, you can create a local::lib in your home +directory to install modules to. For details, see the local::lib documentation: +https://metacpan.org/pod/local::lib ## Documentation diff -Nru libdatetime-perl-1.21/leap_seconds.h libdatetime-perl-1.46/leap_seconds.h --- libdatetime-perl-1.21/leap_seconds.h 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/leap_seconds.h 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,146 @@ +/* + +This file is auto-generated by the leap second code generator (0.04). This +code generator comes with the DateTime.pm module distribution in the tools/ +directory + +Generated LeapSecondsHeader. + +Do not edit this file directly. + +*/ + +#define SET_LEAP_SECONDS(utc_rd, ls) \ +{ \ + { \ + if (utc_rd < 720075) { \ + ls = 0; \ + } else if (utc_rd >= 720075 && utc_rd < 720259) { \ + ls = 1; \ + } else if (utc_rd >= 720259 && utc_rd < 720624) { \ + ls = 2; \ + } else if (utc_rd >= 720624 && utc_rd < 720989) { \ + ls = 3; \ + } else if (utc_rd >= 720989 && utc_rd < 721354) { \ + ls = 4; \ + } else if (utc_rd >= 721354 && utc_rd < 721720) { \ + ls = 5; \ + } else if (utc_rd >= 721720 && utc_rd < 722085) { \ + ls = 6; \ + } else if (utc_rd >= 722085 && utc_rd < 722450) { \ + ls = 7; \ + } else if (utc_rd >= 722450 && utc_rd < 722815) { \ + ls = 8; \ + } else if (utc_rd >= 722815 && utc_rd < 723362) { \ + ls = 9; \ + } else if (utc_rd >= 723362 && utc_rd < 723727) { \ + ls = 10; \ + } else if (utc_rd >= 723727 && utc_rd < 724092) { \ + ls = 11; \ + } else if (utc_rd >= 724092 && utc_rd < 724823) { \ + ls = 12; \ + } else if (utc_rd >= 724823 && utc_rd < 725737) { \ + ls = 13; \ + } else if (utc_rd >= 725737 && utc_rd < 726468) { \ + ls = 14; \ + } else if (utc_rd >= 726468 && utc_rd < 726833) { \ + ls = 15; \ + } else if (utc_rd >= 726833 && utc_rd < 727380) { \ + ls = 16; \ + } else if (utc_rd >= 727380 && utc_rd < 727745) { \ + ls = 17; \ + } else if (utc_rd >= 727745 && utc_rd < 728110) { \ + ls = 18; \ + } else if (utc_rd >= 728110 && utc_rd < 728659) { \ + ls = 19; \ + } else if (utc_rd >= 728659 && utc_rd < 729206) { \ + ls = 20; \ + } else if (utc_rd >= 729206 && utc_rd < 729755) { \ + ls = 21; \ + } else if (utc_rd >= 729755 && utc_rd < 732312) { \ + ls = 22; \ + } else if (utc_rd >= 732312 && utc_rd < 733408) { \ + ls = 23; \ + } else if (utc_rd >= 733408 && utc_rd < 734685) { \ + ls = 24; \ + } else if (utc_rd >= 734685 && utc_rd < 735780) { \ + ls = 25; \ + } else if (utc_rd >= 735780 && utc_rd < 736330) { \ + ls = 26; \ + } else { \ + ls = 27; \ + } \ + } \ +} + +#define SET_EXTRA_SECONDS(utc_rd, es) \ +{ \ + { \ + es = 0; \ + switch (utc_rd) { \ + case 720074: es = 1; break; \ + case 720258: es = 1; break; \ + case 720623: es = 1; break; \ + case 720988: es = 1; break; \ + case 721353: es = 1; break; \ + case 721719: es = 1; break; \ + case 722084: es = 1; break; \ + case 722449: es = 1; break; \ + case 722814: es = 1; break; \ + case 723361: es = 1; break; \ + case 723726: es = 1; break; \ + case 724091: es = 1; break; \ + case 724822: es = 1; break; \ + case 725736: es = 1; break; \ + case 726467: es = 1; break; \ + case 726832: es = 1; break; \ + case 727379: es = 1; break; \ + case 727744: es = 1; break; \ + case 728109: es = 1; break; \ + case 728658: es = 1; break; \ + case 729205: es = 1; break; \ + case 729754: es = 1; break; \ + case 732311: es = 1; break; \ + case 733407: es = 1; break; \ + case 734684: es = 1; break; \ + case 735779: es = 1; break; \ + case 736329: es = 1; break; \ + } \ + } \ +} + +#define SET_DAY_LENGTH(utc_rd, dl) \ +{ \ + { \ + dl = 86400; \ + switch (utc_rd) { \ + case 720074: dl = 86400 + 1; break; \ + case 720258: dl = 86400 + 1; break; \ + case 720623: dl = 86400 + 1; break; \ + case 720988: dl = 86400 + 1; break; \ + case 721353: dl = 86400 + 1; break; \ + case 721719: dl = 86400 + 1; break; \ + case 722084: dl = 86400 + 1; break; \ + case 722449: dl = 86400 + 1; break; \ + case 722814: dl = 86400 + 1; break; \ + case 723361: dl = 86400 + 1; break; \ + case 723726: dl = 86400 + 1; break; \ + case 724091: dl = 86400 + 1; break; \ + case 724822: dl = 86400 + 1; break; \ + case 725736: dl = 86400 + 1; break; \ + case 726467: dl = 86400 + 1; break; \ + case 726832: dl = 86400 + 1; break; \ + case 727379: dl = 86400 + 1; break; \ + case 727744: dl = 86400 + 1; break; \ + case 728109: dl = 86400 + 1; break; \ + case 728658: dl = 86400 + 1; break; \ + case 729205: dl = 86400 + 1; break; \ + case 729754: dl = 86400 + 1; break; \ + case 732311: dl = 86400 + 1; break; \ + case 733407: dl = 86400 + 1; break; \ + case 734684: dl = 86400 + 1; break; \ + case 735779: dl = 86400 + 1; break; \ + case 736329: dl = 86400 + 1; break; \ + } \ + } \ +} diff -Nru libdatetime-perl-1.21/leaptab.txt libdatetime-perl-1.46/leaptab.txt --- libdatetime-perl-1.21/leaptab.txt 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/leaptab.txt 2018-02-11 23:36:51.000000000 +0000 @@ -24,3 +24,4 @@ 2009 Jan. 1 +1 2012 Jul. 1 +1 2015 Jul. 1 +1 +2017 Jan. 1 +1 diff -Nru libdatetime-perl-1.21/lib/DateTime/Conflicts.pm libdatetime-perl-1.46/lib/DateTime/Conflicts.pm --- libdatetime-perl-1.21/lib/DateTime/Conflicts.pm 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/lib/DateTime/Conflicts.pm 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,45 @@ +package # hide from PAUSE + DateTime::Conflicts; + +use strict; +use warnings; + +# this module was generated with Dist::Zilla::Plugin::Conflicts 0.19 + +use Dist::CheckConflicts + -dist => 'DateTime', + -conflicts => { + 'DateTime::Format::Mail' => '0.402', + }, + -also => [ qw( + Carp + DateTime::Locale + DateTime::TimeZone + Dist::CheckConflicts + POSIX + Params::ValidationCompiler + Scalar::Util + Specio + Specio::Declare + Specio::Exporter + Specio::Library::Builtins + Specio::Library::Numeric + Specio::Library::String + Try::Tiny + XSLoader + base + integer + namespace::autoclean + overload + parent + strict + warnings + warnings::register + ) ], + +; + +1; + +# ABSTRACT: Provide information on conflicts for DateTime +# Dist::Zilla: -PodWeaver diff -Nru libdatetime-perl-1.21/lib/DateTime/Duration.pm libdatetime-perl-1.46/lib/DateTime/Duration.pm --- libdatetime-perl-1.21/lib/DateTime/Duration.pm 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/lib/DateTime/Duration.pm 2018-02-11 23:36:51.000000000 +0000 @@ -2,13 +2,16 @@ use strict; use warnings; +use namespace::autoclean; -our $VERSION = '1.21'; +our $VERSION = '1.46'; use Carp (); use DateTime; use DateTime::Helpers; -use Params::Validate qw( validate SCALAR ); +use DateTime::Types; +use Params::ValidationCompiler 0.26 qw( validation_for ); +use Scalar::Util qw( blessed ); use overload ( fallback => 1, @@ -19,58 +22,75 @@ 'cmp' => '_compare_overload', ); -use constant MAX_NANOSECONDS => 1_000_000_000; # 1E9 = almost 32 bits +sub MAX_NANOSECONDS () {1_000_000_000} # 1E9 = almost 32 bits my @all_units = qw( months days minutes seconds nanoseconds ); -# XXX - need to reject non-integers but accept infinity, NaN, & -# 1.56e+18 -sub new { - my $class = shift; - my %p = validate( - @_, { - years => { type => SCALAR, default => 0 }, - months => { type => SCALAR, default => 0 }, - weeks => { type => SCALAR, default => 0 }, - days => { type => SCALAR, default => 0 }, - hours => { type => SCALAR, default => 0 }, - minutes => { type => SCALAR, default => 0 }, - seconds => { type => SCALAR, default => 0 }, - nanoseconds => { type => SCALAR, default => 0 }, +{ + my %units = map { + $_ => { + + # XXX - what we really want is to accept an integer, Inf, -Inf, + # and NaN, but I can't figure out how to accept NaN since it never + # compares to anything. + type => t('Defined'), + default => 0, + } + } qw( + years + months + weeks + days + hours + minutes + seconds + nanoseconds + ); + + my $check = validation_for( + name => '_check_new_params', + name_is_optional => 1, + params => { + %units, end_of_month => { - type => SCALAR, default => undef, - regex => qr/^(?:wrap|limit|preserve)$/ + type => t('EndOfMonthMode'), + optional => 1, }, - } + }, ); - my $self = bless {}, $class; + sub new { + my $class = shift; + my %p = $check->(@_); - $self->{months} = ( $p{years} * 12 ) + $p{months}; + my $self = bless {}, $class; - $self->{days} = ( $p{weeks} * 7 ) + $p{days}; + $self->{months} = ( $p{years} * 12 ) + $p{months}; - $self->{minutes} = ( $p{hours} * 60 ) + $p{minutes}; + $self->{days} = ( $p{weeks} * 7 ) + $p{days}; - $self->{seconds} = $p{seconds}; + $self->{minutes} = ( $p{hours} * 60 ) + $p{minutes}; - if ( $p{nanoseconds} ) { - $self->{nanoseconds} = $p{nanoseconds}; - $self->_normalize_nanoseconds; - } - else { + $self->{seconds} = $p{seconds}; - # shortcut - if they don't need nanoseconds - $self->{nanoseconds} = 0; - } + if ( $p{nanoseconds} ) { + $self->{nanoseconds} = $p{nanoseconds}; + $self->_normalize_nanoseconds; + } + else { - $self->{end_of_month} = ( - defined $p{end_of_month} ? $p{end_of_month} - : $self->{months} < 0 ? 'preserve' - : 'wrap' - ); + # shortcut - if they don't need nanoseconds + $self->{nanoseconds} = 0; + } - return $self; + $self->{end_of_month} = ( + defined $p{end_of_month} ? $p{end_of_month} + : $self->{months} < 0 ? 'preserve' + : 'wrap' + ); + + return $self; + } } # make the signs of seconds, nanos the same; 0 < abs(nanos) < MAX_NANOS @@ -230,17 +250,28 @@ sub add { my $self = shift; - return $self->add_duration( ( ref $self )->new(@_) ); + return $self->add_duration( $self->_duration_object_from_args(@_) ); } -sub subtract_duration { return $_[0]->add_duration( $_[1]->inverse ) } - sub subtract { my $self = shift; - return $self->subtract_duration( ( ref $self )->new(@_) ); + return $self->subtract_duration( $self->_duration_object_from_args(@_) ); } +# Syntactic sugar for add and subtract: use a duration object if it's +# supplied, otherwise build a new one from the arguments. +sub _duration_object_from_args { + my $self = shift; + + return $_[0] + if @_ == 1 && blessed( $_[0] ) && $_[0]->isa(__PACKAGE__); + + return __PACKAGE__->new(@_); +} + +sub subtract_duration { return $_[0]->add_duration( $_[1]->inverse ) } + sub multiply { my $self = shift; my $multiplier = shift; @@ -255,7 +286,7 @@ } sub compare { - my ( $class, $dur1, $dur2, $dt ) = @_; + my ( undef, $dur1, $dur2, $dt ) = @_; $dt ||= DateTime->now; @@ -285,7 +316,7 @@ ( $d1, $d2 ) = ( $d2, $d1 ) if $rev; Carp::croak( - "Cannot subtract a DateTime object from a DateTime::Duration object") + 'Cannot subtract a DateTime object from a DateTime::Duration object') if DateTime::Helpers::isa( $d2, 'DateTime' ); return $d1->clone->subtract_duration($d2); @@ -313,13 +344,15 @@ =pod +=encoding UTF-8 + =head1 NAME DateTime::Duration - Duration objects for date math =head1 VERSION -version 1.21 +version 1.46 =head1 SYNOPSIS @@ -421,8 +454,8 @@ month to Feb 29, 2000 will result in Mar 31, 2000. For positive durations, the "end_of_month" parameter defaults to wrap. -For negative durations, the default is "limit". This should match how -most people "intuitively" expect datetime math to work. +For negative durations, the default is "preserve". This should match +how most people "intuitively" expect datetime math to work. =head2 $dur->clone() @@ -514,9 +547,8 @@ =head2 $dur->add( ... ), $dur->subtract( ... ) -Syntactic sugar for addition and subtraction. The parameters given to -these methods are used to create a new object, which is then passed to -C or C, as appropriate. +These accept either constructor parameters for a new C +object or an already-constructed duration object. =head2 $dur->multiply( $number ) @@ -586,16 +618,27 @@ using C<< <=> >> or C, then an exception will be thrown! Use the C class method instead. +=head1 SEE ALSO + +datetime@perl.org mailing list + +http://datetime.perl.org/ + =head1 SUPPORT Support for this module is provided via the datetime@perl.org email list. See http://lists.perl.org/ for more details. -=head1 SEE ALSO +Bugs may be submitted at L. -datetime@perl.org mailing list +There is a mailing list available for users of this distribution, +L. -http://datetime.perl.org/ +I am also usually active on IRC as 'autarch' on C. + +=head1 SOURCE + +The source code repository for DateTime can be found at L. =head1 AUTHOR @@ -603,10 +646,13 @@ =head1 COPYRIGHT AND LICENSE -This software is Copyright (c) 2015 by Dave Rolsky. +This software is Copyright (c) 2003 - 2018 by Dave Rolsky. This is free software, licensed under: The Artistic License 2.0 (GPL Compatible) +The full text of the license can be found in the +F file included with this distribution. + =cut diff -Nru libdatetime-perl-1.21/lib/DateTime/Helpers.pm libdatetime-perl-1.46/lib/DateTime/Helpers.pm --- libdatetime-perl-1.21/lib/DateTime/Helpers.pm 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/lib/DateTime/Helpers.pm 2018-02-11 23:36:51.000000000 +0000 @@ -3,7 +3,7 @@ use strict; use warnings; -our $VERSION = '1.21'; +our $VERSION = '1.46'; use Scalar::Util (); diff -Nru libdatetime-perl-1.21/lib/DateTime/Infinite.pm libdatetime-perl-1.46/lib/DateTime/Infinite.pm --- libdatetime-perl-1.21/lib/DateTime/Infinite.pm 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/lib/DateTime/Infinite.pm 2018-02-11 23:36:51.000000000 +0000 @@ -1,9 +1,11 @@ +## no critic (Modules::ProhibitMultiplePackages) package DateTime::Infinite; use strict; use warnings; +use namespace::autoclean; -our $VERSION = '1.21'; +our $VERSION = '1.46'; use DateTime; use DateTime::TimeZone; @@ -11,6 +13,7 @@ use base qw(DateTime); foreach my $m (qw( set set_time_zone truncate )) { + ## no critic (TestingAndDebugging::ProhibitNoStrict) no strict 'refs'; *{"DateTime::Infinite::$m"} = sub { return $_[0] }; } @@ -18,6 +21,7 @@ sub is_finite {0} sub is_infinite {1} +## no critic (Subroutines::ProhibitUnusedPrivateSubroutines) sub _rd2ymd { return $_[2] ? ( $_[1] ) x 7 : ( $_[1] ) x 3; } @@ -26,12 +30,46 @@ return ( $_[1] ) x 3; } -sub _stringify { - $_[0]->{utc_rd_days} == DateTime::INFINITY - ? DateTime::INFINITY . '' - : DateTime::NEG_INFINITY . ''; +sub ymd { + return $_[0]->iso8601; } +sub mdy { + return $_[0]->iso8601; +} + +sub dmy { + return $_[0]->iso8601; +} + +sub hms { + return $_[0]->iso8601; +} + +sub hour_12 { + return $_[0]->_infinity_string; +} + +sub hour_12_0 { + return $_[0]->_infinity_string; +} + +sub datetime { + return $_[0]->_infinity_string; +} + +sub stringify { + return $_[0]->_infinity_string; +} + +sub _infinity_string { + return $_[0]->{utc_rd_days} == DateTime::INFINITY + ? DateTime::INFINITY . q{} + : DateTime::NEG_INFINITY . q{}; +} + +sub _week_values { [ $_[0]->{utc_rd_days}, $_[0]->{utc_rd_days} ] } + sub STORABLE_freeze {return} sub STORABLE_thaw {return} @@ -131,6 +169,7 @@ ); for my $meth (@methods) { + ## no critic (TestingAndDebugging::ProhibitNoStrict) no strict 'refs'; *{$meth} = sub {undef}; } @@ -146,6 +185,7 @@ our $AUTOLOAD; +## no critic (ClassHierarchies::ProhibitAutoloading) sub AUTOLOAD { my $self = shift; @@ -166,13 +206,15 @@ =pod +=encoding UTF-8 + =head1 NAME DateTime::Infinite - Infinite past and future DateTime objects =head1 VERSION -version 1.21 +version 1.46 =head1 SYNOPSIS @@ -187,23 +229,19 @@ The objects are in the "floating" timezone, and this cannot be changed. -=head1 BUGS - -There seem to be lots of problems when dealing with infinite numbers -on Win32. This may be a problem with this code, Perl, or Win32's IEEE -math implementation. Either way, the module may not be well-behaved -on Win32 operating systems. - =head1 METHODS The only constructor for these two classes is the C method, as shown in the L. This method takes no parameters. All "get" methods in this module simply return infinity, positive or -negative. If the method is expected to return a string, it return the +negative. If the method is expected to return a string, it returns the string representation of positive or negative infinity used by your system. For example, on my system calling C returns a number -which when printed appears either "inf" or "-inf". +which when printed appears either "Inf" or "-Inf". + +This also applies to methods that are compound stringifications, which return +the same strings even for things like C or C The object is not mutable, so the C, C, and C methods are all do-nothing methods that simply return @@ -218,16 +256,37 @@ http://datetime.perl.org/ +=head1 BUGS + +There seem to be lots of problems when dealing with infinite numbers +on Win32. This may be a problem with this code, Perl, or Win32's IEEE +math implementation. Either way, the module may not be well-behaved +on Win32 operating systems. + +Bugs may be submitted at L. + +There is a mailing list available for users of this distribution, +L. + +I am also usually active on IRC as 'autarch' on C. + +=head1 SOURCE + +The source code repository for DateTime can be found at L. + =head1 AUTHOR Dave Rolsky =head1 COPYRIGHT AND LICENSE -This software is Copyright (c) 2015 by Dave Rolsky. +This software is Copyright (c) 2003 - 2018 by Dave Rolsky. This is free software, licensed under: The Artistic License 2.0 (GPL Compatible) +The full text of the license can be found in the +F file included with this distribution. + =cut diff -Nru libdatetime-perl-1.21/lib/DateTime/LeapSecond.pm libdatetime-perl-1.46/lib/DateTime/LeapSecond.pm --- libdatetime-perl-1.21/lib/DateTime/LeapSecond.pm 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/lib/DateTime/LeapSecond.pm 2018-02-11 23:36:51.000000000 +0000 @@ -2,10 +2,11 @@ use strict; use warnings; +use namespace::autoclean; -our $VERSION = '1.21'; +our $VERSION = '1.46'; -use vars qw( @RD @LEAP_SECONDS %RD_LENGTH ); +our ( @RD, @LEAP_SECONDS, %RD_LENGTH ); use DateTime; @@ -19,10 +20,10 @@ return $tmp; } $tmp = "${tab}if (\$val < " . $RD[ $beg + $step ] . ") {\n"; - $tmp .= _make_utx( $beg, $beg + $step, $tab . " ", $op ); + $tmp .= _make_utx( $beg, $beg + $step, $tab . q{ }, $op ); $tmp .= "${tab}}\n"; $tmp .= "${tab}else {\n"; - $tmp .= _make_utx( $beg + $step, $end, $tab . " ", $op ); + $tmp .= _make_utx( $beg + $step, $end, $tab . q{ }, $op ); $tmp .= "${tab}}\n"; return $tmp; } @@ -36,6 +37,7 @@ # print "$year,$mon,$mday\n"; + ## no critic (Subroutines::ProtectPrivateSubs) my $utc_epoch = DateTime->_ymd2rd( $year, ( $mon =~ /Jan/i ? 1 : 7 ), $mday ); @@ -56,14 +58,14 @@ $tmp = "sub leap_seconds {\n"; $tmp .= " my \$val = shift;\n"; - $tmp .= _make_utx( -1, 1 + $#RD, " ", "+" ); - $tmp .= "}\n"; + $tmp .= _make_utx( -1, 1 + $#RD, q{ }, '+' ); + $tmp .= "}; 1\n"; # NOTE: uncomment the line below to see the code: #warn $tmp; - eval $tmp; - + ## no critic (BuiltinFunctions::ProhibitStringyEval) + eval $tmp or die $@; } sub extra_seconds { @@ -107,8 +109,9 @@ 1999 Jan. 1 +1 2006 Jan. 1 +1 2009 Jan. 1 +1 - 2012 Jun. 1 +1 + 2012 Jul. 1 +1 2015 Jul. 1 +1 + 2017 Jan. 1 +1 ) ); } @@ -123,13 +126,15 @@ =pod +=encoding UTF-8 + =head1 NAME DateTime::LeapSecond - leap seconds table and utilities =head1 VERSION -version 1.21 +version 1.46 =head1 SYNOPSIS @@ -146,7 +151,7 @@ day. It is used when DateTime.pm cannot compile the XS version of this code. -This library is known to be accurate for dates until December 2009. +This library is known to be accurate for dates until Jun 2017. There are no leap seconds before 1972, because that's the year this system was implemented. @@ -155,8 +160,7 @@ =item * leap_seconds( $rd ) -Returns the number of accumulated leap seconds for a given day, -in the range 0 .. 22. +Returns the number of accumulated leap seconds for a given day. =item * extra_seconds( $rd ) @@ -172,20 +176,36 @@ =head1 SEE ALSO -Ehttp://hpiers.obspm.fr/eop-pc/earthor/utc/leapsecond.htmlE +L http://datetime.perl.org +=head1 SUPPORT + +Bugs may be submitted at L. + +There is a mailing list available for users of this distribution, +L. + +I am also usually active on IRC as 'autarch' on C. + +=head1 SOURCE + +The source code repository for DateTime can be found at L. + =head1 AUTHOR Dave Rolsky =head1 COPYRIGHT AND LICENSE -This software is Copyright (c) 2015 by Dave Rolsky. +This software is Copyright (c) 2003 - 2018 by Dave Rolsky. This is free software, licensed under: The Artistic License 2.0 (GPL Compatible) +The full text of the license can be found in the +F file included with this distribution. + =cut diff -Nru libdatetime-perl-1.21/lib/DateTime/PPExtra.pm libdatetime-perl-1.46/lib/DateTime/PPExtra.pm --- libdatetime-perl-1.21/lib/DateTime/PPExtra.pm 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/lib/DateTime/PPExtra.pm 2018-02-11 23:36:51.000000000 +0000 @@ -3,10 +3,11 @@ use strict; use warnings; -our $VERSION = '1.21'; +our $VERSION = '1.46'; use DateTime::LeapSecond; +## no critic (Subroutines::ProhibitUnusedPrivateSubroutines) sub _normalize_tai_seconds { return if @@ -74,6 +75,7 @@ ); for my $sub (@subs) { + ## no critic (TestingAndDebugging::ProhibitNoStrict) no strict 'refs'; *{ 'DateTime::' . $sub } = __PACKAGE__->can($sub); } diff -Nru libdatetime-perl-1.21/lib/DateTime/PP.pm libdatetime-perl-1.46/lib/DateTime/PP.pm --- libdatetime-perl-1.21/lib/DateTime/PP.pm 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/lib/DateTime/PP.pm 2018-02-11 23:36:51.000000000 +0000 @@ -3,9 +3,11 @@ use strict; use warnings; -our $VERSION = '1.21'; +our $VERSION = '1.46'; +## no critic (Variables::ProhibitPackageVars) $DateTime::IsPurePerl = 1; +## use critic my @MonthLengths = ( 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ); @@ -24,6 +26,7 @@ my @EndOfLastMonthDayOfLeapYear = @EndOfLastMonthDayOfYear; $EndOfLastMonthDayOfLeapYear[$_]++ for 2 .. 11; +## no critic (Subroutines::ProhibitUnusedPrivateSubroutines) sub _time_as_seconds { shift; my ( $hour, $min, $sec ) = @_; @@ -63,7 +66,12 @@ / 367; # get the month (3..14 represent March through $d -= ( $m * 367 - 1094 ) / 12; # February of following year) $y += $c * 100 + $yadj * 400; # get the real year, which is off by - ++$y, $m -= 12 if $m > 12; # one if month is January or February + # one if month is January or February + + if ( $m > 12 ) { + ++$y; + $m -= 12; + } if ( $_[0] ) { my $dow; @@ -212,6 +220,7 @@ ); for my $sub (@subs) { + ## no critic (TestingAndDebugging::ProhibitNoStrict) no strict 'refs'; *{ 'DateTime::' . $sub } = __PACKAGE__->can($sub); } diff -Nru libdatetime-perl-1.21/lib/DateTime/Types.pm libdatetime-perl-1.46/lib/DateTime/Types.pm --- libdatetime-perl-1.21/lib/DateTime/Types.pm 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/lib/DateTime/Types.pm 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,209 @@ +package DateTime::Types; + +use strict; +use warnings; +use namespace::autoclean; + +our $VERSION = '1.46'; + +use parent 'Specio::Exporter'; + +use Specio 0.18; +use Specio::Declare; +use Specio::Library::Builtins -reexport; +use Specio::Library::Numeric -reexport; +use Specio::Library::String; + +any_can_type( + 'ConvertibleObject', + methods => ['utc_rd_values'], +); + +declare( + 'DayOfMonth', + parent => t('Int'), + inline => sub { + $_[0]->parent->inline_check( $_[1] ) + . " && $_[1] >= 1 && $_[1] <= 31"; + }, +); + +declare( + 'DayOfYear', + parent => t('Int'), + inline => sub { + $_[0]->parent->inline_check( $_[1] ) + . " && $_[1] >= 1 && $_[1] <= 366"; + }, +); + +object_isa_type( + 'Duration', + class => 'DateTime::Duration', +); + +enum( + 'EndOfMonthMode', + values => [qw( wrap limit preserve )], +); + +any_can_type( + 'Formatter', + methods => ['format_datetime'], +); + +my $locale_object = declare( + 'LocaleObject', + parent => t('Object'), + inline => sub { + + # Can't use $_[1] directly because 5.8 gives very weird errors + my $var = $_[1]; + <<"EOF"; +( + $var->isa('DateTime::Locale::FromData') + || $var->isa('DateTime::Locale::Base') +) +EOF + }, +); + +union( + 'Locale', + of => [ t('NonEmptySimpleStr'), $locale_object ], +); + +my $time_zone_object = object_can_type( + 'TZObject', + methods => [ + qw( + is_floating + is_utc + name + offset_for_datetime + short_name_for_datetime + ) + ], +); + +declare( + 'TimeZone', + of => [ t('NonEmptySimpleStr'), $time_zone_object ], +); + +declare( + 'Hour', + parent => t('PositiveOrZeroInt'), + inline => sub { + $_[0]->parent->inline_check( $_[1] ) + . " && $_[1] >= 0 && $_[1] <= 23"; + }, +); + +declare( + 'Minute', + parent => t('PositiveOrZeroInt'), + inline => sub { + $_[0]->parent->inline_check( $_[1] ) + . " && $_[1] >= 0 && $_[1] <= 59"; + }, +); + +declare( + 'Month', + parent => t('PositiveInt'), + inline => sub { + $_[0]->parent->inline_check( $_[1] ) + . " && $_[1] >= 1 && $_[1] <= 12"; + }, +); + +declare( + 'Nanosecond', + parent => t('PositiveOrZeroInt'), +); + +declare( + 'Second', + parent => t('PositiveOrZeroInt'), + inline => sub { + $_[0]->parent->inline_check( $_[1] ) + . " && $_[1] >= 0 && $_[1] <= 61"; + }, +); + +enum( + 'TruncationLevel', + values => [ + qw( + year + quarter + month + day hour + minute + second + nanosecond + week + local_week + ) + ], +); + +declare( + 'Year', + parent => t('Int'), +); + +1; + +# ABSTRACT: Types used for parameter checking in DateTime + +__END__ + +=pod + +=encoding UTF-8 + +=head1 NAME + +DateTime::Types - Types used for parameter checking in DateTime + +=head1 VERSION + +version 1.46 + +=head1 DESCRIPTION + +This module has no user-facing parts. + +=for Pod::Coverage .* + +=head1 SUPPORT + +Bugs may be submitted at L. + +There is a mailing list available for users of this distribution, +L. + +I am also usually active on IRC as 'autarch' on C. + +=head1 SOURCE + +The source code repository for DateTime can be found at L. + +=head1 AUTHOR + +Dave Rolsky + +=head1 COPYRIGHT AND LICENSE + +This software is Copyright (c) 2003 - 2018 by Dave Rolsky. + +This is free software, licensed under: + + The Artistic License 2.0 (GPL Compatible) + +The full text of the license can be found in the +F file included with this distribution. + +=cut diff -Nru libdatetime-perl-1.21/lib/DateTime.pm libdatetime-perl-1.46/lib/DateTime.pm --- libdatetime-perl-1.21/lib/DateTime.pm 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/lib/DateTime.pm 2018-02-11 23:36:51.000000000 +0000 @@ -1,23 +1,29 @@ +## no critic (Modules::ProhibitExcessMainComplexity) package DateTime; -use 5.008001; +use 5.008004; use strict; use warnings; use warnings::register; +use namespace::autoclean 0.19; -our $VERSION = '1.21'; +our $VERSION = '1.46'; use Carp; use DateTime::Duration; use DateTime::Helpers; -use DateTime::Locale 0.41; -use DateTime::TimeZone 1.74; -use Params::Validate 1.03 - qw( validate validate_pos UNDEF SCALAR BOOLEAN HASHREF OBJECT ); -use POSIX qw(floor); +use DateTime::Locale 1.06; +use DateTime::TimeZone 2.02; +use DateTime::Types; +use POSIX qw( floor fmod ); +use Params::ValidationCompiler 0.26 qw( validation_for ); +use Scalar::Util qw( blessed ); use Try::Tiny; +## no critic (Variables::ProhibitPackageVars) +our $IsPurePerl; + { my $loaded = 0; @@ -31,8 +37,8 @@ : 42 ); - $loaded = 1; - $DateTime::IsPurePerl = 0; + $loaded = 1; + $IsPurePerl = 0; } catch { die $_ if $_ && $_ !~ /object version|loadable object/; @@ -40,6 +46,7 @@ } if ($loaded) { + ## no critic (Variables::ProtectPrivateVars) require DateTime::PPExtra unless defined &DateTime::_normalize_tai_seconds; } @@ -55,37 +62,47 @@ # see: "Calling conventions for binary operations" in overload docs. # use overload ( - 'fallback' => 1, - '<=>' => '_compare_overload', - 'cmp' => '_string_compare_overload', - '""' => '_stringify', - '-' => '_subtract_overload', - '+' => '_add_overload', - 'eq' => '_string_equals_overload', - 'ne' => '_string_not_equals_overload', + fallback => 1, + '<=>' => '_compare_overload', + 'cmp' => '_string_compare_overload', + q{""} => 'stringify', + bool => sub {1}, + '-' => '_subtract_overload', + '+' => '_add_overload', + 'eq' => '_string_equals_overload', + 'ne' => '_string_not_equals_overload', ); # Have to load this after overloading is defined, after BEGIN blocks # or else weird crashes ensue require DateTime::Infinite; -use constant MAX_NANOSECONDS => 1_000_000_000; # 1E9 = almost 32 bits - -use constant INFINITY => ( 100**100**100**100 ); -use constant NEG_INFINITY => -1 * ( 100**100**100**100 ); -use constant NAN => INFINITY - INFINITY; - -use constant SECONDS_PER_DAY => 86400; - -use constant duration_class => 'DateTime::Duration'; - -my ( @MonthLengths, @LeapYearMonthLengths ); +sub MAX_NANOSECONDS () {1_000_000_000} # 1E9 = almost 32 bits +sub INFINITY () { 100**100**100**100 } +sub NEG_INFINITY () { -1 * ( 100**100**100**100 ) } +sub NAN () { INFINITY - INFINITY } + +sub SECONDS_PER_DAY () {86400} + +sub duration_class () {'DateTime::Duration'} + +my ( + @MonthLengths, + @LeapYearMonthLengths, + @QuarterLengths, + @LeapYearQuarterLengths, +); BEGIN { @MonthLengths = ( 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ); @LeapYearMonthLengths = @MonthLengths; $LeapYearMonthLengths[1]++; + + @QuarterLengths = ( 90, 91, 92, 92 ); + + @LeapYearQuarterLengths = @QuarterLengths; + $LeapYearQuarterLengths[0]++; } { @@ -96,7 +113,7 @@ my $DefaultLocale; sub DefaultLocale { - my $class = shift; + shift; if (@_) { my $lang = shift; @@ -106,103 +123,66 @@ return $DefaultLocale; } - - # backwards compat - *DefaultLanguage = \&DefaultLocale; } -__PACKAGE__->DefaultLocale('en_US'); +__PACKAGE__->DefaultLocale('en-US'); -my $BasicValidate = { - year => { - type => SCALAR, - callbacks => { - 'is an integer' => sub { $_[0] =~ /^-?\d+$/ } - }, - }, - month => { - type => SCALAR, - default => 1, - callbacks => { - 'an integer between 1 and 12' => - sub { $_[0] =~ /^\d+$/ && $_[0] >= 1 && $_[0] <= 12 } - }, - }, - day => { - type => SCALAR, - default => 1, - callbacks => { - 'an integer which is a possible valid day of month' => - sub { $_[0] =~ /^\d+$/ && $_[0] >= 1 && $_[0] <= 31 } - }, - }, - hour => { - type => SCALAR, - default => 0, - callbacks => { - 'an integer between 0 and 23' => - sub { $_[0] =~ /^\d+$/ && $_[0] >= 0 && $_[0] <= 23 }, - }, - }, - minute => { - type => SCALAR, - default => 0, - callbacks => { - 'an integer between 0 and 59' => - sub { $_[0] =~ /^\d+$/ && $_[0] >= 0 && $_[0] <= 59 }, - }, - }, - second => { - type => SCALAR, - default => 0, - callbacks => { - 'an integer between 0 and 61' => - sub { $_[0] =~ /^\d+$/ && $_[0] >= 0 && $_[0] <= 61 }, - }, - }, - nanosecond => { - type => SCALAR, - default => 0, - callbacks => { - 'a positive integer' => sub { $_[0] =~ /^\d+$/ && $_[0] >= 0 }, - } - }, - locale => { - type => SCALAR | OBJECT, - default => undef - }, - language => { - type => SCALAR | OBJECT, - optional => 1 - }, - formatter => { - type => UNDEF | SCALAR | OBJECT, - optional => 1, - callbacks => { - 'can format_datetime' => - sub { defined $_[0] ? $_[0]->can('format_datetime') : 1 }, +{ + my $validator = validation_for( + name => '_check_new_params', + name_is_optional => 1, + params => { + year => { type => t('Year') }, + month => { + type => t('Month'), + default => 1, + }, + day => { + type => t('DayOfMonth'), + default => 1, + }, + hour => { + type => t('Hour'), + default => 0, + }, + minute => { + type => t('Minute'), + default => 0, + }, + second => { + type => t('Second'), + default => 0, + }, + nanosecond => { + type => t('Nanosecond'), + default => 0, + }, + locale => { + type => t('Locale'), + optional => 1, + }, + formatter => { + type => t('Formatter'), + optional => 1, + }, + time_zone => { + type => t('TimeZone'), + optional => 1, + }, }, - }, -}; - -my $NewValidate = { - %$BasicValidate, - time_zone => { - type => SCALAR | OBJECT, - default => 'floating' - }, -}; + ); -sub new { - my $class = shift; - my %p = validate( @_, $NewValidate ); + sub new { + my $class = shift; + my %p = $validator->(@_); - Carp::croak( - "Invalid day of month (day = $p{day} - month = $p{month} - year = $p{year})\n" - ) - if $p{day} > 28 - && $p{day} > $class->_month_length( $p{year}, $p{month} ); + Carp::croak( + "Invalid day of month (day = $p{day} - month = $p{month} - year = $p{year})\n" + ) + if $p{day} > 28 + && $p{day} > $class->_month_length( $p{year}, $p{month} ); - return $class->_new(%p); + return $class->_new(%p); + } } sub _new { @@ -213,19 +193,17 @@ if ref $class; # If this method is called from somewhere other than new(), then some of - # these default may not get applied. - $p{month} = 1 unless exists $p{month}; - $p{day} = 1 unless exists $p{day}; - $p{hour} = 0 unless exists $p{hour}; - $p{minute} = 0 unless exists $p{minute}; - $p{second} = 0 unless exists $p{second}; - $p{nanosecond} = 0 unless exists $p{nanosecond}; - $p{time_zone} = 'floating' unless exists $p{time_zone}; + # these defaults may not get applied. + $p{month} = 1 unless exists $p{month}; + $p{day} = 1 unless exists $p{day}; + $p{hour} = 0 unless exists $p{hour}; + $p{minute} = 0 unless exists $p{minute}; + $p{second} = 0 unless exists $p{second}; + $p{nanosecond} = 0 unless exists $p{nanosecond}; + $p{time_zone} = $class->_default_time_zone unless exists $p{time_zone}; my $self = bless {}, $class; - $p{locale} = delete $p{language} if exists $p{language}; - $self->_set_locale( $p{locale} ); $self->{tz} = ( @@ -273,7 +251,7 @@ # If true, this means that the actual calculated leap # second does not occur in the second given to new() ( $self->{utc_rd_secs} - 86399 < $p{second} - 59 ) - ) { + ) { Carp::croak("Invalid second value ($p{second})\n"); } } @@ -281,6 +259,12 @@ return $self; } +# Warning: do not use this environment variable unless you have no choice in +# the matter. +sub _default_time_zone { + return $ENV{PERL_DATETIME_DEFAULT_TZ} || 'floating'; +} + sub _set_locale { my $self = shift; my $locale = shift; @@ -348,7 +332,7 @@ || ( $offset == 0 && $self->{local_rd_secs} > 86399 ) ) - ) { + ) { my $mod = $self->_day_length( $utc_rd_days - 1 ) - SECONDS_PER_DAY; @@ -472,40 +456,69 @@ } { - my $spec = { - epoch => { regex => qr/^-?(?:\d+(?:\.\d*)?|\.\d+)$/ }, - locale => { type => SCALAR | OBJECT, optional => 1 }, - language => { type => SCALAR | OBJECT, optional => 1 }, - time_zone => { type => SCALAR | OBJECT, optional => 1 }, - formatter => { - type => SCALAR | OBJECT, can => 'format_datetime', - optional => 1 + my $validator = validation_for( + name => '_check_from_epoch_params', + name_is_optional => 1, + params => { + epoch => { type => t('Num') }, + formatter => { + type => t('Formatter'), + optional => 1 + }, + locale => { + type => t('Locale'), + optional => 1 + }, + time_zone => { + type => t('TimeZone'), + optional => 1 + }, }, - }; + ); sub from_epoch { my $class = shift; - my %p = validate( @_, $spec ); + my %p = $validator->(@_); my %args; - # Epoch may come from Time::HiRes, so it may not be an integer. - my ( $int, $dec ) = $p{epoch} =~ /^(-?\d+)?(\.\d+)?/; - $int ||= 0; - - $args{nanosecond} = int( $dec * MAX_NANOSECONDS ) - if $dec; + # This does two things. First, if given a negative non-integer epoch, + # it will round the epoch _down_ to the next second and then adjust + # the nanoseconds to be positive. In other words, -0.5 corresponds to + # a second of -1 and a nanosecond value of 500,000. Before this code + # was implemented our handling of negative non-integer epochs was + # quite broken, and would end up rounding some values up, so that -0.5 + # become 0.5 (which is obviously wrong!). + # + # Second, it rounds any decimal values to the nearest microsecond + # (1E6). Here's what Christian Hansen, who wrote this patch, says: + # + # Perl is typically compiled with NV as a double. A double with a + # significand precision of 53 bits can only represent a nanosecond + # epoch without loss of precision if the duration from zero epoch + # is less than ≈ ±104 days. With microseconds the duration is + # ±104,000 days, which is ≈ ±285 years. + if ( int $p{epoch} != $p{epoch} ) { + my ( $floor, $nano, $second ); + + $floor = $nano = fmod( $p{epoch}, 1.0 ); + $second = floor( $p{epoch} - $floor ); + if ( $nano < 0 ) { + $nano += 1; + } + $p{epoch} = $second + floor( $floor - $nano ); + $args{nanosecond} = floor( $nano * 1E6 + 0.5 ) * 1E3; + } # Note, for very large negative values this may give a # blatantly wrong answer. @args{qw( second minute hour day month year )} - = ( gmtime($int) )[ 0 .. 5 ]; + = ( gmtime( $p{epoch} ) )[ 0 .. 5 ]; $args{year} += 1900; $args{month}++; my $self = $class->_new( %p, %args, time_zone => 'UTC' ); - my $tz = $p{time_zone}; $self->_maybe_future_dst_warning( $self->year(), $p{time_zone} ); $self->set_time_zone( $p{time_zone} ) if exists $p{time_zone}; @@ -543,25 +556,32 @@ sub today { shift->now(@_)->truncate( to => 'day' ) } { - my $spec = { - object => { - type => OBJECT, - can => 'utc_rd_values', - }, - locale => { type => SCALAR | OBJECT, optional => 1 }, - language => { type => SCALAR | OBJECT, optional => 1 }, - formatter => { - type => SCALAR | OBJECT, can => 'format_datetime', - optional => 1 + my $validator = validation_for( + name => '_check_from_object_params', + name_is_optional => 1, + params => { + object => { type => t('ConvertibleObject') }, + locale => { + type => t('Locale'), + optional => 1, + }, + formatter => { + type => t('Formatter'), + optional => 1, + }, }, - }; + ); sub from_object { my $class = shift; - my %p = validate( @_, $spec ); + my %p = $validator->(@_); my $object = delete $p{object}; + if ( $object->isa('DateTime::Infinite') ) { + return $object->clone; + } + my ( $rd_days, $rd_secs, $rd_nanosecs ) = $object->utc_rd_values; # A kludge because until all calendars are updated to return all @@ -594,30 +614,63 @@ $new->set_time_zone( $object->time_zone ); } else { - $new->set_time_zone('floating'); + $new->set_time_zone( $class->_default_time_zone ); } return $new; } } -my $LastDayOfMonthValidate = {%$NewValidate}; -foreach ( keys %$LastDayOfMonthValidate ) { - my %copy = %{ $LastDayOfMonthValidate->{$_} }; - - delete $copy{default}; - $copy{optional} = 1 unless $_ eq 'year' || $_ eq 'month'; - - $LastDayOfMonthValidate->{$_} = \%copy; -} +{ + my $validator = validation_for( + name => '_check_last_day_of_month_params', + name_is_optional => 1, + params => { + year => { type => t('Year') }, + month => { type => t('Month') }, + day => { + type => t('DayOfMonth'), + default => 1, + }, + hour => { + type => t('Hour'), + default => 0, + }, + minute => { + type => t('Minute'), + default => 0, + }, + second => { + type => t('Second'), + default => 0, + }, + nanosecond => { + type => t('Nanosecond'), + default => 0, + }, + locale => { + type => t('Locale'), + optional => 1, + }, + formatter => { + type => t('Formatter'), + optional => 1, + }, + time_zone => { + type => t('TimeZone'), + optional => 1, + }, + }, + ); -sub last_day_of_month { - my $class = shift; - my %p = validate( @_, $LastDayOfMonthValidate ); + sub last_day_of_month { + my $class = shift; + my %p = $validator->(@_); - my $day = $class->_month_length( $p{year}, $p{month} ); + my $day = $class->_month_length( $p{year}, $p{month} ); - return $class->_new( %p, day => $day ); + return $class->_new( %p, day => $day ); + } } sub _month_length { @@ -628,49 +681,70 @@ ); } -my $FromDayOfYearValidate = {%$NewValidate}; -foreach ( keys %$FromDayOfYearValidate ) { - next if $_ eq 'month' || $_ eq 'day'; - - my %copy = %{ $FromDayOfYearValidate->{$_} }; - - delete $copy{default}; - $copy{optional} = 1 unless $_ eq 'year' || $_ eq 'month'; - - $FromDayOfYearValidate->{$_} = \%copy; -} -$FromDayOfYearValidate->{day_of_year} = { - type => SCALAR, - callbacks => { - 'is between 1 and 366' => sub { $_[0] >= 1 && $_[0] <= 366 } - } -}; +{ + my $validator = validation_for( + name => '_check_from_day_of_year_params', + name_is_optional => 1, + params => { + year => { type => t('Year') }, + day_of_year => { type => t('DayOfYear') }, + hour => { + type => t('Hour'), + default => 0, + }, + minute => { + type => t('Minute'), + default => 0, + }, + second => { + type => t('Second'), + default => 0, + }, + nanosecond => { + type => t('Nanosecond'), + default => 0, + }, + locale => { + type => t('Locale'), + optional => 1, + }, + formatter => { + type => t('Formatter'), + optional => 1, + }, + time_zone => { + type => t('TimeZone'), + optional => 1, + }, + }, + ); -sub from_day_of_year { - my $class = shift; - my %p = validate( @_, $FromDayOfYearValidate ); + sub from_day_of_year { + my $class = shift; + my %p = $validator->(@_); - Carp::croak("$p{year} is not a leap year.\n") - if $p{day_of_year} == 366 && !$class->_is_leap_year( $p{year} ); + Carp::croak("$p{year} is not a leap year.\n") + if $p{day_of_year} == 366 && !$class->_is_leap_year( $p{year} ); - my $month = 1; - my $day = delete $p{day_of_year}; + my $month = 1; + my $day = delete $p{day_of_year}; - if ( $day > 31 ) { - my $length = $class->_month_length( $p{year}, $month ); + if ( $day > 31 ) { + my $length = $class->_month_length( $p{year}, $month ); - while ( $day > $length ) { - $day -= $length; - $month++; - $length = $class->_month_length( $p{year}, $month ); + while ( $day > $length ) { + $day -= $length; + $month++; + $length = $class->_month_length( $p{year}, $month ); + } } - } - return $class->_new( - %p, - month => $month, - day => $day, - ); + return $class->_new( + %p, + month => $month, + day => $day, + ); + } } sub formatter { $_[0]->{formatter} } @@ -791,7 +865,7 @@ $self->{local_c}{day} ); } -*date = \&ymd; +*date = sub { shift->ymd(@_) }; sub mdy { my ( $self, $sep ) = @_; @@ -854,10 +928,10 @@ return 0 if $self->{tz}->is_floating; - return DateTime->_accumulated_leap_seconds( $self->{utc_rd_days} ); + return $self->_accumulated_leap_seconds( $self->{utc_rd_days} ); } -sub _stringify { +sub stringify { my $self = shift; return $self->iso8601 unless $self->{formatter}; @@ -877,42 +951,64 @@ } # don't want to override CORE::time() -*DateTime::time = \&hms; +*DateTime::time = sub { shift->hms(@_) }; -sub iso8601 { join 'T', $_[0]->ymd('-'), $_[0]->hms(':') } -*datetime = \&iso8601; +sub iso8601 { $_[0]->datetime('T') } + +sub datetime { + my ( $self, $sep ) = @_; + $sep = 'T' unless defined $sep; + return join $sep, $self->ymd('-'), $self->hms(':'); +} sub is_leap_year { $_[0]->_is_leap_year( $_[0]->year ) } +sub month_length { + $_[0]->_month_length( $_[0]->year, $_[0]->month ); +} + +sub quarter_length { + return ( + $_[0]->_is_leap_year( $_[0]->year ) + ? $LeapYearQuarterLengths[ $_[0]->quarter - 1 ] + : $QuarterLengths[ $_[0]->quarter - 1 ] + ); +} + +sub year_length { + $_[0]->_is_leap_year( $_[0]->year ) ? 366 : 365; +} + +sub is_last_day_of_month { + $_[0]->day == $_[0]->_month_length( $_[0]->year, $_[0]->month ); +} + sub week { my $self = shift; - unless ( defined $self->{local_c}{week_year} ) { + $self->{utc_c}{week_year} ||= $self->_week_values; - # This algorithm was taken from Date::Calc's DateCalc.c file - my $jan_one_dow_m1 - = ( ( $self->_ymd2rd( $self->year, 1, 1 ) + 6 ) % 7 ); - - $self->{local_c}{week_number} - = int( ( ( $self->day_of_year - 1 ) + $jan_one_dow_m1 ) / 7 ); - $self->{local_c}{week_number}++ if $jan_one_dow_m1 < 4; - - if ( $self->{local_c}{week_number} == 0 ) { - $self->{local_c}{week_year} = $self->year - 1; - $self->{local_c}{week_number} - = $self->_weeks_in_year( $self->{local_c}{week_year} ); - } - elsif ($self->{local_c}{week_number} == 53 - && $self->_weeks_in_year( $self->year ) == 52 ) { - $self->{local_c}{week_number} = 1; - $self->{local_c}{week_year} = $self->year + 1; - } - else { - $self->{local_c}{week_year} = $self->year; - } + return @{ $self->{utc_c}{week_year} }[ 0, 1 ]; +} + +# This algorithm comes from +# https://en.wikipedia.org/wiki/ISO_week_date#Calculating_the_week_number_of_a_given_date +sub _week_values { + my $self = shift; + + my $week + = int( ( ( $self->day_of_year - $self->day_of_week ) + 10 ) / 7 ); + + my $year = $self->year; + if ( $week == 0 ) { + $year--; + return [ $year, $self->_weeks_in_year($year) ]; + } + elsif ( $week == 53 && $self->_weeks_in_year($year) == 52 ) { + return [ $year + 1, 1 ]; } - return @{ $self->{local_c} }{ 'week_year', 'week_number' }; + return [ $year, $week ]; } sub _weeks_in_year { @@ -960,7 +1056,6 @@ Carp::carp('locale() is a read-only accessor') if @_ > 1; return $_[0]->{locale}; } -*language = \&locale; sub utc_rd_values { @{ $_[0] }{ 'utc_rd_days', 'utc_rd_secs', 'rd_nanosecs' }; @@ -1111,11 +1206,11 @@ # yy is a weird special case, where it must be exactly 2 digits qr/yy/ => sub { my $year = $_[0]->year(); - my $y2 = substr( $year, -2, 2 ) if length $year > 2; + my $y2 = length $year > 2 ? substr( $year, -2, 2 ) : $year; $y2 *= -1 if $year < 0; $_[0]->_zero_padded_number( 'yy', $y2 ); }, - qr/y/ => sub { $_[0]->year() }, + qr/y/ => sub { $_[0]->year() }, qr/(u+)/ => sub { $_[0]->_zero_padded_number( $1, $_[0]->year() ) }, qr/(Y+)/ => sub { $_[0]->_zero_padded_number( $1, $_[0]->week_year() ) }, @@ -1164,7 +1259,7 @@ qr/(D{1,3})/ => sub { $_[0]->_zero_padded_number( $1, $_[0]->day_of_year() ) }, - qr/F/ => 'weekday_of_month', + qr/F/ => 'weekday_of_month', qr/(g+)/ => sub { $_[0]->_zero_padded_number( $1, $_[0]->mjd() ) }, qr/EEEEE/ => sub { @@ -1219,18 +1314,9 @@ qr/(ss?)/ => sub { $_[0]->_zero_padded_number( $1, $_[0]->second() ) }, - # I'm not sure this is what is wanted (notably the trailing - # and leading zeros it can produce), but once again the LDML - # spec is not all that clear. - qr/(S+)/ => sub { - my $l = length $1; - my $val = sprintf( - "%.${l}f", - $_[0]->fractional_second() - $_[0]->second() - ); - $val =~ s/^0\.//; - $val || 0; - }, + # The LDML spec is not 100% clear on how to truncate this field, but + # this way seems as good as anything. + qr/(S+)/ => sub { $_[0]->_format_nanosecs( length($1) ) }, qr/A+/ => sub { ( $_[0]->{local_rd_secs} * 1000 ) + $_[0]->millisecond() }, @@ -1264,22 +1350,14 @@ return sprintf( "%0${size}d", $val ); } - sub _space_padded_string { - my $self = shift; - my $size = length shift; - my $val = shift; - - return sprintf( "% ${size}s", $val ); - } - sub format_cldr { my $self = shift; # make a copy or caller's scalars get munged - my @patterns = @_; + my @p = @_; my @r; - foreach my $p (@patterns) { + foreach my $p (@p) { $p =~ s/\G (?: '((?:[^']|'')*)' # quote escaped bit of text @@ -1315,6 +1393,7 @@ my $self = shift; my $pattern = shift; + ## no critic (ControlStructures::ProhibitCStyleForLoops) for ( my $i = 0; $i < @patterns; $i += 2 ) { if ( $pattern =~ /$patterns[$i]/ ) { my $sub = $patterns[ $i + 1 ]; @@ -1481,7 +1560,8 @@ ); } -sub _adjust_for_positive_difference { +sub _adjust_for_positive_difference +{ ## no critic (Subroutines::ProhibitManyArgs) my ( $self, $month1, $month2, @@ -1529,12 +1609,11 @@ my $dt = shift; my $utc_rd_secs1 = $self->utc_rd_as_seconds; - $utc_rd_secs1 - += DateTime->_accumulated_leap_seconds( $self->{utc_rd_days} ) + $utc_rd_secs1 += $self->_accumulated_leap_seconds( $self->{utc_rd_days} ) if !$self->time_zone->is_floating; my $utc_rd_secs2 = $dt->utc_rd_as_seconds; - $utc_rd_secs2 += DateTime->_accumulated_leap_seconds( $dt->{utc_rd_days} ) + $utc_rd_secs2 += $self->_accumulated_leap_seconds( $dt->{utc_rd_days} ) if !$dt->time_zone->is_floating; my $seconds = $utc_rd_secs1 - $utc_rd_secs2; @@ -1657,30 +1736,52 @@ sub add { my $self = shift; - return $self->add_duration( $self->duration_class->new(@_) ); + return $self->add_duration( $self->_duration_object_from_args(@_) ); } sub subtract { my $self = shift; - my %p = @_; my %eom; - $eom{end_of_month} = delete $p{end_of_month} - if exists $p{end_of_month}; + if ( @_ % 2 == 0 ) { + my %p = @_; - my $dur = $self->duration_class->new(@_)->inverse(%eom); + $eom{end_of_month} = delete $p{end_of_month} + if exists $p{end_of_month}; + } + + my $dur = $self->_duration_object_from_args(@_)->inverse(%eom); return $self->add_duration($dur); } +# Syntactic sugar for add and subtract: use a duration object if it's +# supplied, otherwise build a new one from the arguments. + +sub _duration_object_from_args { + my $self = shift; + + return $_[0] + if @_ == 1 && blessed( $_[0] ) && $_[0]->isa( $self->duration_class ); + + return $self->duration_class->new(@_); +} + sub subtract_duration { return $_[0]->add_duration( $_[1]->inverse ) } { - my @spec = ( { isa => 'DateTime::Duration' } ); + my $validator = validation_for( + name => '_check_add_duration_params', + name_is_optional => 1, + params => [ + { type => t('Duration') }, + ], + ); + ## no critic (Subroutines::ProhibitExcessComplexity) sub add_duration { my $self = shift; - my ($dur) = validate_pos( @_, @spec ); + my ($dur) = $validator->(@_); # simple optimization return $self if $dur->is_zero; @@ -1830,7 +1931,7 @@ } sub _compare { - my ( $class, $dt1, $dt2, $consistent ) = ref $_[0] ? ( undef, @_ ) : @_; + my ( undef, $dt1, $dt2, $consistent ) = ref $_[0] ? ( undef, @_ ) : @_; return undef unless defined $dt2; @@ -1903,27 +2004,62 @@ } } -# Many of the same parameters as new() but all of them are optional, -# and there are no defaults. -my $SetValidate = { - map { - my %copy = %{ $BasicValidate->{$_} }; - delete $copy{default}; - $copy{optional} = 1; - $_ => \%copy - } - keys %$BasicValidate -}; +{ + my $validator = validation_for( + name => '_check_set_params', + name_is_optional => 1, + params => { + year => { + type => t('Year'), + optional => 1, + }, + month => { + type => t('Month'), + optional => 1, + }, + day => { + type => t('DayOfMonth'), + optional => 1, + }, + hour => { + type => t('Hour'), + optional => 1, + }, + minute => { + type => t('Minute'), + optional => 1, + }, + second => { + type => t('Second'), + optional => 1, + }, + nanosecond => { + type => t('Nanosecond'), + optional => 1, + }, + locale => { + type => t('Locale'), + optional => 1, + }, + }, + ); -sub set { - my $self = shift; - my %p = validate( @_, $SetValidate ); + ## no critic (NamingConventions::ProhibitAmbiguousNames) + sub set { + my $self = shift; + my %p = $validator->(@_); - my $new_dt = $self->_new_from_self(%p); + if ( $p{locale} ) { + carp 'You passed a locale to the set() method.' + . ' You should use set_locale() instead, as using set() may alter the local time near a DST boundary.'; + } - %$self = %$new_dt; + my $new_dt = $self->_new_from_self(%p); - return $self; + %$self = %$new_dt; + + return $self; + } } sub set_year { $_[0]->set( year => $_[1] ) } @@ -1938,23 +2074,42 @@ # DST change where the same local time occurs twice then passing it through # _new() can actually change the underlying UTC time, which is bad. -sub set_locale { - my $self = shift; +{ + my $validator = validation_for( + name => '_check_set_locale_params', + name_is_optional => 1, + params => [ + { type => t( 'Maybe', of => t('Locale') ) }, + ], + ); - my ($locale) = validate_pos( @_, $BasicValidate->{locale} ); + sub set_locale { + my $self = shift; + my ($locale) = $validator->(@_); - $self->_set_locale($locale); + $self->_set_locale($locale); - return $self; + return $self; + } } -sub set_formatter { - my $self = shift; - my ($formatter) = validate_pos( @_, $BasicValidate->{formatter} ); +{ + my $validator = validation_for( + name => '_check_set_formatter_params', + name_is_optional => 1, + params => [ + { type => t( 'Maybe', of => t('Formatter') ) }, + ], + ); - $self->{formatter} = $formatter; + sub set_formatter { + my $self = shift; + my ($formatter) = $validator->(@_); - return $self; + $self->{formatter} = $formatter; + + return $self; + } } { @@ -1966,13 +2121,23 @@ second => 0, nanosecond => 0, ); - my $re = join '|', 'year', 'week', 'local_week', + + my $validator = validation_for( + name => '_check_truncate_params', + name_is_optional => 1, + params => { + to => { type => t('TruncationLevel') }, + }, + ); + + my $re = join '|', 'year', 'week', 'local_week', 'quarter', grep { $_ ne 'nanosecond' } keys %TruncateDefault; my $spec = { to => { regex => qr/^(?:$re)$/ } }; + ## no critic (Subroutines::ProhibitBuiltinHomonyms) sub truncate { my $self = shift; - my %p = validate( @_, $spec ); + my %p = $validator->(@_); my %new; if ( $p{to} eq 'week' || $p{to} eq 'local_week' ) { @@ -1998,6 +2163,17 @@ die $_; }; } + elsif ( $p{to} eq 'quarter' ) { + %new = ( + year => $self->year, + month => int( ( $self->month - 1 ) / 3 ) * 3 + 1, + day => 1, + hour => 0, + minute => 0, + second => 0, + nanosecond => 0, + ); + } else { my $truncate; foreach my $f (qw( year month day hour minute second nanosecond )) @@ -2062,15 +2238,14 @@ } sub STORABLE_freeze { - my $self = shift; - my $cloning = shift; + my $self = shift; - my $serialized = ''; + my $serialized = q{}; foreach my $key ( qw( utc_rd_days utc_rd_secs rd_nanosecs ) - ) { + ) { $serialized .= "$key:$self->{$key}|"; } @@ -2084,8 +2259,8 @@ } sub STORABLE_thaw { - my $self = shift; - my $cloning = shift; + my $self = shift; + shift; my $serialized = shift; my %serialized = map { split /:/ } split /\|/, $serialized; @@ -2099,11 +2274,7 @@ else { $tz = DateTime::TimeZone->new( name => delete $serialized{tz} ); - $locale = DateTime::Locale->load( - exists $serialized{language} - ? delete $serialized{language} - : delete $serialized{locale} - ); + $locale = DateTime::Locale->load( delete $serialized{locale} ); } delete $serialized{version}; @@ -2130,6 +2301,7 @@ return $self; } +## no critic (Modules::ProhibitMultiplePackages) package # hide from PAUSE DateTime::_Thawed; @@ -2145,13 +2317,15 @@ =pod +=encoding UTF-8 + =head1 NAME DateTime - A date and time object for Perl =head1 VERSION -version 1.21 +version 1.46 =head1 SYNOPSIS @@ -2249,14 +2423,12 @@ For infinite datetimes, please see the L module. -=encoding UTF-8 - =head1 USAGE =head2 0-based Versus 1-based Numbers -The DateTime.pm module follows a simple consistent logic for -determining whether or not a given number is 0-based or 1-based. +The DateTime.pm module follows a simple logic for determining whether or not a +given number is 0-based or 1-based. Month, day of month, day of week, and day of year are 1-based. Any method that is 1-based also has an equivalent 0-based method ending in @@ -2286,7 +2458,7 @@ All the object methods which return names or abbreviations return data based on a locale. This is done by setting the locale when constructing a DateTime -object. If this is not set, then "en_US" is used. +object. If this is not set, then "en-US" is used. =head2 Floating DateTimes @@ -2336,6 +2508,24 @@ memory calculating all the DST changes from now until the future date. Use UTC or the floating time zone and you will be safe. +=head2 Globally Setting a Default Time Zone + +B + +By default, C uses either the floating time zone or UTC for newly +created objects, depending on the constructor. + +You can force C to use a different time zone by setting the +C environment variable. + +As noted above, this is very dangerous, as it affects all code that creates a +C object, including modules from CPAN. If those modules expect the +normal default, then setting this can cause confusing breakage or subtly +broken data. Before setting this variable, you are strongly encouraged to +audit your CPAN dependencies to see how they use C. Try running the +test suite for each dependency with this environment variable set before using +this in production. + =head2 Upper and Lower Bounds Internally, dates are represented the number of days before or after @@ -2433,16 +2623,15 @@ "day" parameters both default to 1, while the "hour", "minute", "second", and "nanosecond" parameters all default to 0. -The "locale" parameter should be a string matching one of the valid -locales, or a C object. See the -L documentation for details. - -The time_zone parameter can be either a scalar or a -C object. A string will simply be passed to the -C<< DateTime::TimeZone->new >> method as its "name" parameter. This -string may be an Olson DB time zone name ("America/Chicago"), an -offset string ("+0630"), or the words "floating" or "local". See the -C documentation for more details. +The "locale" parameter should be a string containing a locale code, like +"en-US" or "zh-Hant-TW", or an object returned by C<< DateTime::Locale->load +>>. See the L documentation for details. + +The "time_zone" parameter can be either a string or a C +object. A string will simply be passed to the C<< DateTime::TimeZone->new >> +method as its "name" parameter. This string may be an Olson DB time zone name +("America/Chicago"), an offset string ("+0630"), or the words "floating" or +"local". See the C documentation for more details. The default time zone is "floating". @@ -2514,11 +2703,8 @@ an epoch time instead of components. Just as with the C method, it accepts "time_zone", "locale", and "formatter" parameters. -If the epoch value is not an integer, the part after the decimal will -be converted to nanoseconds. This is done in order to be compatible -with C. If the floating portion extends past 9 decimal -places, it will be truncated to nine, so that 1.1234567891 will become -1 second and 123,456,789 nanoseconds. +If the epoch value is a floating-point value, it will be rounded to +nearest microsecond. By default, the returned object will be in the UTC time zone. @@ -2774,20 +2960,50 @@ Also available as C<< $dt->time() >>. -=head3 $dt->datetime() +=head3 $dt->datetime( $optional_separator ) This method is equivalent to: $dt->ymd('-') . 'T' . $dt->hms(':') +The C<$optional_separator> parameter allows you to override the separator +between the date and time, for e.g. C<< $dt->datetime(q{ }) >>. + This method is also available as C<< $dt->iso8601() >>, but it's not really a -very good ISO8601 format, as it lacks a time zone. +very good ISO8601 format, as it lacks a time zone. If called as +C<< $dt->iso8601() >> you cannot change the separator, as ISO8601 specifies +that "T" must be used to separate them. + +=head3 $dt->stringify() + +This method returns a stringified version of the object. It is how +stringification overloading is implemented. If the object has a formatter, +then its C method is used to produce a string. Otherwise, +this method calls C<< $dt->iso8601() >> to produce a string. See L for details. =head3 $dt->is_leap_year() -This method returns a true or false indicating whether or not the +This method returns a true or false value indicating whether or not the datetime object is in a leap year. +=head3 $dt->is_last_day_of_month() + +This method returns a true or false value indicating whether or not the +datetime object is the last day of the month. + +=head3 $dt->month_length() + +This method returns the number of days in the current month. + +=head3 $dt->quarter_length() + +This method returns the number of days in the current quarter. + +=head3 $dt->year_length() + +This method returns the number of days in the current year. + =head3 $dt->week() ($week_year, $week_number) = $dt->week; @@ -2880,10 +3096,8 @@ =head3 $dt->epoch() -Return the UTC epoch value for the datetime object. Internally, this -is implemented using C, which uses the Unix epoch even on -machines with a different epoch (such as MacOS). Datetimes before the -start of the epoch will be returned as a negative number. +Return the UTC epoch value for the datetime object. Datetimes before the start +of the epoch will be returned as a negative number. The return value from this method is always an integer. @@ -2891,11 +3105,6 @@ 1972-12-31T23:59:60 (UTC) is exactly the same as that for 1973-01-01T00:00:00. -This module uses C to calculate the epoch, which may or -may not handle epochs before 1904 or after 2038 (depending on the size -of your system's integers, and whether or not Perl was compiled with -64-bit int support). - =head3 $dt->hires_epoch() Returns the epoch as a floating point number. The floating point @@ -2968,13 +3177,12 @@ =head3 $dt->set( .. ) -This method can be used to change the local components of a date time, -or its locale. This method accepts any parameter allowed by the -C method except for "time_zone". Time zones may be set using -the C method. +This method can be used to change the local components of a date time. This +method accepts any parameter allowed by the C method except for +"locale" or "time_zone". Use C and C for those +instead. -This method performs parameters validation just as is done in the -C method. +This method performs parameter validation just like the C method. B and C methods instead.> @@ -3000,8 +3208,6 @@ =item * $dt->set_nanosecond() -=item * $dt->set_locale() - =back These are shortcuts to calling C with a single key. They all @@ -3011,14 +3217,21 @@ This method allows you to reset some of the local time components in the object to their "zero" values. The "to" parameter is used to specify which -values to truncate, and it may be one of "year", "month", "week", "local_week" -"day", "hour", "minute", or "second". For example, if "month" is specified, -then the local day becomes 1, and the hour, minute, and second all become 0. +values to truncate, and it may be one of "year", "quarter", "month", "week", +"local_week", "day", "hour", "minute", or "second". + +For example, if "month" is specified, then the local day becomes 1, and the +hour, minute, and second all become 0. If "week" is given, then the datetime is set to the Monday of the week in which it occurs, and the time components are all set to 0. If you truncate to "local_week", then the first day of the week is locale-dependent. For example, -in the C locale, the first day of the week is Sunday. +in the C locale, the first day of the week is Sunday. + +=head3 $dt->set_locale( $locale ) + +Sets the object's locale. You can provide either a locale code like "en-US" or +an object returned by C<< DateTime::Locale->load >>. =head3 $dt->set_time_zone( $tz ) @@ -3082,12 +3295,16 @@ This method adds a C to the current datetime. See the L docs for more details. -=head3 $dt->add( DateTime::Duration->new parameters ) +=head3 $dt->add( parameters for DateTime::Duration ) This method is syntactic sugar around the C method. It simply creates a new C object using the parameters given, and then calls the C method. +=head3 $dt->add( $duration_object ) + +A synonym of C<< $dt->add_duration( $duration_object ) >>. + =head3 $dt->subtract_duration( $duration_object ) When given a C object, this method simply calls @@ -3099,6 +3316,10 @@ Like C, this is syntactic sugar for the C method. +=head3 $dt->subtract( $duration_object ) + +A synonym of C<< $dt->subtract_duration( $duration_object ) >>. + =head3 $dt->subtract_datetime( $datetime ) This method returns a new C object representing @@ -3158,7 +3379,7 @@ =head3 DateTime->DefaultLocale( $locale ) This can be used to specify the default locale to be used when -creating DateTime objects. If unset, then "en_US" is used. +creating DateTime objects. If unset, then "en-US" is used. =head3 DateTime->compare( $dt1, $dt2 ), DateTime->compare_ignore_floating( $dt1, $dt2 ) @@ -3303,6 +3524,13 @@ C. Other methods of subtraction are not always reversible. +=item * never do math on two objects where only one is in the floating time zone + +The date math code accounts for leap seconds whenever the C object +is not in the floating time zone. If you try to do math where one object is in +the floating zone and the other isn't, the results will be confusing and +wrong. + =back =head3 Adding a Duration to a Datetime @@ -3999,32 +4227,32 @@ look these up, you get back a different CLDR pattern suitable for the locale. Let's look at some example We'll use C<2008-02-05T18:30:30> as our example -datetime value, and see how this is rendered for the C and C +datetime value, and see how this is rendered for the C and C locales. =over 4 =item * C -The abbreviated month and day as number. For C, we get the pattern -C, which renders as C. For C, we get the pattern +The abbreviated month and day as number. For C, we get the pattern +C, which renders as C. For C, we get the pattern C, which renders as C<5 févr.>. =item * C -The year and abbreviated quarter of year. For C, we get the pattern -C, which renders as C. For C, we get the same pattern, +The year and abbreviated quarter of year. For C, we get the pattern +C, which renders as C. For C, we get the same pattern, C, which renders as C. =item * C -The 12-hour time of day without seconds. For C, we get the pattern -C, which renders as C<6:30 PM>. For C, we get the exact same +The 12-hour time of day without seconds. For C, we get the pattern +C, which renders as C<6:30 PM>. For C, we get the exact same pattern and rendering. =back -The available format for each locale are documented in the POD for that +The available formats for each locale are documented in the POD for that locale. To get back the format, you use the C<< $locale->format_for >> method. For example: @@ -4303,36 +4531,6 @@ If you don't plan to use infinite datetimes you can probably ignore this. This will be fixed (perhaps) in future versions. -=head1 SUPPORT - -Support for this module is provided via the datetime@perl.org email list. See -http://datetime.perl.org/wiki/datetime/page/Mailing_List for details. - -Please submit bugs to the CPAN RT system at -http://rt.cpan.org/NoAuth/Bugs.html?Dist=DateTime or via email at -bug-datetime@rt.cpan.org. - -=head1 DONATIONS - -If you'd like to thank me for the work I've done on this module, -please consider making a "donation" to me via PayPal. I spend a lot of -free time creating free software, and would appreciate any support -you'd care to offer. - -Please note that B in order -for me to continue working on this particular software. I will -continue to do so, inasmuch as I have in the past, for as long as it -interests me. - -Similarly, a donation made in this way will probably not make me work -on this software much more, unless I get so many donations that I can -consider working on free software full time, which seems unlikely at -best. - -To donate, log into PayPal and send money to autarch@urth.org or use -the button on this page: -L - =head1 SEE ALSO L +=head1 SUPPORT + +Bugs may be submitted at L. + +There is a mailing list available for users of this distribution, +L. + +I am also usually active on IRC as 'autarch' on C. + +=head1 SOURCE + +The source code repository for DateTime can be found at L. + +=head1 DONATIONS + +If you'd like to thank me for the work I've done on this module, please +consider making a "donation" to me via PayPal. I spend a lot of free time +creating free software, and would appreciate any support you'd care to offer. + +Please note that B in order for me +to continue working on this particular software. I will continue to do so, +inasmuch as I have in the past, for as long as it interests me. + +Similarly, a donation made in this way will probably not make me work on this +software much more, unless I get so many donations that I can consider working +on free software full time (let's all have a chuckle at that together). + +To donate, log into PayPal and send money to autarch@urth.org, or use the +button at L. + =head1 AUTHOR Dave Rolsky =head1 CONTRIBUTORS -=for stopwords Ben Bennett Christian Hansen Daisuke Maki David E. Wheeler Doug Bell Flávio Soibelmann Glock Gregory Oschwald Iain Truskett Jason McIntosh Joshua Hoblitt Nick Tonkin Ricardo Signes Richard Bowen Ron Hill +=for stopwords Ben Bennett Christian Hansen Daisuke Maki Dan Book Stewart David E. Wheeler Precious Doug Bell Flávio Soibelmann Glock Gianni Ceccarelli Gregory Oschwald Hauke D Iain Truskett Jason McIntosh Joshua Hoblitt Karen Etheridge Michael Conrad R. Davis M Somerville Nick Tonkin Olaf Alders Ovid Philippe Bruhat (BooK) Ricardo Signes Richard Bowen Ron Hill Sam Kington viviparous =over 4 @@ -4367,10 +4595,22 @@ =item * +Dan Book + +=item * + +Dan Stewart + +=item * + David E. Wheeler =item * +David Precious + +=item * + Doug Bell =item * @@ -4379,10 +4619,18 @@ =item * +Gianni Ceccarelli + +=item * + Gregory Oschwald =item * +Hauke D + +=item * + Iain Truskett =item * @@ -4395,10 +4643,38 @@ =item * +Karen Etheridge + +=item * + +Michael Conrad + +=item * + +Michael R. Davis + +=item * + +M Somerville + +=item * + Nick Tonkin <1nickt@users.noreply.github.com> =item * +Olaf Alders + +=item * + +Ovid + +=item * + +Philippe Bruhat (BooK) + +=item * + Ricardo Signes =item * @@ -4409,14 +4685,25 @@ Ron Hill +=item * + +Sam Kington + +=item * + +viviparous + =back =head1 COPYRIGHT AND LICENSE -This software is Copyright (c) 2015 by Dave Rolsky. +This software is Copyright (c) 2003 - 2018 by Dave Rolsky. This is free software, licensed under: The Artistic License 2.0 (GPL Compatible) +The full text of the license can be found in the +F file included with this distribution. + =cut diff -Nru libdatetime-perl-1.21/lib/DateTime.xs libdatetime-perl-1.46/lib/DateTime.xs --- libdatetime-perl-1.21/lib/DateTime.xs 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/lib/DateTime.xs 1970-01-01 00:00:00.000000000 +0000 @@ -1,312 +0,0 @@ -#include "EXTERN.h" -#include "perl.h" -#include "XSUB.h" -#define NEED_sv_2pv_flags -#include "ppport.h" - -#include - -/* This file is generated by tools/leap_seconds_header.pl */ -#include "leap_seconds.h" - -/* This is a temporary hack until a better solution can be found to - get the finite() function on Win32 */ -#ifndef WIN32 -# include -# ifndef isfinite -# ifdef finite -# define finite isfinite -# endif -# endif -#endif - -#define DAYS_PER_400_YEARS 146097 -#define DAYS_PER_4_YEARS 1461 -#define MARCH_1 306 - -#define SECONDS_PER_DAY 86400 - -const int PREVIOUS_MONTH_DOY[12] = { 0, - 31, - 59, - 90, - 120, - 151, - 181, - 212, - 243, - 273, - 304, - 334 }; - -const int PREVIOUS_MONTH_DOLY[12] = { 0, - 31, - 60, - 91, - 121, - 152, - 182, - 213, - 244, - 274, - 305, - 335 }; - - -IV -_real_is_leap_year(IV y) { - /* See http://www.perlmonks.org/?node_id=274247 for where this silliness - comes from */ - return (y % 4) ? 0 : (y % 100) ? 1 : (y % 400) ? 0 : 1; -} - - -MODULE = DateTime PACKAGE = DateTime - -PROTOTYPES: ENABLE - -void -_rd2ymd(self, d, extra = 0) - IV d; - IV extra; - - PREINIT: - IV y, m; - IV c; - IV quarter; - IV yadj = 0; - IV dow, doy, doq; - IV rd_days; - - PPCODE: - rd_days = d; - - d += MARCH_1; - - if (d <= 0) { - yadj = -1 * (((-1 * d) / DAYS_PER_400_YEARS) + 1); - d -= yadj * DAYS_PER_400_YEARS; - } - - /* c is century */ - c = ((d * 4) - 1) / DAYS_PER_400_YEARS; - d -= c * DAYS_PER_400_YEARS / 4; - y = ((d * 4) - 1) / DAYS_PER_4_YEARS; - d -= y * DAYS_PER_4_YEARS / 4; - m = ((d * 12) + 1093) / 367; - d -= ((m * 367) - 1094) / 12; - y += (c * 100) + (yadj * 400); - - if (m > 12) { - ++y; - m -= 12; - } - - EXTEND(SP, extra ? 7 : 3); - mPUSHi(y); - mPUSHi(m); - mPUSHi(d); - - if (extra) { - quarter = ( ( 1.0 / 3.1 ) * m ) + 1; - - dow = rd_days % 7; - if ( dow <= 0 ) { - dow += 7; - } - - mPUSHi(dow); - - if (_real_is_leap_year(y)) { - doy = PREVIOUS_MONTH_DOLY[m - 1] + d; - doq = doy - PREVIOUS_MONTH_DOLY[ (3 * quarter) - 3 ]; - } else { - doy = PREVIOUS_MONTH_DOY[m - 1] + d; - doq = doy - PREVIOUS_MONTH_DOY[ (3 * quarter ) - 3 ]; - } - - mPUSHi(doy); - mPUSHi(quarter); - mPUSHi(doq); - } - -void -_ymd2rd(self, y, m, d) - IV y; - IV m; - IV d; - - PREINIT: - IV adj; - - PPCODE: - if (m <= 2) { - adj = (14 - m) / 12; - y -= adj; - m += 12 * adj; - } else if (m > 14) { - adj = (m - 3) / 12; - y += adj; - m -= 12 * adj; - } - - if (y < 0) { - adj = (399 - y) / 400; - d -= DAYS_PER_400_YEARS * adj; - y += 400 * adj; - } - - d += (m * 367 - 1094) / - 12 + y % 100 * DAYS_PER_4_YEARS / - 4 + (y / 100 * 36524 + y / 400) - MARCH_1; - - EXTEND(SP, 1); - mPUSHi(d); - -void -_seconds_as_components(self, secs, utc_secs = 0, secs_modifier = 0) - IV secs; - IV utc_secs; - IV secs_modifier; - - PREINIT: - IV h, m, s; - - PPCODE: - secs -= secs_modifier; - - h = secs / 3600; - secs -= h * 3600; - - m = secs / 60; - - s = secs - (m * 60); - - if (utc_secs >= SECONDS_PER_DAY) { - if (utc_secs >= SECONDS_PER_DAY + 1) { - /* If we just use %d and the IV, we get a warning that IV is - not an int. */ - croak("Invalid UTC RD seconds value: %s", SvPV_nolen(newSViv(utc_secs))); - } - - s += (utc_secs - SECONDS_PER_DAY) + 60; - m = 59; - h--; - - if (h < 0) { - h = 23; - } - } - - EXTEND(SP, 3); - mPUSHi(h); - mPUSHi(m); - mPUSHi(s); - -#ifdef isfinite -void -_normalize_tai_seconds(self, days, secs) - SV* days; - SV* secs; - - PPCODE: - if (isfinite(SvNV(days)) && isfinite(SvNV(secs))) { - IV d = SvIV(days); - IV s = SvIV(secs); - IV adj; - - if (s < 0) { - adj = (s - (SECONDS_PER_DAY - 1)) / SECONDS_PER_DAY; - } else { - adj = s / SECONDS_PER_DAY; - } - - d += adj; - s -= adj * SECONDS_PER_DAY; - - sv_setiv(days, (IV) d); - sv_setiv(secs, (IV) s); - } - -void -_normalize_leap_seconds(self, days, secs) - SV* days; - SV* secs; - - PPCODE: - if (isfinite(SvNV(days)) && isfinite(SvNV(secs))) { - IV d = SvIV(days); - IV s = SvIV(secs); - IV day_length; - - while (s < 0) { - SET_DAY_LENGTH(d - 1, day_length); - - s += day_length; - d--; - } - - SET_DAY_LENGTH(d, day_length); - - while (s > day_length - 1) { - s -= day_length; - d++; - SET_DAY_LENGTH(d, day_length); - } - - sv_setiv(days, (IV) d); - sv_setiv(secs, (IV) s); - } - -#endif /* ifdef isfinite */ - -void -_time_as_seconds(self, h, m, s) - IV h; - IV m; - IV s; - - PPCODE: - EXTEND(SP, 1); - mPUSHi(h * 3600 + m * 60 + s); - -void -_is_leap_year(self, y) - IV y; - - PPCODE: - EXTEND(SP, 1); - mPUSHi(_real_is_leap_year(y)); - -void -_day_length(self, utc_rd) - IV utc_rd; - - PPCODE: - IV day_length; - SET_DAY_LENGTH(utc_rd, day_length); - - EXTEND(SP, 1); - mPUSHi(day_length); - -void -_day_has_leap_second(self, utc_rd) - IV utc_rd; - - PPCODE: - IV day_length; - SET_DAY_LENGTH(utc_rd, day_length); - - EXTEND(SP, 1); - mPUSHi(day_length > 86400 ? 1 : 0); - -void -_accumulated_leap_seconds(self, utc_rd) - IV utc_rd; - - PPCODE: - IV leap_seconds; - SET_LEAP_SECONDS(utc_rd, leap_seconds); - - EXTEND(SP, 1); - mPUSHi(leap_seconds); diff -Nru libdatetime-perl-1.21/LICENSE libdatetime-perl-1.46/LICENSE --- libdatetime-perl-1.21/LICENSE 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/LICENSE 2018-02-11 23:36:51.000000000 +0000 @@ -1,4 +1,4 @@ -This software is Copyright (c) 2015 by Dave Rolsky. +This software is Copyright (c) 2003 - 2018 by Dave Rolsky. This is free software, licensed under: diff -Nru libdatetime-perl-1.21/Makefile.PL libdatetime-perl-1.46/Makefile.PL --- libdatetime-perl-1.21/Makefile.PL 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/Makefile.PL 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,140 @@ +# This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v6.010. +use strict; +use warnings; + +use 5.008004; + +use ExtUtils::MakeMaker; +check_conflicts(); + +my %WriteMakefileArgs = ( + "ABSTRACT" => "A date and time object for Perl", + "AUTHOR" => "Dave Rolsky ", + "CONFIGURE_REQUIRES" => { + "Dist::CheckConflicts" => "0.02", + "ExtUtils::MakeMaker" => 0 + }, + "DISTNAME" => "DateTime", + "LICENSE" => "artistic_2", + "MIN_PERL_VERSION" => "5.008004", + "NAME" => "DateTime", + "PREREQ_PM" => { + "Carp" => 0, + "DateTime::Locale" => "1.06", + "DateTime::TimeZone" => "2.02", + "Dist::CheckConflicts" => "0.02", + "POSIX" => 0, + "Params::ValidationCompiler" => "0.26", + "Scalar::Util" => 0, + "Specio" => "0.18", + "Specio::Declare" => 0, + "Specio::Exporter" => 0, + "Specio::Library::Builtins" => 0, + "Specio::Library::Numeric" => 0, + "Specio::Library::String" => 0, + "Try::Tiny" => 0, + "XSLoader" => 0, + "base" => 0, + "integer" => 0, + "namespace::autoclean" => "0.19", + "overload" => 0, + "parent" => 0, + "strict" => 0, + "warnings" => 0, + "warnings::register" => 0 + }, + "TEST_REQUIRES" => { + "CPAN::Meta::Check" => "0.011", + "CPAN::Meta::Requirements" => 0, + "ExtUtils::MakeMaker" => 0, + "File::Spec" => 0, + "Storable" => 0, + "Test::Fatal" => 0, + "Test::More" => "0.96", + "Test::Warnings" => "0.005", + "utf8" => 0 + }, + "VERSION" => "1.46", + "test" => { + "TESTS" => "t/*.t" + } +); + + +my %FallbackPrereqs = ( + "CPAN::Meta::Check" => "0.011", + "CPAN::Meta::Requirements" => 0, + "Carp" => 0, + "DateTime::Locale" => "1.06", + "DateTime::TimeZone" => "2.02", + "Dist::CheckConflicts" => "0.02", + "ExtUtils::MakeMaker" => 0, + "File::Spec" => 0, + "POSIX" => 0, + "Params::ValidationCompiler" => "0.26", + "Scalar::Util" => 0, + "Specio" => "0.18", + "Specio::Declare" => 0, + "Specio::Exporter" => 0, + "Specio::Library::Builtins" => 0, + "Specio::Library::Numeric" => 0, + "Specio::Library::String" => 0, + "Storable" => 0, + "Test::Fatal" => 0, + "Test::More" => "0.96", + "Test::Warnings" => "0.005", + "Try::Tiny" => 0, + "XSLoader" => 0, + "base" => 0, + "integer" => 0, + "namespace::autoclean" => "0.19", + "overload" => 0, + "parent" => 0, + "strict" => 0, + "utf8" => 0, + "warnings" => 0, + "warnings::register" => 0 +); + + +unless ( eval { ExtUtils::MakeMaker->VERSION(6.63_03) } ) { + delete $WriteMakefileArgs{TEST_REQUIRES}; + delete $WriteMakefileArgs{BUILD_REQUIRES}; + $WriteMakefileArgs{PREREQ_PM} = \%FallbackPrereqs; +} + +delete $WriteMakefileArgs{CONFIGURE_REQUIRES} + unless eval { ExtUtils::MakeMaker->VERSION(6.52) }; + +WriteMakefile(%WriteMakefileArgs); + +sub check_conflicts { + if ( eval { require './lib/DateTime/Conflicts.pm'; 1; } ) { + if ( eval { DateTime::Conflicts->check_conflicts; 1 } ) { + return; + } + else { + my $err = $@; + $err =~ s/^/ /mg; + warn "***\n$err***\n"; + } + } + else { + print <<'EOF'; +*** + Your toolchain doesn't support configure_requires, so Dist::CheckConflicts + hasn't been installed yet. You should check for conflicting modules + manually by examining the list of conflicts in DateTime::Conflicts once the installation + finishes. +*** +EOF + } + + return if $ENV{AUTOMATED_TESTING} || $ENV{NONINTERACTIVE_TESTING}; + + # More or less copied from Module::Build + return if $ENV{PERL_MM_USE_DEFAULT}; + return unless -t STDIN && ( -t STDOUT || !( -f STDOUT || -c STDOUT ) ); + + sleep 4; +} diff -Nru libdatetime-perl-1.21/MANIFEST libdatetime-perl-1.46/MANIFEST --- libdatetime-perl-1.21/MANIFEST 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/MANIFEST 2018-02-11 23:36:51.000000000 +0000 @@ -1,39 +1,34 @@ -# This file was automatically generated by Dist::Zilla::Plugin::Manifest v5.039. -Build.PL +# This file was automatically generated by Dist::Zilla::Plugin::Manifest v6.010. +CONTRIBUTING.md CREDITS Changes +DateTime.xs INSTALL LICENSE MANIFEST META.json META.yml +Makefile.PL README.md TODO -_build/auto_features -_build/build_params -_build/cleanup -_build/config_data -_build/features -_build/magicnum -_build/notes -_build/prereqs -_build/runtime_params -c/leap_seconds.h -c/ppport.h +appveyor.yml cpanfile dist.ini -inc/MyModuleBuild.pm +inc/LeapSecondsHeader.pm +leap_seconds.h leaptab.txt lib/DateTime.pm -lib/DateTime.xs +lib/DateTime/Conflicts.pm lib/DateTime/Duration.pm lib/DateTime/Helpers.pm lib/DateTime/Infinite.pm lib/DateTime/LeapSecond.pm lib/DateTime/PP.pm lib/DateTime/PPExtra.pm +lib/DateTime/Types.pm perlcriticrc perltidyrc +ppport.h t/00-report-prereqs.dd t/00-report-prereqs.t t/00load.t @@ -82,63 +77,68 @@ t/44set-formatter.t t/45core-time.t t/46warnings.t -t/author-eol.t -t/author-mojibake.t -t/author-no-tabs.t -t/author-pod-spell.t -t/author-test-all-my-deps.t -t/author-test-version.t -t/release-cpan-changes.t -t/release-load-is-xs.t -t/release-pod-coverage.t -t/release-pod-linkcheck.t -t/release-pod-syntax.t -t/release-portability.t -t/release-pp-00load.t -t/release-pp-01sanity.t -t/release-pp-02last-day.t -t/release-pp-03components.t -t/release-pp-04epoch.t -t/release-pp-05set.t -t/release-pp-06add.t -t/release-pp-07compare.t -t/release-pp-09greg.t -t/release-pp-10subtract.t -t/release-pp-11duration.t -t/release-pp-12week.t -t/release-pp-13strftime.t -t/release-pp-14locale.t -t/release-pp-15jd.t -t/release-pp-16truncate.t -t/release-pp-17set-return.t -t/release-pp-18today.t -t/release-pp-19leap-second.t -t/release-pp-20infinite.t -t/release-pp-21bad-params.t -t/release-pp-22from-doy.t -t/release-pp-23storable.t -t/release-pp-24from-object.t -t/release-pp-25add-subtract.t -t/release-pp-27delta.t -t/release-pp-28dow.t -t/release-pp-29overload.t -t/release-pp-30future-tz.t -t/release-pp-31formatter.t -t/release-pp-32leap-second2.t -t/release-pp-33seconds-offset.t -t/release-pp-34set-tz.t -t/release-pp-35rd-values.t -t/release-pp-36invalid-local.t -t/release-pp-37local-add.t -t/release-pp-38local-subtract.t -t/release-pp-40leap-years.t -t/release-pp-41cldr-format.t -t/release-pp-42duration-class.t -t/release-pp-43new-params.t -t/release-pp-44set-formatter.t -t/release-pp-45core-time.t -t/release-pp-46warnings.t -t/release-tidyall.t +t/47default-time-zone.t +t/48rt-115983.t +t/zzz-check-breaks.t tidyall.ini -tools/leap_seconds_header.pl -weaver.ini +xt/author/clean-namespaces.t +xt/author/eol.t +xt/author/mojibake.t +xt/author/no-tabs.t +xt/author/pod-coverage.t +xt/author/pod-spell.t +xt/author/pod-syntax.t +xt/author/portability.t +xt/author/pp-00load.t +xt/author/pp-01sanity.t +xt/author/pp-02last-day.t +xt/author/pp-03components.t +xt/author/pp-04epoch.t +xt/author/pp-05set.t +xt/author/pp-06add.t +xt/author/pp-07compare.t +xt/author/pp-09greg.t +xt/author/pp-10subtract.t +xt/author/pp-11duration.t +xt/author/pp-12week.t +xt/author/pp-13strftime.t +xt/author/pp-14locale.t +xt/author/pp-15jd.t +xt/author/pp-16truncate.t +xt/author/pp-17set-return.t +xt/author/pp-18today.t +xt/author/pp-19leap-second.t +xt/author/pp-20infinite.t +xt/author/pp-21bad-params.t +xt/author/pp-22from-doy.t +xt/author/pp-23storable.t +xt/author/pp-24from-object.t +xt/author/pp-25add-subtract.t +xt/author/pp-27delta.t +xt/author/pp-28dow.t +xt/author/pp-29overload.t +xt/author/pp-30future-tz.t +xt/author/pp-31formatter.t +xt/author/pp-32leap-second2.t +xt/author/pp-33seconds-offset.t +xt/author/pp-34set-tz.t +xt/author/pp-35rd-values.t +xt/author/pp-36invalid-local.t +xt/author/pp-37local-add.t +xt/author/pp-38local-subtract.t +xt/author/pp-40leap-years.t +xt/author/pp-41cldr-format.t +xt/author/pp-42duration-class.t +xt/author/pp-43new-params.t +xt/author/pp-44set-formatter.t +xt/author/pp-45core-time.t +xt/author/pp-46warnings.t +xt/author/pp-47default-time-zone.t +xt/author/pp-48rt-115983.t +xt/author/pp-is-loaded.t +xt/author/test-all-my-deps.t +xt/author/test-version.t +xt/author/tidyall.t +xt/author/xs-is-loaded.t +xt/release/cpan-changes.t +xt/release/meta-json.t diff -Nru libdatetime-perl-1.21/META.json libdatetime-perl-1.46/META.json --- libdatetime-perl-1.21/META.json 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/META.json 2018-02-11 23:36:51.000000000 +0000 @@ -4,7 +4,7 @@ "Dave Rolsky " ], "dynamic_config" : 0, - "generated_by" : "Dist::Zilla version 5.039, CPAN::Meta::Converter version 2.150005", + "generated_by" : "Dist::Zilla version 6.010, CPAN::Meta::Converter version 2.150010", "license" : [ "artistic_2" ], @@ -14,54 +14,74 @@ }, "name" : "DateTime", "prereqs" : { - "build" : { - "requires" : { - "Module::Build" : "0.28" - } - }, "configure" : { "requires" : { - "Module::Build" : "0.28" + "Dist::CheckConflicts" : "0.02", + "ExtUtils::MakeMaker" : "0" + }, + "suggests" : { + "JSON::PP" : "2.27300" } }, "develop" : { "requires" : { - "Code::TidyAll" : "0.24", + "Code::TidyAll" : "0.56", + "Code::TidyAll::Plugin::SortLines::Naturally" : "0.000003", + "Code::TidyAll::Plugin::Test::Vars" : "0.02", + "Cwd" : "0", + "Devel::PPPort" : "3.23", "Module::Implementation" : "0", - "Perl::Critic" : "1.123", - "Perl::Tidy" : "20140711", + "Parallel::ForkManager" : "1.19", + "Perl::Critic" : "1.126", + "Perl::Tidy" : "20160302", "Pod::Coverage::TrustPod" : "0", + "Pod::Wordlist" : "0", + "Storable" : "0", "Test::CPAN::Changes" : "0.19", - "Test::Code::TidyAll" : "0.24", + "Test::CPAN::Meta::JSON" : "0.16", + "Test::CleanNamespaces" : "0.15", + "Test::Code::TidyAll" : "0.50", + "Test::DependentModules" : "0", "Test::EOL" : "0", + "Test::Fatal" : "0", "Test::Mojibake" : "0", - "Test::More" : "0.88", + "Test::More" : "0.96", "Test::NoTabs" : "0", "Test::Pod" : "1.41", "Test::Pod::Coverage" : "1.08", - "Test::Pod::LinkCheck" : "0", + "Test::Portability::Files" : "0", "Test::Spelling" : "0.12", - "Test::Version" : "1", - "autodie" : "0" + "Test::Vars" : "0.009", + "Test::Version" : "2.05", + "Test::Warnings" : "0.005", + "autodie" : "0", + "utf8" : "0" } }, "runtime" : { "requires" : { "Carp" : "0", - "DateTime::Locale" : "0.41", - "DateTime::TimeZone" : "1.74", + "DateTime::Locale" : "1.06", + "DateTime::TimeZone" : "2.02", + "Dist::CheckConflicts" : "0.02", "POSIX" : "0", - "Params::Validate" : "1.03", + "Params::ValidationCompiler" : "0.26", "Scalar::Util" : "0", + "Specio" : "0.18", + "Specio::Declare" : "0", + "Specio::Exporter" : "0", + "Specio::Library::Builtins" : "0", + "Specio::Library::Numeric" : "0", + "Specio::Library::String" : "0", "Try::Tiny" : "0", "XSLoader" : "0", "base" : "0", - "constant" : "0", "integer" : "0", + "namespace::autoclean" : "0.19", "overload" : "0", - "perl" : "5.008001", + "parent" : "0", + "perl" : "5.008004", "strict" : "0", - "vars" : "0", "warnings" : "0", "warnings::register" : "0" } @@ -71,6 +91,8 @@ "CPAN::Meta" : "2.120900" }, "requires" : { + "CPAN::Meta::Check" : "0.011", + "CPAN::Meta::Requirements" : "0", "ExtUtils::MakeMaker" : "0", "File::Spec" : "0", "Storable" : "0", @@ -84,69 +106,91 @@ "provides" : { "DateTime" : { "file" : "lib/DateTime.pm", - "version" : "1.21" + "version" : "1.46" }, "DateTime::Duration" : { "file" : "lib/DateTime/Duration.pm", - "version" : "1.21" + "version" : "1.46" }, "DateTime::Helpers" : { "file" : "lib/DateTime/Helpers.pm", - "version" : "1.21" + "version" : "1.46" }, "DateTime::Infinite" : { "file" : "lib/DateTime/Infinite.pm", - "version" : "1.21" + "version" : "1.46" }, "DateTime::Infinite::Future" : { "file" : "lib/DateTime/Infinite.pm", - "version" : "1.21" + "version" : "1.46" }, "DateTime::Infinite::Past" : { "file" : "lib/DateTime/Infinite.pm", - "version" : "1.21" + "version" : "1.46" }, "DateTime::LeapSecond" : { "file" : "lib/DateTime/LeapSecond.pm", - "version" : "1.21" + "version" : "1.46" }, "DateTime::PP" : { "file" : "lib/DateTime/PP.pm", - "version" : "1.21" + "version" : "1.46" }, "DateTime::PPExtra" : { "file" : "lib/DateTime/PPExtra.pm", - "version" : "1.21" + "version" : "1.46" + }, + "DateTime::Types" : { + "file" : "lib/DateTime/Types.pm", + "version" : "1.46" } }, "release_status" : "stable", "resources" : { "bugtracker" : { - "mailto" : "bug-datetime@rt.cpan.org", - "web" : "http://rt.cpan.org/Public/Dist/Display.html?Name=DateTime" + "web" : "https://github.com/houseabsolute/DateTime.pm/issues" }, "homepage" : "http://metacpan.org/release/DateTime", "repository" : { "type" : "git", - "url" : "git://github.com/autarch/DateTime.pm.git", - "web" : "https://github.com/autarch/DateTime.pm" - } + "url" : "git://github.com/houseabsolute/DateTime.pm.git", + "web" : "https://github.com/houseabsolute/DateTime.pm" + }, + "x_MailingList" : "datetime@perl.org" }, - "version" : "1.21", + "version" : "1.46", "x_Dist_Zilla" : { "perl" : { - "version" : "5.022000" + "version" : "5.026001" }, "plugins" : [ { - "class" : "Dist::Zilla::Plugin::GatherDir", + "class" : "Dist::Zilla::Plugin::PruneCruft", + "name" : "PruneCruft", + "version" : "6.010" + }, + { + "class" : "Dist::Zilla::Plugin::MakeMaker", + "config" : { + "Dist::Zilla::Role::TestRunner" : { + "default_jobs" : 1 + } + }, + "name" : "@DROLSKY/MakeMaker", + "version" : "6.010" + }, + { + "class" : "Dist::Zilla::Plugin::Git::GatherDir", "config" : { "Dist::Zilla::Plugin::GatherDir" : { "exclude_filename" : [ - "Build.PL", + "CONTRIBUTING.md", "LICENSE", + "Makefile.PL", "README.md", - "cpanfile" + "cpanfile", + "leap_seconds.h", + "ppport.h" ], "exclude_match" : [], "follow_symlinks" : 0, @@ -154,15 +198,63 @@ "prefix" : "", "prune_directory" : [], "root" : "." + }, + "Dist::Zilla::Plugin::Git::GatherDir" : { + "include_untracked" : 0 } }, - "name" : "GatherDir", - "version" : "5.039" + "name" : "@DROLSKY/Git::GatherDir", + "version" : "2.043" }, { - "class" : "Dist::Zilla::Plugin::PruneCruft", - "name" : "PruneCruft", - "version" : "5.039" + "class" : "Dist::Zilla::Plugin::ManifestSkip", + "name" : "@DROLSKY/ManifestSkip", + "version" : "6.010" + }, + { + "class" : "Dist::Zilla::Plugin::License", + "name" : "@DROLSKY/License", + "version" : "6.010" + }, + { + "class" : "Dist::Zilla::Plugin::ExecDir", + "name" : "@DROLSKY/ExecDir", + "version" : "6.010" + }, + { + "class" : "Dist::Zilla::Plugin::ShareDir", + "name" : "@DROLSKY/ShareDir", + "version" : "6.010" + }, + { + "class" : "Dist::Zilla::Plugin::Manifest", + "name" : "@DROLSKY/Manifest", + "version" : "6.010" + }, + { + "class" : "Dist::Zilla::Plugin::CheckVersionIncrement", + "name" : "@DROLSKY/CheckVersionIncrement", + "version" : "0.121750" + }, + { + "class" : "Dist::Zilla::Plugin::TestRelease", + "name" : "@DROLSKY/TestRelease", + "version" : "6.010" + }, + { + "class" : "Dist::Zilla::Plugin::ConfirmRelease", + "name" : "@DROLSKY/ConfirmRelease", + "version" : "6.010" + }, + { + "class" : "Dist::Zilla::Plugin::UploadToCPAN", + "name" : "@DROLSKY/UploadToCPAN", + "version" : "6.010" + }, + { + "class" : "Dist::Zilla::Plugin::VersionFromMainModule", + "name" : "@DROLSKY/VersionFromMainModule", + "version" : "0.03" }, { "class" : "Dist::Zilla::Plugin::Authority", @@ -172,17 +264,17 @@ { "class" : "Dist::Zilla::Plugin::AutoPrereqs", "name" : "@DROLSKY/AutoPrereqs", - "version" : "5.039" + "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::CopyFilesFromBuild", "name" : "@DROLSKY/CopyFilesFromBuild", - "version" : "0.151680" + "version" : "0.170880" }, { "class" : "Dist::Zilla::Plugin::GitHub::Meta", "name" : "@DROLSKY/GitHub::Meta", - "version" : "0.41" + "version" : "0.44" }, { "class" : "Dist::Zilla::Plugin::GitHub::Update", @@ -192,12 +284,12 @@ } }, "name" : "@DROLSKY/GitHub::Update", - "version" : "0.41" + "version" : "0.44" }, { "class" : "Dist::Zilla::Plugin::MetaResources", "name" : "@DROLSKY/MetaResources", - "version" : "5.039" + "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::MetaProvides::Package", @@ -207,23 +299,49 @@ { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : "@DROLSKY/MetaProvides::Package/AUTOVIV/:InstallModulesPM", - "version" : "5.039" + "version" : "6.010" } - ] + ], + "include_underscores" : 0 }, "Dist::Zilla::Role::MetaProvider::Provider" : { - "inherit_missing" : "1", - "inherit_version" : "1", - "meta_noindex" : "1" + "$Dist::Zilla::Role::MetaProvider::Provider::VERSION" : "2.002004", + "inherit_missing" : 1, + "inherit_version" : 1, + "meta_noindex" : 1 + }, + "Dist::Zilla::Role::ModuleMetadata" : { + "Module::Metadata" : "1.000033", + "version" : "0.004" } }, "name" : "@DROLSKY/MetaProvides::Package", - "version" : "2.003001" + "version" : "2.004003" + }, + { + "class" : "Dist::Zilla::Plugin::Meta::Contributors", + "name" : "@DROLSKY/Meta::Contributors", + "version" : "0.003" + }, + { + "class" : "Dist::Zilla::Plugin::MetaConfig", + "name" : "@DROLSKY/MetaConfig", + "version" : "6.010" + }, + { + "class" : "Dist::Zilla::Plugin::MetaJSON", + "name" : "@DROLSKY/MetaJSON", + "version" : "6.010" + }, + { + "class" : "Dist::Zilla::Plugin::MetaYAML", + "name" : "@DROLSKY/MetaYAML", + "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::NextRelease", "name" : "@DROLSKY/NextRelease", - "version" : "5.039" + "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::Prereqs", @@ -233,8 +351,8 @@ "type" : "requires" } }, - "name" : "@DROLSKY/Test::More with subtest()", - "version" : "5.039" + "name" : "@DROLSKY/Test::More with subtest", + "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::Prereqs", @@ -245,7 +363,35 @@ } }, "name" : "@DROLSKY/Modules for use with tidyall", - "version" : "5.039" + "version" : "6.010" + }, + { + "class" : "Dist::Zilla::Plugin::Prereqs", + "config" : { + "Dist::Zilla::Plugin::Prereqs" : { + "phase" : "develop", + "type" : "requires" + } + }, + "name" : "@DROLSKY/Test::Version which fixes https://github.com/plicease/Test-Version/issues/7", + "version" : "6.010" + }, + { + "class" : "Dist::Zilla::Plugin::PromptIfStale", + "config" : { + "Dist::Zilla::Plugin::PromptIfStale" : { + "check_all_plugins" : 0, + "check_all_prereqs" : 0, + "modules" : [ + "Dist::Zilla::PluginBundle::DROLSKY" + ], + "phase" : "build", + "run_under_travis" : 0, + "skip" : [] + } + }, + "name" : "@DROLSKY/Dist::Zilla::PluginBundle::DROLSKY", + "version" : "0.054" }, { "class" : "Dist::Zilla::Plugin::PromptIfStale", @@ -255,201 +401,264 @@ "check_all_prereqs" : 1, "modules" : [], "phase" : "release", + "run_under_travis" : 0, "skip" : [ "Dist::Zilla::Plugin::DROLSKY::Contributors", + "Dist::Zilla::Plugin::DROLSKY::Git::CheckFor::CorrectBranch", "Dist::Zilla::Plugin::DROLSKY::License", "Dist::Zilla::Plugin::DROLSKY::TidyAll", - "Dist::Zilla::Plugin::DROLSKY::VersionProvider" + "Dist::Zilla::Plugin::DROLSKY::WeaverConfig", + "Pod::Weaver::PluginBundle::DROLSKY" ] } }, "name" : "@DROLSKY/PromptIfStale", - "version" : "0.047" - }, - { - "class" : "Dist::Zilla::Plugin::ReadmeAnyFromPod", - "config" : { - "Dist::Zilla::Role::FileWatcher" : { - "version" : "0.006" - } - }, - "name" : "@DROLSKY/README.md in build", - "version" : "0.150250" - }, - { - "class" : "Dist::Zilla::Plugin::ReadmeAnyFromPod", - "config" : { - "Dist::Zilla::Role::FileWatcher" : { - "version" : "0.006" - } - }, - "name" : "@DROLSKY/README.md in root", - "version" : "0.150250" + "version" : "0.054" }, { "class" : "Dist::Zilla::Plugin::Test::Pod::Coverage::Configurable", "name" : "@DROLSKY/Test::Pod::Coverage::Configurable", - "version" : "0.05" + "version" : "0.07" }, { "class" : "Dist::Zilla::Plugin::Test::PodSpelling", + "config" : { + "Dist::Zilla::Plugin::Test::PodSpelling" : { + "directories" : [ + "bin", + "lib" + ], + "spell_cmd" : "", + "stopwords" : [ + "Anno", + "BCE", + "CLDR", + "CPAN", + "DATETIME", + "DROLSKY", + "DROLSKY's", + "DateTime", + "DateTimes", + "Datetime", + "Datetimes", + "Domini", + "EEEE", + "EEEEE", + "Fl\u00e1vio", + "Formatters", + "GGGG", + "GGGGG", + "Glock", + "Hant", + "IEEE", + "IEEE", + "LLL", + "LLLL", + "LLLLL", + "Liang", + "Liang's", + "MMM", + "MMMM", + "MMMMM", + "Measham", + "Measham's", + "POSIX", + "PayPal", + "PayPal", + "QQQ", + "QQQQ", + "Rata", + "Rata", + "Rolsky", + "Rolsky's", + "SU", + "Soibelmann", + "Storable", + "TW", + "TZ", + "Tsai", + "UTC", + "VVVV", + "YAPCs", + "ZZZZ", + "ZZZZZ", + "afterwards", + "bian", + "ccc", + "cccc", + "ccccc", + "conformant", + "datetime", + "datetime's", + "datetimes", + "decrement", + "dian", + "drolsky", + "durations", + "eee", + "eeee", + "eeeee", + "fallback", + "formatter", + "hh", + "iCal", + "ji", + "mutiplication", + "na", + "namespace", + "ni", + "nitty", + "other's", + "proleptic", + "qqq", + "qqqq", + "sexagesimal", + "subclasses", + "uu", + "vvvv", + "wiki", + "yy", + "yyyy", + "yyyyy", + "zh", + "zzzz" + ], + "wordlist" : "Pod::Wordlist" + } + }, "name" : "@DROLSKY/Test::PodSpelling", - "version" : "2.006009" - }, - { - "class" : "Dist::Zilla::Plugin::Test::ReportPrereqs", - "name" : "@DROLSKY/Test::ReportPrereqs", - "version" : "0.021" + "version" : "2.007005" }, { - "class" : "Dist::Zilla::Plugin::Test::Version", - "name" : "@DROLSKY/Test::Version", - "version" : "1.05" - }, - { - "class" : "Dist::Zilla::Plugin::ManifestSkip", - "name" : "@DROLSKY/ManifestSkip", - "version" : "5.039" - }, - { - "class" : "Dist::Zilla::Plugin::MetaYAML", - "name" : "@DROLSKY/MetaYAML", - "version" : "5.039" + "class" : "Dist::Zilla::Plugin::PodSyntaxTests", + "name" : "@DROLSKY/PodSyntaxTests", + "version" : "6.010" }, { - "class" : "Dist::Zilla::Plugin::License", - "name" : "@DROLSKY/License", - "version" : "5.039" + "class" : "Dist::Zilla::Plugin::RunExtraTests", + "config" : { + "Dist::Zilla::Role::TestRunner" : { + "default_jobs" : 1 + } + }, + "name" : "@DROLSKY/RunExtraTests", + "version" : "0.029" }, { - "class" : "Dist::Zilla::Plugin::ExtraTests", - "name" : "@DROLSKY/ExtraTests", - "version" : "5.039" + "class" : "Dist::Zilla::Plugin::MojibakeTests", + "name" : "@DROLSKY/MojibakeTests", + "version" : "0.8" }, { - "class" : "Dist::Zilla::Plugin::ExecDir", - "name" : "@DROLSKY/ExecDir", - "version" : "5.039" + "class" : "Dist::Zilla::Plugin::Test::CleanNamespaces", + "config" : { + "Dist::Zilla::Plugin::Test::CleanNamespaces" : { + "filename" : "xt/author/clean-namespaces.t", + "skips" : [ + "DateTime::Conflicts" + ] + } + }, + "name" : "@DROLSKY/Test::CleanNamespaces", + "version" : "0.006" }, { - "class" : "Dist::Zilla::Plugin::ShareDir", - "name" : "@DROLSKY/ShareDir", - "version" : "5.039" + "class" : "Dist::Zilla::Plugin::Test::CPAN::Changes", + "config" : { + "Dist::Zilla::Plugin::Test::CPAN::Changes" : { + "changelog" : "Changes" + } + }, + "name" : "@DROLSKY/Test::CPAN::Changes", + "version" : "0.012" }, { - "class" : "Dist::Zilla::Plugin::Manifest", - "name" : "@DROLSKY/Manifest", - "version" : "5.039" + "class" : "Dist::Zilla::Plugin::Test::CPAN::Meta::JSON", + "name" : "@DROLSKY/Test::CPAN::Meta::JSON", + "version" : "0.004" }, { - "class" : "Dist::Zilla::Plugin::CheckVersionIncrement", - "name" : "@DROLSKY/CheckVersionIncrement", - "version" : "0.121750" + "class" : "Dist::Zilla::Plugin::Test::EOL", + "config" : { + "Dist::Zilla::Plugin::Test::EOL" : { + "filename" : "xt/author/eol.t", + "finder" : [ + ":ExecFiles", + ":InstallModules", + ":TestFiles" + ], + "trailing_whitespace" : 1 + } + }, + "name" : "@DROLSKY/Test::EOL", + "version" : "0.19" }, { - "class" : "Dist::Zilla::Plugin::TestRelease", - "name" : "@DROLSKY/TestRelease", - "version" : "5.039" + "class" : "Dist::Zilla::Plugin::Test::NoTabs", + "config" : { + "Dist::Zilla::Plugin::Test::NoTabs" : { + "filename" : "xt/author/no-tabs.t", + "finder" : [ + ":InstallModules", + ":ExecFiles", + ":TestFiles" + ] + } + }, + "name" : "@DROLSKY/Test::NoTabs", + "version" : "0.15" }, { - "class" : "Dist::Zilla::Plugin::ConfirmRelease", - "name" : "@DROLSKY/ConfirmRelease", - "version" : "5.039" + "class" : "Dist::Zilla::Plugin::Test::Portability", + "config" : { + "Dist::Zilla::Plugin::Test::Portability" : { + "options" : "" + } + }, + "name" : "@DROLSKY/Test::Portability", + "version" : "2.001000" }, { - "class" : "Dist::Zilla::Plugin::UploadToCPAN", - "name" : "@DROLSKY/UploadToCPAN", - "version" : "5.039" + "class" : "Dist::Zilla::Plugin::Test::TidyAll", + "name" : "@DROLSKY/Test::TidyAll", + "version" : "0.04" }, { - "class" : "Dist::Zilla::Plugin::CheckPrereqsIndexed", - "name" : "@DROLSKY/CheckPrereqsIndexed", - "version" : "0.016" + "class" : "Dist::Zilla::Plugin::Test::ReportPrereqs", + "name" : "@DROLSKY/Test::ReportPrereqs", + "version" : "0.027" }, { - "class" : "Dist::Zilla::Plugin::CPANFile", - "name" : "@DROLSKY/CPANFile", - "version" : "5.039" + "class" : "Dist::Zilla::Plugin::Test::Version", + "name" : "@DROLSKY/Test::Version", + "version" : "1.09" }, { "class" : "Dist::Zilla::Plugin::DROLSKY::Contributors", "name" : "@DROLSKY/DROLSKY::Contributors", - "version" : "0.38" - }, - { - "class" : "Dist::Zilla::Plugin::DROLSKY::License", - "name" : "@DROLSKY/DROLSKY::License", - "version" : "0.38" - }, - { - "class" : "Dist::Zilla::Plugin::DROLSKY::TidyAll", - "name" : "@DROLSKY/DROLSKY::TidyAll", - "version" : "0.38" - }, - { - "class" : "Dist::Zilla::Plugin::DROLSKY::VersionProvider", - "name" : "@DROLSKY/DROLSKY::VersionProvider", - "version" : "0.38" - }, - { - "class" : "Dist::Zilla::Plugin::Git::CheckFor::CorrectBranch", - "config" : { - "Dist::Zilla::Role::Git::Repo" : { - "repo_root" : "." - } - }, - "name" : "@DROLSKY/Git::CheckFor::CorrectBranch", - "version" : "0.013" - }, - { - "class" : "Dist::Zilla::Plugin::Git::CheckFor::MergeConflicts", - "config" : { - "Dist::Zilla::Role::Git::Repo" : { - "repo_root" : "." - } - }, - "name" : "@DROLSKY/Git::CheckFor::MergeConflicts", - "version" : "0.013" + "version" : "0.89" }, { "class" : "Dist::Zilla::Plugin::Git::Contributors", "config" : { "Dist::Zilla::Plugin::Git::Contributors" : { + "git_version" : "2.16.1", "include_authors" : 0, "include_releaser" : 1, "order_by" : "name", - "paths" : [ - "." - ] + "paths" : [] } }, "name" : "@DROLSKY/Git::Contributors", - "version" : "0.014" - }, - { - "class" : "Dist::Zilla::Plugin::InstallGuide", - "name" : "@DROLSKY/InstallGuide", - "version" : "1.200006" - }, - { - "class" : "Dist::Zilla::Plugin::Meta::Contributors", - "name" : "@DROLSKY/Meta::Contributors", - "version" : "0.002" - }, - { - "class" : "Dist::Zilla::Plugin::MetaConfig", - "name" : "@DROLSKY/MetaConfig", - "version" : "5.039" - }, - { - "class" : "Dist::Zilla::Plugin::MetaJSON", - "name" : "@DROLSKY/MetaJSON", - "version" : "5.039" + "version" : "0.032" }, { "class" : "Dist::Zilla::Plugin::SurgicalPodWeaver", "config" : { "Dist::Zilla::Plugin::PodWeaver" : { + "config_plugins" : [ + "@DROLSKY" + ], "finder" : [ ":InstallModules", ":ExecFiles" @@ -458,62 +667,132 @@ { "class" : "Pod::Weaver::Plugin::EnsurePod5", "name" : "@CorePrep/EnsurePod5", - "version" : "4.012" + "version" : "4.015" }, { "class" : "Pod::Weaver::Plugin::H1Nester", "name" : "@CorePrep/H1Nester", - "version" : "4.012" + "version" : "4.015" + }, + { + "class" : "Pod::Weaver::Plugin::SingleEncoding", + "name" : "@DROLSKY/SingleEncoding", + "version" : "4.015" + }, + { + "class" : "Pod::Weaver::Plugin::Transformer", + "name" : "@DROLSKY/List", + "version" : "4.015" + }, + { + "class" : "Pod::Weaver::Plugin::Transformer", + "name" : "@DROLSKY/Verbatim", + "version" : "4.015" + }, + { + "class" : "Pod::Weaver::Section::Region", + "name" : "@DROLSKY/header", + "version" : "4.015" }, { "class" : "Pod::Weaver::Section::Name", - "name" : "Name", - "version" : "4.012" + "name" : "@DROLSKY/Name", + "version" : "4.015" }, { "class" : "Pod::Weaver::Section::Version", - "name" : "Version", - "version" : "4.012" + "name" : "@DROLSKY/Version", + "version" : "4.015" }, { "class" : "Pod::Weaver::Section::Region", - "name" : "prelude", - "version" : "4.012" + "name" : "@DROLSKY/prelude", + "version" : "4.015" }, { "class" : "Pod::Weaver::Section::Generic", "name" : "SYNOPSIS", - "version" : "4.012" + "version" : "4.015" }, { "class" : "Pod::Weaver::Section::Generic", "name" : "DESCRIPTION", - "version" : "4.012" + "version" : "4.015" + }, + { + "class" : "Pod::Weaver::Section::Generic", + "name" : "OVERVIEW", + "version" : "4.015" + }, + { + "class" : "Pod::Weaver::Section::Collect", + "name" : "ATTRIBUTES", + "version" : "4.015" + }, + { + "class" : "Pod::Weaver::Section::Collect", + "name" : "METHODS", + "version" : "4.015" + }, + { + "class" : "Pod::Weaver::Section::Collect", + "name" : "FUNCTIONS", + "version" : "4.015" + }, + { + "class" : "Pod::Weaver::Section::Collect", + "name" : "TYPES", + "version" : "4.015" }, { "class" : "Pod::Weaver::Section::Leftovers", - "name" : "Leftovers", - "version" : "4.012" + "name" : "@DROLSKY/Leftovers", + "version" : "4.015" }, { "class" : "Pod::Weaver::Section::Region", - "name" : "postlude", - "version" : "4.012" + "name" : "@DROLSKY/postlude", + "version" : "4.015" + }, + { + "class" : "Pod::Weaver::Section::GenerateSection", + "name" : "@DROLSKY/generate SUPPORT", + "version" : "1.06" + }, + { + "class" : "Pod::Weaver::Section::AllowOverride", + "name" : "@DROLSKY/allow override SUPPORT", + "version" : "0.05" + }, + { + "class" : "Pod::Weaver::Section::GenerateSection", + "name" : "@DROLSKY/generate SOURCE", + "version" : "1.06" + }, + { + "class" : "Pod::Weaver::Section::GenerateSection", + "name" : "@DROLSKY/generate DONATIONS", + "version" : "1.06" }, { "class" : "Pod::Weaver::Section::Authors", - "name" : "Authors", - "version" : "4.012" + "name" : "@DROLSKY/Authors", + "version" : "4.015" }, { "class" : "Pod::Weaver::Section::Contributors", - "name" : "Contributors", + "name" : "@DROLSKY/Contributors", "version" : "0.009" }, { "class" : "Pod::Weaver::Section::Legal", - "name" : "Legal", - "version" : "4.012" + "name" : "@DROLSKY/Legal", + "version" : "4.015" + }, + { + "class" : "Pod::Weaver::Section::Region", + "name" : "@DROLSKY/footer", + "version" : "4.015" } ] } @@ -522,60 +801,117 @@ "version" : "0.0023" }, { - "class" : "Dist::Zilla::Plugin::MojibakeTests", - "name" : "@DROLSKY/MojibakeTests", - "version" : "0.8" + "class" : "Dist::Zilla::Plugin::DROLSKY::WeaverConfig", + "name" : "@DROLSKY/DROLSKY::WeaverConfig", + "version" : "0.89" }, { - "class" : "Dist::Zilla::Plugin::PodSyntaxTests", - "name" : "@DROLSKY/PodSyntaxTests", - "version" : "5.039" + "class" : "Dist::Zilla::Plugin::ReadmeAnyFromPod", + "config" : { + "Dist::Zilla::Role::FileWatcher" : { + "version" : "0.006" + } + }, + "name" : "@DROLSKY/README.md in build", + "version" : "0.163250" }, { - "class" : "Dist::Zilla::Plugin::Test::CPAN::Changes", - "name" : "@DROLSKY/Test::CPAN::Changes", - "version" : "0.009" + "class" : "Dist::Zilla::Plugin::GenerateFile::FromShareDir", + "config" : { + "Dist::Zilla::Plugin::GenerateFile::FromShareDir" : { + "destination_filename" : "CONTRIBUTING.md", + "dist" : "Dist-Zilla-PluginBundle-DROLSKY", + "encoding" : "UTF-8", + "has_xs" : 1, + "location" : "build", + "source_filename" : "CONTRIBUTING.md" + }, + "Dist::Zilla::Role::RepoFileInjector" : { + "allow_overwrite" : 1, + "repo_root" : ".", + "version" : "0.007" + } + }, + "name" : "@DROLSKY/Generate CONTRIBUTING.md", + "version" : "0.013" }, { - "class" : "Dist::Zilla::Plugin::Test::EOL", + "class" : "Dist::Zilla::Plugin::InstallGuide", + "name" : "@DROLSKY/InstallGuide", + "version" : "1.200007" + }, + { + "class" : "Dist::Zilla::Plugin::CPANFile", + "name" : "@DROLSKY/CPANFile", + "version" : "6.010" + }, + { + "class" : "Dist::Zilla::Plugin::PPPort", + "name" : "@DROLSKY/PPPort", + "version" : "0.008" + }, + { + "class" : "Dist::Zilla::Plugin::DROLSKY::License", + "name" : "@DROLSKY/DROLSKY::License", + "version" : "0.89" + }, + { + "class" : "Dist::Zilla::Plugin::CheckStrictVersion", + "name" : "@DROLSKY/CheckStrictVersion", + "version" : "0.001" + }, + { + "class" : "Dist::Zilla::Plugin::CheckSelfDependency", "config" : { - "Dist::Zilla::Plugin::Test::EOL" : { - "filename" : "xt/author/eol.t", + "Dist::Zilla::Plugin::CheckSelfDependency" : { "finder" : [ - ":InstallModules", - ":ExecFiles", - ":TestFiles" - ], - "trailing_whitespace" : "1" + ":InstallModules" + ] + }, + "Dist::Zilla::Role::ModuleMetadata" : { + "Module::Metadata" : "1.000033", + "version" : "0.004" } }, - "name" : "@DROLSKY/Test::EOL", - "version" : "0.18" + "name" : "@DROLSKY/CheckSelfDependency", + "version" : "0.011" }, { - "class" : "Dist::Zilla::Plugin::Test::NoTabs", + "class" : "Dist::Zilla::Plugin::CheckPrereqsIndexed", + "name" : "@DROLSKY/CheckPrereqsIndexed", + "version" : "0.020" + }, + { + "class" : "Dist::Zilla::Plugin::DROLSKY::Git::CheckFor::CorrectBranch", "config" : { - "Dist::Zilla::Plugin::Test::NoTabs" : { - "filename" : "xt/author/no-tabs.t", - "finder" : [ - ":InstallModules", - ":ExecFiles", - ":TestFiles" - ] + "Dist::Zilla::Role::Git::Repo" : { + "git_version" : "2.16.1", + "repo_root" : "." } }, - "name" : "@DROLSKY/Test::NoTabs", - "version" : "0.15" + "name" : "@DROLSKY/DROLSKY::Git::CheckFor::CorrectBranch", + "version" : "0.89" }, { - "class" : "Dist::Zilla::Plugin::Test::Portability", - "name" : "@DROLSKY/Test::Portability", - "version" : "2.000006" + "class" : "Dist::Zilla::Plugin::EnsureChangesHasContent", + "name" : "@DROLSKY/EnsureChangesHasContent", + "version" : "0.02" }, { - "class" : "Dist::Zilla::Plugin::Test::TidyAll", - "name" : "@DROLSKY/Test::TidyAll", - "version" : "0.01" + "class" : "Dist::Zilla::Plugin::Git::CheckFor::MergeConflicts", + "config" : { + "Dist::Zilla::Role::Git::Repo" : { + "git_version" : "2.16.1", + "repo_root" : "." + } + }, + "name" : "@DROLSKY/Git::CheckFor::MergeConflicts", + "version" : "0.014" + }, + { + "class" : "Dist::Zilla::Plugin::DROLSKY::TidyAll", + "name" : "@DROLSKY/DROLSKY::TidyAll", + "version" : "0.89" }, { "class" : "Dist::Zilla::Plugin::Git::Check", @@ -585,23 +921,26 @@ }, "Dist::Zilla::Role::Git::DirtyFiles" : { "allow_dirty" : [ - "Build.PL", "CONTRIBUTING.md", "Changes", "LICENSE", "Makefile.PL", "README.md", - "cpanfile" + "cpanfile", + "leap_seconds.h", + "ppport.h", + "tidyall.ini" ], "allow_dirty_match" : [], "changelog" : "Changes" }, "Dist::Zilla::Role::Git::Repo" : { + "git_version" : "2.16.1", "repo_root" : "." } }, "name" : "@DROLSKY/Git::Check", - "version" : "2.036" + "version" : "2.043" }, { "class" : "Dist::Zilla::Plugin::Git::Commit", @@ -612,26 +951,29 @@ }, "Dist::Zilla::Role::Git::DirtyFiles" : { "allow_dirty" : [ - "Build.PL", "CONTRIBUTING.md", "Changes", "LICENSE", "Makefile.PL", "README.md", - "cpanfile" + "cpanfile", + "leap_seconds.h", + "ppport.h", + "tidyall.ini" ], "allow_dirty_match" : [], "changelog" : "Changes" }, "Dist::Zilla::Role::Git::Repo" : { + "git_version" : "2.16.1", "repo_root" : "." }, "Dist::Zilla::Role::Git::StringFormatter" : { "time_zone" : "local" } }, - "name" : "@DROLSKY/commit generated files", - "version" : "2.036" + "name" : "@DROLSKY/Commit generated files", + "version" : "2.043" }, { "class" : "Dist::Zilla::Plugin::Git::Tag", @@ -640,11 +982,12 @@ "branch" : null, "changelog" : "Changes", "signed" : 0, - "tag" : "v1.21", + "tag" : "v1.46", "tag_format" : "v%v", "tag_message" : "v%v" }, "Dist::Zilla::Role::Git::Repo" : { + "git_version" : "2.16.1", "repo_root" : "." }, "Dist::Zilla::Role::Git::StringFormatter" : { @@ -652,7 +995,7 @@ } }, "name" : "@DROLSKY/Git::Tag", - "version" : "2.036" + "version" : "2.043" }, { "class" : "Dist::Zilla::Plugin::Git::Push", @@ -664,11 +1007,12 @@ "remotes_must_exist" : 1 }, "Dist::Zilla::Role::Git::Repo" : { + "git_version" : "2.16.1", "repo_root" : "." } }, "name" : "@DROLSKY/Git::Push", - "version" : "2.036" + "version" : "2.043" }, { "class" : "Dist::Zilla::Plugin::BumpVersionAfterRelease", @@ -683,7 +1027,7 @@ } }, "name" : "@DROLSKY/BumpVersionAfterRelease", - "version" : "0.012" + "version" : "0.017" }, { "class" : "Dist::Zilla::Plugin::Git::Commit", @@ -703,14 +1047,15 @@ "changelog" : "Changes" }, "Dist::Zilla::Role::Git::Repo" : { + "git_version" : "2.16.1", "repo_root" : "." }, "Dist::Zilla::Role::Git::StringFormatter" : { "time_zone" : "local" } }, - "name" : "@DROLSKY/commit version bump", - "version" : "2.036" + "name" : "@DROLSKY/Commit version bump", + "version" : "2.043" }, { "class" : "Dist::Zilla::Plugin::Git::Push", @@ -722,16 +1067,39 @@ "remotes_must_exist" : 1 }, "Dist::Zilla::Role::Git::Repo" : { + "git_version" : "2.16.1", "repo_root" : "." } }, - "name" : "@DROLSKY/push version bump", - "version" : "2.036" + "name" : "@DROLSKY/Push version bump", + "version" : "2.043" + }, + { + "class" : "Dist::Zilla::Plugin::lib", + "config" : { + "Dist::Zilla::Plugin::lib" : { + "lib" : [ + "inc" + ] + } + }, + "name" : "lib", + "version" : "0.001002" }, { - "class" : "Dist::Zilla::Plugin::Test::Pod::LinkCheck", - "name" : "@DROLSKY/Test::Pod::LinkCheck", - "version" : "1.002" + "class" : "LeapSecondsHeader", + "name" : "=LeapSecondsHeader", + "version" : null + }, + { + "class" : "Dist::Zilla::Plugin::CopyFilesFromBuild", + "name" : "CopyFilesFromBuild", + "version" : "0.170880" + }, + { + "class" : "Dist::Zilla::Plugin::MetaResources", + "name" : "MetaResources", + "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::Prereqs", @@ -742,103 +1110,133 @@ } }, "name" : "DevelopRequires", - "version" : "5.039" + "version" : "6.010" + }, + { + "class" : "Dist::Zilla::Plugin::PurePerlTests", + "name" : "PurePerlTests", + "version" : "0.06" }, { - "class" : "inc::MyModuleBuild", + "class" : "Dist::Zilla::Plugin::Conflicts", + "name" : "Conflicts", + "version" : "0.19" + }, + { + "class" : "Dist::Zilla::Plugin::Test::CheckBreaks", "config" : { - "Dist::Zilla::Role::TestRunner" : { - "default_jobs" : 1 + "Dist::Zilla::Plugin::Test::CheckBreaks" : { + "conflicts_module" : [ + "DateTime::Conflicts" + ], + "no_forced_deps" : 0 + }, + "Dist::Zilla::Role::ModuleMetadata" : { + "Module::Metadata" : "1.000033", + "version" : "0.004" } }, - "name" : "=inc::MyModuleBuild", - "version" : null - }, - { - "class" : "Dist::Zilla::Plugin::PurePerlTests", - "name" : "PurePerlTests", - "version" : "0.05" + "name" : "Test::CheckBreaks", + "version" : "0.019" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":InstallModules", - "version" : "5.039" + "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":IncModules", - "version" : "5.039" + "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":TestFiles", - "version" : "5.039" + "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":ExtraTestFiles", - "version" : "5.039" + "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":ExecFiles", - "version" : "5.039" + "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":PerlExecFiles", - "version" : "5.039" + "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":ShareFiles", - "version" : "5.039" + "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":MainModule", - "version" : "5.039" + "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":AllFiles", - "version" : "5.039" + "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : ":NoFiles", - "version" : "5.039" + "version" : "6.010" }, { "class" : "Dist::Zilla::Plugin::FinderCode", "name" : "@DROLSKY/MetaProvides::Package/AUTOVIV/:InstallModulesPM", - "version" : "5.039" + "version" : "6.010" } ], "zilla" : { "class" : "Dist::Zilla::Dist::Builder", "config" : { - "is_trial" : "0" + "is_trial" : 0 }, - "version" : "5.039" + "version" : "6.010" } }, "x_authority" : "cpan:DROLSKY", + "x_breaks" : { + "DateTime::Format::Mail" : "<= 0.402" + }, "x_contributors" : [ "Ben Bennett ", "Christian Hansen ", "Daisuke Maki ", + "Dan Book ", + "Dan Stewart ", "David E. Wheeler ", + "David Precious ", "Doug Bell ", - "Flávio Soibelmann Glock ", + "Fl\u00e1vio Soibelmann Glock ", + "Gianni Ceccarelli ", "Gregory Oschwald ", + "Hauke D ", "Iain Truskett ", "Jason McIntosh ", "Joshua Hoblitt ", + "Karen Etheridge ", + "Michael Conrad ", + "Michael R. Davis ", + "M Somerville ", "Nick Tonkin <1nickt@users.noreply.github.com>", + "Olaf Alders ", + "Ovid ", + "Philippe Bruhat (BooK) ", "Ricardo Signes ", "Richard Bowen ", - "Ron Hill " - ] + "Ron Hill ", + "Sam Kington ", + "viviparous " + ], + "x_serialization_backend" : "Cpanel::JSON::XS version 3.0239" } diff -Nru libdatetime-perl-1.21/META.yml libdatetime-perl-1.46/META.yml --- libdatetime-perl-1.21/META.yml 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/META.yml 2018-02-11 23:36:51.000000000 +0000 @@ -3,18 +3,20 @@ author: - 'Dave Rolsky ' build_requires: + CPAN::Meta::Check: '0.011' + CPAN::Meta::Requirements: '0' ExtUtils::MakeMaker: '0' File::Spec: '0' - Module::Build: '0.28' Storable: '0' Test::Fatal: '0' Test::More: '0.96' Test::Warnings: '0.005' utf8: '0' configure_requires: - Module::Build: '0.28' + Dist::CheckConflicts: '0.02' + ExtUtils::MakeMaker: '0' dynamic_config: 0 -generated_by: 'Dist::Zilla version 5.039, CPAN::Meta::Converter version 2.150005' +generated_by: 'Dist::Zilla version 6.010, CPAN::Meta::Converter version 2.150010' license: artistic_2 meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html @@ -23,79 +25,142 @@ provides: DateTime: file: lib/DateTime.pm - version: '1.21' + version: '1.46' DateTime::Duration: file: lib/DateTime/Duration.pm - version: '1.21' + version: '1.46' DateTime::Helpers: file: lib/DateTime/Helpers.pm - version: '1.21' + version: '1.46' DateTime::Infinite: file: lib/DateTime/Infinite.pm - version: '1.21' + version: '1.46' DateTime::Infinite::Future: file: lib/DateTime/Infinite.pm - version: '1.21' + version: '1.46' DateTime::Infinite::Past: file: lib/DateTime/Infinite.pm - version: '1.21' + version: '1.46' DateTime::LeapSecond: file: lib/DateTime/LeapSecond.pm - version: '1.21' + version: '1.46' DateTime::PP: file: lib/DateTime/PP.pm - version: '1.21' + version: '1.46' DateTime::PPExtra: file: lib/DateTime/PPExtra.pm - version: '1.21' + version: '1.46' + DateTime::Types: + file: lib/DateTime/Types.pm + version: '1.46' requires: Carp: '0' - DateTime::Locale: '0.41' - DateTime::TimeZone: '1.74' + DateTime::Locale: '1.06' + DateTime::TimeZone: '2.02' + Dist::CheckConflicts: '0.02' POSIX: '0' - Params::Validate: '1.03' + Params::ValidationCompiler: '0.26' Scalar::Util: '0' + Specio: '0.18' + Specio::Declare: '0' + Specio::Exporter: '0' + Specio::Library::Builtins: '0' + Specio::Library::Numeric: '0' + Specio::Library::String: '0' Try::Tiny: '0' XSLoader: '0' base: '0' - constant: '0' integer: '0' + namespace::autoclean: '0.19' overload: '0' - perl: '5.008001' + parent: '0' + perl: '5.008004' strict: '0' - vars: '0' warnings: '0' warnings::register: '0' resources: - bugtracker: http://rt.cpan.org/Public/Dist/Display.html?Name=DateTime + MailingList: datetime@perl.org + bugtracker: https://github.com/houseabsolute/DateTime.pm/issues homepage: http://metacpan.org/release/DateTime - repository: git://github.com/autarch/DateTime.pm.git -version: '1.21' + repository: git://github.com/houseabsolute/DateTime.pm.git +version: '1.46' x_Dist_Zilla: perl: - version: '5.022000' + version: '5.026001' plugins: - - class: Dist::Zilla::Plugin::GatherDir + class: Dist::Zilla::Plugin::PruneCruft + name: PruneCruft + version: '6.010' + - + class: Dist::Zilla::Plugin::MakeMaker + config: + Dist::Zilla::Role::TestRunner: + default_jobs: 1 + name: '@DROLSKY/MakeMaker' + version: '6.010' + - + class: Dist::Zilla::Plugin::Git::GatherDir config: Dist::Zilla::Plugin::GatherDir: exclude_filename: - - Build.PL + - CONTRIBUTING.md - LICENSE + - Makefile.PL - README.md - cpanfile + - leap_seconds.h + - ppport.h exclude_match: [] follow_symlinks: 0 include_dotfiles: 0 prefix: '' prune_directory: [] root: . - name: GatherDir - version: '5.039' + Dist::Zilla::Plugin::Git::GatherDir: + include_untracked: 0 + name: '@DROLSKY/Git::GatherDir' + version: '2.043' - - class: Dist::Zilla::Plugin::PruneCruft - name: PruneCruft - version: '5.039' + class: Dist::Zilla::Plugin::ManifestSkip + name: '@DROLSKY/ManifestSkip' + version: '6.010' + - + class: Dist::Zilla::Plugin::License + name: '@DROLSKY/License' + version: '6.010' + - + class: Dist::Zilla::Plugin::ExecDir + name: '@DROLSKY/ExecDir' + version: '6.010' + - + class: Dist::Zilla::Plugin::ShareDir + name: '@DROLSKY/ShareDir' + version: '6.010' + - + class: Dist::Zilla::Plugin::Manifest + name: '@DROLSKY/Manifest' + version: '6.010' + - + class: Dist::Zilla::Plugin::CheckVersionIncrement + name: '@DROLSKY/CheckVersionIncrement' + version: '0.121750' + - + class: Dist::Zilla::Plugin::TestRelease + name: '@DROLSKY/TestRelease' + version: '6.010' + - + class: Dist::Zilla::Plugin::ConfirmRelease + name: '@DROLSKY/ConfirmRelease' + version: '6.010' + - + class: Dist::Zilla::Plugin::UploadToCPAN + name: '@DROLSKY/UploadToCPAN' + version: '6.010' + - + class: Dist::Zilla::Plugin::VersionFromMainModule + name: '@DROLSKY/VersionFromMainModule' + version: '0.03' - class: Dist::Zilla::Plugin::Authority name: '@DROLSKY/Authority' @@ -103,26 +168,26 @@ - class: Dist::Zilla::Plugin::AutoPrereqs name: '@DROLSKY/AutoPrereqs' - version: '5.039' + version: '6.010' - class: Dist::Zilla::Plugin::CopyFilesFromBuild name: '@DROLSKY/CopyFilesFromBuild' - version: '0.151680' + version: '0.170880' - class: Dist::Zilla::Plugin::GitHub::Meta name: '@DROLSKY/GitHub::Meta' - version: '0.41' + version: '0.44' - class: Dist::Zilla::Plugin::GitHub::Update config: Dist::Zilla::Plugin::GitHub::Update: metacpan: 1 name: '@DROLSKY/GitHub::Update' - version: '0.41' + version: '0.44' - class: Dist::Zilla::Plugin::MetaResources name: '@DROLSKY/MetaResources' - version: '5.039' + version: '6.010' - class: Dist::Zilla::Plugin::MetaProvides::Package config: @@ -131,25 +196,46 @@ - class: Dist::Zilla::Plugin::FinderCode name: '@DROLSKY/MetaProvides::Package/AUTOVIV/:InstallModulesPM' - version: '5.039' + version: '6.010' + include_underscores: 0 Dist::Zilla::Role::MetaProvider::Provider: + $Dist::Zilla::Role::MetaProvider::Provider::VERSION: '2.002004' inherit_missing: '1' inherit_version: '1' meta_noindex: '1' + Dist::Zilla::Role::ModuleMetadata: + Module::Metadata: '1.000033' + version: '0.004' name: '@DROLSKY/MetaProvides::Package' - version: '2.003001' + version: '2.004003' + - + class: Dist::Zilla::Plugin::Meta::Contributors + name: '@DROLSKY/Meta::Contributors' + version: '0.003' + - + class: Dist::Zilla::Plugin::MetaConfig + name: '@DROLSKY/MetaConfig' + version: '6.010' + - + class: Dist::Zilla::Plugin::MetaJSON + name: '@DROLSKY/MetaJSON' + version: '6.010' + - + class: Dist::Zilla::Plugin::MetaYAML + name: '@DROLSKY/MetaYAML' + version: '6.010' - class: Dist::Zilla::Plugin::NextRelease name: '@DROLSKY/NextRelease' - version: '5.039' + version: '6.010' - class: Dist::Zilla::Plugin::Prereqs config: Dist::Zilla::Plugin::Prereqs: phase: test type: requires - name: '@DROLSKY/Test::More with subtest()' - version: '5.039' + name: '@DROLSKY/Test::More with subtest' + version: '6.010' - class: Dist::Zilla::Plugin::Prereqs config: @@ -157,7 +243,28 @@ phase: develop type: requires name: '@DROLSKY/Modules for use with tidyall' - version: '5.039' + version: '6.010' + - + class: Dist::Zilla::Plugin::Prereqs + config: + Dist::Zilla::Plugin::Prereqs: + phase: develop + type: requires + name: '@DROLSKY/Test::Version which fixes https://github.com/plicease/Test-Version/issues/7' + version: '6.010' + - + class: Dist::Zilla::Plugin::PromptIfStale + config: + Dist::Zilla::Plugin::PromptIfStale: + check_all_plugins: 0 + check_all_prereqs: 0 + modules: + - Dist::Zilla::PluginBundle::DROLSKY + phase: build + run_under_travis: 0 + skip: [] + name: '@DROLSKY/Dist::Zilla::PluginBundle::DROLSKY' + version: '0.054' - class: Dist::Zilla::Plugin::PromptIfStale config: @@ -166,156 +273,222 @@ check_all_prereqs: 1 modules: [] phase: release + run_under_travis: 0 skip: - Dist::Zilla::Plugin::DROLSKY::Contributors + - Dist::Zilla::Plugin::DROLSKY::Git::CheckFor::CorrectBranch - Dist::Zilla::Plugin::DROLSKY::License - Dist::Zilla::Plugin::DROLSKY::TidyAll - - Dist::Zilla::Plugin::DROLSKY::VersionProvider + - Dist::Zilla::Plugin::DROLSKY::WeaverConfig + - Pod::Weaver::PluginBundle::DROLSKY name: '@DROLSKY/PromptIfStale' - version: '0.047' - - - class: Dist::Zilla::Plugin::ReadmeAnyFromPod - config: - Dist::Zilla::Role::FileWatcher: - version: '0.006' - name: '@DROLSKY/README.md in build' - version: '0.150250' - - - class: Dist::Zilla::Plugin::ReadmeAnyFromPod - config: - Dist::Zilla::Role::FileWatcher: - version: '0.006' - name: '@DROLSKY/README.md in root' - version: '0.150250' + version: '0.054' - class: Dist::Zilla::Plugin::Test::Pod::Coverage::Configurable name: '@DROLSKY/Test::Pod::Coverage::Configurable' - version: '0.05' + version: '0.07' - class: Dist::Zilla::Plugin::Test::PodSpelling + config: + Dist::Zilla::Plugin::Test::PodSpelling: + directories: + - bin + - lib + spell_cmd: '' + stopwords: + - Anno + - BCE + - CLDR + - CPAN + - DATETIME + - DROLSKY + - "DROLSKY's" + - DateTime + - DateTimes + - Datetime + - Datetimes + - Domini + - EEEE + - EEEEE + - Flávio + - Formatters + - GGGG + - GGGGG + - Glock + - Hant + - IEEE + - IEEE + - LLL + - LLLL + - LLLLL + - Liang + - "Liang's" + - MMM + - MMMM + - MMMMM + - Measham + - "Measham's" + - POSIX + - PayPal + - PayPal + - QQQ + - QQQQ + - Rata + - Rata + - Rolsky + - "Rolsky's" + - SU + - Soibelmann + - Storable + - TW + - TZ + - Tsai + - UTC + - VVVV + - YAPCs + - ZZZZ + - ZZZZZ + - afterwards + - bian + - ccc + - cccc + - ccccc + - conformant + - datetime + - "datetime's" + - datetimes + - decrement + - dian + - drolsky + - durations + - eee + - eeee + - eeeee + - fallback + - formatter + - hh + - iCal + - ji + - mutiplication + - na + - namespace + - ni + - nitty + - "other's" + - proleptic + - qqq + - qqqq + - sexagesimal + - subclasses + - uu + - vvvv + - wiki + - yy + - yyyy + - yyyyy + - zh + - zzzz + wordlist: Pod::Wordlist name: '@DROLSKY/Test::PodSpelling' - version: '2.006009' - - - class: Dist::Zilla::Plugin::Test::ReportPrereqs - name: '@DROLSKY/Test::ReportPrereqs' - version: '0.021' - - - class: Dist::Zilla::Plugin::Test::Version - name: '@DROLSKY/Test::Version' - version: '1.05' - - - class: Dist::Zilla::Plugin::ManifestSkip - name: '@DROLSKY/ManifestSkip' - version: '5.039' + version: '2.007005' - - class: Dist::Zilla::Plugin::MetaYAML - name: '@DROLSKY/MetaYAML' - version: '5.039' + class: Dist::Zilla::Plugin::PodSyntaxTests + name: '@DROLSKY/PodSyntaxTests' + version: '6.010' - - class: Dist::Zilla::Plugin::License - name: '@DROLSKY/License' - version: '5.039' + class: Dist::Zilla::Plugin::RunExtraTests + config: + Dist::Zilla::Role::TestRunner: + default_jobs: 1 + name: '@DROLSKY/RunExtraTests' + version: '0.029' - - class: Dist::Zilla::Plugin::ExtraTests - name: '@DROLSKY/ExtraTests' - version: '5.039' + class: Dist::Zilla::Plugin::MojibakeTests + name: '@DROLSKY/MojibakeTests' + version: '0.8' - - class: Dist::Zilla::Plugin::ExecDir - name: '@DROLSKY/ExecDir' - version: '5.039' + class: Dist::Zilla::Plugin::Test::CleanNamespaces + config: + Dist::Zilla::Plugin::Test::CleanNamespaces: + filename: xt/author/clean-namespaces.t + skips: + - DateTime::Conflicts + name: '@DROLSKY/Test::CleanNamespaces' + version: '0.006' - - class: Dist::Zilla::Plugin::ShareDir - name: '@DROLSKY/ShareDir' - version: '5.039' + class: Dist::Zilla::Plugin::Test::CPAN::Changes + config: + Dist::Zilla::Plugin::Test::CPAN::Changes: + changelog: Changes + name: '@DROLSKY/Test::CPAN::Changes' + version: '0.012' - - class: Dist::Zilla::Plugin::Manifest - name: '@DROLSKY/Manifest' - version: '5.039' + class: Dist::Zilla::Plugin::Test::CPAN::Meta::JSON + name: '@DROLSKY/Test::CPAN::Meta::JSON' + version: '0.004' - - class: Dist::Zilla::Plugin::CheckVersionIncrement - name: '@DROLSKY/CheckVersionIncrement' - version: '0.121750' + class: Dist::Zilla::Plugin::Test::EOL + config: + Dist::Zilla::Plugin::Test::EOL: + filename: xt/author/eol.t + finder: + - ':ExecFiles' + - ':InstallModules' + - ':TestFiles' + trailing_whitespace: 1 + name: '@DROLSKY/Test::EOL' + version: '0.19' - - class: Dist::Zilla::Plugin::TestRelease - name: '@DROLSKY/TestRelease' - version: '5.039' + class: Dist::Zilla::Plugin::Test::NoTabs + config: + Dist::Zilla::Plugin::Test::NoTabs: + filename: xt/author/no-tabs.t + finder: + - ':InstallModules' + - ':ExecFiles' + - ':TestFiles' + name: '@DROLSKY/Test::NoTabs' + version: '0.15' - - class: Dist::Zilla::Plugin::ConfirmRelease - name: '@DROLSKY/ConfirmRelease' - version: '5.039' + class: Dist::Zilla::Plugin::Test::Portability + config: + Dist::Zilla::Plugin::Test::Portability: + options: '' + name: '@DROLSKY/Test::Portability' + version: '2.001000' - - class: Dist::Zilla::Plugin::UploadToCPAN - name: '@DROLSKY/UploadToCPAN' - version: '5.039' + class: Dist::Zilla::Plugin::Test::TidyAll + name: '@DROLSKY/Test::TidyAll' + version: '0.04' - - class: Dist::Zilla::Plugin::CheckPrereqsIndexed - name: '@DROLSKY/CheckPrereqsIndexed' - version: '0.016' + class: Dist::Zilla::Plugin::Test::ReportPrereqs + name: '@DROLSKY/Test::ReportPrereqs' + version: '0.027' - - class: Dist::Zilla::Plugin::CPANFile - name: '@DROLSKY/CPANFile' - version: '5.039' + class: Dist::Zilla::Plugin::Test::Version + name: '@DROLSKY/Test::Version' + version: '1.09' - class: Dist::Zilla::Plugin::DROLSKY::Contributors name: '@DROLSKY/DROLSKY::Contributors' - version: '0.38' - - - class: Dist::Zilla::Plugin::DROLSKY::License - name: '@DROLSKY/DROLSKY::License' - version: '0.38' - - - class: Dist::Zilla::Plugin::DROLSKY::TidyAll - name: '@DROLSKY/DROLSKY::TidyAll' - version: '0.38' - - - class: Dist::Zilla::Plugin::DROLSKY::VersionProvider - name: '@DROLSKY/DROLSKY::VersionProvider' - version: '0.38' - - - class: Dist::Zilla::Plugin::Git::CheckFor::CorrectBranch - config: - Dist::Zilla::Role::Git::Repo: - repo_root: . - name: '@DROLSKY/Git::CheckFor::CorrectBranch' - version: '0.013' - - - class: Dist::Zilla::Plugin::Git::CheckFor::MergeConflicts - config: - Dist::Zilla::Role::Git::Repo: - repo_root: . - name: '@DROLSKY/Git::CheckFor::MergeConflicts' - version: '0.013' + version: '0.89' - class: Dist::Zilla::Plugin::Git::Contributors config: Dist::Zilla::Plugin::Git::Contributors: + git_version: 2.16.1 include_authors: 0 include_releaser: 1 order_by: name - paths: - - . + paths: [] name: '@DROLSKY/Git::Contributors' - version: '0.014' - - - class: Dist::Zilla::Plugin::InstallGuide - name: '@DROLSKY/InstallGuide' - version: '1.200006' - - - class: Dist::Zilla::Plugin::Meta::Contributors - name: '@DROLSKY/Meta::Contributors' - version: '0.002' - - - class: Dist::Zilla::Plugin::MetaConfig - name: '@DROLSKY/MetaConfig' - version: '5.039' - - - class: Dist::Zilla::Plugin::MetaJSON - name: '@DROLSKY/MetaJSON' - version: '5.039' + version: '0.032' - class: Dist::Zilla::Plugin::SurgicalPodWeaver config: Dist::Zilla::Plugin::PodWeaver: + config_plugins: + - '@DROLSKY' finder: - ':InstallModules' - ':ExecFiles' @@ -323,96 +496,195 @@ - class: Pod::Weaver::Plugin::EnsurePod5 name: '@CorePrep/EnsurePod5' - version: '4.012' + version: '4.015' - class: Pod::Weaver::Plugin::H1Nester name: '@CorePrep/H1Nester' - version: '4.012' + version: '4.015' + - + class: Pod::Weaver::Plugin::SingleEncoding + name: '@DROLSKY/SingleEncoding' + version: '4.015' + - + class: Pod::Weaver::Plugin::Transformer + name: '@DROLSKY/List' + version: '4.015' + - + class: Pod::Weaver::Plugin::Transformer + name: '@DROLSKY/Verbatim' + version: '4.015' + - + class: Pod::Weaver::Section::Region + name: '@DROLSKY/header' + version: '4.015' - class: Pod::Weaver::Section::Name - name: Name - version: '4.012' + name: '@DROLSKY/Name' + version: '4.015' - class: Pod::Weaver::Section::Version - name: Version - version: '4.012' + name: '@DROLSKY/Version' + version: '4.015' - class: Pod::Weaver::Section::Region - name: prelude - version: '4.012' + name: '@DROLSKY/prelude' + version: '4.015' - class: Pod::Weaver::Section::Generic name: SYNOPSIS - version: '4.012' + version: '4.015' - class: Pod::Weaver::Section::Generic name: DESCRIPTION - version: '4.012' + version: '4.015' + - + class: Pod::Weaver::Section::Generic + name: OVERVIEW + version: '4.015' + - + class: Pod::Weaver::Section::Collect + name: ATTRIBUTES + version: '4.015' + - + class: Pod::Weaver::Section::Collect + name: METHODS + version: '4.015' + - + class: Pod::Weaver::Section::Collect + name: FUNCTIONS + version: '4.015' + - + class: Pod::Weaver::Section::Collect + name: TYPES + version: '4.015' - class: Pod::Weaver::Section::Leftovers - name: Leftovers - version: '4.012' + name: '@DROLSKY/Leftovers' + version: '4.015' - class: Pod::Weaver::Section::Region - name: postlude - version: '4.012' + name: '@DROLSKY/postlude' + version: '4.015' + - + class: Pod::Weaver::Section::GenerateSection + name: '@DROLSKY/generate SUPPORT' + version: '1.06' + - + class: Pod::Weaver::Section::AllowOverride + name: '@DROLSKY/allow override SUPPORT' + version: '0.05' + - + class: Pod::Weaver::Section::GenerateSection + name: '@DROLSKY/generate SOURCE' + version: '1.06' + - + class: Pod::Weaver::Section::GenerateSection + name: '@DROLSKY/generate DONATIONS' + version: '1.06' - class: Pod::Weaver::Section::Authors - name: Authors - version: '4.012' + name: '@DROLSKY/Authors' + version: '4.015' - class: Pod::Weaver::Section::Contributors - name: Contributors + name: '@DROLSKY/Contributors' version: '0.009' - class: Pod::Weaver::Section::Legal - name: Legal - version: '4.012' + name: '@DROLSKY/Legal' + version: '4.015' + - + class: Pod::Weaver::Section::Region + name: '@DROLSKY/footer' + version: '4.015' name: '@DROLSKY/SurgicalPodWeaver' version: '0.0023' - - class: Dist::Zilla::Plugin::MojibakeTests - name: '@DROLSKY/MojibakeTests' - version: '0.8' + class: Dist::Zilla::Plugin::DROLSKY::WeaverConfig + name: '@DROLSKY/DROLSKY::WeaverConfig' + version: '0.89' - - class: Dist::Zilla::Plugin::PodSyntaxTests - name: '@DROLSKY/PodSyntaxTests' - version: '5.039' + class: Dist::Zilla::Plugin::ReadmeAnyFromPod + config: + Dist::Zilla::Role::FileWatcher: + version: '0.006' + name: '@DROLSKY/README.md in build' + version: '0.163250' - - class: Dist::Zilla::Plugin::Test::CPAN::Changes - name: '@DROLSKY/Test::CPAN::Changes' - version: '0.009' + class: Dist::Zilla::Plugin::GenerateFile::FromShareDir + config: + Dist::Zilla::Plugin::GenerateFile::FromShareDir: + destination_filename: CONTRIBUTING.md + dist: Dist-Zilla-PluginBundle-DROLSKY + encoding: UTF-8 + has_xs: '1' + location: build + source_filename: CONTRIBUTING.md + Dist::Zilla::Role::RepoFileInjector: + allow_overwrite: 1 + repo_root: . + version: '0.007' + name: '@DROLSKY/Generate CONTRIBUTING.md' + version: '0.013' - - class: Dist::Zilla::Plugin::Test::EOL + class: Dist::Zilla::Plugin::InstallGuide + name: '@DROLSKY/InstallGuide' + version: '1.200007' + - + class: Dist::Zilla::Plugin::CPANFile + name: '@DROLSKY/CPANFile' + version: '6.010' + - + class: Dist::Zilla::Plugin::PPPort + name: '@DROLSKY/PPPort' + version: '0.008' + - + class: Dist::Zilla::Plugin::DROLSKY::License + name: '@DROLSKY/DROLSKY::License' + version: '0.89' + - + class: Dist::Zilla::Plugin::CheckStrictVersion + name: '@DROLSKY/CheckStrictVersion' + version: '0.001' + - + class: Dist::Zilla::Plugin::CheckSelfDependency config: - Dist::Zilla::Plugin::Test::EOL: - filename: xt/author/eol.t + Dist::Zilla::Plugin::CheckSelfDependency: finder: - ':InstallModules' - - ':ExecFiles' - - ':TestFiles' - trailing_whitespace: '1' - name: '@DROLSKY/Test::EOL' - version: '0.18' + Dist::Zilla::Role::ModuleMetadata: + Module::Metadata: '1.000033' + version: '0.004' + name: '@DROLSKY/CheckSelfDependency' + version: '0.011' - - class: Dist::Zilla::Plugin::Test::NoTabs + class: Dist::Zilla::Plugin::CheckPrereqsIndexed + name: '@DROLSKY/CheckPrereqsIndexed' + version: '0.020' + - + class: Dist::Zilla::Plugin::DROLSKY::Git::CheckFor::CorrectBranch config: - Dist::Zilla::Plugin::Test::NoTabs: - filename: xt/author/no-tabs.t - finder: - - ':InstallModules' - - ':ExecFiles' - - ':TestFiles' - name: '@DROLSKY/Test::NoTabs' - version: '0.15' + Dist::Zilla::Role::Git::Repo: + git_version: 2.16.1 + repo_root: . + name: '@DROLSKY/DROLSKY::Git::CheckFor::CorrectBranch' + version: '0.89' - - class: Dist::Zilla::Plugin::Test::Portability - name: '@DROLSKY/Test::Portability' - version: '2.000006' + class: Dist::Zilla::Plugin::EnsureChangesHasContent + name: '@DROLSKY/EnsureChangesHasContent' + version: '0.02' - - class: Dist::Zilla::Plugin::Test::TidyAll - name: '@DROLSKY/Test::TidyAll' - version: '0.01' + class: Dist::Zilla::Plugin::Git::CheckFor::MergeConflicts + config: + Dist::Zilla::Role::Git::Repo: + git_version: 2.16.1 + repo_root: . + name: '@DROLSKY/Git::CheckFor::MergeConflicts' + version: '0.014' + - + class: Dist::Zilla::Plugin::DROLSKY::TidyAll + name: '@DROLSKY/DROLSKY::TidyAll' + version: '0.89' - class: Dist::Zilla::Plugin::Git::Check config: @@ -420,19 +692,22 @@ untracked_files: die Dist::Zilla::Role::Git::DirtyFiles: allow_dirty: - - Build.PL - CONTRIBUTING.md - Changes - LICENSE - Makefile.PL - README.md - cpanfile + - leap_seconds.h + - ppport.h + - tidyall.ini allow_dirty_match: [] changelog: Changes Dist::Zilla::Role::Git::Repo: + git_version: 2.16.1 repo_root: . name: '@DROLSKY/Git::Check' - version: '2.036' + version: '2.043' - class: Dist::Zilla::Plugin::Git::Commit config: @@ -441,21 +716,24 @@ commit_msg: v%v%n%n%c Dist::Zilla::Role::Git::DirtyFiles: allow_dirty: - - Build.PL - CONTRIBUTING.md - Changes - LICENSE - Makefile.PL - README.md - cpanfile + - leap_seconds.h + - ppport.h + - tidyall.ini allow_dirty_match: [] changelog: Changes Dist::Zilla::Role::Git::Repo: + git_version: 2.16.1 repo_root: . Dist::Zilla::Role::Git::StringFormatter: time_zone: local - name: '@DROLSKY/commit generated files' - version: '2.036' + name: '@DROLSKY/Commit generated files' + version: '2.043' - class: Dist::Zilla::Plugin::Git::Tag config: @@ -463,15 +741,16 @@ branch: ~ changelog: Changes signed: 0 - tag: v1.21 + tag: v1.46 tag_format: v%v tag_message: v%v Dist::Zilla::Role::Git::Repo: + git_version: 2.16.1 repo_root: . Dist::Zilla::Role::Git::StringFormatter: time_zone: local name: '@DROLSKY/Git::Tag' - version: '2.036' + version: '2.043' - class: Dist::Zilla::Plugin::Git::Push config: @@ -480,9 +759,10 @@ - origin remotes_must_exist: 1 Dist::Zilla::Role::Git::Repo: + git_version: 2.16.1 repo_root: . name: '@DROLSKY/Git::Push' - version: '2.036' + version: '2.043' - class: Dist::Zilla::Plugin::BumpVersionAfterRelease config: @@ -493,7 +773,7 @@ global: 0 munge_makefile_pl: 1 name: '@DROLSKY/BumpVersionAfterRelease' - version: '0.012' + version: '0.017' - class: Dist::Zilla::Plugin::Git::Commit config: @@ -508,11 +788,12 @@ - (?^:.+) changelog: Changes Dist::Zilla::Role::Git::Repo: + git_version: 2.16.1 repo_root: . Dist::Zilla::Role::Git::StringFormatter: time_zone: local - name: '@DROLSKY/commit version bump' - version: '2.036' + name: '@DROLSKY/Commit version bump' + version: '2.043' - class: Dist::Zilla::Plugin::Git::Push config: @@ -521,13 +802,30 @@ - origin remotes_must_exist: 1 Dist::Zilla::Role::Git::Repo: + git_version: 2.16.1 repo_root: . - name: '@DROLSKY/push version bump' - version: '2.036' + name: '@DROLSKY/Push version bump' + version: '2.043' + - + class: Dist::Zilla::Plugin::lib + config: + Dist::Zilla::Plugin::lib: + lib: + - inc + name: lib + version: '0.001002' + - + class: LeapSecondsHeader + name: =LeapSecondsHeader + version: ~ + - + class: Dist::Zilla::Plugin::CopyFilesFromBuild + name: CopyFilesFromBuild + version: '0.170880' - - class: Dist::Zilla::Plugin::Test::Pod::LinkCheck - name: '@DROLSKY/Test::Pod::LinkCheck' - version: '1.002' + class: Dist::Zilla::Plugin::MetaResources + name: MetaResources + version: '6.010' - class: Dist::Zilla::Plugin::Prereqs config: @@ -535,80 +833,106 @@ phase: develop type: requires name: DevelopRequires - version: '5.039' - - - class: inc::MyModuleBuild - config: - Dist::Zilla::Role::TestRunner: - default_jobs: 1 - name: =inc::MyModuleBuild - version: ~ + version: '6.010' - class: Dist::Zilla::Plugin::PurePerlTests name: PurePerlTests - version: '0.05' + version: '0.06' + - + class: Dist::Zilla::Plugin::Conflicts + name: Conflicts + version: '0.19' + - + class: Dist::Zilla::Plugin::Test::CheckBreaks + config: + Dist::Zilla::Plugin::Test::CheckBreaks: + conflicts_module: + - DateTime::Conflicts + no_forced_deps: 0 + Dist::Zilla::Role::ModuleMetadata: + Module::Metadata: '1.000033' + version: '0.004' + name: Test::CheckBreaks + version: '0.019' - class: Dist::Zilla::Plugin::FinderCode name: ':InstallModules' - version: '5.039' + version: '6.010' - class: Dist::Zilla::Plugin::FinderCode name: ':IncModules' - version: '5.039' + version: '6.010' - class: Dist::Zilla::Plugin::FinderCode name: ':TestFiles' - version: '5.039' + version: '6.010' - class: Dist::Zilla::Plugin::FinderCode name: ':ExtraTestFiles' - version: '5.039' + version: '6.010' - class: Dist::Zilla::Plugin::FinderCode name: ':ExecFiles' - version: '5.039' + version: '6.010' - class: Dist::Zilla::Plugin::FinderCode name: ':PerlExecFiles' - version: '5.039' + version: '6.010' - class: Dist::Zilla::Plugin::FinderCode name: ':ShareFiles' - version: '5.039' + version: '6.010' - class: Dist::Zilla::Plugin::FinderCode name: ':MainModule' - version: '5.039' + version: '6.010' - class: Dist::Zilla::Plugin::FinderCode name: ':AllFiles' - version: '5.039' + version: '6.010' - class: Dist::Zilla::Plugin::FinderCode name: ':NoFiles' - version: '5.039' + version: '6.010' - class: Dist::Zilla::Plugin::FinderCode name: '@DROLSKY/MetaProvides::Package/AUTOVIV/:InstallModulesPM' - version: '5.039' + version: '6.010' zilla: class: Dist::Zilla::Dist::Builder config: is_trial: '0' - version: '5.039' + version: '6.010' x_authority: cpan:DROLSKY +x_breaks: + DateTime::Format::Mail: '<= 0.402' x_contributors: - 'Ben Bennett ' - 'Christian Hansen ' - 'Daisuke Maki ' + - 'Dan Book ' + - 'Dan Stewart ' - 'David E. Wheeler ' + - 'David Precious ' - 'Doug Bell ' - 'Flávio Soibelmann Glock ' + - 'Gianni Ceccarelli ' - 'Gregory Oschwald ' + - 'Hauke D ' - 'Iain Truskett ' - 'Jason McIntosh ' - 'Joshua Hoblitt ' + - 'Karen Etheridge ' + - 'Michael Conrad ' + - 'Michael R. Davis ' + - 'M Somerville ' - 'Nick Tonkin <1nickt@users.noreply.github.com>' + - 'Olaf Alders ' + - 'Ovid ' + - 'Philippe Bruhat (BooK) ' - 'Ricardo Signes ' - 'Richard Bowen ' - 'Ron Hill ' + - 'Sam Kington ' + - 'viviparous ' +x_serialization_backend: 'YAML::Tiny version 1.70' diff -Nru libdatetime-perl-1.21/perlcriticrc libdatetime-perl-1.46/perlcriticrc --- libdatetime-perl-1.21/perlcriticrc 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/perlcriticrc 2018-02-11 23:36:51.000000000 +0000 @@ -1,6 +1,7 @@ severity = 3 verbose = 11 -theme = core + pbp + bugs + maintenance + cosmetic + complexity + security + tests + moose +theme = (core && (pbp || bugs || maintenance || cosmetic || complexity || security || tests)) || moose +program-extensions = pl psgi t exclude = Subroutines::ProhibitCallsToUndeclaredSubs @@ -44,6 +45,9 @@ [-Subroutines::RequireFinalReturn] +# This incorrectly thinks signatures are prototypes. +[-Subroutines::ProhibitSubroutinePrototypes] + [-ErrorHandling::RequireCarping] # No need for /xsm everywhere @@ -56,3 +60,16 @@ # "use v5.14" is more readable than "use 5.014" [-ValuesAndExpressions::ProhibitVersionStrings] + +# Explicitly returning undef is a _good_ thing in many cases, since it +# prevents very common errors when using a sub in list context to construct a +# hash and ending up with a missing value or key. +[-Subroutines::ProhibitExplicitReturnUndef] + +# Sometimes I want to write "return unless $x > 4" +[-ControlStructures::ProhibitNegativeExpressionsInUnlessAndUntilConditions] + +# We've removed "second" from the forbidden list since it's pretty unambiguous +# in DateTime +[NamingConventions::ProhibitAmbiguousNames] +forbid = abstract bases close contract last left no record right set diff -Nru libdatetime-perl-1.21/ppport.h libdatetime-perl-1.46/ppport.h --- libdatetime-perl-1.21/ppport.h 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/ppport.h 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,7908 @@ +#if 0 +<<'SKIP'; +#endif +/* +---------------------------------------------------------------------- + + ppport.h -- Perl/Pollution/Portability Version 3.36 + + Automatically created by Devel::PPPort running under perl 5.026001. + + Do NOT edit this file directly! -- Edit PPPort_pm.PL and the + includes in parts/inc/ instead. + + Use 'perldoc ppport.h' to view the documentation below. + +---------------------------------------------------------------------- + +SKIP + +=pod + +=head1 NAME + +ppport.h - Perl/Pollution/Portability version 3.36 + +=head1 SYNOPSIS + + perl ppport.h [options] [source files] + + Searches current directory for files if no [source files] are given + + --help show short help + + --version show version + + --patch=file write one patch file with changes + --copy=suffix write changed copies with suffix + --diff=program use diff program and options + + --compat-version=version provide compatibility with Perl version + --cplusplus accept C++ comments + + --quiet don't output anything except fatal errors + --nodiag don't show diagnostics + --nohints don't show hints + --nochanges don't suggest changes + --nofilter don't filter input files + + --strip strip all script and doc functionality from + ppport.h + + --list-provided list provided API + --list-unsupported list unsupported API + --api-info=name show Perl API portability information + +=head1 COMPATIBILITY + +This version of F is designed to support operation with Perl +installations back to 5.003, and has been tested up to 5.20. + +=head1 OPTIONS + +=head2 --help + +Display a brief usage summary. + +=head2 --version + +Display the version of F. + +=head2 --patch=I + +If this option is given, a single patch file will be created if +any changes are suggested. This requires a working diff program +to be installed on your system. + +=head2 --copy=I + +If this option is given, a copy of each file will be saved with +the given suffix that contains the suggested changes. This does +not require any external programs. Note that this does not +automagically add a dot between the original filename and the +suffix. If you want the dot, you have to include it in the option +argument. + +If neither C<--patch> or C<--copy> are given, the default is to +simply print the diffs for each file. This requires either +C or a C program to be installed. + +=head2 --diff=I + +Manually set the diff program and options to use. The default +is to use C, when installed, and output unified +context diffs. + +=head2 --compat-version=I + +Tell F to check for compatibility with the given +Perl version. The default is to check for compatibility with Perl +version 5.003. You can use this option to reduce the output +of F if you intend to be backward compatible only +down to a certain Perl version. + +=head2 --cplusplus + +Usually, F will detect C++ style comments and +replace them with C style comments for portability reasons. +Using this option instructs F to leave C++ +comments untouched. + +=head2 --quiet + +Be quiet. Don't print anything except fatal errors. + +=head2 --nodiag + +Don't output any diagnostic messages. Only portability +alerts will be printed. + +=head2 --nohints + +Don't output any hints. Hints often contain useful portability +notes. Warnings will still be displayed. + +=head2 --nochanges + +Don't suggest any changes. Only give diagnostic output and hints +unless these are also deactivated. + +=head2 --nofilter + +Don't filter the list of input files. By default, files not looking +like source code (i.e. not *.xs, *.c, *.cc, *.cpp or *.h) are skipped. + +=head2 --strip + +Strip all script and documentation functionality from F. +This reduces the size of F dramatically and may be useful +if you want to include F in smaller modules without +increasing their distribution size too much. + +The stripped F will have a C<--unstrip> option that allows +you to undo the stripping, but only if an appropriate C +module is installed. + +=head2 --list-provided + +Lists the API elements for which compatibility is provided by +F. Also lists if it must be explicitly requested, +if it has dependencies, and if there are hints or warnings for it. + +=head2 --list-unsupported + +Lists the API elements that are known not to be supported by +F and below which version of Perl they probably +won't be available or work. + +=head2 --api-info=I + +Show portability information for API elements matching I. +If I is surrounded by slashes, it is interpreted as a regular +expression. + +=head1 DESCRIPTION + +In order for a Perl extension (XS) module to be as portable as possible +across differing versions of Perl itself, certain steps need to be taken. + +=over 4 + +=item * + +Including this header is the first major one. This alone will give you +access to a large part of the Perl API that hasn't been available in +earlier Perl releases. Use + + perl ppport.h --list-provided + +to see which API elements are provided by ppport.h. + +=item * + +You should avoid using deprecated parts of the API. For example, using +global Perl variables without the C prefix is deprecated. Also, +some API functions used to have a C prefix. Using this form is +also deprecated. You can safely use the supported API, as F +will provide wrappers for older Perl versions. + +=item * + +If you use one of a few functions or variables that were not present in +earlier versions of Perl, and that can't be provided using a macro, you +have to explicitly request support for these functions by adding one or +more C<#define>s in your source code before the inclusion of F. + +These functions or variables will be marked C in the list shown +by C<--list-provided>. + +Depending on whether you module has a single or multiple files that +use such functions or variables, you want either C or global +variants. + +For a C function or variable (used only in a single source +file), use: + + #define NEED_function + #define NEED_variable + +For a global function or variable (used in multiple source files), +use: + + #define NEED_function_GLOBAL + #define NEED_variable_GLOBAL + +Note that you mustn't have more than one global request for the +same function or variable in your project. + + Function / Variable Static Request Global Request + ----------------------------------------------------------------------------------------- + PL_parser NEED_PL_parser NEED_PL_parser_GLOBAL + PL_signals NEED_PL_signals NEED_PL_signals_GLOBAL + SvRX() NEED_SvRX NEED_SvRX_GLOBAL + caller_cx() NEED_caller_cx NEED_caller_cx_GLOBAL + eval_pv() NEED_eval_pv NEED_eval_pv_GLOBAL + grok_bin() NEED_grok_bin NEED_grok_bin_GLOBAL + grok_hex() NEED_grok_hex NEED_grok_hex_GLOBAL + grok_number() NEED_grok_number NEED_grok_number_GLOBAL + grok_numeric_radix() NEED_grok_numeric_radix NEED_grok_numeric_radix_GLOBAL + grok_oct() NEED_grok_oct NEED_grok_oct_GLOBAL + gv_fetchpvn_flags() NEED_gv_fetchpvn_flags NEED_gv_fetchpvn_flags_GLOBAL + load_module() NEED_load_module NEED_load_module_GLOBAL + mg_findext() NEED_mg_findext NEED_mg_findext_GLOBAL + my_snprintf() NEED_my_snprintf NEED_my_snprintf_GLOBAL + my_sprintf() NEED_my_sprintf NEED_my_sprintf_GLOBAL + my_strlcat() NEED_my_strlcat NEED_my_strlcat_GLOBAL + my_strlcpy() NEED_my_strlcpy NEED_my_strlcpy_GLOBAL + newCONSTSUB() NEED_newCONSTSUB NEED_newCONSTSUB_GLOBAL + newRV_noinc() NEED_newRV_noinc NEED_newRV_noinc_GLOBAL + newSV_type() NEED_newSV_type NEED_newSV_type_GLOBAL + newSVpvn_flags() NEED_newSVpvn_flags NEED_newSVpvn_flags_GLOBAL + newSVpvn_share() NEED_newSVpvn_share NEED_newSVpvn_share_GLOBAL + pv_display() NEED_pv_display NEED_pv_display_GLOBAL + pv_escape() NEED_pv_escape NEED_pv_escape_GLOBAL + pv_pretty() NEED_pv_pretty NEED_pv_pretty_GLOBAL + sv_2pv_flags() NEED_sv_2pv_flags NEED_sv_2pv_flags_GLOBAL + sv_2pvbyte() NEED_sv_2pvbyte NEED_sv_2pvbyte_GLOBAL + sv_catpvf_mg() NEED_sv_catpvf_mg NEED_sv_catpvf_mg_GLOBAL + sv_catpvf_mg_nocontext() NEED_sv_catpvf_mg_nocontext NEED_sv_catpvf_mg_nocontext_GLOBAL + sv_pvn_force_flags() NEED_sv_pvn_force_flags NEED_sv_pvn_force_flags_GLOBAL + sv_setpvf_mg() NEED_sv_setpvf_mg NEED_sv_setpvf_mg_GLOBAL + sv_setpvf_mg_nocontext() NEED_sv_setpvf_mg_nocontext NEED_sv_setpvf_mg_nocontext_GLOBAL + sv_unmagicext() NEED_sv_unmagicext NEED_sv_unmagicext_GLOBAL + vload_module() NEED_vload_module NEED_vload_module_GLOBAL + vnewSVpvf() NEED_vnewSVpvf NEED_vnewSVpvf_GLOBAL + warner() NEED_warner NEED_warner_GLOBAL + +To avoid namespace conflicts, you can change the namespace of the +explicitly exported functions / variables using the C +macro. Just C<#define> the macro before including C: + + #define DPPP_NAMESPACE MyOwnNamespace_ + #include "ppport.h" + +The default namespace is C. + +=back + +The good thing is that most of the above can be checked by running +F on your source code. See the next section for +details. + +=head1 EXAMPLES + +To verify whether F is needed for your module, whether you +should make any changes to your code, and whether any special defines +should be used, F can be run as a Perl script to check your +source code. Simply say: + + perl ppport.h + +The result will usually be a list of patches suggesting changes +that should at least be acceptable, if not necessarily the most +efficient solution, or a fix for all possible problems. + +If you know that your XS module uses features only available in +newer Perl releases, if you're aware that it uses C++ comments, +and if you want all suggestions as a single patch file, you could +use something like this: + + perl ppport.h --compat-version=5.6.0 --cplusplus --patch=test.diff + +If you only want your code to be scanned without any suggestions +for changes, use: + + perl ppport.h --nochanges + +You can specify a different C program or options, using +the C<--diff> option: + + perl ppport.h --diff='diff -C 10' + +This would output context diffs with 10 lines of context. + +If you want to create patched copies of your files instead, use: + + perl ppport.h --copy=.new + +To display portability information for the C function, +use: + + perl ppport.h --api-info=newSVpvn + +Since the argument to C<--api-info> can be a regular expression, +you can use + + perl ppport.h --api-info=/_nomg$/ + +to display portability information for all C<_nomg> functions or + + perl ppport.h --api-info=/./ + +to display information for all known API elements. + +=head1 BUGS + +If this version of F is causing failure during +the compilation of this module, please check if newer versions +of either this module or C are available on CPAN +before sending a bug report. + +If F was generated using the latest version of +C and is causing failure of this module, please +file a bug report here: L + +Please include the following information: + +=over 4 + +=item 1. + +The complete output from running "perl -V" + +=item 2. + +This file. + +=item 3. + +The name and version of the module you were trying to build. + +=item 4. + +A full log of the build that failed. + +=item 5. + +Any other information that you think could be relevant. + +=back + +For the latest version of this code, please get the C +module from CPAN. + +=head1 COPYRIGHT + +Version 3.x, Copyright (c) 2004-2013, Marcus Holland-Moritz. + +Version 2.x, Copyright (C) 2001, Paul Marquess. + +Version 1.x, Copyright (C) 1999, Kenneth Albanowski. + +This program is free software; you can redistribute it and/or +modify it under the same terms as Perl itself. + +=head1 SEE ALSO + +See L. + +=cut + +use strict; + +# Disable broken TRIE-optimization +BEGIN { eval '${^RE_TRIE_MAXBUF} = -1' if $] >= 5.009004 && $] <= 5.009005 } + +my $VERSION = 3.36; + +my %opt = ( + quiet => 0, + diag => 1, + hints => 1, + changes => 1, + cplusplus => 0, + filter => 1, + strip => 0, + version => 0, +); + +my($ppport) = $0 =~ /([\w.]+)$/; +my $LF = '(?:\r\n|[\r\n])'; # line feed +my $HS = "[ \t]"; # horizontal whitespace + +# Never use C comments in this file! +my $ccs = '/'.'*'; +my $cce = '*'.'/'; +my $rccs = quotemeta $ccs; +my $rcce = quotemeta $cce; + +eval { + require Getopt::Long; + Getopt::Long::GetOptions(\%opt, qw( + help quiet diag! filter! hints! changes! cplusplus strip version + patch=s copy=s diff=s compat-version=s + list-provided list-unsupported api-info=s + )) or usage(); +}; + +if ($@ and grep /^-/, @ARGV) { + usage() if "@ARGV" =~ /^--?h(?:elp)?$/; + die "Getopt::Long not found. Please don't use any options.\n"; +} + +if ($opt{version}) { + print "This is $0 $VERSION.\n"; + exit 0; +} + +usage() if $opt{help}; +strip() if $opt{strip}; + +if (exists $opt{'compat-version'}) { + my($r,$v,$s) = eval { parse_version($opt{'compat-version'}) }; + if ($@) { + die "Invalid version number format: '$opt{'compat-version'}'\n"; + } + die "Only Perl 5 is supported\n" if $r != 5; + die "Invalid version number: $opt{'compat-version'}\n" if $v >= 1000 || $s >= 1000; + $opt{'compat-version'} = sprintf "%d.%03d%03d", $r, $v, $s; +} +else { + $opt{'compat-version'} = 5; +} + +my %API = map { /^(\w+)\|([^|]*)\|([^|]*)\|(\w*)$/ + ? ( $1 => { + ($2 ? ( base => $2 ) : ()), + ($3 ? ( todo => $3 ) : ()), + (index($4, 'v') >= 0 ? ( varargs => 1 ) : ()), + (index($4, 'p') >= 0 ? ( provided => 1 ) : ()), + (index($4, 'n') >= 0 ? ( nothxarg => 1 ) : ()), + } ) + : die "invalid spec: $_" } qw( +ASCII_TO_NEED||5.007001|n +AvFILLp|5.004050||p +AvFILL||| +BhkDISABLE||5.024000| +BhkENABLE||5.024000| +BhkENTRY_set||5.024000| +BhkENTRY||| +BhkFLAGS||| +CALL_BLOCK_HOOKS||| +CLASS|||n +CPERLscope|5.005000||p +CX_CURPAD_SAVE||| +CX_CURPAD_SV||| +C_ARRAY_END|5.013002||p +C_ARRAY_LENGTH|5.008001||p +CopFILEAV|5.006000||p +CopFILEGV_set|5.006000||p +CopFILEGV|5.006000||p +CopFILESV|5.006000||p +CopFILE_set|5.006000||p +CopFILE|5.006000||p +CopSTASHPV_set|5.006000||p +CopSTASHPV|5.006000||p +CopSTASH_eq|5.006000||p +CopSTASH_set|5.006000||p +CopSTASH|5.006000||p +CopyD|5.009002|5.004050|p +Copy||| +CvPADLIST||5.008001| +CvSTASH||| +CvWEAKOUTSIDE||| +DECLARATION_FOR_LC_NUMERIC_MANIPULATION||5.021010|n +DEFSV_set|5.010001||p +DEFSV|5.004050||p +DO_UTF8||5.006000| +END_EXTERN_C|5.005000||p +ENTER||| +ERRSV|5.004050||p +EXTEND||| +EXTERN_C|5.005000||p +F0convert|||n +FREETMPS||| +GIMME_V||5.004000|n +GIMME|||n +GROK_NUMERIC_RADIX|5.007002||p +G_ARRAY||| +G_DISCARD||| +G_EVAL||| +G_METHOD|5.006001||p +G_NOARGS||| +G_SCALAR||| +G_VOID||5.004000| +GetVars||| +GvAV||| +GvCV||| +GvHV||| +GvSV||| +Gv_AMupdate||5.011000| +HEf_SVKEY|5.003070||p +HeHASH||5.003070| +HeKEY||5.003070| +HeKLEN||5.003070| +HePV||5.004000| +HeSVKEY_force||5.003070| +HeSVKEY_set||5.004000| +HeSVKEY||5.003070| +HeUTF8|5.010001|5.008000|p +HeVAL||5.003070| +HvENAMELEN||5.015004| +HvENAMEUTF8||5.015004| +HvENAME||5.013007| +HvNAMELEN_get|5.009003||p +HvNAMELEN||5.015004| +HvNAMEUTF8||5.015004| +HvNAME_get|5.009003||p +HvNAME||| +INT2PTR|5.006000||p +IN_LOCALE_COMPILETIME|5.007002||p +IN_LOCALE_RUNTIME|5.007002||p +IN_LOCALE|5.007002||p +IN_PERL_COMPILETIME|5.008001||p +IS_NUMBER_GREATER_THAN_UV_MAX|5.007002||p +IS_NUMBER_INFINITY|5.007002||p +IS_NUMBER_IN_UV|5.007002||p +IS_NUMBER_NAN|5.007003||p +IS_NUMBER_NEG|5.007002||p +IS_NUMBER_NOT_INT|5.007002||p +IVSIZE|5.006000||p +IVTYPE|5.006000||p +IVdf|5.006000||p +LEAVE||| +LINKLIST||5.013006| +LVRET||| +MARK||| +MULTICALL||5.024000| +MUTABLE_PTR|5.010001||p +MUTABLE_SV|5.010001||p +MY_CXT_CLONE|5.009002||p +MY_CXT_INIT|5.007003||p +MY_CXT|5.007003||p +MoveD|5.009002|5.004050|p +Move||| +NATIVE_TO_NEED||5.007001|n +NOOP|5.005000||p +NUM2PTR|5.006000||p +NVTYPE|5.006000||p +NVef|5.006001||p +NVff|5.006001||p +NVgf|5.006001||p +Newxc|5.009003||p +Newxz|5.009003||p +Newx|5.009003||p +Nullav||| +Nullch||| +Nullcv||| +Nullhv||| +Nullsv||| +OP_CLASS||5.013007| +OP_DESC||5.007003| +OP_NAME||5.007003| +OP_TYPE_IS_OR_WAS||5.019010| +OP_TYPE_IS||5.019007| +ORIGMARK||| +OpHAS_SIBLING|5.021007||p +OpLASTSIB_set|5.021011||p +OpMAYBESIB_set|5.021011||p +OpMORESIB_set|5.021011||p +OpSIBLING|5.021007||p +PAD_BASE_SV||| +PAD_CLONE_VARS||| +PAD_COMPNAME_FLAGS||| +PAD_COMPNAME_GEN_set||| +PAD_COMPNAME_GEN||| +PAD_COMPNAME_OURSTASH||| +PAD_COMPNAME_PV||| +PAD_COMPNAME_TYPE||| +PAD_RESTORE_LOCAL||| +PAD_SAVE_LOCAL||| +PAD_SAVE_SETNULLPAD||| +PAD_SETSV||| +PAD_SET_CUR_NOSAVE||| +PAD_SET_CUR||| +PAD_SVl||| +PAD_SV||| +PERLIO_FUNCS_CAST|5.009003||p +PERLIO_FUNCS_DECL|5.009003||p +PERL_ABS|5.008001||p +PERL_BCDVERSION|5.024000||p +PERL_GCC_BRACE_GROUPS_FORBIDDEN|5.008001||p +PERL_HASH|5.003070||p +PERL_INT_MAX|5.003070||p +PERL_INT_MIN|5.003070||p +PERL_LONG_MAX|5.003070||p +PERL_LONG_MIN|5.003070||p +PERL_MAGIC_arylen|5.007002||p +PERL_MAGIC_backref|5.007002||p +PERL_MAGIC_bm|5.007002||p +PERL_MAGIC_collxfrm|5.007002||p +PERL_MAGIC_dbfile|5.007002||p +PERL_MAGIC_dbline|5.007002||p +PERL_MAGIC_defelem|5.007002||p +PERL_MAGIC_envelem|5.007002||p +PERL_MAGIC_env|5.007002||p +PERL_MAGIC_ext|5.007002||p +PERL_MAGIC_fm|5.007002||p +PERL_MAGIC_glob|5.024000||p +PERL_MAGIC_isaelem|5.007002||p +PERL_MAGIC_isa|5.007002||p +PERL_MAGIC_mutex|5.024000||p +PERL_MAGIC_nkeys|5.007002||p +PERL_MAGIC_overload_elem|5.024000||p +PERL_MAGIC_overload_table|5.007002||p +PERL_MAGIC_overload|5.024000||p +PERL_MAGIC_pos|5.007002||p +PERL_MAGIC_qr|5.007002||p +PERL_MAGIC_regdata|5.007002||p +PERL_MAGIC_regdatum|5.007002||p +PERL_MAGIC_regex_global|5.007002||p +PERL_MAGIC_shared_scalar|5.007003||p +PERL_MAGIC_shared|5.007003||p +PERL_MAGIC_sigelem|5.007002||p +PERL_MAGIC_sig|5.007002||p +PERL_MAGIC_substr|5.007002||p +PERL_MAGIC_sv|5.007002||p +PERL_MAGIC_taint|5.007002||p +PERL_MAGIC_tiedelem|5.007002||p +PERL_MAGIC_tiedscalar|5.007002||p +PERL_MAGIC_tied|5.007002||p +PERL_MAGIC_utf8|5.008001||p +PERL_MAGIC_uvar_elem|5.007003||p +PERL_MAGIC_uvar|5.007002||p +PERL_MAGIC_vec|5.007002||p +PERL_MAGIC_vstring|5.008001||p +PERL_PV_ESCAPE_ALL|5.009004||p +PERL_PV_ESCAPE_FIRSTCHAR|5.009004||p +PERL_PV_ESCAPE_NOBACKSLASH|5.009004||p +PERL_PV_ESCAPE_NOCLEAR|5.009004||p +PERL_PV_ESCAPE_QUOTE|5.009004||p +PERL_PV_ESCAPE_RE|5.009005||p +PERL_PV_ESCAPE_UNI_DETECT|5.009004||p +PERL_PV_ESCAPE_UNI|5.009004||p +PERL_PV_PRETTY_DUMP|5.009004||p +PERL_PV_PRETTY_ELLIPSES|5.010000||p +PERL_PV_PRETTY_LTGT|5.009004||p +PERL_PV_PRETTY_NOCLEAR|5.010000||p +PERL_PV_PRETTY_QUOTE|5.009004||p +PERL_PV_PRETTY_REGPROP|5.009004||p +PERL_QUAD_MAX|5.003070||p +PERL_QUAD_MIN|5.003070||p +PERL_REVISION|5.006000||p +PERL_SCAN_ALLOW_UNDERSCORES|5.007003||p +PERL_SCAN_DISALLOW_PREFIX|5.007003||p +PERL_SCAN_GREATER_THAN_UV_MAX|5.007003||p +PERL_SCAN_SILENT_ILLDIGIT|5.008001||p +PERL_SHORT_MAX|5.003070||p +PERL_SHORT_MIN|5.003070||p +PERL_SIGNALS_UNSAFE_FLAG|5.008001||p +PERL_SUBVERSION|5.006000||p +PERL_SYS_INIT3||5.006000| +PERL_SYS_INIT||| +PERL_SYS_TERM||5.024000| +PERL_UCHAR_MAX|5.003070||p +PERL_UCHAR_MIN|5.003070||p +PERL_UINT_MAX|5.003070||p +PERL_UINT_MIN|5.003070||p +PERL_ULONG_MAX|5.003070||p +PERL_ULONG_MIN|5.003070||p +PERL_UNUSED_ARG|5.009003||p +PERL_UNUSED_CONTEXT|5.009004||p +PERL_UNUSED_DECL|5.007002||p +PERL_UNUSED_RESULT|5.021001||p +PERL_UNUSED_VAR|5.007002||p +PERL_UQUAD_MAX|5.003070||p +PERL_UQUAD_MIN|5.003070||p +PERL_USE_GCC_BRACE_GROUPS|5.009004||p +PERL_USHORT_MAX|5.003070||p +PERL_USHORT_MIN|5.003070||p +PERL_VERSION|5.006000||p +PL_DBsignal|5.005000||p +PL_DBsingle|||pn +PL_DBsub|||pn +PL_DBtrace|||pn +PL_Sv|5.005000||p +PL_bufend|5.024000||p +PL_bufptr|5.024000||p +PL_check||5.006000| +PL_compiling|5.004050||p +PL_comppad_name||5.017004| +PL_comppad||5.008001| +PL_copline|5.024000||p +PL_curcop|5.004050||p +PL_curpad||5.005000| +PL_curstash|5.004050||p +PL_debstash|5.004050||p +PL_defgv|5.004050||p +PL_diehook|5.004050||p +PL_dirty|5.004050||p +PL_dowarn|||pn +PL_errgv|5.004050||p +PL_error_count|5.024000||p +PL_expect|5.024000||p +PL_hexdigit|5.005000||p +PL_hints|5.005000||p +PL_in_my_stash|5.024000||p +PL_in_my|5.024000||p +PL_keyword_plugin||5.011002| +PL_last_in_gv|||n +PL_laststatval|5.005000||p +PL_lex_state|5.024000||p +PL_lex_stuff|5.024000||p +PL_linestr|5.024000||p +PL_modglobal||5.005000|n +PL_na|5.004050||pn +PL_no_modify|5.006000||p +PL_ofsgv|||n +PL_opfreehook||5.011000|n +PL_parser|5.009005||p +PL_peepp||5.007003|n +PL_perl_destruct_level|5.004050||p +PL_perldb|5.004050||p +PL_ppaddr|5.006000||p +PL_rpeepp||5.013005|n +PL_rsfp_filters|5.024000||p +PL_rsfp|5.024000||p +PL_rs|||n +PL_signals|5.008001||p +PL_stack_base|5.004050||p +PL_stack_sp|5.004050||p +PL_statcache|5.005000||p +PL_stdingv|5.004050||p +PL_sv_arenaroot|5.004050||p +PL_sv_no|5.004050||pn +PL_sv_undef|5.004050||pn +PL_sv_yes|5.004050||pn +PL_tainted|5.004050||p +PL_tainting|5.004050||p +PL_tokenbuf|5.024000||p +POP_MULTICALL||5.024000| +POPi|||n +POPl|||n +POPn|||n +POPpbytex||5.007001|n +POPpx||5.005030|n +POPp|||n +POPs|||n +POPul||5.006000|n +POPu||5.004000|n +PTR2IV|5.006000||p +PTR2NV|5.006000||p +PTR2UV|5.006000||p +PTR2nat|5.009003||p +PTR2ul|5.007001||p +PTRV|5.006000||p +PUSHMARK||| +PUSH_MULTICALL||5.024000| +PUSHi||| +PUSHmortal|5.009002||p +PUSHn||| +PUSHp||| +PUSHs||| +PUSHu|5.004000||p +PUTBACK||| +PadARRAY||5.024000| +PadMAX||5.024000| +PadlistARRAY||5.024000| +PadlistMAX||5.024000| +PadlistNAMESARRAY||5.024000| +PadlistNAMESMAX||5.024000| +PadlistNAMES||5.024000| +PadlistREFCNT||5.017004| +PadnameIsOUR||| +PadnameIsSTATE||| +PadnameLEN||5.024000| +PadnameOURSTASH||| +PadnameOUTER||| +PadnamePV||5.024000| +PadnameREFCNT_dec||5.024000| +PadnameREFCNT||5.024000| +PadnameSV||5.024000| +PadnameTYPE||| +PadnameUTF8||5.021007| +PadnamelistARRAY||5.024000| +PadnamelistMAX||5.024000| +PadnamelistREFCNT_dec||5.024000| +PadnamelistREFCNT||5.024000| +PerlIO_clearerr||5.007003| +PerlIO_close||5.007003| +PerlIO_context_layers||5.009004| +PerlIO_eof||5.007003| +PerlIO_error||5.007003| +PerlIO_fileno||5.007003| +PerlIO_fill||5.007003| +PerlIO_flush||5.007003| +PerlIO_get_base||5.007003| +PerlIO_get_bufsiz||5.007003| +PerlIO_get_cnt||5.007003| +PerlIO_get_ptr||5.007003| +PerlIO_read||5.007003| +PerlIO_restore_errno||| +PerlIO_save_errno||| +PerlIO_seek||5.007003| +PerlIO_set_cnt||5.007003| +PerlIO_set_ptrcnt||5.007003| +PerlIO_setlinebuf||5.007003| +PerlIO_stderr||5.007003| +PerlIO_stdin||5.007003| +PerlIO_stdout||5.007003| +PerlIO_tell||5.007003| +PerlIO_unread||5.007003| +PerlIO_write||5.007003| +Perl_signbit||5.009005|n +PoisonFree|5.009004||p +PoisonNew|5.009004||p +PoisonWith|5.009004||p +Poison|5.008000||p +READ_XDIGIT||5.017006| +RESTORE_LC_NUMERIC||5.024000| +RETVAL|||n +Renewc||| +Renew||| +SAVECLEARSV||| +SAVECOMPPAD||| +SAVEPADSV||| +SAVETMPS||| +SAVE_DEFSV|5.004050||p +SPAGAIN||| +SP||| +START_EXTERN_C|5.005000||p +START_MY_CXT|5.007003||p +STMT_END|||p +STMT_START|||p +STORE_LC_NUMERIC_FORCE_TO_UNDERLYING||5.024000| +STORE_LC_NUMERIC_SET_TO_NEEDED||5.024000| +STR_WITH_LEN|5.009003||p +ST||| +SV_CONST_RETURN|5.009003||p +SV_COW_DROP_PV|5.008001||p +SV_COW_SHARED_HASH_KEYS|5.009005||p +SV_GMAGIC|5.007002||p +SV_HAS_TRAILING_NUL|5.009004||p +SV_IMMEDIATE_UNREF|5.007001||p +SV_MUTABLE_RETURN|5.009003||p +SV_NOSTEAL|5.009002||p +SV_SMAGIC|5.009003||p +SV_UTF8_NO_ENCODING|5.008001||p +SVfARG|5.009005||p +SVf_UTF8|5.006000||p +SVf|5.006000||p +SVt_INVLIST||5.019002| +SVt_IV||| +SVt_NULL||| +SVt_NV||| +SVt_PVAV||| +SVt_PVCV||| +SVt_PVFM||| +SVt_PVGV||| +SVt_PVHV||| +SVt_PVIO||| +SVt_PVIV||| +SVt_PVLV||| +SVt_PVMG||| +SVt_PVNV||| +SVt_PV||| +SVt_REGEXP||5.011000| +Safefree||| +Slab_Alloc||| +Slab_Free||| +Slab_to_ro||| +Slab_to_rw||| +StructCopy||| +SvCUR_set||| +SvCUR||| +SvEND||| +SvGAMAGIC||5.006001| +SvGETMAGIC|5.004050||p +SvGROW||| +SvIOK_UV||5.006000| +SvIOK_notUV||5.006000| +SvIOK_off||| +SvIOK_only_UV||5.006000| +SvIOK_only||| +SvIOK_on||| +SvIOKp||| +SvIOK||| +SvIVX||| +SvIV_nomg|5.009001||p +SvIV_set||| +SvIVx||| +SvIV||| +SvIsCOW_shared_hash||5.008003| +SvIsCOW||5.008003| +SvLEN_set||| +SvLEN||| +SvLOCK||5.007003| +SvMAGIC_set|5.009003||p +SvNIOK_off||| +SvNIOKp||| +SvNIOK||| +SvNOK_off||| +SvNOK_only||| +SvNOK_on||| +SvNOKp||| +SvNOK||| +SvNVX||| +SvNV_nomg||5.013002| +SvNV_set||| +SvNVx||| +SvNV||| +SvOK||| +SvOOK_offset||5.011000| +SvOOK||| +SvPOK_off||| +SvPOK_only_UTF8||5.006000| +SvPOK_only||| +SvPOK_on||| +SvPOKp||| +SvPOK||| +SvPVX_const|5.009003||p +SvPVX_mutable|5.009003||p +SvPVX||| +SvPV_const|5.009003||p +SvPV_flags_const_nolen|5.009003||p +SvPV_flags_const|5.009003||p +SvPV_flags_mutable|5.009003||p +SvPV_flags|5.007002||p +SvPV_force_flags_mutable|5.009003||p +SvPV_force_flags_nolen|5.009003||p +SvPV_force_flags|5.007002||p +SvPV_force_mutable|5.009003||p +SvPV_force_nolen|5.009003||p +SvPV_force_nomg_nolen|5.009003||p +SvPV_force_nomg|5.007002||p +SvPV_force|||p +SvPV_mutable|5.009003||p +SvPV_nolen_const|5.009003||p +SvPV_nolen|5.006000||p +SvPV_nomg_const_nolen|5.009003||p +SvPV_nomg_const|5.009003||p +SvPV_nomg_nolen|5.013007||p +SvPV_nomg|5.007002||p +SvPV_renew|5.009003||p +SvPV_set||| +SvPVbyte_force||5.009002| +SvPVbyte_nolen||5.006000| +SvPVbytex_force||5.006000| +SvPVbytex||5.006000| +SvPVbyte|5.006000||p +SvPVutf8_force||5.006000| +SvPVutf8_nolen||5.006000| +SvPVutf8x_force||5.006000| +SvPVutf8x||5.006000| +SvPVutf8||5.006000| +SvPVx||| +SvPV||| +SvREFCNT_dec_NN||5.017007| +SvREFCNT_dec||| +SvREFCNT_inc_NN|5.009004||p +SvREFCNT_inc_simple_NN|5.009004||p +SvREFCNT_inc_simple_void_NN|5.009004||p +SvREFCNT_inc_simple_void|5.009004||p +SvREFCNT_inc_simple|5.009004||p +SvREFCNT_inc_void_NN|5.009004||p +SvREFCNT_inc_void|5.009004||p +SvREFCNT_inc|||p +SvREFCNT||| +SvROK_off||| +SvROK_on||| +SvROK||| +SvRV_set|5.009003||p +SvRV||| +SvRXOK|5.009005||p +SvRX|5.009005||p +SvSETMAGIC||| +SvSHARED_HASH|5.009003||p +SvSHARE||5.007003| +SvSTASH_set|5.009003||p +SvSTASH||| +SvSetMagicSV_nosteal||5.004000| +SvSetMagicSV||5.004000| +SvSetSV_nosteal||5.004000| +SvSetSV||| +SvTAINTED_off||5.004000| +SvTAINTED_on||5.004000| +SvTAINTED||5.004000| +SvTAINT||| +SvTHINKFIRST||| +SvTRUE_nomg||5.013006| +SvTRUE||| +SvTYPE||| +SvUNLOCK||5.007003| +SvUOK|5.007001|5.006000|p +SvUPGRADE||| +SvUTF8_off||5.006000| +SvUTF8_on||5.006000| +SvUTF8||5.006000| +SvUVXx|5.004000||p +SvUVX|5.004000||p +SvUV_nomg|5.009001||p +SvUV_set|5.009003||p +SvUVx|5.004000||p +SvUV|5.004000||p +SvVOK||5.008001| +SvVSTRING_mg|5.009004||p +THIS|||n +UNDERBAR|5.009002||p +UTF8SKIP||5.006000| +UTF8_MAXBYTES|5.009002||p +UVCHR_SKIP||5.022000| +UVSIZE|5.006000||p +UVTYPE|5.006000||p +UVXf|5.007001||p +UVof|5.006000||p +UVuf|5.006000||p +UVxf|5.006000||p +WARN_ALL|5.006000||p +WARN_AMBIGUOUS|5.006000||p +WARN_ASSERTIONS|5.024000||p +WARN_BAREWORD|5.006000||p +WARN_CLOSED|5.006000||p +WARN_CLOSURE|5.006000||p +WARN_DEBUGGING|5.006000||p +WARN_DEPRECATED|5.006000||p +WARN_DIGIT|5.006000||p +WARN_EXEC|5.006000||p +WARN_EXITING|5.006000||p +WARN_GLOB|5.006000||p +WARN_INPLACE|5.006000||p +WARN_INTERNAL|5.006000||p +WARN_IO|5.006000||p +WARN_LAYER|5.008000||p +WARN_MALLOC|5.006000||p +WARN_MISC|5.006000||p +WARN_NEWLINE|5.006000||p +WARN_NUMERIC|5.006000||p +WARN_ONCE|5.006000||p +WARN_OVERFLOW|5.006000||p +WARN_PACK|5.006000||p +WARN_PARENTHESIS|5.006000||p +WARN_PIPE|5.006000||p +WARN_PORTABLE|5.006000||p +WARN_PRECEDENCE|5.006000||p +WARN_PRINTF|5.006000||p +WARN_PROTOTYPE|5.006000||p +WARN_QW|5.006000||p +WARN_RECURSION|5.006000||p +WARN_REDEFINE|5.006000||p +WARN_REGEXP|5.006000||p +WARN_RESERVED|5.006000||p +WARN_SEMICOLON|5.006000||p +WARN_SEVERE|5.006000||p +WARN_SIGNAL|5.006000||p +WARN_SUBSTR|5.006000||p +WARN_SYNTAX|5.006000||p +WARN_TAINT|5.006000||p +WARN_THREADS|5.008000||p +WARN_UNINITIALIZED|5.006000||p +WARN_UNOPENED|5.006000||p +WARN_UNPACK|5.006000||p +WARN_UNTIE|5.006000||p +WARN_UTF8|5.006000||p +WARN_VOID|5.006000||p +WIDEST_UTYPE|5.015004||p +XCPT_CATCH|5.009002||p +XCPT_RETHROW|5.009002||p +XCPT_TRY_END|5.009002||p +XCPT_TRY_START|5.009002||p +XPUSHi||| +XPUSHmortal|5.009002||p +XPUSHn||| +XPUSHp||| +XPUSHs||| +XPUSHu|5.004000||p +XSPROTO|5.010000||p +XSRETURN_EMPTY||| +XSRETURN_IV||| +XSRETURN_NO||| +XSRETURN_NV||| +XSRETURN_PV||| +XSRETURN_UNDEF||| +XSRETURN_UV|5.008001||p +XSRETURN_YES||| +XSRETURN|||p +XST_mIV||| +XST_mNO||| +XST_mNV||| +XST_mPV||| +XST_mUNDEF||| +XST_mUV|5.008001||p +XST_mYES||| +XS_APIVERSION_BOOTCHECK||5.024000| +XS_EXTERNAL||5.024000| +XS_INTERNAL||5.024000| +XS_VERSION_BOOTCHECK||5.024000| +XS_VERSION||| +XSprePUSH|5.006000||p +XS||| +XopDISABLE||5.024000| +XopENABLE||5.024000| +XopENTRYCUSTOM||5.024000| +XopENTRY_set||5.024000| +XopENTRY||5.024000| +XopFLAGS||5.013007| +ZeroD|5.009002||p +Zero||| +_aMY_CXT|5.007003||p +_add_range_to_invlist||| +_append_range_to_invlist||| +_core_swash_init||| +_get_encoding||| +_get_regclass_nonbitmap_data||| +_get_swash_invlist||| +_invlistEQ||| +_invlist_array_init|||n +_invlist_contains_cp|||n +_invlist_dump||| +_invlist_intersection_maybe_complement_2nd||| +_invlist_intersection||| +_invlist_invert||| +_invlist_len|||n +_invlist_populate_swatch|||n +_invlist_search|||n +_invlist_subtract||| +_invlist_union_maybe_complement_2nd||| +_invlist_union||| +_is_cur_LC_category_utf8||| +_is_in_locale_category||5.021001| +_is_uni_FOO||5.017008| +_is_uni_perl_idcont||5.017008| +_is_uni_perl_idstart||5.017007| +_is_utf8_FOO||5.017008| +_is_utf8_char_slow||5.021001|n +_is_utf8_idcont||5.021001| +_is_utf8_idstart||5.021001| +_is_utf8_mark||5.017008| +_is_utf8_perl_idcont||5.017008| +_is_utf8_perl_idstart||5.017007| +_is_utf8_xidcont||5.021001| +_is_utf8_xidstart||5.021001| +_load_PL_utf8_foldclosures||| +_make_exactf_invlist||| +_new_invlist_C_array||| +_new_invlist||| +_pMY_CXT|5.007003||p +_setlocale_debug_string|||n +_setup_canned_invlist||| +_swash_inversion_hash||| +_swash_to_invlist||| +_to_fold_latin1||| +_to_uni_fold_flags||5.014000| +_to_upper_title_latin1||| +_to_utf8_case||| +_to_utf8_fold_flags||5.019009| +_to_utf8_lower_flags||5.019009| +_to_utf8_title_flags||5.019009| +_to_utf8_upper_flags||5.019009| +_warn_problematic_locale|||n +aMY_CXT_|5.007003||p +aMY_CXT|5.007003||p +aTHXR_|5.024000||p +aTHXR|5.024000||p +aTHX_|5.006000||p +aTHX|5.006000||p +add_above_Latin1_folds||| +add_cp_to_invlist||| +add_data|||n +add_multi_match||| +add_utf16_textfilter||| +adjust_size_and_find_bucket|||n +advance_one_LB||| +advance_one_SB||| +advance_one_WB||| +alloc_maybe_populate_EXACT||| +alloccopstash||| +allocmy||| +amagic_call||| +amagic_cmp_locale||| +amagic_cmp||| +amagic_deref_call||5.013007| +amagic_i_ncmp||| +amagic_is_enabled||| +amagic_ncmp||| +anonymise_cv_maybe||| +any_dup||| +ao||| +append_utf8_from_native_byte||5.019004|n +apply_attrs_my||| +apply_attrs_string||5.006001| +apply_attrs||| +apply||| +assert_uft8_cache_coherent||| +assignment_type||| +atfork_lock||5.007003|n +atfork_unlock||5.007003|n +av_arylen_p||5.009003| +av_clear||| +av_create_and_push||5.009005| +av_create_and_unshift_one||5.009005| +av_delete||5.006000| +av_exists||5.006000| +av_extend_guts||| +av_extend||| +av_fetch||| +av_fill||| +av_iter_p||5.011000| +av_len||| +av_make||| +av_pop||| +av_push||| +av_reify||| +av_shift||| +av_store||| +av_tindex||5.017009| +av_top_index||5.017009| +av_undef||| +av_unshift||| +ax|||n +backup_one_LB||| +backup_one_SB||| +backup_one_WB||| +bad_type_gv||| +bad_type_pv||| +bind_match||| +block_end||5.004000| +block_gimme||5.004000| +block_start||5.004000| +blockhook_register||5.013003| +boolSV|5.004000||p +boot_core_PerlIO||| +boot_core_UNIVERSAL||| +boot_core_mro||| +bytes_cmp_utf8||5.013007| +bytes_from_utf8||5.007001| +bytes_to_utf8||5.006001| +cBOOL|5.013000||p +call_argv|5.006000||p +call_atexit||5.006000| +call_list||5.004000| +call_method|5.006000||p +call_pv|5.006000||p +call_sv|5.006000||p +caller_cx|5.013005|5.006000|p +calloc||5.007002|n +cando||| +cast_i32||5.006000|n +cast_iv||5.006000|n +cast_ulong||5.006000|n +cast_uv||5.006000|n +check_locale_boundary_crossing||| +check_type_and_open||| +check_uni||| +check_utf8_print||| +checkcomma||| +ckWARN|5.006000||p +ck_entersub_args_core||| +ck_entersub_args_list||5.013006| +ck_entersub_args_proto_or_list||5.013006| +ck_entersub_args_proto||5.013006| +ck_warner_d||5.011001|v +ck_warner||5.011001|v +ckwarn_common||| +ckwarn_d||5.009003| +ckwarn||5.009003| +clear_defarray||5.023008| +clear_placeholders||| +clear_special_blocks||| +clone_params_del|||n +clone_params_new|||n +closest_cop||| +cntrl_to_mnemonic|||n +compute_EXACTish|||n +construct_ahocorasick_from_trie||| +cop_fetch_label||5.015001| +cop_free||| +cop_hints_2hv||5.013007| +cop_hints_fetch_pvn||5.013007| +cop_hints_fetch_pvs||5.013007| +cop_hints_fetch_pv||5.013007| +cop_hints_fetch_sv||5.013007| +cop_store_label||5.015001| +cophh_2hv||5.013007| +cophh_copy||5.013007| +cophh_delete_pvn||5.013007| +cophh_delete_pvs||5.013007| +cophh_delete_pv||5.013007| +cophh_delete_sv||5.013007| +cophh_fetch_pvn||5.013007| +cophh_fetch_pvs||5.013007| +cophh_fetch_pv||5.013007| +cophh_fetch_sv||5.013007| +cophh_free||5.013007| +cophh_new_empty||5.024000| +cophh_store_pvn||5.013007| +cophh_store_pvs||5.013007| +cophh_store_pv||5.013007| +cophh_store_sv||5.013007| +core_prototype||| +coresub_op||| +cr_textfilter||| +create_eval_scope||| +croak_memory_wrap||5.019003|n +croak_no_mem|||n +croak_no_modify||5.013003|n +croak_nocontext|||vn +croak_popstack|||n +croak_sv||5.013001| +croak_xs_usage||5.010001|n +croak|||v +csighandler||5.009003|n +current_re_engine||| +curse||| +custom_op_desc||5.007003| +custom_op_get_field||| +custom_op_name||5.007003| +custom_op_register||5.013007| +custom_op_xop||5.013007| +cv_ckproto_len_flags||| +cv_clone_into||| +cv_clone||| +cv_const_sv_or_av|||n +cv_const_sv||5.003070|n +cv_dump||| +cv_forget_slab||| +cv_get_call_checker||5.013006| +cv_name||5.021005| +cv_set_call_checker_flags||5.021004| +cv_set_call_checker||5.013006| +cv_undef_flags||| +cv_undef||| +cvgv_from_hek||| +cvgv_set||| +cvstash_set||| +cx_dump||5.005000| +cx_dup||| +cx_popblock||5.023008| +cx_popeval||5.023008| +cx_popformat||5.023008| +cx_popgiven||5.023008| +cx_poploop||5.023008| +cx_popsub_args||5.023008| +cx_popsub_common||5.023008| +cx_popsub||5.023008| +cx_popwhen||5.023008| +cx_pushblock||5.023008| +cx_pusheval||5.023008| +cx_pushformat||5.023008| +cx_pushgiven||5.023008| +cx_pushloop_for||5.023008| +cx_pushloop_plain||5.023008| +cx_pushsub||5.023008| +cx_pushwhen||5.023008| +cx_topblock||5.023008| +cxinc||| +dAXMARK|5.009003||p +dAX|5.007002||p +dITEMS|5.007002||p +dMARK||| +dMULTICALL||5.009003| +dMY_CXT_SV|5.007003||p +dMY_CXT|5.007003||p +dNOOP|5.006000||p +dORIGMARK||| +dSP||| +dTHR|5.004050||p +dTHXR|5.024000||p +dTHXa|5.006000||p +dTHXoa|5.006000||p +dTHX|5.006000||p +dUNDERBAR|5.009002||p +dVAR|5.009003||p +dXCPT|5.009002||p +dXSARGS||| +dXSI32||| +dXSTARG|5.006000||p +deb_curcv||| +deb_nocontext|||vn +deb_stack_all||| +deb_stack_n||| +debop||5.005000| +debprofdump||5.005000| +debprof||| +debstackptrs||5.007003| +debstack||5.007003| +debug_start_match||| +deb||5.007003|v +defelem_target||| +del_sv||| +delete_eval_scope||| +delimcpy||5.004000|n +deprecate_commaless_var_list||| +despatch_signals||5.007001| +destroy_matcher||| +die_nocontext|||vn +die_sv||5.013001| +die_unwind||| +die|||v +dirp_dup||| +div128||| +djSP||| +do_aexec5||| +do_aexec||| +do_aspawn||| +do_binmode||5.004050| +do_chomp||| +do_close||| +do_delete_local||| +do_dump_pad||| +do_eof||| +do_exec3||| +do_execfree||| +do_exec||| +do_gv_dump||5.006000| +do_gvgv_dump||5.006000| +do_hv_dump||5.006000| +do_ipcctl||| +do_ipcget||| +do_join||| +do_magic_dump||5.006000| +do_msgrcv||| +do_msgsnd||| +do_ncmp||| +do_oddball||| +do_op_dump||5.006000| +do_open6||| +do_open9||5.006000| +do_open_raw||| +do_openn||5.007001| +do_open||5.003070| +do_pmop_dump||5.006000| +do_print||| +do_readline||| +do_seek||| +do_semop||| +do_shmio||| +do_smartmatch||| +do_spawn_nowait||| +do_spawn||| +do_sprintf||| +do_sv_dump||5.006000| +do_sysseek||| +do_tell||| +do_trans_complex_utf8||| +do_trans_complex||| +do_trans_count_utf8||| +do_trans_count||| +do_trans_simple_utf8||| +do_trans_simple||| +do_trans||| +do_vecget||| +do_vecset||| +do_vop||| +docatch||| +doeval_compile||| +dofile||| +dofindlabel||| +doform||| +doing_taint||5.008001|n +dooneliner||| +doopen_pm||| +doparseform||| +dopoptoeval||| +dopoptogivenfor||| +dopoptolabel||| +dopoptoloop||| +dopoptosub_at||| +dopoptowhen||| +doref||5.009003| +dounwind||| +dowantarray||| +drand48_init_r|||n +drand48_r|||n +dtrace_probe_call||| +dtrace_probe_load||| +dtrace_probe_op||| +dtrace_probe_phase||| +dump_all_perl||| +dump_all||5.006000| +dump_c_backtrace||| +dump_eval||5.006000| +dump_exec_pos||| +dump_form||5.006000| +dump_indent||5.006000|v +dump_mstats||| +dump_packsubs_perl||| +dump_packsubs||5.006000| +dump_sub_perl||| +dump_sub||5.006000| +dump_sv_child||| +dump_trie_interim_list||| +dump_trie_interim_table||| +dump_trie||| +dump_vindent||5.006000| +dumpuntil||| +dup_attrlist||| +edit_distance|||n +emulate_cop_io||| +eval_pv|5.006000||p +eval_sv|5.006000||p +exec_failed||| +expect_number||| +fbm_compile||5.005000| +fbm_instr||5.005000| +feature_is_enabled||| +filter_add||| +filter_del||| +filter_gets||| +filter_read||| +finalize_optree||| +finalize_op||| +find_and_forget_pmops||| +find_array_subscript||| +find_beginning||| +find_byclass||| +find_default_stash||| +find_hash_subscript||| +find_in_my_stash||| +find_lexical_cv||| +find_runcv_where||| +find_runcv||5.008001| +find_rundefsvoffset||5.009002| +find_rundefsv||5.013002| +find_script||| +find_uninit_var||| +first_symbol|||n +fixup_errno_string||| +foldEQ_latin1||5.013008|n +foldEQ_locale||5.013002|n +foldEQ_utf8_flags||5.013010| +foldEQ_utf8||5.013002| +foldEQ||5.013002|n +fold_constants||| +forbid_setid||| +force_ident_maybe_lex||| +force_ident||| +force_list||| +force_next||| +force_strict_version||| +force_version||| +force_word||| +forget_pmop||| +form_nocontext|||vn +form_short_octal_warning||| +form||5.004000|v +fp_dup||| +fprintf_nocontext|||vn +free_c_backtrace||| +free_global_struct||| +free_tied_hv_pool||| +free_tmps||| +gen_constant_list||| +get_ANYOF_cp_list_for_ssc||| +get_and_check_backslash_N_name||| +get_aux_mg||| +get_av|5.006000||p +get_c_backtrace_dump||| +get_c_backtrace||| +get_context||5.006000|n +get_cvn_flags||| +get_cvs|5.011000||p +get_cv|5.006000||p +get_db_sub||| +get_debug_opts||| +get_hash_seed||| +get_hv|5.006000||p +get_invlist_iter_addr|||n +get_invlist_offset_addr|||n +get_invlist_previous_index_addr|||n +get_mstats||| +get_no_modify||| +get_num||| +get_op_descs||5.005000| +get_op_names||5.005000| +get_opargs||| +get_ppaddr||5.006000| +get_re_arg||| +get_sv|5.006000||p +get_vtbl||5.005030| +getcwd_sv||5.007002| +getenv_len||| +glob_2number||| +glob_assign_glob||| +gp_dup||| +gp_free||| +gp_ref||| +grok_atoUV|||n +grok_bin|5.007003||p +grok_bslash_N||| +grok_bslash_c||| +grok_bslash_o||| +grok_bslash_x||| +grok_hex|5.007003||p +grok_infnan||5.021004| +grok_number_flags||5.021002| +grok_number|5.007002||p +grok_numeric_radix|5.007002||p +grok_oct|5.007003||p +group_end||| +gv_AVadd||| +gv_HVadd||| +gv_IOadd||| +gv_SVadd||| +gv_add_by_type||5.011000| +gv_autoload4||5.004000| +gv_autoload_pvn||5.015004| +gv_autoload_pv||5.015004| +gv_autoload_sv||5.015004| +gv_check||| +gv_const_sv||5.009003| +gv_dump||5.006000| +gv_efullname3||5.003070| +gv_efullname4||5.006001| +gv_efullname||| +gv_fetchfile_flags||5.009005| +gv_fetchfile||| +gv_fetchmeth_autoload||5.007003| +gv_fetchmeth_internal||| +gv_fetchmeth_pv_autoload||5.015004| +gv_fetchmeth_pvn_autoload||5.015004| +gv_fetchmeth_pvn||5.015004| +gv_fetchmeth_pv||5.015004| +gv_fetchmeth_sv_autoload||5.015004| +gv_fetchmeth_sv||5.015004| +gv_fetchmethod_autoload||5.004000| +gv_fetchmethod_pv_flags||5.015004| +gv_fetchmethod_pvn_flags||5.015004| +gv_fetchmethod_sv_flags||5.015004| +gv_fetchmethod||| +gv_fetchmeth||| +gv_fetchpvn_flags|5.009002||p +gv_fetchpvs|5.009004||p +gv_fetchpv||| +gv_fetchsv||| +gv_fullname3||5.003070| +gv_fullname4||5.006001| +gv_fullname||| +gv_handler||5.007001| +gv_init_pvn||| +gv_init_pv||5.015004| +gv_init_svtype||| +gv_init_sv||5.015004| +gv_init||| +gv_is_in_main||| +gv_magicalize_isa||| +gv_magicalize||| +gv_name_set||5.009004| +gv_override||| +gv_setref||| +gv_stashpvn_internal||| +gv_stashpvn|5.003070||p +gv_stashpvs|5.009003||p +gv_stashpv||| +gv_stashsvpvn_cached||| +gv_stashsv||| +gv_try_downgrade||| +handle_named_backref||| +handle_possible_posix||| +handle_regex_sets||| +he_dup||| +hek_dup||| +hfree_next_entry||| +hfreeentries||| +hsplit||| +hv_assert||| +hv_auxinit_internal|||n +hv_auxinit||| +hv_backreferences_p||| +hv_clear_placeholders||5.009001| +hv_clear||| +hv_common_key_len||5.010000| +hv_common||5.010000| +hv_copy_hints_hv||5.009004| +hv_delayfree_ent||5.004000| +hv_delete_common||| +hv_delete_ent||5.003070| +hv_delete||| +hv_eiter_p||5.009003| +hv_eiter_set||5.009003| +hv_ename_add||| +hv_ename_delete||| +hv_exists_ent||5.003070| +hv_exists||| +hv_fetch_ent||5.003070| +hv_fetchs|5.009003||p +hv_fetch||| +hv_fill||5.013002| +hv_free_ent_ret||| +hv_free_ent||5.004000| +hv_iterinit||| +hv_iterkeysv||5.003070| +hv_iterkey||| +hv_iternext_flags||5.008000| +hv_iternextsv||| +hv_iternext||| +hv_iterval||| +hv_kill_backrefs||| +hv_ksplit||5.003070| +hv_magic_check|||n +hv_magic||| +hv_name_set||5.009003| +hv_notallowed||| +hv_placeholders_get||5.009003| +hv_placeholders_p||| +hv_placeholders_set||5.009003| +hv_rand_set||5.018000| +hv_riter_p||5.009003| +hv_riter_set||5.009003| +hv_scalar||5.009001| +hv_store_ent||5.003070| +hv_store_flags||5.008000| +hv_stores|5.009004||p +hv_store||| +hv_undef_flags||| +hv_undef||| +ibcmp_locale||5.004000| +ibcmp_utf8||5.007003| +ibcmp||| +incline||| +incpush_if_exists||| +incpush_use_sep||| +incpush||| +ingroup||| +init_argv_symbols||| +init_constants||| +init_dbargs||| +init_debugger||| +init_global_struct||| +init_i18nl10n||5.006000| +init_i18nl14n||5.006000| +init_ids||| +init_interp||| +init_main_stash||| +init_perllib||| +init_postdump_symbols||| +init_predump_symbols||| +init_stacks||5.005000| +init_tm||5.007002| +inplace_aassign||| +instr|||n +intro_my||5.004000| +intuit_method||| +intuit_more||| +invert||| +invlist_array|||n +invlist_clear||| +invlist_clone||| +invlist_contents||| +invlist_extend||| +invlist_highest|||n +invlist_is_iterating|||n +invlist_iterfinish|||n +invlist_iterinit|||n +invlist_iternext|||n +invlist_max|||n +invlist_previous_index|||n +invlist_replace_list_destroys_src||| +invlist_set_len||| +invlist_set_previous_index|||n +invlist_trim|||n +invoke_exception_hook||| +io_close||| +isALNUMC|5.006000||p +isALNUM_lazy||5.021001| +isALPHANUMERIC||5.017008| +isALPHA||| +isASCII|5.006000||p +isBLANK|5.006001||p +isCNTRL|5.006000||p +isDIGIT||| +isFOO_lc||| +isFOO_utf8_lc||| +isGCB|||n +isGRAPH|5.006000||p +isIDCONT||5.017008| +isIDFIRST_lazy||5.021001| +isIDFIRST||| +isLB||| +isLOWER||| +isOCTAL||5.013005| +isPRINT|5.004000||p +isPSXSPC|5.006001||p +isPUNCT|5.006000||p +isSB||| +isSPACE||| +isUPPER||| +isUTF8_CHAR||5.021001| +isWB||| +isWORDCHAR||5.013006| +isXDIGIT|5.006000||p +is_an_int||| +is_ascii_string||5.011000| +is_handle_constructor|||n +is_invariant_string||5.021007|n +is_lvalue_sub||5.007001| +is_safe_syscall||5.019004| +is_ssc_worth_it|||n +is_uni_alnum_lc||5.006000| +is_uni_alnumc_lc||5.017007| +is_uni_alnumc||5.017007| +is_uni_alnum||5.006000| +is_uni_alpha_lc||5.006000| +is_uni_alpha||5.006000| +is_uni_ascii_lc||5.006000| +is_uni_ascii||5.006000| +is_uni_blank_lc||5.017002| +is_uni_blank||5.017002| +is_uni_cntrl_lc||5.006000| +is_uni_cntrl||5.006000| +is_uni_digit_lc||5.006000| +is_uni_digit||5.006000| +is_uni_graph_lc||5.006000| +is_uni_graph||5.006000| +is_uni_idfirst_lc||5.006000| +is_uni_idfirst||5.006000| +is_uni_lower_lc||5.006000| +is_uni_lower||5.006000| +is_uni_print_lc||5.006000| +is_uni_print||5.006000| +is_uni_punct_lc||5.006000| +is_uni_punct||5.006000| +is_uni_space_lc||5.006000| +is_uni_space||5.006000| +is_uni_upper_lc||5.006000| +is_uni_upper||5.006000| +is_uni_xdigit_lc||5.006000| +is_uni_xdigit||5.006000| +is_utf8_alnumc||5.017007| +is_utf8_alnum||5.006000| +is_utf8_alpha||5.006000| +is_utf8_ascii||5.006000| +is_utf8_blank||5.017002| +is_utf8_char_buf||5.015008|n +is_utf8_char||5.006000|n +is_utf8_cntrl||5.006000| +is_utf8_common||| +is_utf8_digit||5.006000| +is_utf8_graph||5.006000| +is_utf8_idcont||5.008000| +is_utf8_idfirst||5.006000| +is_utf8_lower||5.006000| +is_utf8_mark||5.006000| +is_utf8_perl_space||5.011001| +is_utf8_perl_word||5.011001| +is_utf8_posix_digit||5.011001| +is_utf8_print||5.006000| +is_utf8_punct||5.006000| +is_utf8_space||5.006000| +is_utf8_string_loclen||5.009003|n +is_utf8_string_loc||5.008001|n +is_utf8_string||5.006001|n +is_utf8_upper||5.006000| +is_utf8_xdigit||5.006000| +is_utf8_xidcont||5.013010| +is_utf8_xidfirst||5.013010| +isa_lookup||| +isinfnansv||| +isinfnan||5.021004|n +items|||n +ix|||n +jmaybe||| +join_exact||| +keyword_plugin_standard||| +keyword||| +leave_adjust_stacks||5.023008| +leave_scope||| +lex_bufutf8||5.011002| +lex_discard_to||5.011002| +lex_grow_linestr||5.011002| +lex_next_chunk||5.011002| +lex_peek_unichar||5.011002| +lex_read_space||5.011002| +lex_read_to||5.011002| +lex_read_unichar||5.011002| +lex_start||5.009005| +lex_stuff_pvn||5.011002| +lex_stuff_pvs||5.013005| +lex_stuff_pv||5.013006| +lex_stuff_sv||5.011002| +lex_unstuff||5.011002| +listkids||| +list||| +load_module_nocontext|||vn +load_module|5.006000||pv +localize||| +looks_like_bool||| +looks_like_number||| +lop||| +mPUSHi|5.009002||p +mPUSHn|5.009002||p +mPUSHp|5.009002||p +mPUSHs|5.010001||p +mPUSHu|5.009002||p +mXPUSHi|5.009002||p +mXPUSHn|5.009002||p +mXPUSHp|5.009002||p +mXPUSHs|5.010001||p +mXPUSHu|5.009002||p +magic_clear_all_env||| +magic_cleararylen_p||| +magic_clearenv||| +magic_clearhints||| +magic_clearhint||| +magic_clearisa||| +magic_clearpack||| +magic_clearsig||| +magic_copycallchecker||| +magic_dump||5.006000| +magic_existspack||| +magic_freearylen_p||| +magic_freeovrld||| +magic_getarylen||| +magic_getdebugvar||| +magic_getdefelem||| +magic_getnkeys||| +magic_getpack||| +magic_getpos||| +magic_getsig||| +magic_getsubstr||| +magic_gettaint||| +magic_getuvar||| +magic_getvec||| +magic_get||| +magic_killbackrefs||| +magic_methcall1||| +magic_methcall|||v +magic_methpack||| +magic_nextpack||| +magic_regdata_cnt||| +magic_regdatum_get||| +magic_regdatum_set||| +magic_scalarpack||| +magic_set_all_env||| +magic_setarylen||| +magic_setcollxfrm||| +magic_setdbline||| +magic_setdebugvar||| +magic_setdefelem||| +magic_setenv||| +magic_sethint||| +magic_setisa||| +magic_setlvref||| +magic_setmglob||| +magic_setnkeys||| +magic_setpack||| +magic_setpos||| +magic_setregexp||| +magic_setsig||| +magic_setsubstr||| +magic_settaint||| +magic_setutf8||| +magic_setuvar||| +magic_setvec||| +magic_set||| +magic_sizepack||| +magic_wipepack||| +make_matcher||| +make_trie||| +malloc_good_size|||n +malloced_size|||n +malloc||5.007002|n +markstack_grow||5.021001| +matcher_matches_sv||| +maybe_multimagic_gv||| +mayberelocate||| +measure_struct||| +memEQs|5.009005||p +memEQ|5.004000||p +memNEs|5.009005||p +memNE|5.004000||p +mem_collxfrm||| +mem_log_alloc|||n +mem_log_common|||n +mem_log_free|||n +mem_log_realloc|||n +mess_alloc||| +mess_nocontext|||vn +mess_sv||5.013001| +mess||5.006000|v +mfree||5.007002|n +mg_clear||| +mg_copy||| +mg_dup||| +mg_find_mglob||| +mg_findext|5.013008||pn +mg_find|||n +mg_free_type||5.013006| +mg_free||| +mg_get||| +mg_length||5.005000| +mg_localize||| +mg_magical|||n +mg_set||| +mg_size||5.005000| +mini_mktime||5.007002|n +minus_v||| +missingterm||| +mode_from_discipline||| +modkids||| +more_bodies||| +more_sv||| +moreswitches||| +move_proto_attr||| +mro_clean_isarev||| +mro_gather_and_rename||| +mro_get_from_name||5.010001| +mro_get_linear_isa_dfs||| +mro_get_linear_isa||5.009005| +mro_get_private_data||5.010001| +mro_isa_changed_in||| +mro_meta_dup||| +mro_meta_init||| +mro_method_changed_in||5.009005| +mro_package_moved||| +mro_register||5.010001| +mro_set_mro||5.010001| +mro_set_private_data||5.010001| +mul128||| +mulexp10|||n +multideref_stringify||| +my_atof2||5.007002| +my_atof||5.006000| +my_attrs||| +my_bcopy||5.004050|n +my_bytes_to_utf8|||n +my_bzero|||n +my_chsize||| +my_clearenv||| +my_cxt_index||| +my_cxt_init||| +my_dirfd||5.009005|n +my_exit_jump||| +my_exit||| +my_failure_exit||5.004000| +my_fflush_all||5.006000| +my_fork||5.007003|n +my_kid||| +my_lstat_flags||| +my_lstat||5.024000| +my_memcmp|||n +my_memset|||n +my_pclose||5.003070| +my_popen_list||5.007001| +my_popen||5.003070| +my_setenv||| +my_setlocale||| +my_snprintf|5.009004||pvn +my_socketpair||5.007003|n +my_sprintf|5.009003||pvn +my_stat_flags||| +my_stat||5.024000| +my_strerror||5.021001| +my_strftime||5.007002| +my_strlcat|5.009004||pn +my_strlcpy|5.009004||pn +my_unexec||| +my_vsnprintf||5.009004|n +need_utf8|||n +newANONATTRSUB||5.006000| +newANONHASH||| +newANONLIST||| +newANONSUB||| +newASSIGNOP||| +newATTRSUB_x||| +newATTRSUB||5.006000| +newAVREF||| +newAV||| +newBINOP||| +newCONDOP||| +newCONSTSUB_flags||5.015006| +newCONSTSUB|5.004050||p +newCVREF||| +newDEFSVOP||5.021006| +newFORM||| +newFOROP||5.013007| +newGIVENOP||5.009003| +newGIVWHENOP||| +newGP||| +newGVOP||| +newGVREF||| +newGVgen_flags||5.015004| +newGVgen||| +newHVREF||| +newHVhv||5.005000| +newHV||| +newIO||| +newLISTOP||| +newLOGOP||| +newLOOPEX||| +newLOOPOP||| +newMETHOP_internal||| +newMETHOP_named||5.021005| +newMETHOP||5.021005| +newMYSUB||5.017004| +newNULLLIST||| +newOP||| +newPADNAMELIST||5.021007|n +newPADNAMEouter||5.021007|n +newPADNAMEpvn||5.021007|n +newPADOP||| +newPMOP||| +newPROG||| +newPVOP||| +newRANGE||| +newRV_inc|5.004000||p +newRV_noinc|5.004000||p +newRV||| +newSLICEOP||| +newSTATEOP||| +newSTUB||| +newSUB||| +newSVOP||| +newSVREF||| +newSV_type|5.009005||p +newSVavdefelem||| +newSVhek||5.009003| +newSViv||| +newSVnv||| +newSVpadname||5.017004| +newSVpv_share||5.013006| +newSVpvf_nocontext|||vn +newSVpvf||5.004000|v +newSVpvn_flags|5.010001||p +newSVpvn_share|5.007001||p +newSVpvn_utf8|5.010001||p +newSVpvn|5.004050||p +newSVpvs_flags|5.010001||p +newSVpvs_share|5.009003||p +newSVpvs|5.009003||p +newSVpv||| +newSVrv||| +newSVsv||| +newSVuv|5.006000||p +newSV||| +newUNOP_AUX||5.021007| +newUNOP||| +newWHENOP||5.009003| +newWHILEOP||5.013007| +newXS_deffile||| +newXS_flags||5.009004| +newXS_len_flags||| +newXSproto||5.006000| +newXS||5.006000| +new_collate||5.006000| +new_constant||| +new_ctype||5.006000| +new_he||| +new_logop||| +new_numeric||5.006000| +new_stackinfo||5.005000| +new_version||5.009000| +new_warnings_bitfield||| +next_symbol||| +nextargv||| +nextchar||| +ninstr|||n +no_bareword_allowed||| +no_fh_allowed||| +no_op||| +noperl_die|||vn +not_a_number||| +not_incrementable||| +nothreadhook||5.008000| +nuke_stacks||| +num_overflow|||n +oopsAV||| +oopsHV||| +op_append_elem||5.013006| +op_append_list||5.013006| +op_clear||| +op_contextualize||5.013006| +op_convert_list||5.021006| +op_dump||5.006000| +op_free||| +op_integerize||| +op_linklist||5.013006| +op_lvalue_flags||| +op_lvalue||5.013007| +op_null||5.007002| +op_parent|||n +op_prepend_elem||5.013006| +op_refcnt_dec||| +op_refcnt_inc||| +op_refcnt_lock||5.009002| +op_refcnt_unlock||5.009002| +op_relocate_sv||| +op_scope||5.013007| +op_sibling_splice||5.021002|n +op_std_init||| +op_unscope||| +open_script||| +openn_cleanup||| +openn_setup||| +opmethod_stash||| +opslab_force_free||| +opslab_free_nopad||| +opslab_free||| +output_or_return_posix_warnings||| +pMY_CXT_|5.007003||p +pMY_CXT|5.007003||p +pTHX_|5.006000||p +pTHX|5.006000||p +packWARN|5.007003||p +pack_cat||5.007003| +pack_rec||| +package_version||| +package||| +packlist||5.008001| +pad_add_anon||5.008001| +pad_add_name_pvn||5.015001| +pad_add_name_pvs||5.015001| +pad_add_name_pv||5.015001| +pad_add_name_sv||5.015001| +pad_add_weakref||| +pad_alloc_name||| +pad_alloc||| +pad_block_start||| +pad_check_dup||| +pad_compname_type||5.009003| +pad_findlex||| +pad_findmy_pvn||5.015001| +pad_findmy_pvs||5.015001| +pad_findmy_pv||5.015001| +pad_findmy_sv||5.015001| +pad_fixup_inner_anons||| +pad_free||| +pad_leavemy||| +pad_new||5.008001| +pad_push||| +pad_reset||| +pad_setsv||| +pad_sv||| +pad_swipe||| +pad_tidy||5.008001| +padlist_dup||| +padlist_store||| +padname_dup||| +padname_free||| +padnamelist_dup||| +padnamelist_fetch||5.021007|n +padnamelist_free||| +padnamelist_store||5.021007| +parse_arithexpr||5.013008| +parse_barestmt||5.013007| +parse_block||5.013007| +parse_body||| +parse_fullexpr||5.013008| +parse_fullstmt||5.013005| +parse_gv_stash_name||| +parse_ident||| +parse_label||5.013007| +parse_listexpr||5.013008| +parse_lparen_question_flags||| +parse_stmtseq||5.013006| +parse_subsignature||| +parse_termexpr||5.013008| +parse_unicode_opts||| +parser_dup||| +parser_free_nexttoke_ops||| +parser_free||| +path_is_searchable|||n +peep||| +pending_ident||| +perl_alloc_using|||n +perl_alloc|||n +perl_clone_using|||n +perl_clone|||n +perl_construct|||n +perl_destruct||5.007003|n +perl_free|||n +perl_parse||5.006000|n +perl_run|||n +pidgone||| +pm_description||| +pmop_dump||5.006000| +pmruntime||| +pmtrans||| +pop_scope||| +populate_ANYOF_from_invlist||| +populate_isa|||v +pregcomp||5.009005| +pregexec||| +pregfree2||5.011000| +pregfree||| +prescan_version||5.011004| +printbuf||| +printf_nocontext|||vn +process_special_blocks||| +ptr_hash|||n +ptr_table_clear||5.009005| +ptr_table_fetch||5.009005| +ptr_table_find|||n +ptr_table_free||5.009005| +ptr_table_new||5.009005| +ptr_table_split||5.009005| +ptr_table_store||5.009005| +push_scope||| +put_charclass_bitmap_innards_common||| +put_charclass_bitmap_innards_invlist||| +put_charclass_bitmap_innards||| +put_code_point||| +put_range||| +pv_display|5.006000||p +pv_escape|5.009004||p +pv_pretty|5.009004||p +pv_uni_display||5.007003| +qerror||| +qsortsvu||| +quadmath_format_needed|||n +quadmath_format_single|||n +re_compile||5.009005| +re_croak2||| +re_dup_guts||| +re_exec_indentf|||v +re_indentf|||v +re_intuit_start||5.019001| +re_intuit_string||5.006000| +re_op_compile||| +re_printf|||v +realloc||5.007002|n +reentrant_free||5.024000| +reentrant_init||5.024000| +reentrant_retry||5.024000|vn +reentrant_size||5.024000| +ref_array_or_hash||| +refcounted_he_chain_2hv||| +refcounted_he_fetch_pvn||| +refcounted_he_fetch_pvs||| +refcounted_he_fetch_pv||| +refcounted_he_fetch_sv||| +refcounted_he_free||| +refcounted_he_inc||| +refcounted_he_new_pvn||| +refcounted_he_new_pvs||| +refcounted_he_new_pv||| +refcounted_he_new_sv||| +refcounted_he_value||| +refkids||| +refto||| +ref||5.024000| +reg2Lanode||| +reg_check_named_buff_matched|||n +reg_named_buff_all||5.009005| +reg_named_buff_exists||5.009005| +reg_named_buff_fetch||5.009005| +reg_named_buff_firstkey||5.009005| +reg_named_buff_iter||| +reg_named_buff_nextkey||5.009005| +reg_named_buff_scalar||5.009005| +reg_named_buff||| +reg_node||| +reg_numbered_buff_fetch||| +reg_numbered_buff_length||| +reg_numbered_buff_store||| +reg_qr_package||| +reg_recode||| +reg_scan_name||| +reg_skipcomment|||n +reg_temp_copy||| +reganode||| +regatom||| +regbranch||| +regclass_swash||5.009004| +regclass||| +regcppop||| +regcppush||| +regcurly|||n +regdump_extflags||| +regdump_intflags||| +regdump||5.005000| +regdupe_internal||| +regex_set_precedence|||n +regexec_flags||5.005000| +regfree_internal||5.009005| +reghop3|||n +reghop4|||n +reghopmaybe3|||n +reginclass||| +reginitcolors||5.006000| +reginsert||| +regmatch||| +regnext||5.005000| +regnode_guts||| +regpiece||| +regprop||| +regrepeat||| +regtail_study||| +regtail||| +regtry||| +reg||| +repeatcpy|||n +report_evil_fh||| +report_redefined_cv||| +report_uninit||| +report_wrongway_fh||| +require_pv||5.006000| +require_tie_mod||| +restore_magic||| +rninstr|||n +rpeep||| +rsignal_restore||| +rsignal_save||| +rsignal_state||5.004000| +rsignal||5.004000| +run_body||| +run_user_filter||| +runops_debug||5.005000| +runops_standard||5.005000| +rv2cv_op_cv||5.013006| +rvpv_dup||| +rxres_free||| +rxres_restore||| +rxres_save||| +safesyscalloc||5.006000|n +safesysfree||5.006000|n +safesysmalloc||5.006000|n +safesysrealloc||5.006000|n +same_dirent||| +save_I16||5.004000| +save_I32||| +save_I8||5.006000| +save_adelete||5.011000| +save_aelem_flags||5.011000| +save_aelem||5.004050| +save_alloc||5.006000| +save_aptr||| +save_ary||| +save_bool||5.008001| +save_clearsv||| +save_delete||| +save_destructor_x||5.006000| +save_destructor||5.006000| +save_freeop||| +save_freepv||| +save_freesv||| +save_generic_pvref||5.006001| +save_generic_svref||5.005030| +save_gp||5.004000| +save_hash||| +save_hdelete||5.011000| +save_hek_flags|||n +save_helem_flags||5.011000| +save_helem||5.004050| +save_hints||5.010001| +save_hptr||| +save_int||| +save_item||| +save_iv||5.005000| +save_lines||| +save_list||| +save_long||| +save_magic_flags||| +save_mortalizesv||5.007001| +save_nogv||| +save_op||5.005000| +save_padsv_and_mortalize||5.010001| +save_pptr||| +save_pushi32ptr||5.010001| +save_pushptri32ptr||| +save_pushptrptr||5.010001| +save_pushptr||5.010001| +save_re_context||5.006000| +save_scalar_at||| +save_scalar||| +save_set_svflags||5.009000| +save_shared_pvref||5.007003| +save_sptr||| +save_strlen||| +save_svref||| +save_vptr||5.006000| +savepvn||| +savepvs||5.009003| +savepv||| +savesharedpvn||5.009005| +savesharedpvs||5.013006| +savesharedpv||5.007003| +savesharedsvpv||5.013006| +savestack_grow_cnt||5.008001| +savestack_grow||| +savesvpv||5.009002| +savetmps||5.023008| +sawparens||| +scalar_mod_type|||n +scalarboolean||| +scalarkids||| +scalarseq||| +scalarvoid||| +scalar||| +scan_bin||5.006000| +scan_commit||| +scan_const||| +scan_formline||| +scan_heredoc||| +scan_hex||| +scan_ident||| +scan_inputsymbol||| +scan_num||5.007001| +scan_oct||| +scan_pat||| +scan_str||| +scan_subst||| +scan_trans||| +scan_version||5.009001| +scan_vstring||5.009005| +scan_word||| +search_const||| +seed||5.008001| +sequence_num||| +set_ANYOF_arg||| +set_caret_X||| +set_context||5.006000|n +set_numeric_local||5.006000| +set_numeric_radix||5.006000| +set_numeric_standard||5.006000| +set_padlist|||n +setdefout||| +share_hek_flags||| +share_hek||5.004000| +should_warn_nl|||n +si_dup||| +sighandler|||n +simplify_sort||| +skip_to_be_ignored_text||| +skipspace_flags||| +softref2xv||| +sortcv_stacked||| +sortcv_xsub||| +sortcv||| +sortsv_flags||5.009003| +sortsv||5.007003| +space_join_names_mortal||| +ss_dup||| +ssc_add_range||| +ssc_and||| +ssc_anything||| +ssc_clear_locale|||n +ssc_cp_and||| +ssc_finalize||| +ssc_init||| +ssc_intersection||| +ssc_is_anything|||n +ssc_is_cp_posixl_init|||n +ssc_or||| +ssc_union||| +stack_grow||| +start_glob||| +start_subparse||5.004000| +stdize_locale||| +strEQ||| +strGE||| +strGT||| +strLE||| +strLT||| +strNE||| +str_to_version||5.006000| +strip_return||| +strnEQ||| +strnNE||| +study_chunk||| +sub_crush_depth||| +sublex_done||| +sublex_push||| +sublex_start||| +sv_2bool_flags||5.013006| +sv_2bool||| +sv_2cv||| +sv_2io||| +sv_2iuv_common||| +sv_2iuv_non_preserve||| +sv_2iv_flags||5.009001| +sv_2iv||| +sv_2mortal||| +sv_2num||| +sv_2nv_flags||5.013001| +sv_2pv_flags|5.007002||p +sv_2pv_nolen|5.006000||p +sv_2pvbyte_nolen|5.006000||p +sv_2pvbyte|5.006000||p +sv_2pvutf8_nolen||5.006000| +sv_2pvutf8||5.006000| +sv_2pv||| +sv_2uv_flags||5.009001| +sv_2uv|5.004000||p +sv_add_arena||| +sv_add_backref||| +sv_backoff|||n +sv_bless||| +sv_buf_to_ro||| +sv_buf_to_rw||| +sv_cat_decode||5.008001| +sv_catpv_flags||5.013006| +sv_catpv_mg|5.004050||p +sv_catpv_nomg||5.013006| +sv_catpvf_mg_nocontext|||pvn +sv_catpvf_mg|5.006000|5.004000|pv +sv_catpvf_nocontext|||vn +sv_catpvf||5.004000|v +sv_catpvn_flags||5.007002| +sv_catpvn_mg|5.004050||p +sv_catpvn_nomg|5.007002||p +sv_catpvn||| +sv_catpvs_flags||5.013006| +sv_catpvs_mg||5.013006| +sv_catpvs_nomg||5.013006| +sv_catpvs|5.009003||p +sv_catpv||| +sv_catsv_flags||5.007002| +sv_catsv_mg|5.004050||p +sv_catsv_nomg|5.007002||p +sv_catsv||| +sv_chop||| +sv_clean_all||| +sv_clean_objs||| +sv_clear||| +sv_cmp_flags||5.013006| +sv_cmp_locale_flags||5.013006| +sv_cmp_locale||5.004000| +sv_cmp||| +sv_collxfrm_flags||5.013006| +sv_collxfrm||| +sv_copypv_flags||5.017002| +sv_copypv_nomg||5.017002| +sv_copypv||| +sv_dec_nomg||5.013002| +sv_dec||| +sv_del_backref||| +sv_derived_from_pvn||5.015004| +sv_derived_from_pv||5.015004| +sv_derived_from_sv||5.015004| +sv_derived_from||5.004000| +sv_destroyable||5.010000| +sv_display||| +sv_does_pvn||5.015004| +sv_does_pv||5.015004| +sv_does_sv||5.015004| +sv_does||5.009004| +sv_dump||| +sv_dup_common||| +sv_dup_inc_multiple||| +sv_dup_inc||| +sv_dup||| +sv_eq_flags||5.013006| +sv_eq||| +sv_exp_grow||| +sv_force_normal_flags||5.007001| +sv_force_normal||5.006000| +sv_free2||| +sv_free_arenas||| +sv_free||| +sv_get_backrefs||5.021008|n +sv_gets||5.003070| +sv_grow||| +sv_i_ncmp||| +sv_inc_nomg||5.013002| +sv_inc||| +sv_insert_flags||5.010001| +sv_insert||| +sv_isa||| +sv_isobject||| +sv_iv||5.005000| +sv_kill_backrefs||| +sv_len_utf8_nomg||| +sv_len_utf8||5.006000| +sv_len||| +sv_magic_portable|5.024000|5.004000|p +sv_magicext_mglob||| +sv_magicext||5.007003| +sv_magic||| +sv_mortalcopy_flags||| +sv_mortalcopy||| +sv_ncmp||| +sv_newmortal||| +sv_newref||| +sv_nolocking||5.007003| +sv_nosharing||5.007003| +sv_nounlocking||| +sv_nv||5.005000| +sv_only_taint_gmagic|||n +sv_or_pv_pos_u2b||| +sv_peek||5.005000| +sv_pos_b2u_flags||5.019003| +sv_pos_b2u_midway||| +sv_pos_b2u||5.006000| +sv_pos_u2b_cached||| +sv_pos_u2b_flags||5.011005| +sv_pos_u2b_forwards|||n +sv_pos_u2b_midway|||n +sv_pos_u2b||5.006000| +sv_pvbyten_force||5.006000| +sv_pvbyten||5.006000| +sv_pvbyte||5.006000| +sv_pvn_force_flags|5.007002||p +sv_pvn_force||| +sv_pvn_nomg|5.007003|5.005000|p +sv_pvn||5.005000| +sv_pvutf8n_force||5.006000| +sv_pvutf8n||5.006000| +sv_pvutf8||5.006000| +sv_pv||5.006000| +sv_recode_to_utf8||5.007003| +sv_reftype||| +sv_ref||5.015004| +sv_replace||| +sv_report_used||| +sv_resetpvn||| +sv_reset||| +sv_rvweaken||5.006000| +sv_sethek||| +sv_setiv_mg|5.004050||p +sv_setiv||| +sv_setnv_mg|5.006000||p +sv_setnv||| +sv_setpv_mg|5.004050||p +sv_setpvf_mg_nocontext|||pvn +sv_setpvf_mg|5.006000|5.004000|pv +sv_setpvf_nocontext|||vn +sv_setpvf||5.004000|v +sv_setpviv_mg||5.008001| +sv_setpviv||5.008001| +sv_setpvn_mg|5.004050||p +sv_setpvn||| +sv_setpvs_mg||5.013006| +sv_setpvs|5.009004||p +sv_setpv||| +sv_setref_iv||| +sv_setref_nv||| +sv_setref_pvn||| +sv_setref_pvs||5.024000| +sv_setref_pv||| +sv_setref_uv||5.007001| +sv_setsv_cow||| +sv_setsv_flags||5.007002| +sv_setsv_mg|5.004050||p +sv_setsv_nomg|5.007002||p +sv_setsv||| +sv_setuv_mg|5.004050||p +sv_setuv|5.004000||p +sv_tainted||5.004000| +sv_taint||5.004000| +sv_true||5.005000| +sv_unglob||| +sv_uni_display||5.007003| +sv_unmagicext|5.013008||p +sv_unmagic||| +sv_unref_flags||5.007001| +sv_unref||| +sv_untaint||5.004000| +sv_upgrade||| +sv_usepvn_flags||5.009004| +sv_usepvn_mg|5.004050||p +sv_usepvn||| +sv_utf8_decode||5.006000| +sv_utf8_downgrade||5.006000| +sv_utf8_encode||5.006000| +sv_utf8_upgrade_flags_grow||5.011000| +sv_utf8_upgrade_flags||5.007002| +sv_utf8_upgrade_nomg||5.007002| +sv_utf8_upgrade||5.007001| +sv_uv|5.005000||p +sv_vcatpvf_mg|5.006000|5.004000|p +sv_vcatpvfn_flags||5.017002| +sv_vcatpvfn||5.004000| +sv_vcatpvf|5.006000|5.004000|p +sv_vsetpvf_mg|5.006000|5.004000|p +sv_vsetpvfn||5.004000| +sv_vsetpvf|5.006000|5.004000|p +svtype||| +swallow_bom||| +swash_fetch||5.007002| +swash_init||5.006000| +swash_scan_list_line||| +swatch_get||| +sync_locale||5.021004| +sys_init3||5.010000|n +sys_init||5.010000|n +sys_intern_clear||| +sys_intern_dup||| +sys_intern_init||| +sys_term||5.010000|n +taint_env||| +taint_proper||| +tied_method|||v +tmps_grow_p||| +toFOLD_utf8||5.019001| +toFOLD_uvchr||5.023009| +toFOLD||5.019001| +toLOWER_L1||5.019001| +toLOWER_LC||5.004000| +toLOWER_utf8||5.015007| +toLOWER_uvchr||5.023009| +toLOWER||| +toTITLE_utf8||5.015007| +toTITLE_uvchr||5.023009| +toTITLE||5.019001| +toUPPER_utf8||5.015007| +toUPPER_uvchr||5.023009| +toUPPER||| +to_byte_substr||| +to_lower_latin1|||n +to_uni_fold||5.007003| +to_uni_lower_lc||5.006000| +to_uni_lower||5.007003| +to_uni_title_lc||5.006000| +to_uni_title||5.007003| +to_uni_upper_lc||5.006000| +to_uni_upper||5.007003| +to_utf8_case||5.007003| +to_utf8_fold||5.015007| +to_utf8_lower||5.015007| +to_utf8_substr||| +to_utf8_title||5.015007| +to_utf8_upper||5.015007| +tokenize_use||| +tokeq||| +tokereport||| +too_few_arguments_pv||| +too_many_arguments_pv||| +translate_substr_offsets|||n +try_amagic_bin||| +try_amagic_un||| +uiv_2buf|||n +unlnk||| +unpack_rec||| +unpack_str||5.007003| +unpackstring||5.008001| +unreferenced_to_tmp_stack||| +unshare_hek_or_pvn||| +unshare_hek||| +unsharepvn||5.003070| +unwind_handler_stack||| +update_debugger_info||| +upg_version||5.009005| +usage||| +utf16_textfilter||| +utf16_to_utf8_reversed||5.006001| +utf16_to_utf8||5.006001| +utf8_distance||5.006000| +utf8_hop||5.006000|n +utf8_length||5.007001| +utf8_mg_len_cache_update||| +utf8_mg_pos_cache_update||| +utf8_to_bytes||5.006001| +utf8_to_uvchr_buf||5.015009| +utf8_to_uvchr||5.007001| +utf8_to_uvuni_buf||5.015009| +utf8_to_uvuni||5.007001| +utf8n_to_uvchr||5.007001| +utf8n_to_uvuni||5.007001| +utilize||| +uvchr_to_utf8_flags||5.007003| +uvchr_to_utf8||5.007001| +uvoffuni_to_utf8_flags||5.019004| +uvuni_to_utf8_flags||5.007003| +uvuni_to_utf8||5.007001| +valid_utf8_to_uvchr||5.015009| +valid_utf8_to_uvuni||5.015009| +validate_proto||| +validate_suid||| +varname||| +vcmp||5.009000| +vcroak||5.006000| +vdeb||5.007003| +vform||5.006000| +visit||| +vivify_defelem||| +vivify_ref||| +vload_module|5.006000||p +vmess||5.006000| +vnewSVpvf|5.006000|5.004000|p +vnormal||5.009002| +vnumify||5.009000| +vstringify||5.009000| +vverify||5.009003| +vwarner||5.006000| +vwarn||5.006000| +wait4pid||| +warn_nocontext|||vn +warn_sv||5.013001| +warner_nocontext|||vn +warner|5.006000|5.004000|pv +warn|||v +was_lvalue_sub||| +watch||| +whichsig_pvn||5.015004| +whichsig_pv||5.015004| +whichsig_sv||5.015004| +whichsig||| +win32_croak_not_implemented|||n +with_queued_errors||| +wrap_op_checker||5.015008| +write_to_stderr||| +xs_boot_epilog||| +xs_handshake|||vn +xs_version_bootcheck||| +yyerror_pvn||| +yyerror_pv||| +yyerror||| +yylex||| +yyparse||| +yyunlex||| +yywarn||| +); + +if (exists $opt{'list-unsupported'}) { + my $f; + for $f (sort { lc $a cmp lc $b } keys %API) { + next unless $API{$f}{todo}; + print "$f ", '.'x(40-length($f)), " ", format_version($API{$f}{todo}), "\n"; + } + exit 0; +} + +# Scan for possible replacement candidates + +my(%replace, %need, %hints, %warnings, %depends); +my $replace = 0; +my($hint, $define, $function); + +sub find_api +{ + my $code = shift; + $code =~ s{ + / (?: \*[^*]*\*+(?:[^$ccs][^*]*\*+)* / | /[^\r\n]*) + | "[^"\\]*(?:\\.[^"\\]*)*" + | '[^'\\]*(?:\\.[^'\\]*)*' }{}egsx; + grep { exists $API{$_} } $code =~ /(\w+)/mg; +} + +while () { + if ($hint) { + my $h = $hint->[0] eq 'Hint' ? \%hints : \%warnings; + if (m{^\s*\*\s(.*?)\s*$}) { + for (@{$hint->[1]}) { + $h->{$_} ||= ''; # suppress warning with older perls + $h->{$_} .= "$1\n"; + } + } + else { undef $hint } + } + + $hint = [$1, [split /,?\s+/, $2]] + if m{^\s*$rccs\s+(Hint|Warning):\s+(\w+(?:,?\s+\w+)*)\s*$}; + + if ($define) { + if ($define->[1] =~ /\\$/) { + $define->[1] .= $_; + } + else { + if (exists $API{$define->[0]} && $define->[1] !~ /^DPPP_\(/) { + my @n = find_api($define->[1]); + push @{$depends{$define->[0]}}, @n if @n + } + undef $define; + } + } + + $define = [$1, $2] if m{^\s*#\s*define\s+(\w+)(?:\([^)]*\))?\s+(.*)}; + + if ($function) { + if (/^}/) { + if (exists $API{$function->[0]}) { + my @n = find_api($function->[1]); + push @{$depends{$function->[0]}}, @n if @n + } + undef $function; + } + else { + $function->[1] .= $_; + } + } + + $function = [$1, ''] if m{^DPPP_\(my_(\w+)\)}; + + $replace = $1 if m{^\s*$rccs\s+Replace:\s+(\d+)\s+$rcce\s*$}; + $replace{$2} = $1 if $replace and m{^\s*#\s*define\s+(\w+)(?:\([^)]*\))?\s+(\w+)}; + $replace{$2} = $1 if m{^\s*#\s*define\s+(\w+)(?:\([^)]*\))?\s+(\w+).*$rccs\s+Replace\s+$rcce}; + $replace{$1} = $2 if m{^\s*$rccs\s+Replace (\w+) with (\w+)\s+$rcce\s*$}; + + if (m{^\s*$rccs\s+(\w+(\s*,\s*\w+)*)\s+depends\s+on\s+(\w+(\s*,\s*\w+)*)\s+$rcce\s*$}) { + my @deps = map { s/\s+//g; $_ } split /,/, $3; + my $d; + for $d (map { s/\s+//g; $_ } split /,/, $1) { + push @{$depends{$d}}, @deps; + } + } + + $need{$1} = 1 if m{^#if\s+defined\(NEED_(\w+)(?:_GLOBAL)?\)}; +} + +for (values %depends) { + my %s; + $_ = [sort grep !$s{$_}++, @$_]; +} + +if (exists $opt{'api-info'}) { + my $f; + my $count = 0; + my $match = $opt{'api-info'} =~ m!^/(.*)/$! ? $1 : "^\Q$opt{'api-info'}\E\$"; + for $f (sort { lc $a cmp lc $b } keys %API) { + next unless $f =~ /$match/; + print "\n=== $f ===\n\n"; + my $info = 0; + if ($API{$f}{base} || $API{$f}{todo}) { + my $base = format_version($API{$f}{base} || $API{$f}{todo}); + print "Supported at least starting from perl-$base.\n"; + $info++; + } + if ($API{$f}{provided}) { + my $todo = $API{$f}{todo} ? format_version($API{$f}{todo}) : "5.003"; + print "Support by $ppport provided back to perl-$todo.\n"; + print "Support needs to be explicitly requested by NEED_$f.\n" if exists $need{$f}; + print "Depends on: ", join(', ', @{$depends{$f}}), ".\n" if exists $depends{$f}; + print "\n$hints{$f}" if exists $hints{$f}; + print "\nWARNING:\n$warnings{$f}" if exists $warnings{$f}; + $info++; + } + print "No portability information available.\n" unless $info; + $count++; + } + $count or print "Found no API matching '$opt{'api-info'}'."; + print "\n"; + exit 0; +} + +if (exists $opt{'list-provided'}) { + my $f; + for $f (sort { lc $a cmp lc $b } keys %API) { + next unless $API{$f}{provided}; + my @flags; + push @flags, 'explicit' if exists $need{$f}; + push @flags, 'depend' if exists $depends{$f}; + push @flags, 'hint' if exists $hints{$f}; + push @flags, 'warning' if exists $warnings{$f}; + my $flags = @flags ? ' ['.join(', ', @flags).']' : ''; + print "$f$flags\n"; + } + exit 0; +} + +my @files; +my @srcext = qw( .xs .c .h .cc .cpp -c.inc -xs.inc ); +my $srcext = join '|', map { quotemeta $_ } @srcext; + +if (@ARGV) { + my %seen; + for (@ARGV) { + if (-e) { + if (-f) { + push @files, $_ unless $seen{$_}++; + } + else { warn "'$_' is not a file.\n" } + } + else { + my @new = grep { -f } glob $_ + or warn "'$_' does not exist.\n"; + push @files, grep { !$seen{$_}++ } @new; + } + } +} +else { + eval { + require File::Find; + File::Find::find(sub { + $File::Find::name =~ /($srcext)$/i + and push @files, $File::Find::name; + }, '.'); + }; + if ($@) { + @files = map { glob "*$_" } @srcext; + } +} + +if (!@ARGV || $opt{filter}) { + my(@in, @out); + my %xsc = map { /(.*)\.xs$/ ? ("$1.c" => 1, "$1.cc" => 1) : () } @files; + for (@files) { + my $out = exists $xsc{$_} || /\b\Q$ppport\E$/i || !/($srcext)$/i; + push @{ $out ? \@out : \@in }, $_; + } + if (@ARGV && @out) { + warning("Skipping the following files (use --nofilter to avoid this):\n| ", join "\n| ", @out); + } + @files = @in; +} + +die "No input files given!\n" unless @files; + +my(%files, %global, %revreplace); +%revreplace = reverse %replace; +my $filename; +my $patch_opened = 0; + +for $filename (@files) { + unless (open IN, "<$filename") { + warn "Unable to read from $filename: $!\n"; + next; + } + + info("Scanning $filename ..."); + + my $c = do { local $/; }; + close IN; + + my %file = (orig => $c, changes => 0); + + # Temporarily remove C/XS comments and strings from the code + my @ccom; + + $c =~ s{ + ( ^$HS*\#$HS*include\b[^\r\n]+\b(?:\Q$ppport\E|XSUB\.h)\b[^\r\n]* + | ^$HS*\#$HS*(?:define|elif|if(?:def)?)\b[^\r\n]* ) + | ( ^$HS*\#[^\r\n]* + | "[^"\\]*(?:\\.[^"\\]*)*" + | '[^'\\]*(?:\\.[^'\\]*)*' + | / (?: \*[^*]*\*+(?:[^$ccs][^*]*\*+)* / | /[^\r\n]* ) ) + }{ defined $2 and push @ccom, $2; + defined $1 ? $1 : "$ccs$#ccom$cce" }mgsex; + + $file{ccom} = \@ccom; + $file{code} = $c; + $file{has_inc_ppport} = $c =~ /^$HS*#$HS*include[^\r\n]+\b\Q$ppport\E\b/m; + + my $func; + + for $func (keys %API) { + my $match = $func; + $match .= "|$revreplace{$func}" if exists $revreplace{$func}; + if ($c =~ /\b(?:Perl_)?($match)\b/) { + $file{uses_replace}{$1}++ if exists $revreplace{$func} && $1 eq $revreplace{$func}; + $file{uses_Perl}{$func}++ if $c =~ /\bPerl_$func\b/; + if (exists $API{$func}{provided}) { + $file{uses_provided}{$func}++; + if (!exists $API{$func}{base} || $API{$func}{base} > $opt{'compat-version'}) { + $file{uses}{$func}++; + my @deps = rec_depend($func); + if (@deps) { + $file{uses_deps}{$func} = \@deps; + for (@deps) { + $file{uses}{$_} = 0 unless exists $file{uses}{$_}; + } + } + for ($func, @deps) { + $file{needs}{$_} = 'static' if exists $need{$_}; + } + } + } + if (exists $API{$func}{todo} && $API{$func}{todo} > $opt{'compat-version'}) { + if ($c =~ /\b$func\b/) { + $file{uses_todo}{$func}++; + } + } + } + } + + while ($c =~ /^$HS*#$HS*define$HS+(NEED_(\w+?)(_GLOBAL)?)\b/mg) { + if (exists $need{$2}) { + $file{defined $3 ? 'needed_global' : 'needed_static'}{$2}++; + } + else { warning("Possibly wrong #define $1 in $filename") } + } + + for (qw(uses needs uses_todo needed_global needed_static)) { + for $func (keys %{$file{$_}}) { + push @{$global{$_}{$func}}, $filename; + } + } + + $files{$filename} = \%file; +} + +# Globally resolve NEED_'s +my $need; +for $need (keys %{$global{needs}}) { + if (@{$global{needs}{$need}} > 1) { + my @targets = @{$global{needs}{$need}}; + my @t = grep $files{$_}{needed_global}{$need}, @targets; + @targets = @t if @t; + @t = grep /\.xs$/i, @targets; + @targets = @t if @t; + my $target = shift @targets; + $files{$target}{needs}{$need} = 'global'; + for (@{$global{needs}{$need}}) { + $files{$_}{needs}{$need} = 'extern' if $_ ne $target; + } + } +} + +for $filename (@files) { + exists $files{$filename} or next; + + info("=== Analyzing $filename ==="); + + my %file = %{$files{$filename}}; + my $func; + my $c = $file{code}; + my $warnings = 0; + + for $func (sort keys %{$file{uses_Perl}}) { + if ($API{$func}{varargs}) { + unless ($API{$func}{nothxarg}) { + my $changes = ($c =~ s{\b(Perl_$func\s*\(\s*)(?!aTHX_?)(\)|[^\s)]*\))} + { $1 . ($2 eq ')' ? 'aTHX' : 'aTHX_ ') . $2 }ge); + if ($changes) { + warning("Doesn't pass interpreter argument aTHX to Perl_$func"); + $file{changes} += $changes; + } + } + } + else { + warning("Uses Perl_$func instead of $func"); + $file{changes} += ($c =~ s{\bPerl_$func(\s*)\((\s*aTHX_?)?\s*} + {$func$1(}g); + } + } + + for $func (sort keys %{$file{uses_replace}}) { + warning("Uses $func instead of $replace{$func}"); + $file{changes} += ($c =~ s/\b$func\b/$replace{$func}/g); + } + + for $func (sort keys %{$file{uses_provided}}) { + if ($file{uses}{$func}) { + if (exists $file{uses_deps}{$func}) { + diag("Uses $func, which depends on ", join(', ', @{$file{uses_deps}{$func}})); + } + else { + diag("Uses $func"); + } + } + $warnings += hint($func); + } + + unless ($opt{quiet}) { + for $func (sort keys %{$file{uses_todo}}) { + print "*** WARNING: Uses $func, which may not be portable below perl ", + format_version($API{$func}{todo}), ", even with '$ppport'\n"; + $warnings++; + } + } + + for $func (sort keys %{$file{needed_static}}) { + my $message = ''; + if (not exists $file{uses}{$func}) { + $message = "No need to define NEED_$func if $func is never used"; + } + elsif (exists $file{needs}{$func} && $file{needs}{$func} ne 'static') { + $message = "No need to define NEED_$func when already needed globally"; + } + if ($message) { + diag($message); + $file{changes} += ($c =~ s/^$HS*#$HS*define$HS+NEED_$func\b.*$LF//mg); + } + } + + for $func (sort keys %{$file{needed_global}}) { + my $message = ''; + if (not exists $global{uses}{$func}) { + $message = "No need to define NEED_${func}_GLOBAL if $func is never used"; + } + elsif (exists $file{needs}{$func}) { + if ($file{needs}{$func} eq 'extern') { + $message = "No need to define NEED_${func}_GLOBAL when already needed globally"; + } + elsif ($file{needs}{$func} eq 'static') { + $message = "No need to define NEED_${func}_GLOBAL when only used in this file"; + } + } + if ($message) { + diag($message); + $file{changes} += ($c =~ s/^$HS*#$HS*define$HS+NEED_${func}_GLOBAL\b.*$LF//mg); + } + } + + $file{needs_inc_ppport} = keys %{$file{uses}}; + + if ($file{needs_inc_ppport}) { + my $pp = ''; + + for $func (sort keys %{$file{needs}}) { + my $type = $file{needs}{$func}; + next if $type eq 'extern'; + my $suffix = $type eq 'global' ? '_GLOBAL' : ''; + unless (exists $file{"needed_$type"}{$func}) { + if ($type eq 'global') { + diag("Files [@{$global{needs}{$func}}] need $func, adding global request"); + } + else { + diag("File needs $func, adding static request"); + } + $pp .= "#define NEED_$func$suffix\n"; + } + } + + if ($pp && ($c =~ s/^(?=$HS*#$HS*define$HS+NEED_\w+)/$pp/m)) { + $pp = ''; + $file{changes}++; + } + + unless ($file{has_inc_ppport}) { + diag("Needs to include '$ppport'"); + $pp .= qq(#include "$ppport"\n) + } + + if ($pp) { + $file{changes} += ($c =~ s/^($HS*#$HS*define$HS+NEED_\w+.*?)^/$1$pp/ms) + || ($c =~ s/^(?=$HS*#$HS*include.*\Q$ppport\E)/$pp/m) + || ($c =~ s/^($HS*#$HS*include.*XSUB.*\s*?)^/$1$pp/m) + || ($c =~ s/^/$pp/); + } + } + else { + if ($file{has_inc_ppport}) { + diag("No need to include '$ppport'"); + $file{changes} += ($c =~ s/^$HS*?#$HS*include.*\Q$ppport\E.*?$LF//m); + } + } + + # put back in our C comments + my $ix; + my $cppc = 0; + my @ccom = @{$file{ccom}}; + for $ix (0 .. $#ccom) { + if (!$opt{cplusplus} && $ccom[$ix] =~ s!^//!!) { + $cppc++; + $file{changes} += $c =~ s/$rccs$ix$rcce/$ccs$ccom[$ix] $cce/; + } + else { + $c =~ s/$rccs$ix$rcce/$ccom[$ix]/; + } + } + + if ($cppc) { + my $s = $cppc != 1 ? 's' : ''; + warning("Uses $cppc C++ style comment$s, which is not portable"); + } + + my $s = $warnings != 1 ? 's' : ''; + my $warn = $warnings ? " ($warnings warning$s)" : ''; + info("Analysis completed$warn"); + + if ($file{changes}) { + if (exists $opt{copy}) { + my $newfile = "$filename$opt{copy}"; + if (-e $newfile) { + error("'$newfile' already exists, refusing to write copy of '$filename'"); + } + else { + local *F; + if (open F, ">$newfile") { + info("Writing copy of '$filename' with changes to '$newfile'"); + print F $c; + close F; + } + else { + error("Cannot open '$newfile' for writing: $!"); + } + } + } + elsif (exists $opt{patch} || $opt{changes}) { + if (exists $opt{patch}) { + unless ($patch_opened) { + if (open PATCH, ">$opt{patch}") { + $patch_opened = 1; + } + else { + error("Cannot open '$opt{patch}' for writing: $!"); + delete $opt{patch}; + $opt{changes} = 1; + goto fallback; + } + } + mydiff(\*PATCH, $filename, $c); + } + else { +fallback: + info("Suggested changes:"); + mydiff(\*STDOUT, $filename, $c); + } + } + else { + my $s = $file{changes} == 1 ? '' : 's'; + info("$file{changes} potentially required change$s detected"); + } + } + else { + info("Looks good"); + } +} + +close PATCH if $patch_opened; + +exit 0; + + +sub try_use { eval "use @_;"; return $@ eq '' } + +sub mydiff +{ + local *F = shift; + my($file, $str) = @_; + my $diff; + + if (exists $opt{diff}) { + $diff = run_diff($opt{diff}, $file, $str); + } + + if (!defined $diff and try_use('Text::Diff')) { + $diff = Text::Diff::diff($file, \$str, { STYLE => 'Unified' }); + $diff = <
$tmp") { + print F $str; + close F; + + if (open F, "$prog $file $tmp |") { + while () { + s/\Q$tmp\E/$file.patched/; + $diff .= $_; + } + close F; + unlink $tmp; + return $diff; + } + + unlink $tmp; + } + else { + error("Cannot open '$tmp' for writing: $!"); + } + + return undef; +} + +sub rec_depend +{ + my($func, $seen) = @_; + return () unless exists $depends{$func}; + $seen = {%{$seen||{}}}; + return () if $seen->{$func}++; + my %s; + grep !$s{$_}++, map { ($_, rec_depend($_, $seen)) } @{$depends{$func}}; +} + +sub parse_version +{ + my $ver = shift; + + if ($ver =~ /^(\d+)\.(\d+)\.(\d+)$/) { + return ($1, $2, $3); + } + elsif ($ver !~ /^\d+\.[\d_]+$/) { + die "cannot parse version '$ver'\n"; + } + + $ver =~ s/_//g; + $ver =~ s/$/000000/; + + my($r,$v,$s) = $ver =~ /(\d+)\.(\d{3})(\d{3})/; + + $v = int $v; + $s = int $s; + + if ($r < 5 || ($r == 5 && $v < 6)) { + if ($s % 10) { + die "cannot parse version '$ver'\n"; + } + } + + return ($r, $v, $s); +} + +sub format_version +{ + my $ver = shift; + + $ver =~ s/$/000000/; + my($r,$v,$s) = $ver =~ /(\d+)\.(\d{3})(\d{3})/; + + $v = int $v; + $s = int $s; + + if ($r < 5 || ($r == 5 && $v < 6)) { + if ($s % 10) { + die "invalid version '$ver'\n"; + } + $s /= 10; + + $ver = sprintf "%d.%03d", $r, $v; + $s > 0 and $ver .= sprintf "_%02d", $s; + + return $ver; + } + + return sprintf "%d.%d.%d", $r, $v, $s; +} + +sub info +{ + $opt{quiet} and return; + print @_, "\n"; +} + +sub diag +{ + $opt{quiet} and return; + $opt{diag} and print @_, "\n"; +} + +sub warning +{ + $opt{quiet} and return; + print "*** ", @_, "\n"; +} + +sub error +{ + print "*** ERROR: ", @_, "\n"; +} + +my %given_hints; +my %given_warnings; +sub hint +{ + $opt{quiet} and return; + my $func = shift; + my $rv = 0; + if (exists $warnings{$func} && !$given_warnings{$func}++) { + my $warn = $warnings{$func}; + $warn =~ s!^!*** !mg; + print "*** WARNING: $func\n", $warn; + $rv++; + } + if ($opt{hints} && exists $hints{$func} && !$given_hints{$func}++) { + my $hint = $hints{$func}; + $hint =~ s/^/ /mg; + print " --- hint for $func ---\n", $hint; + } + $rv; +} + +sub usage +{ + my($usage) = do { local(@ARGV,$/)=($0); <> } =~ /^=head\d$HS+SYNOPSIS\s*^(.*?)\s*^=/ms; + my %M = ( 'I' => '*' ); + $usage =~ s/^\s*perl\s+\S+/$^X $0/; + $usage =~ s/([A-Z])<([^>]+)>/$M{$1}$2$M{$1}/g; + + print < }; + my($copy) = $self =~ /^=head\d\s+COPYRIGHT\s*^(.*?)^=\w+/ms; + $copy =~ s/^(?=\S+)/ /gms; + $self =~ s/^$HS+Do NOT edit.*?(?=^-)/$copy/ms; + $self =~ s/^SKIP.*(?=^__DATA__)/SKIP +if (\@ARGV && \$ARGV[0] eq '--unstrip') { + eval { require Devel::PPPort }; + \$@ and die "Cannot require Devel::PPPort, please install.\\n"; + if (eval \$Devel::PPPort::VERSION < $VERSION) { + die "$0 was originally generated with Devel::PPPort $VERSION.\\n" + . "Your Devel::PPPort is only version \$Devel::PPPort::VERSION.\\n" + . "Please install a newer version, or --unstrip will not work.\\n"; + } + Devel::PPPort::WriteFile(\$0); + exit 0; +} +print <$0" or die "cannot strip $0: $!\n"; + print OUT "$pl$c\n"; + + exit 0; +} + +__DATA__ +*/ + +#ifndef _P_P_PORTABILITY_H_ +#define _P_P_PORTABILITY_H_ + +#ifndef DPPP_NAMESPACE +# define DPPP_NAMESPACE DPPP_ +#endif + +#define DPPP_CAT2(x,y) CAT2(x,y) +#define DPPP_(name) DPPP_CAT2(DPPP_NAMESPACE, name) + +#ifndef PERL_REVISION +# if !defined(__PATCHLEVEL_H_INCLUDED__) && !(defined(PATCHLEVEL) && defined(SUBVERSION)) +# define PERL_PATCHLEVEL_H_IMPLICIT +# include +# endif +# if !(defined(PERL_VERSION) || (defined(SUBVERSION) && defined(PATCHLEVEL))) +# include +# endif +# ifndef PERL_REVISION +# define PERL_REVISION (5) + /* Replace: 1 */ +# define PERL_VERSION PATCHLEVEL +# define PERL_SUBVERSION SUBVERSION + /* Replace PERL_PATCHLEVEL with PERL_VERSION */ + /* Replace: 0 */ +# endif +#endif + +#define _dpppDEC2BCD(dec) ((((dec)/100)<<8)|((((dec)%100)/10)<<4)|((dec)%10)) +#define PERL_BCDVERSION ((_dpppDEC2BCD(PERL_REVISION)<<24)|(_dpppDEC2BCD(PERL_VERSION)<<12)|_dpppDEC2BCD(PERL_SUBVERSION)) + +/* It is very unlikely that anyone will try to use this with Perl 6 + (or greater), but who knows. + */ +#if PERL_REVISION != 5 +# error ppport.h only works with Perl version 5 +#endif /* PERL_REVISION != 5 */ +#ifndef dTHR +# define dTHR dNOOP +#endif +#ifndef dTHX +# define dTHX dNOOP +#endif + +#ifndef dTHXa +# define dTHXa(x) dNOOP +#endif +#ifndef pTHX +# define pTHX void +#endif + +#ifndef pTHX_ +# define pTHX_ +#endif + +#ifndef aTHX +# define aTHX +#endif + +#ifndef aTHX_ +# define aTHX_ +#endif + +#if (PERL_BCDVERSION < 0x5006000) +# ifdef USE_THREADS +# define aTHXR thr +# define aTHXR_ thr, +# else +# define aTHXR +# define aTHXR_ +# endif +# define dTHXR dTHR +#else +# define aTHXR aTHX +# define aTHXR_ aTHX_ +# define dTHXR dTHX +#endif +#ifndef dTHXoa +# define dTHXoa(x) dTHXa(x) +#endif + +#ifdef I_LIMITS +# include +#endif + +#ifndef PERL_UCHAR_MIN +# define PERL_UCHAR_MIN ((unsigned char)0) +#endif + +#ifndef PERL_UCHAR_MAX +# ifdef UCHAR_MAX +# define PERL_UCHAR_MAX ((unsigned char)UCHAR_MAX) +# else +# ifdef MAXUCHAR +# define PERL_UCHAR_MAX ((unsigned char)MAXUCHAR) +# else +# define PERL_UCHAR_MAX ((unsigned char)~(unsigned)0) +# endif +# endif +#endif + +#ifndef PERL_USHORT_MIN +# define PERL_USHORT_MIN ((unsigned short)0) +#endif + +#ifndef PERL_USHORT_MAX +# ifdef USHORT_MAX +# define PERL_USHORT_MAX ((unsigned short)USHORT_MAX) +# else +# ifdef MAXUSHORT +# define PERL_USHORT_MAX ((unsigned short)MAXUSHORT) +# else +# ifdef USHRT_MAX +# define PERL_USHORT_MAX ((unsigned short)USHRT_MAX) +# else +# define PERL_USHORT_MAX ((unsigned short)~(unsigned)0) +# endif +# endif +# endif +#endif + +#ifndef PERL_SHORT_MAX +# ifdef SHORT_MAX +# define PERL_SHORT_MAX ((short)SHORT_MAX) +# else +# ifdef MAXSHORT /* Often used in */ +# define PERL_SHORT_MAX ((short)MAXSHORT) +# else +# ifdef SHRT_MAX +# define PERL_SHORT_MAX ((short)SHRT_MAX) +# else +# define PERL_SHORT_MAX ((short) (PERL_USHORT_MAX >> 1)) +# endif +# endif +# endif +#endif + +#ifndef PERL_SHORT_MIN +# ifdef SHORT_MIN +# define PERL_SHORT_MIN ((short)SHORT_MIN) +# else +# ifdef MINSHORT +# define PERL_SHORT_MIN ((short)MINSHORT) +# else +# ifdef SHRT_MIN +# define PERL_SHORT_MIN ((short)SHRT_MIN) +# else +# define PERL_SHORT_MIN (-PERL_SHORT_MAX - ((3 & -1) == 3)) +# endif +# endif +# endif +#endif + +#ifndef PERL_UINT_MAX +# ifdef UINT_MAX +# define PERL_UINT_MAX ((unsigned int)UINT_MAX) +# else +# ifdef MAXUINT +# define PERL_UINT_MAX ((unsigned int)MAXUINT) +# else +# define PERL_UINT_MAX (~(unsigned int)0) +# endif +# endif +#endif + +#ifndef PERL_UINT_MIN +# define PERL_UINT_MIN ((unsigned int)0) +#endif + +#ifndef PERL_INT_MAX +# ifdef INT_MAX +# define PERL_INT_MAX ((int)INT_MAX) +# else +# ifdef MAXINT /* Often used in */ +# define PERL_INT_MAX ((int)MAXINT) +# else +# define PERL_INT_MAX ((int)(PERL_UINT_MAX >> 1)) +# endif +# endif +#endif + +#ifndef PERL_INT_MIN +# ifdef INT_MIN +# define PERL_INT_MIN ((int)INT_MIN) +# else +# ifdef MININT +# define PERL_INT_MIN ((int)MININT) +# else +# define PERL_INT_MIN (-PERL_INT_MAX - ((3 & -1) == 3)) +# endif +# endif +#endif + +#ifndef PERL_ULONG_MAX +# ifdef ULONG_MAX +# define PERL_ULONG_MAX ((unsigned long)ULONG_MAX) +# else +# ifdef MAXULONG +# define PERL_ULONG_MAX ((unsigned long)MAXULONG) +# else +# define PERL_ULONG_MAX (~(unsigned long)0) +# endif +# endif +#endif + +#ifndef PERL_ULONG_MIN +# define PERL_ULONG_MIN ((unsigned long)0L) +#endif + +#ifndef PERL_LONG_MAX +# ifdef LONG_MAX +# define PERL_LONG_MAX ((long)LONG_MAX) +# else +# ifdef MAXLONG +# define PERL_LONG_MAX ((long)MAXLONG) +# else +# define PERL_LONG_MAX ((long) (PERL_ULONG_MAX >> 1)) +# endif +# endif +#endif + +#ifndef PERL_LONG_MIN +# ifdef LONG_MIN +# define PERL_LONG_MIN ((long)LONG_MIN) +# else +# ifdef MINLONG +# define PERL_LONG_MIN ((long)MINLONG) +# else +# define PERL_LONG_MIN (-PERL_LONG_MAX - ((3 & -1) == 3)) +# endif +# endif +#endif + +#if defined(HAS_QUAD) && (defined(convex) || defined(uts)) +# ifndef PERL_UQUAD_MAX +# ifdef ULONGLONG_MAX +# define PERL_UQUAD_MAX ((unsigned long long)ULONGLONG_MAX) +# else +# ifdef MAXULONGLONG +# define PERL_UQUAD_MAX ((unsigned long long)MAXULONGLONG) +# else +# define PERL_UQUAD_MAX (~(unsigned long long)0) +# endif +# endif +# endif + +# ifndef PERL_UQUAD_MIN +# define PERL_UQUAD_MIN ((unsigned long long)0L) +# endif + +# ifndef PERL_QUAD_MAX +# ifdef LONGLONG_MAX +# define PERL_QUAD_MAX ((long long)LONGLONG_MAX) +# else +# ifdef MAXLONGLONG +# define PERL_QUAD_MAX ((long long)MAXLONGLONG) +# else +# define PERL_QUAD_MAX ((long long) (PERL_UQUAD_MAX >> 1)) +# endif +# endif +# endif + +# ifndef PERL_QUAD_MIN +# ifdef LONGLONG_MIN +# define PERL_QUAD_MIN ((long long)LONGLONG_MIN) +# else +# ifdef MINLONGLONG +# define PERL_QUAD_MIN ((long long)MINLONGLONG) +# else +# define PERL_QUAD_MIN (-PERL_QUAD_MAX - ((3 & -1) == 3)) +# endif +# endif +# endif +#endif + +/* This is based on code from 5.003 perl.h */ +#ifdef HAS_QUAD +# ifdef cray +#ifndef IVTYPE +# define IVTYPE int +#endif + +#ifndef IV_MIN +# define IV_MIN PERL_INT_MIN +#endif + +#ifndef IV_MAX +# define IV_MAX PERL_INT_MAX +#endif + +#ifndef UV_MIN +# define UV_MIN PERL_UINT_MIN +#endif + +#ifndef UV_MAX +# define UV_MAX PERL_UINT_MAX +#endif + +# ifdef INTSIZE +#ifndef IVSIZE +# define IVSIZE INTSIZE +#endif + +# endif +# else +# if defined(convex) || defined(uts) +#ifndef IVTYPE +# define IVTYPE long long +#endif + +#ifndef IV_MIN +# define IV_MIN PERL_QUAD_MIN +#endif + +#ifndef IV_MAX +# define IV_MAX PERL_QUAD_MAX +#endif + +#ifndef UV_MIN +# define UV_MIN PERL_UQUAD_MIN +#endif + +#ifndef UV_MAX +# define UV_MAX PERL_UQUAD_MAX +#endif + +# ifdef LONGLONGSIZE +#ifndef IVSIZE +# define IVSIZE LONGLONGSIZE +#endif + +# endif +# else +#ifndef IVTYPE +# define IVTYPE long +#endif + +#ifndef IV_MIN +# define IV_MIN PERL_LONG_MIN +#endif + +#ifndef IV_MAX +# define IV_MAX PERL_LONG_MAX +#endif + +#ifndef UV_MIN +# define UV_MIN PERL_ULONG_MIN +#endif + +#ifndef UV_MAX +# define UV_MAX PERL_ULONG_MAX +#endif + +# ifdef LONGSIZE +#ifndef IVSIZE +# define IVSIZE LONGSIZE +#endif + +# endif +# endif +# endif +#ifndef IVSIZE +# define IVSIZE 8 +#endif + +#ifndef LONGSIZE +# define LONGSIZE 8 +#endif + +#ifndef PERL_QUAD_MIN +# define PERL_QUAD_MIN IV_MIN +#endif + +#ifndef PERL_QUAD_MAX +# define PERL_QUAD_MAX IV_MAX +#endif + +#ifndef PERL_UQUAD_MIN +# define PERL_UQUAD_MIN UV_MIN +#endif + +#ifndef PERL_UQUAD_MAX +# define PERL_UQUAD_MAX UV_MAX +#endif + +#else +#ifndef IVTYPE +# define IVTYPE long +#endif + +#ifndef LONGSIZE +# define LONGSIZE 4 +#endif + +#ifndef IV_MIN +# define IV_MIN PERL_LONG_MIN +#endif + +#ifndef IV_MAX +# define IV_MAX PERL_LONG_MAX +#endif + +#ifndef UV_MIN +# define UV_MIN PERL_ULONG_MIN +#endif + +#ifndef UV_MAX +# define UV_MAX PERL_ULONG_MAX +#endif + +#endif + +#ifndef IVSIZE +# ifdef LONGSIZE +# define IVSIZE LONGSIZE +# else +# define IVSIZE 4 /* A bold guess, but the best we can make. */ +# endif +#endif +#ifndef UVTYPE +# define UVTYPE unsigned IVTYPE +#endif + +#ifndef UVSIZE +# define UVSIZE IVSIZE +#endif +#ifndef sv_setuv +# define sv_setuv(sv, uv) \ + STMT_START { \ + UV TeMpUv = uv; \ + if (TeMpUv <= IV_MAX) \ + sv_setiv(sv, TeMpUv); \ + else \ + sv_setnv(sv, (double)TeMpUv); \ + } STMT_END +#endif +#ifndef newSVuv +# define newSVuv(uv) ((uv) <= IV_MAX ? newSViv((IV)uv) : newSVnv((NV)uv)) +#endif +#ifndef sv_2uv +# define sv_2uv(sv) ((PL_Sv = (sv)), (UV) (SvNOK(PL_Sv) ? SvNV(PL_Sv) : sv_2nv(PL_Sv))) +#endif + +#ifndef SvUVX +# define SvUVX(sv) ((UV)SvIVX(sv)) +#endif + +#ifndef SvUVXx +# define SvUVXx(sv) SvUVX(sv) +#endif + +#ifndef SvUV +# define SvUV(sv) (SvIOK(sv) ? SvUVX(sv) : sv_2uv(sv)) +#endif + +#ifndef SvUVx +# define SvUVx(sv) ((PL_Sv = (sv)), SvUV(PL_Sv)) +#endif + +/* Hint: sv_uv + * Always use the SvUVx() macro instead of sv_uv(). + */ +#ifndef sv_uv +# define sv_uv(sv) SvUVx(sv) +#endif + +#if !defined(SvUOK) && defined(SvIOK_UV) +# define SvUOK(sv) SvIOK_UV(sv) +#endif +#ifndef XST_mUV +# define XST_mUV(i,v) (ST(i) = sv_2mortal(newSVuv(v)) ) +#endif + +#ifndef XSRETURN_UV +# define XSRETURN_UV(v) STMT_START { XST_mUV(0,v); XSRETURN(1); } STMT_END +#endif +#ifndef PUSHu +# define PUSHu(u) STMT_START { sv_setuv(TARG, (UV)(u)); PUSHTARG; } STMT_END +#endif + +#ifndef XPUSHu +# define XPUSHu(u) STMT_START { sv_setuv(TARG, (UV)(u)); XPUSHTARG; } STMT_END +#endif + +#ifdef HAS_MEMCMP +#ifndef memNE +# define memNE(s1,s2,l) (memcmp(s1,s2,l)) +#endif + +#ifndef memEQ +# define memEQ(s1,s2,l) (!memcmp(s1,s2,l)) +#endif + +#else +#ifndef memNE +# define memNE(s1,s2,l) (bcmp(s1,s2,l)) +#endif + +#ifndef memEQ +# define memEQ(s1,s2,l) (!bcmp(s1,s2,l)) +#endif + +#endif +#ifndef memEQs +# define memEQs(s1, l, s2) \ + (sizeof(s2)-1 == l && memEQ(s1, (s2 ""), (sizeof(s2)-1))) +#endif + +#ifndef memNEs +# define memNEs(s1, l, s2) !memEQs(s1, l, s2) +#endif +#ifndef MoveD +# define MoveD(s,d,n,t) memmove((char*)(d),(char*)(s), (n) * sizeof(t)) +#endif + +#ifndef CopyD +# define CopyD(s,d,n,t) memcpy((char*)(d),(char*)(s), (n) * sizeof(t)) +#endif + +#ifdef HAS_MEMSET +#ifndef ZeroD +# define ZeroD(d,n,t) memzero((char*)(d), (n) * sizeof(t)) +#endif + +#else +#ifndef ZeroD +# define ZeroD(d,n,t) ((void)memzero((char*)(d), (n) * sizeof(t)), d) +#endif + +#endif +#ifndef PoisonWith +# define PoisonWith(d,n,t,b) (void)memset((char*)(d), (U8)(b), (n) * sizeof(t)) +#endif + +#ifndef PoisonNew +# define PoisonNew(d,n,t) PoisonWith(d,n,t,0xAB) +#endif + +#ifndef PoisonFree +# define PoisonFree(d,n,t) PoisonWith(d,n,t,0xEF) +#endif + +#ifndef Poison +# define Poison(d,n,t) PoisonFree(d,n,t) +#endif +#ifndef Newx +# define Newx(v,n,t) New(0,v,n,t) +#endif + +#ifndef Newxc +# define Newxc(v,n,t,c) Newc(0,v,n,t,c) +#endif + +#ifndef Newxz +# define Newxz(v,n,t) Newz(0,v,n,t) +#endif +#ifndef PERL_MAGIC_qr +# define PERL_MAGIC_qr 'r' +#endif +#ifndef cBOOL +# define cBOOL(cbool) ((cbool) ? (bool)1 : (bool)0) +#endif + +#ifndef OpHAS_SIBLING +# define OpHAS_SIBLING(o) (cBOOL((o)->op_sibling)) +#endif + +#ifndef OpSIBLING +# define OpSIBLING(o) (0 + (o)->op_sibling) +#endif + +#ifndef OpMORESIB_set +# define OpMORESIB_set(o, sib) ((o)->op_sibling = (sib)) +#endif + +#ifndef OpLASTSIB_set +# define OpLASTSIB_set(o, parent) ((o)->op_sibling = NULL) +#endif + +#ifndef OpMAYBESIB_set +# define OpMAYBESIB_set(o, sib, parent) ((o)->op_sibling = (sib)) +#endif + +#ifndef SvRX +#if defined(NEED_SvRX) +static void * DPPP_(my_SvRX)(pTHX_ SV *rv); +static +#else +extern void * DPPP_(my_SvRX)(pTHX_ SV *rv); +#endif + +#ifdef SvRX +# undef SvRX +#endif +#define SvRX(a) DPPP_(my_SvRX)(aTHX_ a) + +#if defined(NEED_SvRX) || defined(NEED_SvRX_GLOBAL) + +void * +DPPP_(my_SvRX)(pTHX_ SV *rv) +{ + if (SvROK(rv)) { + SV *sv = SvRV(rv); + if (SvMAGICAL(sv)) { + MAGIC *mg = mg_find(sv, PERL_MAGIC_qr); + if (mg && mg->mg_obj) { + return mg->mg_obj; + } + } + } + return 0; +} +#endif +#endif +#ifndef SvRXOK +# define SvRXOK(sv) (!!SvRX(sv)) +#endif + +#ifndef PERL_UNUSED_DECL +# ifdef HASATTRIBUTE +# if (defined(__GNUC__) && defined(__cplusplus)) || defined(__INTEL_COMPILER) +# define PERL_UNUSED_DECL +# else +# define PERL_UNUSED_DECL __attribute__((unused)) +# endif +# else +# define PERL_UNUSED_DECL +# endif +#endif + +#ifndef PERL_UNUSED_ARG +# if defined(lint) && defined(S_SPLINT_S) /* www.splint.org */ +# include +# define PERL_UNUSED_ARG(x) NOTE(ARGUNUSED(x)) +# else +# define PERL_UNUSED_ARG(x) ((void)x) +# endif +#endif + +#ifndef PERL_UNUSED_VAR +# define PERL_UNUSED_VAR(x) ((void)x) +#endif + +#ifndef PERL_UNUSED_CONTEXT +# ifdef USE_ITHREADS +# define PERL_UNUSED_CONTEXT PERL_UNUSED_ARG(my_perl) +# else +# define PERL_UNUSED_CONTEXT +# endif +#endif + +#ifndef PERL_UNUSED_RESULT +# if defined(__GNUC__) && defined(HASATTRIBUTE_WARN_UNUSED_RESULT) +# define PERL_UNUSED_RESULT(v) STMT_START { __typeof__(v) z = (v); (void)sizeof(z); } STMT_END +# else +# define PERL_UNUSED_RESULT(v) ((void)(v)) +# endif +#endif +#ifndef NOOP +# define NOOP /*EMPTY*/(void)0 +#endif + +#ifndef dNOOP +# define dNOOP extern int /*@unused@*/ Perl___notused PERL_UNUSED_DECL +#endif + +#ifndef NVTYPE +# if defined(USE_LONG_DOUBLE) && defined(HAS_LONG_DOUBLE) +# define NVTYPE long double +# else +# define NVTYPE double +# endif +typedef NVTYPE NV; +#endif + +#ifndef INT2PTR +# if (IVSIZE == PTRSIZE) && (UVSIZE == PTRSIZE) +# define PTRV UV +# define INT2PTR(any,d) (any)(d) +# else +# if PTRSIZE == LONGSIZE +# define PTRV unsigned long +# else +# define PTRV unsigned +# endif +# define INT2PTR(any,d) (any)(PTRV)(d) +# endif +#endif + +#ifndef PTR2ul +# if PTRSIZE == LONGSIZE +# define PTR2ul(p) (unsigned long)(p) +# else +# define PTR2ul(p) INT2PTR(unsigned long,p) +# endif +#endif +#ifndef PTR2nat +# define PTR2nat(p) (PTRV)(p) +#endif + +#ifndef NUM2PTR +# define NUM2PTR(any,d) (any)PTR2nat(d) +#endif + +#ifndef PTR2IV +# define PTR2IV(p) INT2PTR(IV,p) +#endif + +#ifndef PTR2UV +# define PTR2UV(p) INT2PTR(UV,p) +#endif + +#ifndef PTR2NV +# define PTR2NV(p) NUM2PTR(NV,p) +#endif + +#undef START_EXTERN_C +#undef END_EXTERN_C +#undef EXTERN_C +#ifdef __cplusplus +# define START_EXTERN_C extern "C" { +# define END_EXTERN_C } +# define EXTERN_C extern "C" +#else +# define START_EXTERN_C +# define END_EXTERN_C +# define EXTERN_C extern +#endif + +#if defined(PERL_GCC_PEDANTIC) +# ifndef PERL_GCC_BRACE_GROUPS_FORBIDDEN +# define PERL_GCC_BRACE_GROUPS_FORBIDDEN +# endif +#endif + +#if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN) && !defined(__cplusplus) +# ifndef PERL_USE_GCC_BRACE_GROUPS +# define PERL_USE_GCC_BRACE_GROUPS +# endif +#endif + +#undef STMT_START +#undef STMT_END +#ifdef PERL_USE_GCC_BRACE_GROUPS +# define STMT_START (void)( /* gcc supports ``({ STATEMENTS; })'' */ +# define STMT_END ) +#else +# if defined(VOIDFLAGS) && (VOIDFLAGS) && (defined(sun) || defined(__sun__)) && !defined(__GNUC__) +# define STMT_START if (1) +# define STMT_END else (void)0 +# else +# define STMT_START do +# define STMT_END while (0) +# endif +#endif +#ifndef boolSV +# define boolSV(b) ((b) ? &PL_sv_yes : &PL_sv_no) +#endif + +/* DEFSV appears first in 5.004_56 */ +#ifndef DEFSV +# define DEFSV GvSV(PL_defgv) +#endif + +#ifndef SAVE_DEFSV +# define SAVE_DEFSV SAVESPTR(GvSV(PL_defgv)) +#endif + +#ifndef DEFSV_set +# define DEFSV_set(sv) (DEFSV = (sv)) +#endif + +/* Older perls (<=5.003) lack AvFILLp */ +#ifndef AvFILLp +# define AvFILLp AvFILL +#endif +#ifndef ERRSV +# define ERRSV get_sv("@",FALSE) +#endif + +/* Hint: gv_stashpvn + * This function's backport doesn't support the length parameter, but + * rather ignores it. Portability can only be ensured if the length + * parameter is used for speed reasons, but the length can always be + * correctly computed from the string argument. + */ +#ifndef gv_stashpvn +# define gv_stashpvn(str,len,create) gv_stashpv(str,create) +#endif + +/* Replace: 1 */ +#ifndef get_cv +# define get_cv perl_get_cv +#endif + +#ifndef get_sv +# define get_sv perl_get_sv +#endif + +#ifndef get_av +# define get_av perl_get_av +#endif + +#ifndef get_hv +# define get_hv perl_get_hv +#endif + +/* Replace: 0 */ +#ifndef dUNDERBAR +# define dUNDERBAR dNOOP +#endif + +#ifndef UNDERBAR +# define UNDERBAR DEFSV +#endif +#ifndef dAX +# define dAX I32 ax = MARK - PL_stack_base + 1 +#endif + +#ifndef dITEMS +# define dITEMS I32 items = SP - MARK +#endif +#ifndef dXSTARG +# define dXSTARG SV * targ = sv_newmortal() +#endif +#ifndef dAXMARK +# define dAXMARK I32 ax = POPMARK; \ + register SV ** const mark = PL_stack_base + ax++ +#endif +#ifndef XSprePUSH +# define XSprePUSH (sp = PL_stack_base + ax - 1) +#endif + +#if (PERL_BCDVERSION < 0x5005000) +# undef XSRETURN +# define XSRETURN(off) \ + STMT_START { \ + PL_stack_sp = PL_stack_base + ax + ((off) - 1); \ + return; \ + } STMT_END +#endif +#ifndef XSPROTO +# define XSPROTO(name) void name(pTHX_ CV* cv) +#endif + +#ifndef SVfARG +# define SVfARG(p) ((void*)(p)) +#endif +#ifndef PERL_ABS +# define PERL_ABS(x) ((x) < 0 ? -(x) : (x)) +#endif +#ifndef dVAR +# define dVAR dNOOP +#endif +#ifndef SVf +# define SVf "_" +#endif +#ifndef UTF8_MAXBYTES +# define UTF8_MAXBYTES UTF8_MAXLEN +#endif +#ifndef CPERLscope +# define CPERLscope(x) x +#endif +#ifndef PERL_HASH +# define PERL_HASH(hash,str,len) \ + STMT_START { \ + const char *s_PeRlHaSh = str; \ + I32 i_PeRlHaSh = len; \ + U32 hash_PeRlHaSh = 0; \ + while (i_PeRlHaSh--) \ + hash_PeRlHaSh = hash_PeRlHaSh * 33 + *s_PeRlHaSh++; \ + (hash) = hash_PeRlHaSh; \ + } STMT_END +#endif + +#ifndef PERLIO_FUNCS_DECL +# ifdef PERLIO_FUNCS_CONST +# define PERLIO_FUNCS_DECL(funcs) const PerlIO_funcs funcs +# define PERLIO_FUNCS_CAST(funcs) (PerlIO_funcs*)(funcs) +# else +# define PERLIO_FUNCS_DECL(funcs) PerlIO_funcs funcs +# define PERLIO_FUNCS_CAST(funcs) (funcs) +# endif +#endif + +/* provide these typedefs for older perls */ +#if (PERL_BCDVERSION < 0x5009003) + +# ifdef ARGSproto +typedef OP* (CPERLscope(*Perl_ppaddr_t))(ARGSproto); +# else +typedef OP* (CPERLscope(*Perl_ppaddr_t))(pTHX); +# endif + +typedef OP* (CPERLscope(*Perl_check_t)) (pTHX_ OP*); + +#endif +#ifndef isPSXSPC +# define isPSXSPC(c) (isSPACE(c) || (c) == '\v') +#endif + +#ifndef isBLANK +# define isBLANK(c) ((c) == ' ' || (c) == '\t') +#endif + +#ifdef EBCDIC +#ifndef isALNUMC +# define isALNUMC(c) isalnum(c) +#endif + +#ifndef isASCII +# define isASCII(c) isascii(c) +#endif + +#ifndef isCNTRL +# define isCNTRL(c) iscntrl(c) +#endif + +#ifndef isGRAPH +# define isGRAPH(c) isgraph(c) +#endif + +#ifndef isPRINT +# define isPRINT(c) isprint(c) +#endif + +#ifndef isPUNCT +# define isPUNCT(c) ispunct(c) +#endif + +#ifndef isXDIGIT +# define isXDIGIT(c) isxdigit(c) +#endif + +#else +# if (PERL_BCDVERSION < 0x5010000) +/* Hint: isPRINT + * The implementation in older perl versions includes all of the + * isSPACE() characters, which is wrong. The version provided by + * Devel::PPPort always overrides a present buggy version. + */ +# undef isPRINT +# endif + +#ifdef HAS_QUAD +# ifdef U64TYPE +# define WIDEST_UTYPE U64TYPE +# else +# define WIDEST_UTYPE Quad_t +# endif +#else +# define WIDEST_UTYPE U32 +#endif +#ifndef isALNUMC +# define isALNUMC(c) (isALPHA(c) || isDIGIT(c)) +#endif + +#ifndef isASCII +# define isASCII(c) ((WIDEST_UTYPE) (c) <= 127) +#endif + +#ifndef isCNTRL +# define isCNTRL(c) ((WIDEST_UTYPE) (c) < ' ' || (c) == 127) +#endif + +#ifndef isGRAPH +# define isGRAPH(c) (isALNUM(c) || isPUNCT(c)) +#endif + +#ifndef isPRINT +# define isPRINT(c) (((c) >= 32 && (c) < 127)) +#endif + +#ifndef isPUNCT +# define isPUNCT(c) (((c) >= 33 && (c) <= 47) || ((c) >= 58 && (c) <= 64) || ((c) >= 91 && (c) <= 96) || ((c) >= 123 && (c) <= 126)) +#endif + +#ifndef isXDIGIT +# define isXDIGIT(c) (isDIGIT(c) || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F')) +#endif + +#endif + +/* Until we figure out how to support this in older perls... */ +#if (PERL_BCDVERSION >= 0x5008000) +#ifndef HeUTF8 +# define HeUTF8(he) ((HeKLEN(he) == HEf_SVKEY) ? \ + SvUTF8(HeKEY_sv(he)) : \ + (U32)HeKUTF8(he)) +#endif + +#endif +#ifndef C_ARRAY_LENGTH +# define C_ARRAY_LENGTH(a) (sizeof(a)/sizeof((a)[0])) +#endif + +#ifndef C_ARRAY_END +# define C_ARRAY_END(a) ((a) + C_ARRAY_LENGTH(a)) +#endif + +#ifndef PERL_SIGNALS_UNSAFE_FLAG + +#define PERL_SIGNALS_UNSAFE_FLAG 0x0001 + +#if (PERL_BCDVERSION < 0x5008000) +# define D_PPP_PERL_SIGNALS_INIT PERL_SIGNALS_UNSAFE_FLAG +#else +# define D_PPP_PERL_SIGNALS_INIT 0 +#endif + +#if defined(NEED_PL_signals) +static U32 DPPP_(my_PL_signals) = D_PPP_PERL_SIGNALS_INIT; +#elif defined(NEED_PL_signals_GLOBAL) +U32 DPPP_(my_PL_signals) = D_PPP_PERL_SIGNALS_INIT; +#else +extern U32 DPPP_(my_PL_signals); +#endif +#define PL_signals DPPP_(my_PL_signals) + +#endif + +/* Hint: PL_ppaddr + * Calling an op via PL_ppaddr requires passing a context argument + * for threaded builds. Since the context argument is different for + * 5.005 perls, you can use aTHXR (supplied by ppport.h), which will + * automatically be defined as the correct argument. + */ + +#if (PERL_BCDVERSION <= 0x5005005) +/* Replace: 1 */ +# define PL_ppaddr ppaddr +# define PL_no_modify no_modify +/* Replace: 0 */ +#endif + +#if (PERL_BCDVERSION <= 0x5004005) +/* Replace: 1 */ +# define PL_DBsignal DBsignal +# define PL_DBsingle DBsingle +# define PL_DBsub DBsub +# define PL_DBtrace DBtrace +# define PL_Sv Sv +# define PL_bufend bufend +# define PL_bufptr bufptr +# define PL_compiling compiling +# define PL_copline copline +# define PL_curcop curcop +# define PL_curstash curstash +# define PL_debstash debstash +# define PL_defgv defgv +# define PL_diehook diehook +# define PL_dirty dirty +# define PL_dowarn dowarn +# define PL_errgv errgv +# define PL_error_count error_count +# define PL_expect expect +# define PL_hexdigit hexdigit +# define PL_hints hints +# define PL_in_my in_my +# define PL_laststatval laststatval +# define PL_lex_state lex_state +# define PL_lex_stuff lex_stuff +# define PL_linestr linestr +# define PL_na na +# define PL_perl_destruct_level perl_destruct_level +# define PL_perldb perldb +# define PL_rsfp_filters rsfp_filters +# define PL_rsfp rsfp +# define PL_stack_base stack_base +# define PL_stack_sp stack_sp +# define PL_statcache statcache +# define PL_stdingv stdingv +# define PL_sv_arenaroot sv_arenaroot +# define PL_sv_no sv_no +# define PL_sv_undef sv_undef +# define PL_sv_yes sv_yes +# define PL_tainted tainted +# define PL_tainting tainting +# define PL_tokenbuf tokenbuf +/* Replace: 0 */ +#endif + +/* Warning: PL_parser + * For perl versions earlier than 5.9.5, this is an always + * non-NULL dummy. Also, it cannot be dereferenced. Don't + * use it if you can avoid is and unless you absolutely know + * what you're doing. + * If you always check that PL_parser is non-NULL, you can + * define DPPP_PL_parser_NO_DUMMY to avoid the creation of + * a dummy parser structure. + */ + +#if (PERL_BCDVERSION >= 0x5009005) +# ifdef DPPP_PL_parser_NO_DUMMY +# define D_PPP_my_PL_parser_var(var) ((PL_parser ? PL_parser : \ + (croak("panic: PL_parser == NULL in %s:%d", \ + __FILE__, __LINE__), (yy_parser *) NULL))->var) +# else +# ifdef DPPP_PL_parser_NO_DUMMY_WARNING +# define D_PPP_parser_dummy_warning(var) +# else +# define D_PPP_parser_dummy_warning(var) \ + warn("warning: dummy PL_" #var " used in %s:%d", __FILE__, __LINE__), +# endif +# define D_PPP_my_PL_parser_var(var) ((PL_parser ? PL_parser : \ + (D_PPP_parser_dummy_warning(var) &DPPP_(dummy_PL_parser)))->var) +#if defined(NEED_PL_parser) +static yy_parser DPPP_(dummy_PL_parser); +#elif defined(NEED_PL_parser_GLOBAL) +yy_parser DPPP_(dummy_PL_parser); +#else +extern yy_parser DPPP_(dummy_PL_parser); +#endif + +# endif + +/* PL_expect, PL_copline, PL_rsfp, PL_rsfp_filters, PL_linestr, PL_bufptr, PL_bufend, PL_lex_state, PL_lex_stuff, PL_tokenbuf depends on PL_parser */ +/* Warning: PL_expect, PL_copline, PL_rsfp, PL_rsfp_filters, PL_linestr, PL_bufptr, PL_bufend, PL_lex_state, PL_lex_stuff, PL_tokenbuf + * Do not use this variable unless you know exactly what you're + * doing. It is internal to the perl parser and may change or even + * be removed in the future. As of perl 5.9.5, you have to check + * for (PL_parser != NULL) for this variable to have any effect. + * An always non-NULL PL_parser dummy is provided for earlier + * perl versions. + * If PL_parser is NULL when you try to access this variable, a + * dummy is being accessed instead and a warning is issued unless + * you define DPPP_PL_parser_NO_DUMMY_WARNING. + * If DPPP_PL_parser_NO_DUMMY is defined, the code trying to access + * this variable will croak with a panic message. + */ + +# define PL_expect D_PPP_my_PL_parser_var(expect) +# define PL_copline D_PPP_my_PL_parser_var(copline) +# define PL_rsfp D_PPP_my_PL_parser_var(rsfp) +# define PL_rsfp_filters D_PPP_my_PL_parser_var(rsfp_filters) +# define PL_linestr D_PPP_my_PL_parser_var(linestr) +# define PL_bufptr D_PPP_my_PL_parser_var(bufptr) +# define PL_bufend D_PPP_my_PL_parser_var(bufend) +# define PL_lex_state D_PPP_my_PL_parser_var(lex_state) +# define PL_lex_stuff D_PPP_my_PL_parser_var(lex_stuff) +# define PL_tokenbuf D_PPP_my_PL_parser_var(tokenbuf) +# define PL_in_my D_PPP_my_PL_parser_var(in_my) +# define PL_in_my_stash D_PPP_my_PL_parser_var(in_my_stash) +# define PL_error_count D_PPP_my_PL_parser_var(error_count) + + +#else + +/* ensure that PL_parser != NULL and cannot be dereferenced */ +# define PL_parser ((void *) 1) + +#endif +#ifndef mPUSHs +# define mPUSHs(s) PUSHs(sv_2mortal(s)) +#endif + +#ifndef PUSHmortal +# define PUSHmortal PUSHs(sv_newmortal()) +#endif + +#ifndef mPUSHp +# define mPUSHp(p,l) sv_setpvn(PUSHmortal, (p), (l)) +#endif + +#ifndef mPUSHn +# define mPUSHn(n) sv_setnv(PUSHmortal, (NV)(n)) +#endif + +#ifndef mPUSHi +# define mPUSHi(i) sv_setiv(PUSHmortal, (IV)(i)) +#endif + +#ifndef mPUSHu +# define mPUSHu(u) sv_setuv(PUSHmortal, (UV)(u)) +#endif +#ifndef mXPUSHs +# define mXPUSHs(s) XPUSHs(sv_2mortal(s)) +#endif + +#ifndef XPUSHmortal +# define XPUSHmortal XPUSHs(sv_newmortal()) +#endif + +#ifndef mXPUSHp +# define mXPUSHp(p,l) STMT_START { EXTEND(sp,1); sv_setpvn(PUSHmortal, (p), (l)); } STMT_END +#endif + +#ifndef mXPUSHn +# define mXPUSHn(n) STMT_START { EXTEND(sp,1); sv_setnv(PUSHmortal, (NV)(n)); } STMT_END +#endif + +#ifndef mXPUSHi +# define mXPUSHi(i) STMT_START { EXTEND(sp,1); sv_setiv(PUSHmortal, (IV)(i)); } STMT_END +#endif + +#ifndef mXPUSHu +# define mXPUSHu(u) STMT_START { EXTEND(sp,1); sv_setuv(PUSHmortal, (UV)(u)); } STMT_END +#endif + +/* Replace: 1 */ +#ifndef call_sv +# define call_sv perl_call_sv +#endif + +#ifndef call_pv +# define call_pv perl_call_pv +#endif + +#ifndef call_argv +# define call_argv perl_call_argv +#endif + +#ifndef call_method +# define call_method perl_call_method +#endif +#ifndef eval_sv +# define eval_sv perl_eval_sv +#endif + +/* Replace: 0 */ +#ifndef PERL_LOADMOD_DENY +# define PERL_LOADMOD_DENY 0x1 +#endif + +#ifndef PERL_LOADMOD_NOIMPORT +# define PERL_LOADMOD_NOIMPORT 0x2 +#endif + +#ifndef PERL_LOADMOD_IMPORT_OPS +# define PERL_LOADMOD_IMPORT_OPS 0x4 +#endif + +#ifndef G_METHOD +# define G_METHOD 64 +# ifdef call_sv +# undef call_sv +# endif +# if (PERL_BCDVERSION < 0x5006000) +# define call_sv(sv, flags) ((flags) & G_METHOD ? perl_call_method((char *) SvPV_nolen_const(sv), \ + (flags) & ~G_METHOD) : perl_call_sv(sv, flags)) +# else +# define call_sv(sv, flags) ((flags) & G_METHOD ? Perl_call_method(aTHX_ (char *) SvPV_nolen_const(sv), \ + (flags) & ~G_METHOD) : Perl_call_sv(aTHX_ sv, flags)) +# endif +#endif + +/* Replace perl_eval_pv with eval_pv */ + +#ifndef eval_pv +#if defined(NEED_eval_pv) +static SV* DPPP_(my_eval_pv)(char *p, I32 croak_on_error); +static +#else +extern SV* DPPP_(my_eval_pv)(char *p, I32 croak_on_error); +#endif + +#ifdef eval_pv +# undef eval_pv +#endif +#define eval_pv(a,b) DPPP_(my_eval_pv)(aTHX_ a,b) +#define Perl_eval_pv DPPP_(my_eval_pv) + +#if defined(NEED_eval_pv) || defined(NEED_eval_pv_GLOBAL) + +SV* +DPPP_(my_eval_pv)(char *p, I32 croak_on_error) +{ + dSP; + SV* sv = newSVpv(p, 0); + + PUSHMARK(sp); + eval_sv(sv, G_SCALAR); + SvREFCNT_dec(sv); + + SPAGAIN; + sv = POPs; + PUTBACK; + + if (croak_on_error && SvTRUE(GvSV(errgv))) + croak(SvPVx(GvSV(errgv), na)); + + return sv; +} + +#endif +#endif + +#ifndef vload_module +#if defined(NEED_vload_module) +static void DPPP_(my_vload_module)(U32 flags, SV *name, SV *ver, va_list *args); +static +#else +extern void DPPP_(my_vload_module)(U32 flags, SV *name, SV *ver, va_list *args); +#endif + +#ifdef vload_module +# undef vload_module +#endif +#define vload_module(a,b,c,d) DPPP_(my_vload_module)(aTHX_ a,b,c,d) +#define Perl_vload_module DPPP_(my_vload_module) + +#if defined(NEED_vload_module) || defined(NEED_vload_module_GLOBAL) + +void +DPPP_(my_vload_module)(U32 flags, SV *name, SV *ver, va_list *args) +{ + dTHR; + dVAR; + OP *veop, *imop; + + OP * const modname = newSVOP(OP_CONST, 0, name); + /* 5.005 has a somewhat hacky force_normal that doesn't croak on + SvREADONLY() if PL_compling is true. Current perls take care in + ck_require() to correctly turn off SvREADONLY before calling + force_normal_flags(). This seems a better fix than fudging PL_compling + */ + SvREADONLY_off(((SVOP*)modname)->op_sv); + modname->op_private |= OPpCONST_BARE; + if (ver) { + veop = newSVOP(OP_CONST, 0, ver); + } + else + veop = NULL; + if (flags & PERL_LOADMOD_NOIMPORT) { + imop = sawparens(newNULLLIST()); + } + else if (flags & PERL_LOADMOD_IMPORT_OPS) { + imop = va_arg(*args, OP*); + } + else { + SV *sv; + imop = NULL; + sv = va_arg(*args, SV*); + while (sv) { + imop = append_elem(OP_LIST, imop, newSVOP(OP_CONST, 0, sv)); + sv = va_arg(*args, SV*); + } + } + { + const line_t ocopline = PL_copline; + COP * const ocurcop = PL_curcop; + const int oexpect = PL_expect; + +#if (PERL_BCDVERSION >= 0x5004000) + utilize(!(flags & PERL_LOADMOD_DENY), start_subparse(FALSE, 0), + veop, modname, imop); +#elif (PERL_BCDVERSION > 0x5003000) + utilize(!(flags & PERL_LOADMOD_DENY), start_subparse(), + veop, modname, imop); +#else + utilize(!(flags & PERL_LOADMOD_DENY), start_subparse(), + modname, imop); +#endif + PL_expect = oexpect; + PL_copline = ocopline; + PL_curcop = ocurcop; + } +} + +#endif +#endif + +#ifndef load_module +#if defined(NEED_load_module) +static void DPPP_(my_load_module)(U32 flags, SV *name, SV *ver, ...); +static +#else +extern void DPPP_(my_load_module)(U32 flags, SV *name, SV *ver, ...); +#endif + +#ifdef load_module +# undef load_module +#endif +#define load_module DPPP_(my_load_module) +#define Perl_load_module DPPP_(my_load_module) + +#if defined(NEED_load_module) || defined(NEED_load_module_GLOBAL) + +void +DPPP_(my_load_module)(U32 flags, SV *name, SV *ver, ...) +{ + va_list args; + va_start(args, ver); + vload_module(flags, name, ver, &args); + va_end(args); +} + +#endif +#endif +#ifndef newRV_inc +# define newRV_inc(sv) newRV(sv) /* Replace */ +#endif + +#ifndef newRV_noinc +#if defined(NEED_newRV_noinc) +static SV * DPPP_(my_newRV_noinc)(SV *sv); +static +#else +extern SV * DPPP_(my_newRV_noinc)(SV *sv); +#endif + +#ifdef newRV_noinc +# undef newRV_noinc +#endif +#define newRV_noinc(a) DPPP_(my_newRV_noinc)(aTHX_ a) +#define Perl_newRV_noinc DPPP_(my_newRV_noinc) + +#if defined(NEED_newRV_noinc) || defined(NEED_newRV_noinc_GLOBAL) +SV * +DPPP_(my_newRV_noinc)(SV *sv) +{ + SV *rv = (SV *)newRV(sv); + SvREFCNT_dec(sv); + return rv; +} +#endif +#endif + +/* Hint: newCONSTSUB + * Returns a CV* as of perl-5.7.1. This return value is not supported + * by Devel::PPPort. + */ + +/* newCONSTSUB from IO.xs is in the core starting with 5.004_63 */ +#if (PERL_BCDVERSION < 0x5004063) && (PERL_BCDVERSION != 0x5004005) +#if defined(NEED_newCONSTSUB) +static void DPPP_(my_newCONSTSUB)(HV *stash, const char *name, SV *sv); +static +#else +extern void DPPP_(my_newCONSTSUB)(HV *stash, const char *name, SV *sv); +#endif + +#ifdef newCONSTSUB +# undef newCONSTSUB +#endif +#define newCONSTSUB(a,b,c) DPPP_(my_newCONSTSUB)(aTHX_ a,b,c) +#define Perl_newCONSTSUB DPPP_(my_newCONSTSUB) + +#if defined(NEED_newCONSTSUB) || defined(NEED_newCONSTSUB_GLOBAL) + +/* This is just a trick to avoid a dependency of newCONSTSUB on PL_parser */ +/* (There's no PL_parser in perl < 5.005, so this is completely safe) */ +#define D_PPP_PL_copline PL_copline + +void +DPPP_(my_newCONSTSUB)(HV *stash, const char *name, SV *sv) +{ + U32 oldhints = PL_hints; + HV *old_cop_stash = PL_curcop->cop_stash; + HV *old_curstash = PL_curstash; + line_t oldline = PL_curcop->cop_line; + PL_curcop->cop_line = D_PPP_PL_copline; + + PL_hints &= ~HINT_BLOCK_SCOPE; + if (stash) + PL_curstash = PL_curcop->cop_stash = stash; + + newSUB( + +#if (PERL_BCDVERSION < 0x5003022) + start_subparse(), +#elif (PERL_BCDVERSION == 0x5003022) + start_subparse(0), +#else /* 5.003_23 onwards */ + start_subparse(FALSE, 0), +#endif + + newSVOP(OP_CONST, 0, newSVpv((char *) name, 0)), + newSVOP(OP_CONST, 0, &PL_sv_no), /* SvPV(&PL_sv_no) == "" -- GMB */ + newSTATEOP(0, Nullch, newSVOP(OP_CONST, 0, sv)) + ); + + PL_hints = oldhints; + PL_curcop->cop_stash = old_cop_stash; + PL_curstash = old_curstash; + PL_curcop->cop_line = oldline; +} +#endif +#endif + +/* + * Boilerplate macros for initializing and accessing interpreter-local + * data from C. All statics in extensions should be reworked to use + * this, if you want to make the extension thread-safe. See ext/re/re.xs + * for an example of the use of these macros. + * + * Code that uses these macros is responsible for the following: + * 1. #define MY_CXT_KEY to a unique string, e.g. "DynaLoader_guts" + * 2. Declare a typedef named my_cxt_t that is a structure that contains + * all the data that needs to be interpreter-local. + * 3. Use the START_MY_CXT macro after the declaration of my_cxt_t. + * 4. Use the MY_CXT_INIT macro such that it is called exactly once + * (typically put in the BOOT: section). + * 5. Use the members of the my_cxt_t structure everywhere as + * MY_CXT.member. + * 6. Use the dMY_CXT macro (a declaration) in all the functions that + * access MY_CXT. + */ + +#if defined(MULTIPLICITY) || defined(PERL_OBJECT) || \ + defined(PERL_CAPI) || defined(PERL_IMPLICIT_CONTEXT) + +#ifndef START_MY_CXT + +/* This must appear in all extensions that define a my_cxt_t structure, + * right after the definition (i.e. at file scope). The non-threads + * case below uses it to declare the data as static. */ +#define START_MY_CXT + +#if (PERL_BCDVERSION < 0x5004068) +/* Fetches the SV that keeps the per-interpreter data. */ +#define dMY_CXT_SV \ + SV *my_cxt_sv = get_sv(MY_CXT_KEY, FALSE) +#else /* >= perl5.004_68 */ +#define dMY_CXT_SV \ + SV *my_cxt_sv = *hv_fetch(PL_modglobal, MY_CXT_KEY, \ + sizeof(MY_CXT_KEY)-1, TRUE) +#endif /* < perl5.004_68 */ + +/* This declaration should be used within all functions that use the + * interpreter-local data. */ +#define dMY_CXT \ + dMY_CXT_SV; \ + my_cxt_t *my_cxtp = INT2PTR(my_cxt_t*,SvUV(my_cxt_sv)) + +/* Creates and zeroes the per-interpreter data. + * (We allocate my_cxtp in a Perl SV so that it will be released when + * the interpreter goes away.) */ +#define MY_CXT_INIT \ + dMY_CXT_SV; \ + /* newSV() allocates one more than needed */ \ + my_cxt_t *my_cxtp = (my_cxt_t*)SvPVX(newSV(sizeof(my_cxt_t)-1));\ + Zero(my_cxtp, 1, my_cxt_t); \ + sv_setuv(my_cxt_sv, PTR2UV(my_cxtp)) + +/* This macro must be used to access members of the my_cxt_t structure. + * e.g. MYCXT.some_data */ +#define MY_CXT (*my_cxtp) + +/* Judicious use of these macros can reduce the number of times dMY_CXT + * is used. Use is similar to pTHX, aTHX etc. */ +#define pMY_CXT my_cxt_t *my_cxtp +#define pMY_CXT_ pMY_CXT, +#define _pMY_CXT ,pMY_CXT +#define aMY_CXT my_cxtp +#define aMY_CXT_ aMY_CXT, +#define _aMY_CXT ,aMY_CXT + +#endif /* START_MY_CXT */ + +#ifndef MY_CXT_CLONE +/* Clones the per-interpreter data. */ +#define MY_CXT_CLONE \ + dMY_CXT_SV; \ + my_cxt_t *my_cxtp = (my_cxt_t*)SvPVX(newSV(sizeof(my_cxt_t)-1));\ + Copy(INT2PTR(my_cxt_t*, SvUV(my_cxt_sv)), my_cxtp, 1, my_cxt_t);\ + sv_setuv(my_cxt_sv, PTR2UV(my_cxtp)) +#endif + +#else /* single interpreter */ + +#ifndef START_MY_CXT + +#define START_MY_CXT static my_cxt_t my_cxt; +#define dMY_CXT_SV dNOOP +#define dMY_CXT dNOOP +#define MY_CXT_INIT NOOP +#define MY_CXT my_cxt + +#define pMY_CXT void +#define pMY_CXT_ +#define _pMY_CXT +#define aMY_CXT +#define aMY_CXT_ +#define _aMY_CXT + +#endif /* START_MY_CXT */ + +#ifndef MY_CXT_CLONE +#define MY_CXT_CLONE NOOP +#endif + +#endif + +#ifndef IVdf +# if IVSIZE == LONGSIZE +# define IVdf "ld" +# define UVuf "lu" +# define UVof "lo" +# define UVxf "lx" +# define UVXf "lX" +# elif IVSIZE == INTSIZE +# define IVdf "d" +# define UVuf "u" +# define UVof "o" +# define UVxf "x" +# define UVXf "X" +# else +# error "cannot define IV/UV formats" +# endif +#endif + +#ifndef NVef +# if defined(USE_LONG_DOUBLE) && defined(HAS_LONG_DOUBLE) && \ + defined(PERL_PRIfldbl) && (PERL_BCDVERSION != 0x5006000) + /* Not very likely, but let's try anyway. */ +# define NVef PERL_PRIeldbl +# define NVff PERL_PRIfldbl +# define NVgf PERL_PRIgldbl +# else +# define NVef "e" +# define NVff "f" +# define NVgf "g" +# endif +#endif + +#ifndef SvREFCNT_inc +# ifdef PERL_USE_GCC_BRACE_GROUPS +# define SvREFCNT_inc(sv) \ + ({ \ + SV * const _sv = (SV*)(sv); \ + if (_sv) \ + (SvREFCNT(_sv))++; \ + _sv; \ + }) +# else +# define SvREFCNT_inc(sv) \ + ((PL_Sv=(SV*)(sv)) ? (++(SvREFCNT(PL_Sv)),PL_Sv) : NULL) +# endif +#endif + +#ifndef SvREFCNT_inc_simple +# ifdef PERL_USE_GCC_BRACE_GROUPS +# define SvREFCNT_inc_simple(sv) \ + ({ \ + if (sv) \ + (SvREFCNT(sv))++; \ + (SV *)(sv); \ + }) +# else +# define SvREFCNT_inc_simple(sv) \ + ((sv) ? (SvREFCNT(sv)++,(SV*)(sv)) : NULL) +# endif +#endif + +#ifndef SvREFCNT_inc_NN +# ifdef PERL_USE_GCC_BRACE_GROUPS +# define SvREFCNT_inc_NN(sv) \ + ({ \ + SV * const _sv = (SV*)(sv); \ + SvREFCNT(_sv)++; \ + _sv; \ + }) +# else +# define SvREFCNT_inc_NN(sv) \ + (PL_Sv=(SV*)(sv),++(SvREFCNT(PL_Sv)),PL_Sv) +# endif +#endif + +#ifndef SvREFCNT_inc_void +# ifdef PERL_USE_GCC_BRACE_GROUPS +# define SvREFCNT_inc_void(sv) \ + ({ \ + SV * const _sv = (SV*)(sv); \ + if (_sv) \ + (void)(SvREFCNT(_sv)++); \ + }) +# else +# define SvREFCNT_inc_void(sv) \ + (void)((PL_Sv=(SV*)(sv)) ? ++(SvREFCNT(PL_Sv)) : 0) +# endif +#endif +#ifndef SvREFCNT_inc_simple_void +# define SvREFCNT_inc_simple_void(sv) STMT_START { if (sv) SvREFCNT(sv)++; } STMT_END +#endif + +#ifndef SvREFCNT_inc_simple_NN +# define SvREFCNT_inc_simple_NN(sv) (++SvREFCNT(sv), (SV*)(sv)) +#endif + +#ifndef SvREFCNT_inc_void_NN +# define SvREFCNT_inc_void_NN(sv) (void)(++SvREFCNT((SV*)(sv))) +#endif + +#ifndef SvREFCNT_inc_simple_void_NN +# define SvREFCNT_inc_simple_void_NN(sv) (void)(++SvREFCNT((SV*)(sv))) +#endif + +#ifndef newSV_type + +#if defined(NEED_newSV_type) +static SV* DPPP_(my_newSV_type)(pTHX_ svtype const t); +static +#else +extern SV* DPPP_(my_newSV_type)(pTHX_ svtype const t); +#endif + +#ifdef newSV_type +# undef newSV_type +#endif +#define newSV_type(a) DPPP_(my_newSV_type)(aTHX_ a) +#define Perl_newSV_type DPPP_(my_newSV_type) + +#if defined(NEED_newSV_type) || defined(NEED_newSV_type_GLOBAL) + +SV* +DPPP_(my_newSV_type)(pTHX_ svtype const t) +{ + SV* const sv = newSV(0); + sv_upgrade(sv, t); + return sv; +} + +#endif + +#endif + +#if (PERL_BCDVERSION < 0x5006000) +# define D_PPP_CONSTPV_ARG(x) ((char *) (x)) +#else +# define D_PPP_CONSTPV_ARG(x) (x) +#endif +#ifndef newSVpvn +# define newSVpvn(data,len) ((data) \ + ? ((len) ? newSVpv((data), (len)) : newSVpv("", 0)) \ + : newSV(0)) +#endif +#ifndef newSVpvn_utf8 +# define newSVpvn_utf8(s, len, u) newSVpvn_flags((s), (len), (u) ? SVf_UTF8 : 0) +#endif +#ifndef SVf_UTF8 +# define SVf_UTF8 0 +#endif + +#ifndef newSVpvn_flags + +#if defined(NEED_newSVpvn_flags) +static SV * DPPP_(my_newSVpvn_flags)(pTHX_ const char *s, STRLEN len, U32 flags); +static +#else +extern SV * DPPP_(my_newSVpvn_flags)(pTHX_ const char *s, STRLEN len, U32 flags); +#endif + +#ifdef newSVpvn_flags +# undef newSVpvn_flags +#endif +#define newSVpvn_flags(a,b,c) DPPP_(my_newSVpvn_flags)(aTHX_ a,b,c) +#define Perl_newSVpvn_flags DPPP_(my_newSVpvn_flags) + +#if defined(NEED_newSVpvn_flags) || defined(NEED_newSVpvn_flags_GLOBAL) + +SV * +DPPP_(my_newSVpvn_flags)(pTHX_ const char *s, STRLEN len, U32 flags) +{ + SV *sv = newSVpvn(D_PPP_CONSTPV_ARG(s), len); + SvFLAGS(sv) |= (flags & SVf_UTF8); + return (flags & SVs_TEMP) ? sv_2mortal(sv) : sv; +} + +#endif + +#endif + +/* Backwards compatibility stuff... :-( */ +#if !defined(NEED_sv_2pv_flags) && defined(NEED_sv_2pv_nolen) +# define NEED_sv_2pv_flags +#endif +#if !defined(NEED_sv_2pv_flags_GLOBAL) && defined(NEED_sv_2pv_nolen_GLOBAL) +# define NEED_sv_2pv_flags_GLOBAL +#endif + +/* Hint: sv_2pv_nolen + * Use the SvPV_nolen() or SvPV_nolen_const() macros instead of sv_2pv_nolen(). + */ +#ifndef sv_2pv_nolen +# define sv_2pv_nolen(sv) SvPV_nolen(sv) +#endif + +#ifdef SvPVbyte + +/* Hint: SvPVbyte + * Does not work in perl-5.6.1, ppport.h implements a version + * borrowed from perl-5.7.3. + */ + +#if (PERL_BCDVERSION < 0x5007000) + +#if defined(NEED_sv_2pvbyte) +static char * DPPP_(my_sv_2pvbyte)(pTHX_ SV *sv, STRLEN *lp); +static +#else +extern char * DPPP_(my_sv_2pvbyte)(pTHX_ SV *sv, STRLEN *lp); +#endif + +#ifdef sv_2pvbyte +# undef sv_2pvbyte +#endif +#define sv_2pvbyte(a,b) DPPP_(my_sv_2pvbyte)(aTHX_ a,b) +#define Perl_sv_2pvbyte DPPP_(my_sv_2pvbyte) + +#if defined(NEED_sv_2pvbyte) || defined(NEED_sv_2pvbyte_GLOBAL) + +char * +DPPP_(my_sv_2pvbyte)(pTHX_ SV *sv, STRLEN *lp) +{ + sv_utf8_downgrade(sv,0); + return SvPV(sv,*lp); +} + +#endif + +/* Hint: sv_2pvbyte + * Use the SvPVbyte() macro instead of sv_2pvbyte(). + */ + +#undef SvPVbyte + +#define SvPVbyte(sv, lp) \ + ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8)) == (SVf_POK) \ + ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pvbyte(sv, &lp)) + +#endif + +#else + +# define SvPVbyte SvPV +# define sv_2pvbyte sv_2pv + +#endif +#ifndef sv_2pvbyte_nolen +# define sv_2pvbyte_nolen(sv) sv_2pv_nolen(sv) +#endif + +/* Hint: sv_pvn + * Always use the SvPV() macro instead of sv_pvn(). + */ + +/* Hint: sv_pvn_force + * Always use the SvPV_force() macro instead of sv_pvn_force(). + */ + +/* If these are undefined, they're not handled by the core anyway */ +#ifndef SV_IMMEDIATE_UNREF +# define SV_IMMEDIATE_UNREF 0 +#endif + +#ifndef SV_GMAGIC +# define SV_GMAGIC 0 +#endif + +#ifndef SV_COW_DROP_PV +# define SV_COW_DROP_PV 0 +#endif + +#ifndef SV_UTF8_NO_ENCODING +# define SV_UTF8_NO_ENCODING 0 +#endif + +#ifndef SV_NOSTEAL +# define SV_NOSTEAL 0 +#endif + +#ifndef SV_CONST_RETURN +# define SV_CONST_RETURN 0 +#endif + +#ifndef SV_MUTABLE_RETURN +# define SV_MUTABLE_RETURN 0 +#endif + +#ifndef SV_SMAGIC +# define SV_SMAGIC 0 +#endif + +#ifndef SV_HAS_TRAILING_NUL +# define SV_HAS_TRAILING_NUL 0 +#endif + +#ifndef SV_COW_SHARED_HASH_KEYS +# define SV_COW_SHARED_HASH_KEYS 0 +#endif + +#if (PERL_BCDVERSION < 0x5007002) + +#if defined(NEED_sv_2pv_flags) +static char * DPPP_(my_sv_2pv_flags)(pTHX_ SV *sv, STRLEN *lp, I32 flags); +static +#else +extern char * DPPP_(my_sv_2pv_flags)(pTHX_ SV *sv, STRLEN *lp, I32 flags); +#endif + +#ifdef sv_2pv_flags +# undef sv_2pv_flags +#endif +#define sv_2pv_flags(a,b,c) DPPP_(my_sv_2pv_flags)(aTHX_ a,b,c) +#define Perl_sv_2pv_flags DPPP_(my_sv_2pv_flags) + +#if defined(NEED_sv_2pv_flags) || defined(NEED_sv_2pv_flags_GLOBAL) + +char * +DPPP_(my_sv_2pv_flags)(pTHX_ SV *sv, STRLEN *lp, I32 flags) +{ + STRLEN n_a = (STRLEN) flags; + return sv_2pv(sv, lp ? lp : &n_a); +} + +#endif + +#if defined(NEED_sv_pvn_force_flags) +static char * DPPP_(my_sv_pvn_force_flags)(pTHX_ SV *sv, STRLEN *lp, I32 flags); +static +#else +extern char * DPPP_(my_sv_pvn_force_flags)(pTHX_ SV *sv, STRLEN *lp, I32 flags); +#endif + +#ifdef sv_pvn_force_flags +# undef sv_pvn_force_flags +#endif +#define sv_pvn_force_flags(a,b,c) DPPP_(my_sv_pvn_force_flags)(aTHX_ a,b,c) +#define Perl_sv_pvn_force_flags DPPP_(my_sv_pvn_force_flags) + +#if defined(NEED_sv_pvn_force_flags) || defined(NEED_sv_pvn_force_flags_GLOBAL) + +char * +DPPP_(my_sv_pvn_force_flags)(pTHX_ SV *sv, STRLEN *lp, I32 flags) +{ + STRLEN n_a = (STRLEN) flags; + return sv_pvn_force(sv, lp ? lp : &n_a); +} + +#endif + +#endif + +#if (PERL_BCDVERSION < 0x5008008) || ( (PERL_BCDVERSION >= 0x5009000) && (PERL_BCDVERSION < 0x5009003) ) +# define DPPP_SVPV_NOLEN_LP_ARG &PL_na +#else +# define DPPP_SVPV_NOLEN_LP_ARG 0 +#endif +#ifndef SvPV_const +# define SvPV_const(sv, lp) SvPV_flags_const(sv, lp, SV_GMAGIC) +#endif + +#ifndef SvPV_mutable +# define SvPV_mutable(sv, lp) SvPV_flags_mutable(sv, lp, SV_GMAGIC) +#endif +#ifndef SvPV_flags +# define SvPV_flags(sv, lp, flags) \ + ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ + ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pv_flags(sv, &lp, flags)) +#endif +#ifndef SvPV_flags_const +# define SvPV_flags_const(sv, lp, flags) \ + ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ + ? ((lp = SvCUR(sv)), SvPVX_const(sv)) : \ + (const char*) sv_2pv_flags(sv, &lp, flags|SV_CONST_RETURN)) +#endif +#ifndef SvPV_flags_const_nolen +# define SvPV_flags_const_nolen(sv, flags) \ + ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ + ? SvPVX_const(sv) : \ + (const char*) sv_2pv_flags(sv, DPPP_SVPV_NOLEN_LP_ARG, flags|SV_CONST_RETURN)) +#endif +#ifndef SvPV_flags_mutable +# define SvPV_flags_mutable(sv, lp, flags) \ + ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ + ? ((lp = SvCUR(sv)), SvPVX_mutable(sv)) : \ + sv_2pv_flags(sv, &lp, flags|SV_MUTABLE_RETURN)) +#endif +#ifndef SvPV_force +# define SvPV_force(sv, lp) SvPV_force_flags(sv, lp, SV_GMAGIC) +#endif + +#ifndef SvPV_force_nolen +# define SvPV_force_nolen(sv) SvPV_force_flags_nolen(sv, SV_GMAGIC) +#endif + +#ifndef SvPV_force_mutable +# define SvPV_force_mutable(sv, lp) SvPV_force_flags_mutable(sv, lp, SV_GMAGIC) +#endif + +#ifndef SvPV_force_nomg +# define SvPV_force_nomg(sv, lp) SvPV_force_flags(sv, lp, 0) +#endif + +#ifndef SvPV_force_nomg_nolen +# define SvPV_force_nomg_nolen(sv) SvPV_force_flags_nolen(sv, 0) +#endif +#ifndef SvPV_force_flags +# define SvPV_force_flags(sv, lp, flags) \ + ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST)) == SVf_POK \ + ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_pvn_force_flags(sv, &lp, flags)) +#endif +#ifndef SvPV_force_flags_nolen +# define SvPV_force_flags_nolen(sv, flags) \ + ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST)) == SVf_POK \ + ? SvPVX(sv) : sv_pvn_force_flags(sv, DPPP_SVPV_NOLEN_LP_ARG, flags)) +#endif +#ifndef SvPV_force_flags_mutable +# define SvPV_force_flags_mutable(sv, lp, flags) \ + ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST)) == SVf_POK \ + ? ((lp = SvCUR(sv)), SvPVX_mutable(sv)) \ + : sv_pvn_force_flags(sv, &lp, flags|SV_MUTABLE_RETURN)) +#endif +#ifndef SvPV_nolen +# define SvPV_nolen(sv) \ + ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ + ? SvPVX(sv) : sv_2pv_flags(sv, DPPP_SVPV_NOLEN_LP_ARG, SV_GMAGIC)) +#endif +#ifndef SvPV_nolen_const +# define SvPV_nolen_const(sv) \ + ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ + ? SvPVX_const(sv) : sv_2pv_flags(sv, DPPP_SVPV_NOLEN_LP_ARG, SV_GMAGIC|SV_CONST_RETURN)) +#endif +#ifndef SvPV_nomg +# define SvPV_nomg(sv, lp) SvPV_flags(sv, lp, 0) +#endif + +#ifndef SvPV_nomg_const +# define SvPV_nomg_const(sv, lp) SvPV_flags_const(sv, lp, 0) +#endif + +#ifndef SvPV_nomg_const_nolen +# define SvPV_nomg_const_nolen(sv) SvPV_flags_const_nolen(sv, 0) +#endif + +#ifndef SvPV_nomg_nolen +# define SvPV_nomg_nolen(sv) ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ + ? SvPVX(sv) : sv_2pv_flags(sv, DPPP_SVPV_NOLEN_LP_ARG, 0)) +#endif +#ifndef SvPV_renew +# define SvPV_renew(sv,n) STMT_START { SvLEN_set(sv, n); \ + SvPV_set((sv), (char *) saferealloc( \ + (Malloc_t)SvPVX(sv), (MEM_SIZE)((n)))); \ + } STMT_END +#endif +#ifndef SvMAGIC_set +# define SvMAGIC_set(sv, val) \ + STMT_START { assert(SvTYPE(sv) >= SVt_PVMG); \ + (((XPVMG*) SvANY(sv))->xmg_magic = (val)); } STMT_END +#endif + +#if (PERL_BCDVERSION < 0x5009003) +#ifndef SvPVX_const +# define SvPVX_const(sv) ((const char*) (0 + SvPVX(sv))) +#endif + +#ifndef SvPVX_mutable +# define SvPVX_mutable(sv) (0 + SvPVX(sv)) +#endif +#ifndef SvRV_set +# define SvRV_set(sv, val) \ + STMT_START { assert(SvTYPE(sv) >= SVt_RV); \ + (((XRV*) SvANY(sv))->xrv_rv = (val)); } STMT_END +#endif + +#else +#ifndef SvPVX_const +# define SvPVX_const(sv) ((const char*)((sv)->sv_u.svu_pv)) +#endif + +#ifndef SvPVX_mutable +# define SvPVX_mutable(sv) ((sv)->sv_u.svu_pv) +#endif +#ifndef SvRV_set +# define SvRV_set(sv, val) \ + STMT_START { assert(SvTYPE(sv) >= SVt_RV); \ + ((sv)->sv_u.svu_rv = (val)); } STMT_END +#endif + +#endif +#ifndef SvSTASH_set +# define SvSTASH_set(sv, val) \ + STMT_START { assert(SvTYPE(sv) >= SVt_PVMG); \ + (((XPVMG*) SvANY(sv))->xmg_stash = (val)); } STMT_END +#endif + +#if (PERL_BCDVERSION < 0x5004000) +#ifndef SvUV_set +# define SvUV_set(sv, val) \ + STMT_START { assert(SvTYPE(sv) == SVt_IV || SvTYPE(sv) >= SVt_PVIV); \ + (((XPVIV*) SvANY(sv))->xiv_iv = (IV) (val)); } STMT_END +#endif + +#else +#ifndef SvUV_set +# define SvUV_set(sv, val) \ + STMT_START { assert(SvTYPE(sv) == SVt_IV || SvTYPE(sv) >= SVt_PVIV); \ + (((XPVUV*) SvANY(sv))->xuv_uv = (val)); } STMT_END +#endif + +#endif + +#if (PERL_BCDVERSION >= 0x5004000) && !defined(vnewSVpvf) +#if defined(NEED_vnewSVpvf) +static SV * DPPP_(my_vnewSVpvf)(pTHX_ const char *pat, va_list *args); +static +#else +extern SV * DPPP_(my_vnewSVpvf)(pTHX_ const char *pat, va_list *args); +#endif + +#ifdef vnewSVpvf +# undef vnewSVpvf +#endif +#define vnewSVpvf(a,b) DPPP_(my_vnewSVpvf)(aTHX_ a,b) +#define Perl_vnewSVpvf DPPP_(my_vnewSVpvf) + +#if defined(NEED_vnewSVpvf) || defined(NEED_vnewSVpvf_GLOBAL) + +SV * +DPPP_(my_vnewSVpvf)(pTHX_ const char *pat, va_list *args) +{ + register SV *sv = newSV(0); + sv_vsetpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*)); + return sv; +} + +#endif +#endif + +#if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_vcatpvf) +# define sv_vcatpvf(sv, pat, args) sv_vcatpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*)) +#endif + +#if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_vsetpvf) +# define sv_vsetpvf(sv, pat, args) sv_vsetpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*)) +#endif + +#if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_catpvf_mg) +#if defined(NEED_sv_catpvf_mg) +static void DPPP_(my_sv_catpvf_mg)(pTHX_ SV *sv, const char *pat, ...); +static +#else +extern void DPPP_(my_sv_catpvf_mg)(pTHX_ SV *sv, const char *pat, ...); +#endif + +#define Perl_sv_catpvf_mg DPPP_(my_sv_catpvf_mg) + +#if defined(NEED_sv_catpvf_mg) || defined(NEED_sv_catpvf_mg_GLOBAL) + +void +DPPP_(my_sv_catpvf_mg)(pTHX_ SV *sv, const char *pat, ...) +{ + va_list args; + va_start(args, pat); + sv_vcatpvfn(sv, pat, strlen(pat), &args, Null(SV**), 0, Null(bool*)); + SvSETMAGIC(sv); + va_end(args); +} + +#endif +#endif + +#ifdef PERL_IMPLICIT_CONTEXT +#if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_catpvf_mg_nocontext) +#if defined(NEED_sv_catpvf_mg_nocontext) +static void DPPP_(my_sv_catpvf_mg_nocontext)(SV *sv, const char *pat, ...); +static +#else +extern void DPPP_(my_sv_catpvf_mg_nocontext)(SV *sv, const char *pat, ...); +#endif + +#define sv_catpvf_mg_nocontext DPPP_(my_sv_catpvf_mg_nocontext) +#define Perl_sv_catpvf_mg_nocontext DPPP_(my_sv_catpvf_mg_nocontext) + +#if defined(NEED_sv_catpvf_mg_nocontext) || defined(NEED_sv_catpvf_mg_nocontext_GLOBAL) + +void +DPPP_(my_sv_catpvf_mg_nocontext)(SV *sv, const char *pat, ...) +{ + dTHX; + va_list args; + va_start(args, pat); + sv_vcatpvfn(sv, pat, strlen(pat), &args, Null(SV**), 0, Null(bool*)); + SvSETMAGIC(sv); + va_end(args); +} + +#endif +#endif +#endif + +/* sv_catpvf_mg depends on sv_catpvf_mg_nocontext */ +#ifndef sv_catpvf_mg +# ifdef PERL_IMPLICIT_CONTEXT +# define sv_catpvf_mg Perl_sv_catpvf_mg_nocontext +# else +# define sv_catpvf_mg Perl_sv_catpvf_mg +# endif +#endif + +#if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_vcatpvf_mg) +# define sv_vcatpvf_mg(sv, pat, args) \ + STMT_START { \ + sv_vcatpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*)); \ + SvSETMAGIC(sv); \ + } STMT_END +#endif + +#if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_setpvf_mg) +#if defined(NEED_sv_setpvf_mg) +static void DPPP_(my_sv_setpvf_mg)(pTHX_ SV *sv, const char *pat, ...); +static +#else +extern void DPPP_(my_sv_setpvf_mg)(pTHX_ SV *sv, const char *pat, ...); +#endif + +#define Perl_sv_setpvf_mg DPPP_(my_sv_setpvf_mg) + +#if defined(NEED_sv_setpvf_mg) || defined(NEED_sv_setpvf_mg_GLOBAL) + +void +DPPP_(my_sv_setpvf_mg)(pTHX_ SV *sv, const char *pat, ...) +{ + va_list args; + va_start(args, pat); + sv_vsetpvfn(sv, pat, strlen(pat), &args, Null(SV**), 0, Null(bool*)); + SvSETMAGIC(sv); + va_end(args); +} + +#endif +#endif + +#ifdef PERL_IMPLICIT_CONTEXT +#if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_setpvf_mg_nocontext) +#if defined(NEED_sv_setpvf_mg_nocontext) +static void DPPP_(my_sv_setpvf_mg_nocontext)(SV *sv, const char *pat, ...); +static +#else +extern void DPPP_(my_sv_setpvf_mg_nocontext)(SV *sv, const char *pat, ...); +#endif + +#define sv_setpvf_mg_nocontext DPPP_(my_sv_setpvf_mg_nocontext) +#define Perl_sv_setpvf_mg_nocontext DPPP_(my_sv_setpvf_mg_nocontext) + +#if defined(NEED_sv_setpvf_mg_nocontext) || defined(NEED_sv_setpvf_mg_nocontext_GLOBAL) + +void +DPPP_(my_sv_setpvf_mg_nocontext)(SV *sv, const char *pat, ...) +{ + dTHX; + va_list args; + va_start(args, pat); + sv_vsetpvfn(sv, pat, strlen(pat), &args, Null(SV**), 0, Null(bool*)); + SvSETMAGIC(sv); + va_end(args); +} + +#endif +#endif +#endif + +/* sv_setpvf_mg depends on sv_setpvf_mg_nocontext */ +#ifndef sv_setpvf_mg +# ifdef PERL_IMPLICIT_CONTEXT +# define sv_setpvf_mg Perl_sv_setpvf_mg_nocontext +# else +# define sv_setpvf_mg Perl_sv_setpvf_mg +# endif +#endif + +#if (PERL_BCDVERSION >= 0x5004000) && !defined(sv_vsetpvf_mg) +# define sv_vsetpvf_mg(sv, pat, args) \ + STMT_START { \ + sv_vsetpvfn(sv, pat, strlen(pat), args, Null(SV**), 0, Null(bool*)); \ + SvSETMAGIC(sv); \ + } STMT_END +#endif + +/* Hint: newSVpvn_share + * The SVs created by this function only mimic the behaviour of + * shared PVs without really being shared. Only use if you know + * what you're doing. + */ + +#ifndef newSVpvn_share + +#if defined(NEED_newSVpvn_share) +static SV * DPPP_(my_newSVpvn_share)(pTHX_ const char *src, I32 len, U32 hash); +static +#else +extern SV * DPPP_(my_newSVpvn_share)(pTHX_ const char *src, I32 len, U32 hash); +#endif + +#ifdef newSVpvn_share +# undef newSVpvn_share +#endif +#define newSVpvn_share(a,b,c) DPPP_(my_newSVpvn_share)(aTHX_ a,b,c) +#define Perl_newSVpvn_share DPPP_(my_newSVpvn_share) + +#if defined(NEED_newSVpvn_share) || defined(NEED_newSVpvn_share_GLOBAL) + +SV * +DPPP_(my_newSVpvn_share)(pTHX_ const char *src, I32 len, U32 hash) +{ + SV *sv; + if (len < 0) + len = -len; + if (!hash) + PERL_HASH(hash, (char*) src, len); + sv = newSVpvn((char *) src, len); + sv_upgrade(sv, SVt_PVIV); + SvIVX(sv) = hash; + SvREADONLY_on(sv); + SvPOK_on(sv); + return sv; +} + +#endif + +#endif +#ifndef SvSHARED_HASH +# define SvSHARED_HASH(sv) (0 + SvUVX(sv)) +#endif +#ifndef HvNAME_get +# define HvNAME_get(hv) HvNAME(hv) +#endif +#ifndef HvNAMELEN_get +# define HvNAMELEN_get(hv) (HvNAME_get(hv) ? (I32)strlen(HvNAME_get(hv)) : 0) +#endif + +#ifndef gv_fetchpvn_flags +#if defined(NEED_gv_fetchpvn_flags) +static GV* DPPP_(my_gv_fetchpvn_flags)(pTHX_ const char* name, STRLEN len, int flags, int types); +static +#else +extern GV* DPPP_(my_gv_fetchpvn_flags)(pTHX_ const char* name, STRLEN len, int flags, int types); +#endif + +#ifdef gv_fetchpvn_flags +# undef gv_fetchpvn_flags +#endif +#define gv_fetchpvn_flags(a,b,c,d) DPPP_(my_gv_fetchpvn_flags)(aTHX_ a,b,c,d) +#define Perl_gv_fetchpvn_flags DPPP_(my_gv_fetchpvn_flags) + +#if defined(NEED_gv_fetchpvn_flags) || defined(NEED_gv_fetchpvn_flags_GLOBAL) + +GV* +DPPP_(my_gv_fetchpvn_flags)(pTHX_ const char* name, STRLEN len, int flags, int types) { + char *namepv = savepvn(name, len); + GV* stash = gv_fetchpv(namepv, TRUE, SVt_PVHV); + Safefree(namepv); + return stash; +} + +#endif +#endif +#ifndef GvSVn +# define GvSVn(gv) GvSV(gv) +#endif + +#ifndef isGV_with_GP +# define isGV_with_GP(gv) isGV(gv) +#endif + +#ifndef gv_fetchsv +# define gv_fetchsv(name, flags, svt) gv_fetchpv(SvPV_nolen_const(name), flags, svt) +#endif +#ifndef get_cvn_flags +# define get_cvn_flags(name, namelen, flags) get_cv(name, flags) +#endif + +#ifndef gv_init_pvn +# define gv_init_pvn(gv, stash, ptr, len, flags) gv_init(gv, stash, ptr, len, flags & GV_ADDMULTI ? TRUE : FALSE) +#endif +#ifndef WARN_ALL +# define WARN_ALL 0 +#endif + +#ifndef WARN_CLOSURE +# define WARN_CLOSURE 1 +#endif + +#ifndef WARN_DEPRECATED +# define WARN_DEPRECATED 2 +#endif + +#ifndef WARN_EXITING +# define WARN_EXITING 3 +#endif + +#ifndef WARN_GLOB +# define WARN_GLOB 4 +#endif + +#ifndef WARN_IO +# define WARN_IO 5 +#endif + +#ifndef WARN_CLOSED +# define WARN_CLOSED 6 +#endif + +#ifndef WARN_EXEC +# define WARN_EXEC 7 +#endif + +#ifndef WARN_LAYER +# define WARN_LAYER 8 +#endif + +#ifndef WARN_NEWLINE +# define WARN_NEWLINE 9 +#endif + +#ifndef WARN_PIPE +# define WARN_PIPE 10 +#endif + +#ifndef WARN_UNOPENED +# define WARN_UNOPENED 11 +#endif + +#ifndef WARN_MISC +# define WARN_MISC 12 +#endif + +#ifndef WARN_NUMERIC +# define WARN_NUMERIC 13 +#endif + +#ifndef WARN_ONCE +# define WARN_ONCE 14 +#endif + +#ifndef WARN_OVERFLOW +# define WARN_OVERFLOW 15 +#endif + +#ifndef WARN_PACK +# define WARN_PACK 16 +#endif + +#ifndef WARN_PORTABLE +# define WARN_PORTABLE 17 +#endif + +#ifndef WARN_RECURSION +# define WARN_RECURSION 18 +#endif + +#ifndef WARN_REDEFINE +# define WARN_REDEFINE 19 +#endif + +#ifndef WARN_REGEXP +# define WARN_REGEXP 20 +#endif + +#ifndef WARN_SEVERE +# define WARN_SEVERE 21 +#endif + +#ifndef WARN_DEBUGGING +# define WARN_DEBUGGING 22 +#endif + +#ifndef WARN_INPLACE +# define WARN_INPLACE 23 +#endif + +#ifndef WARN_INTERNAL +# define WARN_INTERNAL 24 +#endif + +#ifndef WARN_MALLOC +# define WARN_MALLOC 25 +#endif + +#ifndef WARN_SIGNAL +# define WARN_SIGNAL 26 +#endif + +#ifndef WARN_SUBSTR +# define WARN_SUBSTR 27 +#endif + +#ifndef WARN_SYNTAX +# define WARN_SYNTAX 28 +#endif + +#ifndef WARN_AMBIGUOUS +# define WARN_AMBIGUOUS 29 +#endif + +#ifndef WARN_BAREWORD +# define WARN_BAREWORD 30 +#endif + +#ifndef WARN_DIGIT +# define WARN_DIGIT 31 +#endif + +#ifndef WARN_PARENTHESIS +# define WARN_PARENTHESIS 32 +#endif + +#ifndef WARN_PRECEDENCE +# define WARN_PRECEDENCE 33 +#endif + +#ifndef WARN_PRINTF +# define WARN_PRINTF 34 +#endif + +#ifndef WARN_PROTOTYPE +# define WARN_PROTOTYPE 35 +#endif + +#ifndef WARN_QW +# define WARN_QW 36 +#endif + +#ifndef WARN_RESERVED +# define WARN_RESERVED 37 +#endif + +#ifndef WARN_SEMICOLON +# define WARN_SEMICOLON 38 +#endif + +#ifndef WARN_TAINT +# define WARN_TAINT 39 +#endif + +#ifndef WARN_THREADS +# define WARN_THREADS 40 +#endif + +#ifndef WARN_UNINITIALIZED +# define WARN_UNINITIALIZED 41 +#endif + +#ifndef WARN_UNPACK +# define WARN_UNPACK 42 +#endif + +#ifndef WARN_UNTIE +# define WARN_UNTIE 43 +#endif + +#ifndef WARN_UTF8 +# define WARN_UTF8 44 +#endif + +#ifndef WARN_VOID +# define WARN_VOID 45 +#endif + +#ifndef WARN_ASSERTIONS +# define WARN_ASSERTIONS 46 +#endif +#ifndef packWARN +# define packWARN(a) (a) +#endif + +#ifndef ckWARN +# ifdef G_WARN_ON +# define ckWARN(a) (PL_dowarn & G_WARN_ON) +# else +# define ckWARN(a) PL_dowarn +# endif +#endif + +#if (PERL_BCDVERSION >= 0x5004000) && !defined(warner) +#if defined(NEED_warner) +static void DPPP_(my_warner)(U32 err, const char *pat, ...); +static +#else +extern void DPPP_(my_warner)(U32 err, const char *pat, ...); +#endif + +#define Perl_warner DPPP_(my_warner) + +#if defined(NEED_warner) || defined(NEED_warner_GLOBAL) + +void +DPPP_(my_warner)(U32 err, const char *pat, ...) +{ + SV *sv; + va_list args; + + PERL_UNUSED_ARG(err); + + va_start(args, pat); + sv = vnewSVpvf(pat, &args); + va_end(args); + sv_2mortal(sv); + warn("%s", SvPV_nolen(sv)); +} + +#define warner Perl_warner + +#define Perl_warner_nocontext Perl_warner + +#endif +#endif + +/* concatenating with "" ensures that only literal strings are accepted as argument + * note that STR_WITH_LEN() can't be used as argument to macros or functions that + * under some configurations might be macros + */ +#ifndef STR_WITH_LEN +# define STR_WITH_LEN(s) (s ""), (sizeof(s)-1) +#endif +#ifndef newSVpvs +# define newSVpvs(str) newSVpvn(str "", sizeof(str) - 1) +#endif + +#ifndef newSVpvs_flags +# define newSVpvs_flags(str, flags) newSVpvn_flags(str "", sizeof(str) - 1, flags) +#endif + +#ifndef newSVpvs_share +# define newSVpvs_share(str) newSVpvn_share(str "", sizeof(str) - 1, 0) +#endif + +#ifndef sv_catpvs +# define sv_catpvs(sv, str) sv_catpvn(sv, str "", sizeof(str) - 1) +#endif + +#ifndef sv_setpvs +# define sv_setpvs(sv, str) sv_setpvn(sv, str "", sizeof(str) - 1) +#endif + +#ifndef hv_fetchs +# define hv_fetchs(hv, key, lval) hv_fetch(hv, key "", sizeof(key) - 1, lval) +#endif + +#ifndef hv_stores +# define hv_stores(hv, key, val) hv_store(hv, key "", sizeof(key) - 1, val, 0) +#endif +#ifndef gv_fetchpvs +# define gv_fetchpvs(name, flags, svt) gv_fetchpvn_flags(name "", sizeof(name) - 1, flags, svt) +#endif + +#ifndef gv_stashpvs +# define gv_stashpvs(name, flags) gv_stashpvn(name "", sizeof(name) - 1, flags) +#endif +#ifndef get_cvs +# define get_cvs(name, flags) get_cvn_flags(name "", sizeof(name)-1, flags) +#endif +#ifndef SvGETMAGIC +# define SvGETMAGIC(x) STMT_START { if (SvGMAGICAL(x)) mg_get(x); } STMT_END +#endif + +/* Some random bits for sv_unmagicext. These should probably be pulled in for + real and organized at some point */ +#ifndef HEf_SVKEY +# define HEf_SVKEY -2 +#endif + +#ifndef MUTABLE_PTR +#if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN) +# define MUTABLE_PTR(p) ({ void *_p = (p); _p; }) +#else +# define MUTABLE_PTR(p) ((void *) (p)) +#endif +#endif +#ifndef MUTABLE_SV +# define MUTABLE_SV(p) ((SV *)MUTABLE_PTR(p)) +#endif + +/* end of random bits */ +#ifndef PERL_MAGIC_sv +# define PERL_MAGIC_sv '\0' +#endif + +#ifndef PERL_MAGIC_overload +# define PERL_MAGIC_overload 'A' +#endif + +#ifndef PERL_MAGIC_overload_elem +# define PERL_MAGIC_overload_elem 'a' +#endif + +#ifndef PERL_MAGIC_overload_table +# define PERL_MAGIC_overload_table 'c' +#endif + +#ifndef PERL_MAGIC_bm +# define PERL_MAGIC_bm 'B' +#endif + +#ifndef PERL_MAGIC_regdata +# define PERL_MAGIC_regdata 'D' +#endif + +#ifndef PERL_MAGIC_regdatum +# define PERL_MAGIC_regdatum 'd' +#endif + +#ifndef PERL_MAGIC_env +# define PERL_MAGIC_env 'E' +#endif + +#ifndef PERL_MAGIC_envelem +# define PERL_MAGIC_envelem 'e' +#endif + +#ifndef PERL_MAGIC_fm +# define PERL_MAGIC_fm 'f' +#endif + +#ifndef PERL_MAGIC_regex_global +# define PERL_MAGIC_regex_global 'g' +#endif + +#ifndef PERL_MAGIC_isa +# define PERL_MAGIC_isa 'I' +#endif + +#ifndef PERL_MAGIC_isaelem +# define PERL_MAGIC_isaelem 'i' +#endif + +#ifndef PERL_MAGIC_nkeys +# define PERL_MAGIC_nkeys 'k' +#endif + +#ifndef PERL_MAGIC_dbfile +# define PERL_MAGIC_dbfile 'L' +#endif + +#ifndef PERL_MAGIC_dbline +# define PERL_MAGIC_dbline 'l' +#endif + +#ifndef PERL_MAGIC_mutex +# define PERL_MAGIC_mutex 'm' +#endif + +#ifndef PERL_MAGIC_shared +# define PERL_MAGIC_shared 'N' +#endif + +#ifndef PERL_MAGIC_shared_scalar +# define PERL_MAGIC_shared_scalar 'n' +#endif + +#ifndef PERL_MAGIC_collxfrm +# define PERL_MAGIC_collxfrm 'o' +#endif + +#ifndef PERL_MAGIC_tied +# define PERL_MAGIC_tied 'P' +#endif + +#ifndef PERL_MAGIC_tiedelem +# define PERL_MAGIC_tiedelem 'p' +#endif + +#ifndef PERL_MAGIC_tiedscalar +# define PERL_MAGIC_tiedscalar 'q' +#endif + +#ifndef PERL_MAGIC_qr +# define PERL_MAGIC_qr 'r' +#endif + +#ifndef PERL_MAGIC_sig +# define PERL_MAGIC_sig 'S' +#endif + +#ifndef PERL_MAGIC_sigelem +# define PERL_MAGIC_sigelem 's' +#endif + +#ifndef PERL_MAGIC_taint +# define PERL_MAGIC_taint 't' +#endif + +#ifndef PERL_MAGIC_uvar +# define PERL_MAGIC_uvar 'U' +#endif + +#ifndef PERL_MAGIC_uvar_elem +# define PERL_MAGIC_uvar_elem 'u' +#endif + +#ifndef PERL_MAGIC_vstring +# define PERL_MAGIC_vstring 'V' +#endif + +#ifndef PERL_MAGIC_vec +# define PERL_MAGIC_vec 'v' +#endif + +#ifndef PERL_MAGIC_utf8 +# define PERL_MAGIC_utf8 'w' +#endif + +#ifndef PERL_MAGIC_substr +# define PERL_MAGIC_substr 'x' +#endif + +#ifndef PERL_MAGIC_defelem +# define PERL_MAGIC_defelem 'y' +#endif + +#ifndef PERL_MAGIC_glob +# define PERL_MAGIC_glob '*' +#endif + +#ifndef PERL_MAGIC_arylen +# define PERL_MAGIC_arylen '#' +#endif + +#ifndef PERL_MAGIC_pos +# define PERL_MAGIC_pos '.' +#endif + +#ifndef PERL_MAGIC_backref +# define PERL_MAGIC_backref '<' +#endif + +#ifndef PERL_MAGIC_ext +# define PERL_MAGIC_ext '~' +#endif + +/* That's the best we can do... */ +#ifndef sv_catpvn_nomg +# define sv_catpvn_nomg sv_catpvn +#endif + +#ifndef sv_catsv_nomg +# define sv_catsv_nomg sv_catsv +#endif + +#ifndef sv_setsv_nomg +# define sv_setsv_nomg sv_setsv +#endif + +#ifndef sv_pvn_nomg +# define sv_pvn_nomg sv_pvn +#endif + +#ifndef SvIV_nomg +# define SvIV_nomg SvIV +#endif + +#ifndef SvUV_nomg +# define SvUV_nomg SvUV +#endif + +#ifndef sv_catpv_mg +# define sv_catpv_mg(sv, ptr) \ + STMT_START { \ + SV *TeMpSv = sv; \ + sv_catpv(TeMpSv,ptr); \ + SvSETMAGIC(TeMpSv); \ + } STMT_END +#endif + +#ifndef sv_catpvn_mg +# define sv_catpvn_mg(sv, ptr, len) \ + STMT_START { \ + SV *TeMpSv = sv; \ + sv_catpvn(TeMpSv,ptr,len); \ + SvSETMAGIC(TeMpSv); \ + } STMT_END +#endif + +#ifndef sv_catsv_mg +# define sv_catsv_mg(dsv, ssv) \ + STMT_START { \ + SV *TeMpSv = dsv; \ + sv_catsv(TeMpSv,ssv); \ + SvSETMAGIC(TeMpSv); \ + } STMT_END +#endif + +#ifndef sv_setiv_mg +# define sv_setiv_mg(sv, i) \ + STMT_START { \ + SV *TeMpSv = sv; \ + sv_setiv(TeMpSv,i); \ + SvSETMAGIC(TeMpSv); \ + } STMT_END +#endif + +#ifndef sv_setnv_mg +# define sv_setnv_mg(sv, num) \ + STMT_START { \ + SV *TeMpSv = sv; \ + sv_setnv(TeMpSv,num); \ + SvSETMAGIC(TeMpSv); \ + } STMT_END +#endif + +#ifndef sv_setpv_mg +# define sv_setpv_mg(sv, ptr) \ + STMT_START { \ + SV *TeMpSv = sv; \ + sv_setpv(TeMpSv,ptr); \ + SvSETMAGIC(TeMpSv); \ + } STMT_END +#endif + +#ifndef sv_setpvn_mg +# define sv_setpvn_mg(sv, ptr, len) \ + STMT_START { \ + SV *TeMpSv = sv; \ + sv_setpvn(TeMpSv,ptr,len); \ + SvSETMAGIC(TeMpSv); \ + } STMT_END +#endif + +#ifndef sv_setsv_mg +# define sv_setsv_mg(dsv, ssv) \ + STMT_START { \ + SV *TeMpSv = dsv; \ + sv_setsv(TeMpSv,ssv); \ + SvSETMAGIC(TeMpSv); \ + } STMT_END +#endif + +#ifndef sv_setuv_mg +# define sv_setuv_mg(sv, i) \ + STMT_START { \ + SV *TeMpSv = sv; \ + sv_setuv(TeMpSv,i); \ + SvSETMAGIC(TeMpSv); \ + } STMT_END +#endif + +#ifndef sv_usepvn_mg +# define sv_usepvn_mg(sv, ptr, len) \ + STMT_START { \ + SV *TeMpSv = sv; \ + sv_usepvn(TeMpSv,ptr,len); \ + SvSETMAGIC(TeMpSv); \ + } STMT_END +#endif +#ifndef SvVSTRING_mg +# define SvVSTRING_mg(sv) (SvMAGICAL(sv) ? mg_find(sv, PERL_MAGIC_vstring) : NULL) +#endif + +/* Hint: sv_magic_portable + * This is a compatibility function that is only available with + * Devel::PPPort. It is NOT in the perl core. + * Its purpose is to mimic the 5.8.0 behaviour of sv_magic() when + * it is being passed a name pointer with namlen == 0. In that + * case, perl 5.8.0 and later store the pointer, not a copy of it. + * The compatibility can be provided back to perl 5.004. With + * earlier versions, the code will not compile. + */ + +#if (PERL_BCDVERSION < 0x5004000) + + /* code that uses sv_magic_portable will not compile */ + +#elif (PERL_BCDVERSION < 0x5008000) + +# define sv_magic_portable(sv, obj, how, name, namlen) \ + STMT_START { \ + SV *SvMp_sv = (sv); \ + char *SvMp_name = (char *) (name); \ + I32 SvMp_namlen = (namlen); \ + if (SvMp_name && SvMp_namlen == 0) \ + { \ + MAGIC *mg; \ + sv_magic(SvMp_sv, obj, how, 0, 0); \ + mg = SvMAGIC(SvMp_sv); \ + mg->mg_len = -42; /* XXX: this is the tricky part */ \ + mg->mg_ptr = SvMp_name; \ + } \ + else \ + { \ + sv_magic(SvMp_sv, obj, how, SvMp_name, SvMp_namlen); \ + } \ + } STMT_END + +#else + +# define sv_magic_portable(a, b, c, d, e) sv_magic(a, b, c, d, e) + +#endif + +#if !defined(mg_findext) +#if defined(NEED_mg_findext) +static MAGIC * DPPP_(my_mg_findext)(SV * sv, int type, const MGVTBL *vtbl); +static +#else +extern MAGIC * DPPP_(my_mg_findext)(SV * sv, int type, const MGVTBL *vtbl); +#endif + +#define mg_findext DPPP_(my_mg_findext) +#define Perl_mg_findext DPPP_(my_mg_findext) + +#if defined(NEED_mg_findext) || defined(NEED_mg_findext_GLOBAL) + +MAGIC * +DPPP_(my_mg_findext)(SV * sv, int type, const MGVTBL *vtbl) { + if (sv) { + MAGIC *mg; + +#ifdef AvPAD_NAMELIST + assert(!(SvTYPE(sv) == SVt_PVAV && AvPAD_NAMELIST(sv))); +#endif + + for (mg = SvMAGIC (sv); mg; mg = mg->mg_moremagic) { + if (mg->mg_type == type && mg->mg_virtual == vtbl) + return mg; + } + } + + return NULL; +} + +#endif +#endif + +#if !defined(sv_unmagicext) +#if defined(NEED_sv_unmagicext) +static int DPPP_(my_sv_unmagicext)(pTHX_ SV * const sv, const int type, MGVTBL * vtbl); +static +#else +extern int DPPP_(my_sv_unmagicext)(pTHX_ SV * const sv, const int type, MGVTBL * vtbl); +#endif + +#ifdef sv_unmagicext +# undef sv_unmagicext +#endif +#define sv_unmagicext(a,b,c) DPPP_(my_sv_unmagicext)(aTHX_ a,b,c) +#define Perl_sv_unmagicext DPPP_(my_sv_unmagicext) + +#if defined(NEED_sv_unmagicext) || defined(NEED_sv_unmagicext_GLOBAL) + +int +DPPP_(my_sv_unmagicext)(pTHX_ SV *const sv, const int type, MGVTBL *vtbl) +{ + MAGIC* mg; + MAGIC** mgp; + + if (SvTYPE(sv) < SVt_PVMG || !SvMAGIC(sv)) + return 0; + mgp = &(SvMAGIC(sv)); + for (mg = *mgp; mg; mg = *mgp) { + const MGVTBL* const virt = mg->mg_virtual; + if (mg->mg_type == type && virt == vtbl) { + *mgp = mg->mg_moremagic; + if (virt && virt->svt_free) + virt->svt_free(aTHX_ sv, mg); + if (mg->mg_ptr && mg->mg_type != PERL_MAGIC_regex_global) { + if (mg->mg_len > 0) + Safefree(mg->mg_ptr); + else if (mg->mg_len == HEf_SVKEY) /* Questionable on older perls... */ + SvREFCNT_dec(MUTABLE_SV(mg->mg_ptr)); + else if (mg->mg_type == PERL_MAGIC_utf8) + Safefree(mg->mg_ptr); + } + if (mg->mg_flags & MGf_REFCOUNTED) + SvREFCNT_dec(mg->mg_obj); + Safefree(mg); + } + else + mgp = &mg->mg_moremagic; + } + if (SvMAGIC(sv)) { + if (SvMAGICAL(sv)) /* if we're under save_magic, wait for restore_magic; */ + mg_magical(sv); /* else fix the flags now */ + } + else { + SvMAGICAL_off(sv); + SvFLAGS(sv) |= (SvFLAGS(sv) & (SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT; + } + return 0; +} + +#endif +#endif + +#ifdef USE_ITHREADS +#ifndef CopFILE +# define CopFILE(c) ((c)->cop_file) +#endif + +#ifndef CopFILEGV +# define CopFILEGV(c) (CopFILE(c) ? gv_fetchfile(CopFILE(c)) : Nullgv) +#endif + +#ifndef CopFILE_set +# define CopFILE_set(c,pv) ((c)->cop_file = savepv(pv)) +#endif + +#ifndef CopFILESV +# define CopFILESV(c) (CopFILE(c) ? GvSV(gv_fetchfile(CopFILE(c))) : Nullsv) +#endif + +#ifndef CopFILEAV +# define CopFILEAV(c) (CopFILE(c) ? GvAV(gv_fetchfile(CopFILE(c))) : Nullav) +#endif + +#ifndef CopSTASHPV +# define CopSTASHPV(c) ((c)->cop_stashpv) +#endif + +#ifndef CopSTASHPV_set +# define CopSTASHPV_set(c,pv) ((c)->cop_stashpv = ((pv) ? savepv(pv) : Nullch)) +#endif + +#ifndef CopSTASH +# define CopSTASH(c) (CopSTASHPV(c) ? gv_stashpv(CopSTASHPV(c),GV_ADD) : Nullhv) +#endif + +#ifndef CopSTASH_set +# define CopSTASH_set(c,hv) CopSTASHPV_set(c, (hv) ? HvNAME(hv) : Nullch) +#endif + +#ifndef CopSTASH_eq +# define CopSTASH_eq(c,hv) ((hv) && (CopSTASHPV(c) == HvNAME(hv) \ + || (CopSTASHPV(c) && HvNAME(hv) \ + && strEQ(CopSTASHPV(c), HvNAME(hv))))) +#endif + +#else +#ifndef CopFILEGV +# define CopFILEGV(c) ((c)->cop_filegv) +#endif + +#ifndef CopFILEGV_set +# define CopFILEGV_set(c,gv) ((c)->cop_filegv = (GV*)SvREFCNT_inc(gv)) +#endif + +#ifndef CopFILE_set +# define CopFILE_set(c,pv) CopFILEGV_set((c), gv_fetchfile(pv)) +#endif + +#ifndef CopFILESV +# define CopFILESV(c) (CopFILEGV(c) ? GvSV(CopFILEGV(c)) : Nullsv) +#endif + +#ifndef CopFILEAV +# define CopFILEAV(c) (CopFILEGV(c) ? GvAV(CopFILEGV(c)) : Nullav) +#endif + +#ifndef CopFILE +# define CopFILE(c) (CopFILESV(c) ? SvPVX(CopFILESV(c)) : Nullch) +#endif + +#ifndef CopSTASH +# define CopSTASH(c) ((c)->cop_stash) +#endif + +#ifndef CopSTASH_set +# define CopSTASH_set(c,hv) ((c)->cop_stash = (hv)) +#endif + +#ifndef CopSTASHPV +# define CopSTASHPV(c) (CopSTASH(c) ? HvNAME(CopSTASH(c)) : Nullch) +#endif + +#ifndef CopSTASHPV_set +# define CopSTASHPV_set(c,pv) CopSTASH_set((c), gv_stashpv(pv,GV_ADD)) +#endif + +#ifndef CopSTASH_eq +# define CopSTASH_eq(c,hv) (CopSTASH(c) == (hv)) +#endif + +#endif /* USE_ITHREADS */ + +#if (PERL_BCDVERSION >= 0x5006000) +#ifndef caller_cx + +# if defined(NEED_caller_cx) || defined(NEED_caller_cx_GLOBAL) +static I32 +DPPP_dopoptosub_at(const PERL_CONTEXT *cxstk, I32 startingblock) +{ + I32 i; + + for (i = startingblock; i >= 0; i--) { + register const PERL_CONTEXT * const cx = &cxstk[i]; + switch (CxTYPE(cx)) { + default: + continue; + case CXt_EVAL: + case CXt_SUB: + case CXt_FORMAT: + return i; + } + } + return i; +} +# endif + +# if defined(NEED_caller_cx) +static const PERL_CONTEXT * DPPP_(my_caller_cx)(pTHX_ I32 count, const PERL_CONTEXT **dbcxp); +static +#else +extern const PERL_CONTEXT * DPPP_(my_caller_cx)(pTHX_ I32 count, const PERL_CONTEXT **dbcxp); +#endif + +#ifdef caller_cx +# undef caller_cx +#endif +#define caller_cx(a,b) DPPP_(my_caller_cx)(aTHX_ a,b) +#define Perl_caller_cx DPPP_(my_caller_cx) + +#if defined(NEED_caller_cx) || defined(NEED_caller_cx_GLOBAL) + +const PERL_CONTEXT * +DPPP_(my_caller_cx)(pTHX_ I32 count, const PERL_CONTEXT **dbcxp) +{ + register I32 cxix = DPPP_dopoptosub_at(cxstack, cxstack_ix); + register const PERL_CONTEXT *cx; + register const PERL_CONTEXT *ccstack = cxstack; + const PERL_SI *top_si = PL_curstackinfo; + + for (;;) { + /* we may be in a higher stacklevel, so dig down deeper */ + while (cxix < 0 && top_si->si_type != PERLSI_MAIN) { + top_si = top_si->si_prev; + ccstack = top_si->si_cxstack; + cxix = DPPP_dopoptosub_at(ccstack, top_si->si_cxix); + } + if (cxix < 0) + return NULL; + /* caller() should not report the automatic calls to &DB::sub */ + if (PL_DBsub && GvCV(PL_DBsub) && cxix >= 0 && + ccstack[cxix].blk_sub.cv == GvCV(PL_DBsub)) + count++; + if (!count--) + break; + cxix = DPPP_dopoptosub_at(ccstack, cxix - 1); + } + + cx = &ccstack[cxix]; + if (dbcxp) *dbcxp = cx; + + if (CxTYPE(cx) == CXt_SUB || CxTYPE(cx) == CXt_FORMAT) { + const I32 dbcxix = DPPP_dopoptosub_at(ccstack, cxix - 1); + /* We expect that ccstack[dbcxix] is CXt_SUB, anyway, the + field below is defined for any cx. */ + /* caller() should not report the automatic calls to &DB::sub */ + if (PL_DBsub && GvCV(PL_DBsub) && dbcxix >= 0 && ccstack[dbcxix].blk_sub.cv == GvCV(PL_DBsub)) + cx = &ccstack[dbcxix]; + } + + return cx; +} + +# endif +#endif /* caller_cx */ +#endif /* 5.6.0 */ +#ifndef IN_PERL_COMPILETIME +# define IN_PERL_COMPILETIME (PL_curcop == &PL_compiling) +#endif + +#ifndef IN_LOCALE_RUNTIME +# define IN_LOCALE_RUNTIME (PL_curcop->op_private & HINT_LOCALE) +#endif + +#ifndef IN_LOCALE_COMPILETIME +# define IN_LOCALE_COMPILETIME (PL_hints & HINT_LOCALE) +#endif + +#ifndef IN_LOCALE +# define IN_LOCALE (IN_PERL_COMPILETIME ? IN_LOCALE_COMPILETIME : IN_LOCALE_RUNTIME) +#endif +#ifndef IS_NUMBER_IN_UV +# define IS_NUMBER_IN_UV 0x01 +#endif + +#ifndef IS_NUMBER_GREATER_THAN_UV_MAX +# define IS_NUMBER_GREATER_THAN_UV_MAX 0x02 +#endif + +#ifndef IS_NUMBER_NOT_INT +# define IS_NUMBER_NOT_INT 0x04 +#endif + +#ifndef IS_NUMBER_NEG +# define IS_NUMBER_NEG 0x08 +#endif + +#ifndef IS_NUMBER_INFINITY +# define IS_NUMBER_INFINITY 0x10 +#endif + +#ifndef IS_NUMBER_NAN +# define IS_NUMBER_NAN 0x20 +#endif +#ifndef GROK_NUMERIC_RADIX +# define GROK_NUMERIC_RADIX(sp, send) grok_numeric_radix(sp, send) +#endif +#ifndef PERL_SCAN_GREATER_THAN_UV_MAX +# define PERL_SCAN_GREATER_THAN_UV_MAX 0x02 +#endif + +#ifndef PERL_SCAN_SILENT_ILLDIGIT +# define PERL_SCAN_SILENT_ILLDIGIT 0x04 +#endif + +#ifndef PERL_SCAN_ALLOW_UNDERSCORES +# define PERL_SCAN_ALLOW_UNDERSCORES 0x01 +#endif + +#ifndef PERL_SCAN_DISALLOW_PREFIX +# define PERL_SCAN_DISALLOW_PREFIX 0x02 +#endif + +#ifndef grok_numeric_radix +#if defined(NEED_grok_numeric_radix) +static bool DPPP_(my_grok_numeric_radix)(pTHX_ const char ** sp, const char * send); +static +#else +extern bool DPPP_(my_grok_numeric_radix)(pTHX_ const char ** sp, const char * send); +#endif + +#ifdef grok_numeric_radix +# undef grok_numeric_radix +#endif +#define grok_numeric_radix(a,b) DPPP_(my_grok_numeric_radix)(aTHX_ a,b) +#define Perl_grok_numeric_radix DPPP_(my_grok_numeric_radix) + +#if defined(NEED_grok_numeric_radix) || defined(NEED_grok_numeric_radix_GLOBAL) +bool +DPPP_(my_grok_numeric_radix)(pTHX_ const char **sp, const char *send) +{ +#ifdef USE_LOCALE_NUMERIC +#ifdef PL_numeric_radix_sv + if (PL_numeric_radix_sv && IN_LOCALE) { + STRLEN len; + char* radix = SvPV(PL_numeric_radix_sv, len); + if (*sp + len <= send && memEQ(*sp, radix, len)) { + *sp += len; + return TRUE; + } + } +#else + /* older perls don't have PL_numeric_radix_sv so the radix + * must manually be requested from locale.h + */ +#include + dTHR; /* needed for older threaded perls */ + struct lconv *lc = localeconv(); + char *radix = lc->decimal_point; + if (radix && IN_LOCALE) { + STRLEN len = strlen(radix); + if (*sp + len <= send && memEQ(*sp, radix, len)) { + *sp += len; + return TRUE; + } + } +#endif +#endif /* USE_LOCALE_NUMERIC */ + /* always try "." if numeric radix didn't match because + * we may have data from different locales mixed */ + if (*sp < send && **sp == '.') { + ++*sp; + return TRUE; + } + return FALSE; +} +#endif +#endif + +#ifndef grok_number +#if defined(NEED_grok_number) +static int DPPP_(my_grok_number)(pTHX_ const char * pv, STRLEN len, UV * valuep); +static +#else +extern int DPPP_(my_grok_number)(pTHX_ const char * pv, STRLEN len, UV * valuep); +#endif + +#ifdef grok_number +# undef grok_number +#endif +#define grok_number(a,b,c) DPPP_(my_grok_number)(aTHX_ a,b,c) +#define Perl_grok_number DPPP_(my_grok_number) + +#if defined(NEED_grok_number) || defined(NEED_grok_number_GLOBAL) +int +DPPP_(my_grok_number)(pTHX_ const char *pv, STRLEN len, UV *valuep) +{ + const char *s = pv; + const char *send = pv + len; + const UV max_div_10 = UV_MAX / 10; + const char max_mod_10 = UV_MAX % 10; + int numtype = 0; + int sawinf = 0; + int sawnan = 0; + + while (s < send && isSPACE(*s)) + s++; + if (s == send) { + return 0; + } else if (*s == '-') { + s++; + numtype = IS_NUMBER_NEG; + } + else if (*s == '+') + s++; + + if (s == send) + return 0; + + /* next must be digit or the radix separator or beginning of infinity */ + if (isDIGIT(*s)) { + /* UVs are at least 32 bits, so the first 9 decimal digits cannot + overflow. */ + UV value = *s - '0'; + /* This construction seems to be more optimiser friendly. + (without it gcc does the isDIGIT test and the *s - '0' separately) + With it gcc on arm is managing 6 instructions (6 cycles) per digit. + In theory the optimiser could deduce how far to unroll the loop + before checking for overflow. */ + if (++s < send) { + int digit = *s - '0'; + if (digit >= 0 && digit <= 9) { + value = value * 10 + digit; + if (++s < send) { + digit = *s - '0'; + if (digit >= 0 && digit <= 9) { + value = value * 10 + digit; + if (++s < send) { + digit = *s - '0'; + if (digit >= 0 && digit <= 9) { + value = value * 10 + digit; + if (++s < send) { + digit = *s - '0'; + if (digit >= 0 && digit <= 9) { + value = value * 10 + digit; + if (++s < send) { + digit = *s - '0'; + if (digit >= 0 && digit <= 9) { + value = value * 10 + digit; + if (++s < send) { + digit = *s - '0'; + if (digit >= 0 && digit <= 9) { + value = value * 10 + digit; + if (++s < send) { + digit = *s - '0'; + if (digit >= 0 && digit <= 9) { + value = value * 10 + digit; + if (++s < send) { + digit = *s - '0'; + if (digit >= 0 && digit <= 9) { + value = value * 10 + digit; + if (++s < send) { + /* Now got 9 digits, so need to check + each time for overflow. */ + digit = *s - '0'; + while (digit >= 0 && digit <= 9 + && (value < max_div_10 + || (value == max_div_10 + && digit <= max_mod_10))) { + value = value * 10 + digit; + if (++s < send) + digit = *s - '0'; + else + break; + } + if (digit >= 0 && digit <= 9 + && (s < send)) { + /* value overflowed. + skip the remaining digits, don't + worry about setting *valuep. */ + do { + s++; + } while (s < send && isDIGIT(*s)); + numtype |= + IS_NUMBER_GREATER_THAN_UV_MAX; + goto skip_value; + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + numtype |= IS_NUMBER_IN_UV; + if (valuep) + *valuep = value; + + skip_value: + if (GROK_NUMERIC_RADIX(&s, send)) { + numtype |= IS_NUMBER_NOT_INT; + while (s < send && isDIGIT(*s)) /* optional digits after the radix */ + s++; + } + } + else if (GROK_NUMERIC_RADIX(&s, send)) { + numtype |= IS_NUMBER_NOT_INT | IS_NUMBER_IN_UV; /* valuep assigned below */ + /* no digits before the radix means we need digits after it */ + if (s < send && isDIGIT(*s)) { + do { + s++; + } while (s < send && isDIGIT(*s)); + if (valuep) { + /* integer approximation is valid - it's 0. */ + *valuep = 0; + } + } + else + return 0; + } else if (*s == 'I' || *s == 'i') { + s++; if (s == send || (*s != 'N' && *s != 'n')) return 0; + s++; if (s == send || (*s != 'F' && *s != 'f')) return 0; + s++; if (s < send && (*s == 'I' || *s == 'i')) { + s++; if (s == send || (*s != 'N' && *s != 'n')) return 0; + s++; if (s == send || (*s != 'I' && *s != 'i')) return 0; + s++; if (s == send || (*s != 'T' && *s != 't')) return 0; + s++; if (s == send || (*s != 'Y' && *s != 'y')) return 0; + s++; + } + sawinf = 1; + } else if (*s == 'N' || *s == 'n') { + /* XXX TODO: There are signaling NaNs and quiet NaNs. */ + s++; if (s == send || (*s != 'A' && *s != 'a')) return 0; + s++; if (s == send || (*s != 'N' && *s != 'n')) return 0; + s++; + sawnan = 1; + } else + return 0; + + if (sawinf) { + numtype &= IS_NUMBER_NEG; /* Keep track of sign */ + numtype |= IS_NUMBER_INFINITY | IS_NUMBER_NOT_INT; + } else if (sawnan) { + numtype &= IS_NUMBER_NEG; /* Keep track of sign */ + numtype |= IS_NUMBER_NAN | IS_NUMBER_NOT_INT; + } else if (s < send) { + /* we can have an optional exponent part */ + if (*s == 'e' || *s == 'E') { + /* The only flag we keep is sign. Blow away any "it's UV" */ + numtype &= IS_NUMBER_NEG; + numtype |= IS_NUMBER_NOT_INT; + s++; + if (s < send && (*s == '-' || *s == '+')) + s++; + if (s < send && isDIGIT(*s)) { + do { + s++; + } while (s < send && isDIGIT(*s)); + } + else + return 0; + } + } + while (s < send && isSPACE(*s)) + s++; + if (s >= send) + return numtype; + if (len == 10 && memEQ(pv, "0 but true", 10)) { + if (valuep) + *valuep = 0; + return IS_NUMBER_IN_UV; + } + return 0; +} +#endif +#endif + +/* + * The grok_* routines have been modified to use warn() instead of + * Perl_warner(). Also, 'hexdigit' was the former name of PL_hexdigit, + * which is why the stack variable has been renamed to 'xdigit'. + */ + +#ifndef grok_bin +#if defined(NEED_grok_bin) +static UV DPPP_(my_grok_bin)(pTHX_ const char * start, STRLEN * len_p, I32 * flags, NV * result); +static +#else +extern UV DPPP_(my_grok_bin)(pTHX_ const char * start, STRLEN * len_p, I32 * flags, NV * result); +#endif + +#ifdef grok_bin +# undef grok_bin +#endif +#define grok_bin(a,b,c,d) DPPP_(my_grok_bin)(aTHX_ a,b,c,d) +#define Perl_grok_bin DPPP_(my_grok_bin) + +#if defined(NEED_grok_bin) || defined(NEED_grok_bin_GLOBAL) +UV +DPPP_(my_grok_bin)(pTHX_ const char *start, STRLEN *len_p, I32 *flags, NV *result) +{ + const char *s = start; + STRLEN len = *len_p; + UV value = 0; + NV value_nv = 0; + + const UV max_div_2 = UV_MAX / 2; + bool allow_underscores = *flags & PERL_SCAN_ALLOW_UNDERSCORES; + bool overflowed = FALSE; + + if (!(*flags & PERL_SCAN_DISALLOW_PREFIX)) { + /* strip off leading b or 0b. + for compatibility silently suffer "b" and "0b" as valid binary + numbers. */ + if (len >= 1) { + if (s[0] == 'b') { + s++; + len--; + } + else if (len >= 2 && s[0] == '0' && s[1] == 'b') { + s+=2; + len-=2; + } + } + } + + for (; len-- && *s; s++) { + char bit = *s; + if (bit == '0' || bit == '1') { + /* Write it in this wonky order with a goto to attempt to get the + compiler to make the common case integer-only loop pretty tight. + With gcc seems to be much straighter code than old scan_bin. */ + redo: + if (!overflowed) { + if (value <= max_div_2) { + value = (value << 1) | (bit - '0'); + continue; + } + /* Bah. We're just overflowed. */ + warn("Integer overflow in binary number"); + overflowed = TRUE; + value_nv = (NV) value; + } + value_nv *= 2.0; + /* If an NV has not enough bits in its mantissa to + * represent a UV this summing of small low-order numbers + * is a waste of time (because the NV cannot preserve + * the low-order bits anyway): we could just remember when + * did we overflow and in the end just multiply value_nv by the + * right amount. */ + value_nv += (NV)(bit - '0'); + continue; + } + if (bit == '_' && len && allow_underscores && (bit = s[1]) + && (bit == '0' || bit == '1')) + { + --len; + ++s; + goto redo; + } + if (!(*flags & PERL_SCAN_SILENT_ILLDIGIT)) + warn("Illegal binary digit '%c' ignored", *s); + break; + } + + if ( ( overflowed && value_nv > 4294967295.0) +#if UVSIZE > 4 + || (!overflowed && value > 0xffffffff ) +#endif + ) { + warn("Binary number > 0b11111111111111111111111111111111 non-portable"); + } + *len_p = s - start; + if (!overflowed) { + *flags = 0; + return value; + } + *flags = PERL_SCAN_GREATER_THAN_UV_MAX; + if (result) + *result = value_nv; + return UV_MAX; +} +#endif +#endif + +#ifndef grok_hex +#if defined(NEED_grok_hex) +static UV DPPP_(my_grok_hex)(pTHX_ const char * start, STRLEN * len_p, I32 * flags, NV * result); +static +#else +extern UV DPPP_(my_grok_hex)(pTHX_ const char * start, STRLEN * len_p, I32 * flags, NV * result); +#endif + +#ifdef grok_hex +# undef grok_hex +#endif +#define grok_hex(a,b,c,d) DPPP_(my_grok_hex)(aTHX_ a,b,c,d) +#define Perl_grok_hex DPPP_(my_grok_hex) + +#if defined(NEED_grok_hex) || defined(NEED_grok_hex_GLOBAL) +UV +DPPP_(my_grok_hex)(pTHX_ const char *start, STRLEN *len_p, I32 *flags, NV *result) +{ + const char *s = start; + STRLEN len = *len_p; + UV value = 0; + NV value_nv = 0; + + const UV max_div_16 = UV_MAX / 16; + bool allow_underscores = *flags & PERL_SCAN_ALLOW_UNDERSCORES; + bool overflowed = FALSE; + const char *xdigit; + + if (!(*flags & PERL_SCAN_DISALLOW_PREFIX)) { + /* strip off leading x or 0x. + for compatibility silently suffer "x" and "0x" as valid hex numbers. + */ + if (len >= 1) { + if (s[0] == 'x') { + s++; + len--; + } + else if (len >= 2 && s[0] == '0' && s[1] == 'x') { + s+=2; + len-=2; + } + } + } + + for (; len-- && *s; s++) { + xdigit = strchr((char *) PL_hexdigit, *s); + if (xdigit) { + /* Write it in this wonky order with a goto to attempt to get the + compiler to make the common case integer-only loop pretty tight. + With gcc seems to be much straighter code than old scan_hex. */ + redo: + if (!overflowed) { + if (value <= max_div_16) { + value = (value << 4) | ((xdigit - PL_hexdigit) & 15); + continue; + } + warn("Integer overflow in hexadecimal number"); + overflowed = TRUE; + value_nv = (NV) value; + } + value_nv *= 16.0; + /* If an NV has not enough bits in its mantissa to + * represent a UV this summing of small low-order numbers + * is a waste of time (because the NV cannot preserve + * the low-order bits anyway): we could just remember when + * did we overflow and in the end just multiply value_nv by the + * right amount of 16-tuples. */ + value_nv += (NV)((xdigit - PL_hexdigit) & 15); + continue; + } + if (*s == '_' && len && allow_underscores && s[1] + && (xdigit = strchr((char *) PL_hexdigit, s[1]))) + { + --len; + ++s; + goto redo; + } + if (!(*flags & PERL_SCAN_SILENT_ILLDIGIT)) + warn("Illegal hexadecimal digit '%c' ignored", *s); + break; + } + + if ( ( overflowed && value_nv > 4294967295.0) +#if UVSIZE > 4 + || (!overflowed && value > 0xffffffff ) +#endif + ) { + warn("Hexadecimal number > 0xffffffff non-portable"); + } + *len_p = s - start; + if (!overflowed) { + *flags = 0; + return value; + } + *flags = PERL_SCAN_GREATER_THAN_UV_MAX; + if (result) + *result = value_nv; + return UV_MAX; +} +#endif +#endif + +#ifndef grok_oct +#if defined(NEED_grok_oct) +static UV DPPP_(my_grok_oct)(pTHX_ const char * start, STRLEN * len_p, I32 * flags, NV * result); +static +#else +extern UV DPPP_(my_grok_oct)(pTHX_ const char * start, STRLEN * len_p, I32 * flags, NV * result); +#endif + +#ifdef grok_oct +# undef grok_oct +#endif +#define grok_oct(a,b,c,d) DPPP_(my_grok_oct)(aTHX_ a,b,c,d) +#define Perl_grok_oct DPPP_(my_grok_oct) + +#if defined(NEED_grok_oct) || defined(NEED_grok_oct_GLOBAL) +UV +DPPP_(my_grok_oct)(pTHX_ const char *start, STRLEN *len_p, I32 *flags, NV *result) +{ + const char *s = start; + STRLEN len = *len_p; + UV value = 0; + NV value_nv = 0; + + const UV max_div_8 = UV_MAX / 8; + bool allow_underscores = *flags & PERL_SCAN_ALLOW_UNDERSCORES; + bool overflowed = FALSE; + + for (; len-- && *s; s++) { + /* gcc 2.95 optimiser not smart enough to figure that this subtraction + out front allows slicker code. */ + int digit = *s - '0'; + if (digit >= 0 && digit <= 7) { + /* Write it in this wonky order with a goto to attempt to get the + compiler to make the common case integer-only loop pretty tight. + */ + redo: + if (!overflowed) { + if (value <= max_div_8) { + value = (value << 3) | digit; + continue; + } + /* Bah. We're just overflowed. */ + warn("Integer overflow in octal number"); + overflowed = TRUE; + value_nv = (NV) value; + } + value_nv *= 8.0; + /* If an NV has not enough bits in its mantissa to + * represent a UV this summing of small low-order numbers + * is a waste of time (because the NV cannot preserve + * the low-order bits anyway): we could just remember when + * did we overflow and in the end just multiply value_nv by the + * right amount of 8-tuples. */ + value_nv += (NV)digit; + continue; + } + if (digit == ('_' - '0') && len && allow_underscores + && (digit = s[1] - '0') && (digit >= 0 && digit <= 7)) + { + --len; + ++s; + goto redo; + } + /* Allow \octal to work the DWIM way (that is, stop scanning + * as soon as non-octal characters are seen, complain only iff + * someone seems to want to use the digits eight and nine). */ + if (digit == 8 || digit == 9) { + if (!(*flags & PERL_SCAN_SILENT_ILLDIGIT)) + warn("Illegal octal digit '%c' ignored", *s); + } + break; + } + + if ( ( overflowed && value_nv > 4294967295.0) +#if UVSIZE > 4 + || (!overflowed && value > 0xffffffff ) +#endif + ) { + warn("Octal number > 037777777777 non-portable"); + } + *len_p = s - start; + if (!overflowed) { + *flags = 0; + return value; + } + *flags = PERL_SCAN_GREATER_THAN_UV_MAX; + if (result) + *result = value_nv; + return UV_MAX; +} +#endif +#endif + +#if !defined(my_snprintf) +#if defined(NEED_my_snprintf) +static int DPPP_(my_my_snprintf)(char * buffer, const Size_t len, const char * format, ...); +static +#else +extern int DPPP_(my_my_snprintf)(char * buffer, const Size_t len, const char * format, ...); +#endif + +#define my_snprintf DPPP_(my_my_snprintf) +#define Perl_my_snprintf DPPP_(my_my_snprintf) + +#if defined(NEED_my_snprintf) || defined(NEED_my_snprintf_GLOBAL) + +int +DPPP_(my_my_snprintf)(char *buffer, const Size_t len, const char *format, ...) +{ + dTHX; + int retval; + va_list ap; + va_start(ap, format); +#ifdef HAS_VSNPRINTF + retval = vsnprintf(buffer, len, format, ap); +#else + retval = vsprintf(buffer, format, ap); +#endif + va_end(ap); + if (retval < 0 || (len > 0 && (Size_t)retval >= len)) + Perl_croak(aTHX_ "panic: my_snprintf buffer overflow"); + return retval; +} + +#endif +#endif + +#if !defined(my_sprintf) +#if defined(NEED_my_sprintf) +static int DPPP_(my_my_sprintf)(char * buffer, const char * pat, ...); +static +#else +extern int DPPP_(my_my_sprintf)(char * buffer, const char * pat, ...); +#endif + +#define my_sprintf DPPP_(my_my_sprintf) +#define Perl_my_sprintf DPPP_(my_my_sprintf) + +#if defined(NEED_my_sprintf) || defined(NEED_my_sprintf_GLOBAL) + +int +DPPP_(my_my_sprintf)(char *buffer, const char* pat, ...) +{ + va_list args; + va_start(args, pat); + vsprintf(buffer, pat, args); + va_end(args); + return strlen(buffer); +} + +#endif +#endif + +#ifdef NO_XSLOCKS +# ifdef dJMPENV +# define dXCPT dJMPENV; int rEtV = 0 +# define XCPT_TRY_START JMPENV_PUSH(rEtV); if (rEtV == 0) +# define XCPT_TRY_END JMPENV_POP; +# define XCPT_CATCH if (rEtV != 0) +# define XCPT_RETHROW JMPENV_JUMP(rEtV) +# else +# define dXCPT Sigjmp_buf oldTOP; int rEtV = 0 +# define XCPT_TRY_START Copy(top_env, oldTOP, 1, Sigjmp_buf); rEtV = Sigsetjmp(top_env, 1); if (rEtV == 0) +# define XCPT_TRY_END Copy(oldTOP, top_env, 1, Sigjmp_buf); +# define XCPT_CATCH if (rEtV != 0) +# define XCPT_RETHROW Siglongjmp(top_env, rEtV) +# endif +#endif + +#if !defined(my_strlcat) +#if defined(NEED_my_strlcat) +static Size_t DPPP_(my_my_strlcat)(char * dst, const char * src, Size_t size); +static +#else +extern Size_t DPPP_(my_my_strlcat)(char * dst, const char * src, Size_t size); +#endif + +#define my_strlcat DPPP_(my_my_strlcat) +#define Perl_my_strlcat DPPP_(my_my_strlcat) + +#if defined(NEED_my_strlcat) || defined(NEED_my_strlcat_GLOBAL) + +Size_t +DPPP_(my_my_strlcat)(char *dst, const char *src, Size_t size) +{ + Size_t used, length, copy; + + used = strlen(dst); + length = strlen(src); + if (size > 0 && used < size - 1) { + copy = (length >= size - used) ? size - used - 1 : length; + memcpy(dst + used, src, copy); + dst[used + copy] = '\0'; + } + return used + length; +} +#endif +#endif + +#if !defined(my_strlcpy) +#if defined(NEED_my_strlcpy) +static Size_t DPPP_(my_my_strlcpy)(char * dst, const char * src, Size_t size); +static +#else +extern Size_t DPPP_(my_my_strlcpy)(char * dst, const char * src, Size_t size); +#endif + +#define my_strlcpy DPPP_(my_my_strlcpy) +#define Perl_my_strlcpy DPPP_(my_my_strlcpy) + +#if defined(NEED_my_strlcpy) || defined(NEED_my_strlcpy_GLOBAL) + +Size_t +DPPP_(my_my_strlcpy)(char *dst, const char *src, Size_t size) +{ + Size_t length, copy; + + length = strlen(src); + if (size > 0) { + copy = (length >= size) ? size - 1 : length; + memcpy(dst, src, copy); + dst[copy] = '\0'; + } + return length; +} + +#endif +#endif +#ifndef PERL_PV_ESCAPE_QUOTE +# define PERL_PV_ESCAPE_QUOTE 0x0001 +#endif + +#ifndef PERL_PV_PRETTY_QUOTE +# define PERL_PV_PRETTY_QUOTE PERL_PV_ESCAPE_QUOTE +#endif + +#ifndef PERL_PV_PRETTY_ELLIPSES +# define PERL_PV_PRETTY_ELLIPSES 0x0002 +#endif + +#ifndef PERL_PV_PRETTY_LTGT +# define PERL_PV_PRETTY_LTGT 0x0004 +#endif + +#ifndef PERL_PV_ESCAPE_FIRSTCHAR +# define PERL_PV_ESCAPE_FIRSTCHAR 0x0008 +#endif + +#ifndef PERL_PV_ESCAPE_UNI +# define PERL_PV_ESCAPE_UNI 0x0100 +#endif + +#ifndef PERL_PV_ESCAPE_UNI_DETECT +# define PERL_PV_ESCAPE_UNI_DETECT 0x0200 +#endif + +#ifndef PERL_PV_ESCAPE_ALL +# define PERL_PV_ESCAPE_ALL 0x1000 +#endif + +#ifndef PERL_PV_ESCAPE_NOBACKSLASH +# define PERL_PV_ESCAPE_NOBACKSLASH 0x2000 +#endif + +#ifndef PERL_PV_ESCAPE_NOCLEAR +# define PERL_PV_ESCAPE_NOCLEAR 0x4000 +#endif + +#ifndef PERL_PV_ESCAPE_RE +# define PERL_PV_ESCAPE_RE 0x8000 +#endif + +#ifndef PERL_PV_PRETTY_NOCLEAR +# define PERL_PV_PRETTY_NOCLEAR PERL_PV_ESCAPE_NOCLEAR +#endif +#ifndef PERL_PV_PRETTY_DUMP +# define PERL_PV_PRETTY_DUMP PERL_PV_PRETTY_ELLIPSES|PERL_PV_PRETTY_QUOTE +#endif + +#ifndef PERL_PV_PRETTY_REGPROP +# define PERL_PV_PRETTY_REGPROP PERL_PV_PRETTY_ELLIPSES|PERL_PV_PRETTY_LTGT|PERL_PV_ESCAPE_RE +#endif + +/* Hint: pv_escape + * Note that unicode functionality is only backported to + * those perl versions that support it. For older perl + * versions, the implementation will fall back to bytes. + */ + +#ifndef pv_escape +#if defined(NEED_pv_escape) +static char * DPPP_(my_pv_escape)(pTHX_ SV * dsv, char const * const str, const STRLEN count, const STRLEN max, STRLEN * const escaped, const U32 flags); +static +#else +extern char * DPPP_(my_pv_escape)(pTHX_ SV * dsv, char const * const str, const STRLEN count, const STRLEN max, STRLEN * const escaped, const U32 flags); +#endif + +#ifdef pv_escape +# undef pv_escape +#endif +#define pv_escape(a,b,c,d,e,f) DPPP_(my_pv_escape)(aTHX_ a,b,c,d,e,f) +#define Perl_pv_escape DPPP_(my_pv_escape) + +#if defined(NEED_pv_escape) || defined(NEED_pv_escape_GLOBAL) + +char * +DPPP_(my_pv_escape)(pTHX_ SV *dsv, char const * const str, + const STRLEN count, const STRLEN max, + STRLEN * const escaped, const U32 flags) +{ + const char esc = flags & PERL_PV_ESCAPE_RE ? '%' : '\\'; + const char dq = flags & PERL_PV_ESCAPE_QUOTE ? '"' : esc; + char octbuf[32] = "%123456789ABCDF"; + STRLEN wrote = 0; + STRLEN chsize = 0; + STRLEN readsize = 1; +#if defined(is_utf8_string) && defined(utf8_to_uvchr) + bool isuni = flags & PERL_PV_ESCAPE_UNI ? 1 : 0; +#endif + const char *pv = str; + const char * const end = pv + count; + octbuf[0] = esc; + + if (!(flags & PERL_PV_ESCAPE_NOCLEAR)) + sv_setpvs(dsv, ""); + +#if defined(is_utf8_string) && defined(utf8_to_uvchr) + if ((flags & PERL_PV_ESCAPE_UNI_DETECT) && is_utf8_string((U8*)pv, count)) + isuni = 1; +#endif + + for (; pv < end && (!max || wrote < max) ; pv += readsize) { + const UV u = +#if defined(is_utf8_string) && defined(utf8_to_uvchr) + isuni ? utf8_to_uvchr((U8*)pv, &readsize) : +#endif + (U8)*pv; + const U8 c = (U8)u & 0xFF; + + if (u > 255 || (flags & PERL_PV_ESCAPE_ALL)) { + if (flags & PERL_PV_ESCAPE_FIRSTCHAR) + chsize = my_snprintf(octbuf, sizeof octbuf, + "%" UVxf, u); + else + chsize = my_snprintf(octbuf, sizeof octbuf, + "%cx{%" UVxf "}", esc, u); + } else if (flags & PERL_PV_ESCAPE_NOBACKSLASH) { + chsize = 1; + } else { + if (c == dq || c == esc || !isPRINT(c)) { + chsize = 2; + switch (c) { + case '\\' : /* fallthrough */ + case '%' : if (c == esc) + octbuf[1] = esc; + else + chsize = 1; + break; + case '\v' : octbuf[1] = 'v'; break; + case '\t' : octbuf[1] = 't'; break; + case '\r' : octbuf[1] = 'r'; break; + case '\n' : octbuf[1] = 'n'; break; + case '\f' : octbuf[1] = 'f'; break; + case '"' : if (dq == '"') + octbuf[1] = '"'; + else + chsize = 1; + break; + default: chsize = my_snprintf(octbuf, sizeof octbuf, + pv < end && isDIGIT((U8)*(pv+readsize)) + ? "%c%03o" : "%c%o", esc, c); + } + } else { + chsize = 1; + } + } + if (max && wrote + chsize > max) { + break; + } else if (chsize > 1) { + sv_catpvn(dsv, octbuf, chsize); + wrote += chsize; + } else { + char tmp[2]; + my_snprintf(tmp, sizeof tmp, "%c", c); + sv_catpvn(dsv, tmp, 1); + wrote++; + } + if (flags & PERL_PV_ESCAPE_FIRSTCHAR) + break; + } + if (escaped != NULL) + *escaped= pv - str; + return SvPVX(dsv); +} + +#endif +#endif + +#ifndef pv_pretty +#if defined(NEED_pv_pretty) +static char * DPPP_(my_pv_pretty)(pTHX_ SV * dsv, char const * const str, const STRLEN count, const STRLEN max, char const * const start_color, char const * const end_color, const U32 flags); +static +#else +extern char * DPPP_(my_pv_pretty)(pTHX_ SV * dsv, char const * const str, const STRLEN count, const STRLEN max, char const * const start_color, char const * const end_color, const U32 flags); +#endif + +#ifdef pv_pretty +# undef pv_pretty +#endif +#define pv_pretty(a,b,c,d,e,f,g) DPPP_(my_pv_pretty)(aTHX_ a,b,c,d,e,f,g) +#define Perl_pv_pretty DPPP_(my_pv_pretty) + +#if defined(NEED_pv_pretty) || defined(NEED_pv_pretty_GLOBAL) + +char * +DPPP_(my_pv_pretty)(pTHX_ SV *dsv, char const * const str, const STRLEN count, + const STRLEN max, char const * const start_color, char const * const end_color, + const U32 flags) +{ + const U8 dq = (flags & PERL_PV_PRETTY_QUOTE) ? '"' : '%'; + STRLEN escaped; + + if (!(flags & PERL_PV_PRETTY_NOCLEAR)) + sv_setpvs(dsv, ""); + + if (dq == '"') + sv_catpvs(dsv, "\""); + else if (flags & PERL_PV_PRETTY_LTGT) + sv_catpvs(dsv, "<"); + + if (start_color != NULL) + sv_catpv(dsv, D_PPP_CONSTPV_ARG(start_color)); + + pv_escape(dsv, str, count, max, &escaped, flags | PERL_PV_ESCAPE_NOCLEAR); + + if (end_color != NULL) + sv_catpv(dsv, D_PPP_CONSTPV_ARG(end_color)); + + if (dq == '"') + sv_catpvs(dsv, "\""); + else if (flags & PERL_PV_PRETTY_LTGT) + sv_catpvs(dsv, ">"); + + if ((flags & PERL_PV_PRETTY_ELLIPSES) && escaped < count) + sv_catpvs(dsv, "..."); + + return SvPVX(dsv); +} + +#endif +#endif + +#ifndef pv_display +#if defined(NEED_pv_display) +static char * DPPP_(my_pv_display)(pTHX_ SV * dsv, const char * pv, STRLEN cur, STRLEN len, STRLEN pvlim); +static +#else +extern char * DPPP_(my_pv_display)(pTHX_ SV * dsv, const char * pv, STRLEN cur, STRLEN len, STRLEN pvlim); +#endif + +#ifdef pv_display +# undef pv_display +#endif +#define pv_display(a,b,c,d,e) DPPP_(my_pv_display)(aTHX_ a,b,c,d,e) +#define Perl_pv_display DPPP_(my_pv_display) + +#if defined(NEED_pv_display) || defined(NEED_pv_display_GLOBAL) + +char * +DPPP_(my_pv_display)(pTHX_ SV *dsv, const char *pv, STRLEN cur, STRLEN len, STRLEN pvlim) +{ + pv_pretty(dsv, pv, cur, pvlim, NULL, NULL, PERL_PV_PRETTY_DUMP); + if (len > cur && pv[cur] == '\0') + sv_catpvs(dsv, "\\0"); + return SvPVX(dsv); +} + +#endif +#endif + +#endif /* _P_P_PORTABILITY_H_ */ + +/* End of File ppport.h */ diff -Nru libdatetime-perl-1.21/README.md libdatetime-perl-1.46/README.md --- libdatetime-perl-1.21/README.md 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/README.md 2018-02-11 23:36:51.000000000 +0000 @@ -1,2214 +1,2265 @@ -NAME +# NAME - DateTime - A date and time object for Perl +DateTime - A date and time object for Perl -VERSION +# VERSION - version 1.21 +version 1.46 -SYNOPSIS +# SYNOPSIS - use DateTime; - - $dt = DateTime->new( - year => 1964, - month => 10, - day => 16, - hour => 16, - minute => 12, - second => 47, - nanosecond => 500000000, - time_zone => 'Asia/Taipei', - ); - - $dt = DateTime->from_epoch( epoch => $epoch ); - $dt = DateTime->now; # same as ( epoch => time() ) - - $year = $dt->year; - $month = $dt->month; # 1-12 - - $day = $dt->day; # 1-31 - - $dow = $dt->day_of_week; # 1-7 (Monday is 1) - - $hour = $dt->hour; # 0-23 - $minute = $dt->minute; # 0-59 - - $second = $dt->second; # 0-61 (leap seconds!) - - $doy = $dt->day_of_year; # 1-366 (leap years) - - $doq = $dt->day_of_quarter; # 1.. - - $qtr = $dt->quarter; # 1-4 - - # all of the start-at-1 methods above have corresponding start-at-0 - # methods, such as $dt->day_of_month_0, $dt->month_0 and so on - - $ymd = $dt->ymd; # 2002-12-06 - $ymd = $dt->ymd('/'); # 2002/12/06 - - $mdy = $dt->mdy; # 12-06-2002 - $mdy = $dt->mdy('/'); # 12/06/2002 - - $dmy = $dt->dmy; # 06-12-2002 - $dmy = $dt->dmy('/'); # 06/12/2002 - - $hms = $dt->hms; # 14:02:29 - $hms = $dt->hms('!'); # 14!02!29 - - $is_leap = $dt->is_leap_year; - - # these are localizable, see Locales section - $month_name = $dt->month_name; # January, February, ... - $month_abbr = $dt->month_abbr; # Jan, Feb, ... - $day_name = $dt->day_name; # Monday, Tuesday, ... - $day_abbr = $dt->day_abbr; # Mon, Tue, ... - - # May not work for all possible datetime, see the docs on this - # method for more details. - $epoch_time = $dt->epoch; - - $dt2 = $dt + $duration_object; - - $dt3 = $dt - $duration_object; - - $duration_object = $dt - $dt2; - - $dt->set( year => 1882 ); - - $dt->set_time_zone( 'America/Chicago' ); - - $dt->set_formatter( $formatter ); + use DateTime; -DESCRIPTION + $dt = DateTime->new( + year => 1964, + month => 10, + day => 16, + hour => 16, + minute => 12, + second => 47, + nanosecond => 500000000, + time_zone => 'Asia/Taipei', + ); - DateTime is a class for the representation of date/time combinations, - and is part of the Perl DateTime project. For details on this project - please see http://datetime.perl.org/. The DateTime site has a FAQ which - may help answer many "how do I do X?" questions. The FAQ is at - http://datetime.perl.org/wiki/datetime/page/FAQ. + $dt = DateTime->from_epoch( epoch => $epoch ); + $dt = DateTime->now; # same as ( epoch => time() ) - It represents the Gregorian calendar, extended backwards in time before - its creation (in 1582). This is sometimes known as the "proleptic - Gregorian calendar". In this calendar, the first day of the calendar - (the epoch), is the first day of year 1, which corresponds to the date - which was (incorrectly) believed to be the birth of Jesus Christ. + $year = $dt->year; + $month = $dt->month; # 1-12 - The calendar represented does have a year 0, and in that way differs - from how dates are often written using "BCE/CE" or "BC/AD". + $day = $dt->day; # 1-31 - For infinite datetimes, please see the DateTime::Infinite module. + $dow = $dt->day_of_week; # 1-7 (Monday is 1) -USAGE + $hour = $dt->hour; # 0-23 + $minute = $dt->minute; # 0-59 - 0-based Versus 1-based Numbers + $second = $dt->second; # 0-61 (leap seconds!) - The DateTime.pm module follows a simple consistent logic for - determining whether or not a given number is 0-based or 1-based. + $doy = $dt->day_of_year; # 1-366 (leap years) - Month, day of month, day of week, and day of year are 1-based. Any - method that is 1-based also has an equivalent 0-based method ending in - "_0". So for example, this class provides both day_of_week() and - day_of_week_0() methods. + $doq = $dt->day_of_quarter; # 1.. - The day_of_week_0() method still treats Monday as the first day of the - week. + $qtr = $dt->quarter; # 1-4 - All time-related numbers such as hour, minute, and second are 0-based. + # all of the start-at-1 methods above have corresponding start-at-0 + # methods, such as $dt->day_of_month_0, $dt->month_0 and so on - Years are neither, as they can be both positive or negative, unlike any - other datetime component. There is a year 0. + $ymd = $dt->ymd; # 2002-12-06 + $ymd = $dt->ymd('/'); # 2002/12/06 - There is no quarter_0() method. + $mdy = $dt->mdy; # 12-06-2002 + $mdy = $dt->mdy('/'); # 12/06/2002 - Error Handling + $dmy = $dt->dmy; # 06-12-2002 + $dmy = $dt->dmy('/'); # 06/12/2002 - Some errors may cause this module to die with an error string. This can - only happen when calling constructor methods, methods that change the - object, such as set(), or methods that take parameters. Methods that - retrieve information about the object, such as year() or epoch(), will - never die. + $hms = $dt->hms; # 14:02:29 + $hms = $dt->hms('!'); # 14!02!29 - Locales + $is_leap = $dt->is_leap_year; - All the object methods which return names or abbreviations return data - based on a locale. This is done by setting the locale when constructing - a DateTime object. If this is not set, then "en_US" is used. + # these are localizable, see Locales section + $month_name = $dt->month_name; # January, February, ... + $month_abbr = $dt->month_abbr; # Jan, Feb, ... + $day_name = $dt->day_name; # Monday, Tuesday, ... + $day_abbr = $dt->day_abbr; # Mon, Tue, ... - Floating DateTimes + # May not work for all possible datetime, see the docs on this + # method for more details. + $epoch_time = $dt->epoch; - The default time zone for new DateTime objects, except where stated - otherwise, is the "floating" time zone. This concept comes from the - iCal standard. A floating datetime is one which is not anchored to any - particular time zone. In addition, floating datetimes do not include - leap seconds, since we cannot apply them without knowing the datetime's - time zone. + $dt2 = $dt + $duration_object; - The results of date math and comparison between a floating datetime and - one with a real time zone are not really valid, because one includes - leap seconds and the other does not. Similarly, the results of datetime - math between two floating datetimes and two datetimes with time zones - are not really comparable. + $dt3 = $dt - $duration_object; - If you are planning to use any objects with a real time zone, it is - strongly recommended that you do not mix these with floating datetimes. + $duration_object = $dt - $dt2; - Math + $dt->set( year => 1882 ); - If you are going to be doing date math, please read the section "How - DateTime Math Works". + $dt->set_time_zone( 'America/Chicago' ); - Determining the Local Time Zone Can Be Slow + $dt->set_formatter( $formatter ); - If $ENV{TZ} is not set, it may involve reading a number of files in - /etc or elsewhere. If you know that the local time zone won't change - while your code is running, and you need to make many objects for the - local time zone, it is strongly recommended that you retrieve the local - time zone once and cache it: +# DESCRIPTION - our $App::LocalTZ = DateTime::TimeZone->new( name => 'local' ); - - ... # then everywhere else - - my $dt = DateTime->new( ..., time_zone => $App::LocalTZ ); +DateTime is a class for the representation of date/time combinations, +and is part of the Perl DateTime project. For details on this project +please see [http://datetime.perl.org/](http://datetime.perl.org/). The DateTime site has a FAQ +which may help answer many "how do I do X?" questions. The FAQ is at +[http://datetime.perl.org/wiki/datetime/page/FAQ](http://datetime.perl.org/wiki/datetime/page/FAQ). - DateTime itself does not do this internally because local time zones - can change, and there's no good way to determine if it's changed - without doing all the work to look it up. +It represents the Gregorian calendar, extended backwards in time +before its creation (in 1582). This is sometimes known as the +"proleptic Gregorian calendar". In this calendar, the first day of +the calendar (the epoch), is the first day of year 1, which +corresponds to the date which was (incorrectly) believed to be the +birth of Jesus Christ. - Do not try to use named time zones (like "America/Chicago") with dates - very far in the future (thousands of years). The current implementation - of DateTime::TimeZone will use a huge amount of memory calculating all - the DST changes from now until the future date. Use UTC or the floating - time zone and you will be safe. +The calendar represented does have a year 0, and in that way differs +from how dates are often written using "BCE/CE" or "BC/AD". - Upper and Lower Bounds +For infinite datetimes, please see the +[DateTime::Infinite](https://metacpan.org/pod/DateTime::Infinite) module. - Internally, dates are represented the number of days before or after - 0001-01-01. This is stored as an integer, meaning that the upper and - lower bounds are based on your Perl's integer size ($Config{ivsize}). +# USAGE - The limit on 32-bit systems is around 2^29 days, which gets you to year - (+/-)1,469,903. On a 64-bit system you get 2^62 days, - (+/-)12,626,367,463,883,278 (12.626 quadrillion). +## 0-based Versus 1-based Numbers -METHODS +The DateTime.pm module follows a simple logic for determining whether or not a +given number is 0-based or 1-based. - DateTime provide many methods. The documentation breaks them down into - groups based on what they do (constructor, accessors, modifiers, etc.). +Month, day of month, day of week, and day of year are 1-based. Any +method that is 1-based also has an equivalent 0-based method ending in +"\_0". So for example, this class provides both `day_of_week()` and +`day_of_week_0()` methods. - Constructors +The `day_of_week_0()` method still treats Monday as the first day of +the week. - All constructors can die when invalid parameters are given. +All _time_-related numbers such as hour, minute, and second are +0-based. - Warnings +Years are neither, as they can be both positive or negative, unlike +any other datetime component. There _is_ a year 0. - Currently, constructors will warn if you try to create a far future - DateTime (year >= 5000) with any time zone besides floating or UTC. - This can be very slow if the time zone has future DST transitions that - need to be calculated. If the date is sufficiently far in the future - this can be really slow (minutes). +There is no `quarter_0()` method. - All warnings from DateTime use the DateTime category and can be - suppressed with: +## Error Handling - no warnings 'DateTime'; +Some errors may cause this module to die with an error string. This +can only happen when calling constructor methods, methods that change +the object, such as `set()`, or methods that take parameters. +Methods that retrieve information about the object, such as `year()` +or `epoch()`, will never die. - This warning may be removed in the future if DateTime::TimeZone is made - much faster. +## Locales - DateTime->new( ... ) +All the object methods which return names or abbreviations return data based +on a locale. This is done by setting the locale when constructing a DateTime +object. If this is not set, then "en-US" is used. - This class method accepts parameters for each date and time component: - "year", "month", "day", "hour", "minute", "second", "nanosecond". It - also accepts "locale", "time_zone", and "formatter" parameters. +## Floating DateTimes - my $dt = DateTime->new( - year => 1966, - month => 10, - day => 25, - hour => 7, - minute => 15, - second => 47, - nanosecond => 500000000, - time_zone => 'America/Chicago', - ); +The default time zone for new DateTime objects, except where stated +otherwise, is the "floating" time zone. This concept comes from the +iCal standard. A floating datetime is one which is not anchored to +any particular time zone. In addition, floating datetimes do not +include leap seconds, since we cannot apply them without knowing the +datetime's time zone. - DateTime validates the "month", "day", "hour", "minute", and "second", - and "nanosecond" parameters. The valid values for these parameters are: +The results of date math and comparison between a floating datetime +and one with a real time zone are not really valid, because one +includes leap seconds and the other does not. Similarly, the results +of datetime math between two floating datetimes and two datetimes with +time zones are not really comparable. - * month +If you are planning to use any objects with a real time zone, it is +strongly recommended that you **do not** mix these with floating +datetimes. - An integer from 1-12. +## Math - * day +If you are going to be doing date math, please read the section ["How DateTime +Math Works"](#how-datetime-math-works). - An integer from 1-31, and it must be within the valid range of days - for the specified month. +## Determining the Local Time Zone Can Be Slow - * hour +If `$ENV{TZ}` is not set, it may involve reading a number of files in `/etc` +or elsewhere. If you know that the local time zone won't change while your +code is running, and you need to make many objects for the local time zone, it +is strongly recommended that you retrieve the local time zone once and cache +it: - An integer from 0-23. + our $App::LocalTZ = DateTime::TimeZone->new( name => 'local' ); - * minute + ... # then everywhere else - An integer from 0-59. + my $dt = DateTime->new( ..., time_zone => $App::LocalTZ ); - * second +DateTime itself does not do this internally because local time zones can +change, and there's no good way to determine if it's changed without doing all +the work to look it up. - An integer from 0-61 (to allow for leap seconds). Values of 60 or 61 - are only allowed when they match actual leap seconds. +Do not try to use named time zones (like "America/Chicago") with dates +very far in the future (thousands of years). The current +implementation of `DateTime::TimeZone` will use a huge amount of +memory calculating all the DST changes from now until the future +date. Use UTC or the floating time zone and you will be safe. - * nanosecond +## Globally Setting a Default Time Zone - An integer >= 0. If this number is greater than 1 billion, it will be - normalized into the second value for the DateTime object. +**Warning: This is very dangerous. Do this at your own risk!** - Invalid parameter types (like an array reference) will cause the - constructor to die. +By default, `DateTime` uses either the floating time zone or UTC for newly +created objects, depending on the constructor. - The value for seconds may be from 0 to 61, to account for leap seconds. - If you give a value greater than 59, DateTime does check to see that it - really matches a valid leap second. +You can force `DateTime` to use a different time zone by setting the +`PERL_DATETIME_DEFAULT_TZ` environment variable. - All of the parameters are optional except for "year". The "month" and - "day" parameters both default to 1, while the "hour", "minute", - "second", and "nanosecond" parameters all default to 0. +As noted above, this is very dangerous, as it affects all code that creates a +`DateTime` object, including modules from CPAN. If those modules expect the +normal default, then setting this can cause confusing breakage or subtly +broken data. Before setting this variable, you are strongly encouraged to +audit your CPAN dependencies to see how they use `DateTime`. Try running the +test suite for each dependency with this environment variable set before using +this in production. - The "locale" parameter should be a string matching one of the valid - locales, or a DateTime::Locale object. See the DateTime::Locale - documentation for details. +## Upper and Lower Bounds - The time_zone parameter can be either a scalar or a DateTime::TimeZone - object. A string will simply be passed to the DateTime::TimeZone->new - method as its "name" parameter. This string may be an Olson DB time - zone name ("America/Chicago"), an offset string ("+0630"), or the words - "floating" or "local". See the DateTime::TimeZone documentation for - more details. +Internally, dates are represented the number of days before or after +0001-01-01. This is stored as an integer, meaning that the upper and lower +bounds are based on your Perl's integer size (`$Config{ivsize}`). - The default time zone is "floating". +The limit on 32-bit systems is around 2^29 days, which gets you to year +(+/-)1,469,903. On a 64-bit system you get 2^62 days, +(+/-)12,626,367,463,883,278 (12.626 quadrillion). - The "formatter" can be either a scalar or an object, but the class - specified by the scalar or the object must implement a - format_datetime() method. +# METHODS - Parsing Dates +DateTime provide many methods. The documentation breaks them down into groups +based on what they do (constructor, accessors, modifiers, etc.). - This module does not parse dates! That means there is no constructor to - which you can pass things like "March 3, 1970 12:34". +## Constructors - Instead, take a look at the various DateTime::Format::* modules on - CPAN. These parse all sorts of different date formats, and you're bound - to find something that can handle your particular needs. +All constructors can die when invalid parameters are given. - Ambiguous Local Times +### Warnings - Because of Daylight Saving Time, it is possible to specify a local time - that is ambiguous. For example, in the US in 2003, the transition from - to saving to standard time occurred on October 26, at 02:00:00 local - time. The local clock changed from 01:59:59 (saving time) to 01:00:00 - (standard time). This means that the hour from 01:00:00 through - 01:59:59 actually occurs twice, though the UTC time continues to move - forward. +Currently, constructors will warn if you try to create a far future DateTime +(year >= 5000) with any time zone besides floating or UTC. This can be very +slow if the time zone has future DST transitions that need to be +calculated. If the date is sufficiently far in the future this can be +_really_ slow (minutes). - If you specify an ambiguous time, then the latest UTC time is always - used, in effect always choosing standard time. In this case, you can - simply subtract an hour to the object in order to move to saving time, - for example: +All warnings from DateTime use the `DateTime` category and can be suppressed +with: - # This object represent 01:30:00 standard time - my $dt = DateTime->new( - year => 2003, - month => 10, - day => 26, - hour => 1, - minute => 30, - second => 0, - time_zone => 'America/Chicago', - ); - - print $dt->hms; # prints 01:30:00 - - # Now the object represent 01:30:00 saving time - $dt->subtract( hours => 1 ); - - print $dt->hms; # still prints 01:30:00 + no warnings 'DateTime'; - Alternately, you could create the object with the UTC time zone, and - then call the set_time_zone() method to change the time zone. This is a - good way to ensure that the time is not ambiguous. +This warning may be removed in the future if [DateTime::TimeZone](https://metacpan.org/pod/DateTime::TimeZone) is made +much faster. - Invalid Local Times +### DateTime->new( ... ) - Another problem introduced by Daylight Saving Time is that certain - local times just do not exist. For example, in the US in 2003, the - transition from standard to saving time occurred on April 6, at the - change to 2:00:00 local time. The local clock changes from 01:59:59 - (standard time) to 03:00:00 (saving time). This means that there is no - 02:00:00 through 02:59:59 on April 6! +This class method accepts parameters for each date and time component: +"year", "month", "day", "hour", "minute", "second", "nanosecond". +It also accepts "locale", "time\_zone", and "formatter" parameters. - Attempting to create an invalid time currently causes a fatal error. - This may change in future version of this module. + my $dt = DateTime->new( + year => 1966, + month => 10, + day => 25, + hour => 7, + minute => 15, + second => 47, + nanosecond => 500000000, + time_zone => 'America/Chicago', + ); - DateTime->from_epoch( epoch => $epoch, ... ) +DateTime validates the "month", "day", "hour", "minute", and "second", +and "nanosecond" parameters. The valid values for these parameters are: - This class method can be used to construct a new DateTime object from - an epoch time instead of components. Just as with the new() method, it - accepts "time_zone", "locale", and "formatter" parameters. +- month - If the epoch value is not an integer, the part after the decimal will - be converted to nanoseconds. This is done in order to be compatible - with Time::HiRes. If the floating portion extends past 9 decimal - places, it will be truncated to nine, so that 1.1234567891 will become - 1 second and 123,456,789 nanoseconds. + An integer from 1-12. - By default, the returned object will be in the UTC time zone. +- day - DateTime->now( ... ) + An integer from 1-31, and it must be within the valid range of days for the + specified month. - This class method is equivalent to calling from_epoch() with the value - returned from Perl's time() function. Just as with the new() method, it - accepts "time_zone" and "locale" parameters. +- hour - By default, the returned object will be in the UTC time zone. + An integer from 0-23. - DateTime->today( ... ) +- minute - This class method is equivalent to: + An integer from 0-59. - DateTime->now(@_)->truncate( to => 'day' ); +- second - DateTime->from_object( object => $object, ... ) + An integer from 0-61 (to allow for leap seconds). Values of 60 or 61 are only + allowed when they match actual leap seconds. - This class method can be used to construct a new DateTime object from - any object that implements the utc_rd_values() method. All - DateTime::Calendar modules must implement this method in order to - provide cross-calendar compatibility. This method accepts a "locale" - and "formatter" parameter +- nanosecond - If the object passed to this method has a time_zone() method, that is - used to set the time zone of the newly created DateTime.pm object. + An integer >= 0. If this number is greater than 1 billion, it will be + normalized into the second value for the DateTime object. - Otherwise, the returned object will be in the floating time zone. +Invalid parameter types (like an array reference) will cause the +constructor to die. - DateTime->last_day_of_month( ... ) +The value for seconds may be from 0 to 61, to account for leap +seconds. If you give a value greater than 59, DateTime does check to +see that it really matches a valid leap second. - This constructor takes the same arguments as can be given to the new() - method, except for "day". Additionally, both "year" and "month" are - required. +All of the parameters are optional except for "year". The "month" and +"day" parameters both default to 1, while the "hour", "minute", +"second", and "nanosecond" parameters all default to 0. - DateTime->from_day_of_year( ... ) +The "locale" parameter should be a string containing a locale code, like +"en-US" or "zh-Hant-TW", or an object returned by `DateTime::Locale->load`. See the [DateTime::Locale](https://metacpan.org/pod/DateTime::Locale) documentation for details. - This constructor takes the same arguments as can be given to the new() - method, except that it does not accept a "month" or "day" argument. - Instead, it requires both "year" and "day_of_year". The day of year - must be between 1 and 366, and 366 is only allowed for leap years. +The "time\_zone" parameter can be either a string or a `DateTime::TimeZone` +object. A string will simply be passed to the `DateTime::TimeZone->new` +method as its "name" parameter. This string may be an Olson DB time zone name +("America/Chicago"), an offset string ("+0630"), or the words "floating" or +"local". See the `DateTime::TimeZone` documentation for more details. - $dt->clone() +The default time zone is "floating". - This object method returns a new object that is replica of the object - upon which the method is called. +The "formatter" can be either a scalar or an object, but the class +specified by the scalar or the object must implement a +`format_datetime()` method. - "Get" Methods +#### Parsing Dates - This class has many methods for retrieving information about an object. +**This module does not parse dates!** That means there is no +constructor to which you can pass things like "March 3, 1970 12:34". - $dt->year() +Instead, take a look at the various `DateTime::Format::*` modules on +CPAN. These parse all sorts of different date formats, and you're +bound to find something that can handle your particular needs. - Returns the year. +#### Ambiguous Local Times - $dt->ce_year() +Because of Daylight Saving Time, it is possible to specify a local +time that is ambiguous. For example, in the US in 2003, the +transition from to saving to standard time occurred on October 26, at +02:00:00 local time. The local clock changed from 01:59:59 (saving +time) to 01:00:00 (standard time). This means that the hour from +01:00:00 through 01:59:59 actually occurs twice, though the UTC time +continues to move forward. - Returns the year according to the BCE/CE numbering system. The year - before year 1 in this system is year -1, aka "1 BCE". +If you specify an ambiguous time, then the latest UTC time is always +used, in effect always choosing standard time. In this case, you can +simply subtract an hour to the object in order to move to saving time, +for example: - $dt->era_name() + # This object represent 01:30:00 standard time + my $dt = DateTime->new( + year => 2003, + month => 10, + day => 26, + hour => 1, + minute => 30, + second => 0, + time_zone => 'America/Chicago', + ); - Returns the long name of the current era, something like "Before - Christ". See the Locales section for more details. + print $dt->hms; # prints 01:30:00 - $dt->era_abbr() + # Now the object represent 01:30:00 saving time + $dt->subtract( hours => 1 ); - Returns the abbreviated name of the current era, something like "BC". - See the Locales section for more details. + print $dt->hms; # still prints 01:30:00 - $dt->christian_era() +Alternately, you could create the object with the UTC time zone, and +then call the `set_time_zone()` method to change the time zone. This +is a good way to ensure that the time is not ambiguous. - Returns a string, either "BC" or "AD", according to the year. +#### Invalid Local Times - $dt->secular_era() +Another problem introduced by Daylight Saving Time is that certain +local times just do not exist. For example, in the US in 2003, the +transition from standard to saving time occurred on April 6, at the +change to 2:00:00 local time. The local clock changes from 01:59:59 +(standard time) to 03:00:00 (saving time). This means that there is +no 02:00:00 through 02:59:59 on April 6! - Returns a string, either "BCE" or "CE", according to the year. +Attempting to create an invalid time currently causes a fatal error. +This may change in future version of this module. - $dt->year_with_era() +### DateTime->from\_epoch( epoch => $epoch, ... ) - Returns a string containing the year immediately followed by its era - abbreviation. The year is the absolute value of ce_year(), so that year - 1 is "1AD" and year 0 is "1BC". +This class method can be used to construct a new DateTime object from +an epoch time instead of components. Just as with the `new()` +method, it accepts "time\_zone", "locale", and "formatter" parameters. - $dt->year_with_christian_era() +If the epoch value is a floating-point value, it will be rounded to +nearest microsecond. - Like year_with_era(), but uses the christian_era() method to get the - era name. +By default, the returned object will be in the UTC time zone. - $dt->year_with_secular_era() +### DateTime->now( ... ) - Like year_with_era(), but uses the secular_era() method to get the era - name. +This class method is equivalent to calling `from_epoch()` with the +value returned from Perl's `time()` function. Just as with the +`new()` method, it accepts "time\_zone" and "locale" parameters. - $dt->month() +By default, the returned object will be in the UTC time zone. - Returns the month of the year, from 1..12. +### DateTime->today( ... ) - Also available as $dt->mon(). +This class method is equivalent to: - $dt->month_name() + DateTime->now(@_)->truncate( to => 'day' ); - Returns the name of the current month. See the Locales section for more - details. +### DateTime->from\_object( object => $object, ... ) - $dt->month_abbr() +This class method can be used to construct a new DateTime object from +any object that implements the `utc_rd_values()` method. All +`DateTime::Calendar` modules must implement this method in order to +provide cross-calendar compatibility. This method accepts a +"locale" and "formatter" parameter - Returns the abbreviated name of the current month. See the Locales - section for more details. +If the object passed to this method has a `time_zone()` method, that +is used to set the time zone of the newly created `DateTime.pm` +object. - $dt->day() +Otherwise, the returned object will be in the floating time zone. - Returns the day of the month, from 1..31. +### DateTime->last\_day\_of\_month( ... ) - Also available as $dt->mday() and $dt->day_of_month(). +This constructor takes the same arguments as can be given to the +`new()` method, except for "day". Additionally, both "year" and +"month" are required. - $dt->day_of_week() +### DateTime->from\_day\_of\_year( ... ) - Returns the day of the week as a number, from 1..7, with 1 being Monday - and 7 being Sunday. +This constructor takes the same arguments as can be given to the +`new()` method, except that it does not accept a "month" or "day" +argument. Instead, it requires both "year" and "day\_of\_year". The +day of year must be between 1 and 366, and 366 is only allowed for +leap years. - Also available as $dt->wday() and $dt->dow(). +### $dt->clone() - $dt->local_day_of_week() +This object method returns a new object that is replica of the object +upon which the method is called. - Returns the day of the week as a number, from 1..7. The day - corresponding to 1 will vary based on the locale. +## "Get" Methods - $dt->day_name() +This class has many methods for retrieving information about an +object. - Returns the name of the current day of the week. See the Locales - section for more details. +### $dt->year() - $dt->day_abbr() +Returns the year. - Returns the abbreviated name of the current day of the week. See the - Locales section for more details. +### $dt->ce\_year() - $dt->day_of_year() +Returns the year according to the BCE/CE numbering system. The year +before year 1 in this system is year -1, aka "1 BCE". - Returns the day of the year. +### $dt->era\_name() - Also available as $dt->doy(). +Returns the long name of the current era, something like "Before +Christ". See the [Locales](#locales) section for more details. - $dt->quarter() +### $dt->era\_abbr() - Returns the quarter of the year, from 1..4. +Returns the abbreviated name of the current era, something like "BC". +See the [Locales](#locales) section for more details. - $dt->quarter_name() +### $dt->christian\_era() - Returns the name of the current quarter. See the Locales section for - more details. +Returns a string, either "BC" or "AD", according to the year. - $dt->quarter_abbr() +### $dt->secular\_era() - Returns the abbreviated name of the current quarter. See the Locales - section for more details. +Returns a string, either "BCE" or "CE", according to the year. - $dt->day_of_quarter() +### $dt->year\_with\_era() - Returns the day of the quarter. +Returns a string containing the year immediately followed by its era +abbreviation. The year is the absolute value of `ce_year()`, so that +year 1 is "1AD" and year 0 is "1BC". - Also available as $dt->doq(). +### $dt->year\_with\_christian\_era() - $dt->weekday_of_month() +Like `year_with_era()`, but uses the christian\_era() method to get the era +name. - Returns a number from 1..5 indicating which week day of the month this - is. For example, June 9, 2003 is the second Monday of the month, and so - this method returns 2 for that day. +### $dt->year\_with\_secular\_era() - $dt->ymd( $optional_separator ), $dt->mdy(...), $dt->dmy(...) +Like `year_with_era()`, but uses the secular\_era() method to get the +era name. - Each method returns the year, month, and day, in the order indicated by - the method name. Years are zero-padded to four digits. Months and days - are 0-padded to two digits. +### $dt->month() - By default, the values are separated by a dash (-), but this can be - overridden by passing a value to the method. +Returns the month of the year, from 1..12. - The $dt->ymd() method is also available as $dt->date(). +Also available as `$dt->mon()`. - $dt->hour() +### $dt->month\_name() - Returns the hour of the day, from 0..23. +Returns the name of the current month. See the +[Locales](#locales) section for more details. - $dt->hour_1() +### $dt->month\_abbr() - Returns the hour of the day, from 1..24. +Returns the abbreviated name of the current month. See the +[Locales](#locales) section for more details. - $dt->hour_12() +### $dt->day() - Returns the hour of the day, from 1..12. +Returns the day of the month, from 1..31. - $dt->hour_12_0() +Also available as `$dt->mday()` and `$dt->day_of_month()`. - Returns the hour of the day, from 0..11. +### $dt->day\_of\_week() - $dt->am_or_pm() +Returns the day of the week as a number, from 1..7, with 1 being +Monday and 7 being Sunday. - Returns the appropriate localized abbreviation, depending on the - current hour. +Also available as `$dt->wday()` and `$dt->dow()`. - $dt->minute() +### $dt->local\_day\_of\_week() - Returns the minute of the hour, from 0..59. +Returns the day of the week as a number, from 1..7. The day +corresponding to 1 will vary based on the locale. - Also available as $dt->min(). +### $dt->day\_name() - $dt->second() +Returns the name of the current day of the week. See the +[Locales](#locales) section for more details. - Returns the second, from 0..61. The values 60 and 61 are used for leap - seconds. +### $dt->day\_abbr() - Also available as $dt->sec(). +Returns the abbreviated name of the current day of the week. See the +[Locales](#locales) section for more details. - $dt->fractional_second() +### $dt->day\_of\_year() - Returns the second, as a real number from 0.0 until 61.999999999 +Returns the day of the year. - The values 60 and 61 are used for leap seconds. +Also available as `$dt->doy()`. - $dt->millisecond() +### $dt->quarter() - Returns the fractional part of the second as milliseconds (1E-3 - seconds). +Returns the quarter of the year, from 1..4. - Half a second is 500 milliseconds. +### $dt->quarter\_name() - This value will always be rounded down to the nearest integer. +Returns the name of the current quarter. See the +[Locales](#locales) section for more details. - $dt->microsecond() +### $dt->quarter\_abbr() - Returns the fractional part of the second as microseconds (1E-6 - seconds). +Returns the abbreviated name of the current quarter. See the +[Locales](#locales) section for more details. - Half a second is 500_000 microseconds. +### $dt->day\_of\_quarter() - This value will always be rounded down to the nearest integer. +Returns the day of the quarter. + +Also available as `$dt->doq()`. + +### $dt->weekday\_of\_month() + +Returns a number from 1..5 indicating which week day of the month this +is. For example, June 9, 2003 is the second Monday of the month, and +so this method returns 2 for that day. + +### $dt->ymd( $optional\_separator ), $dt->mdy(...), $dt->dmy(...) + +Each method returns the year, month, and day, in the order indicated +by the method name. Years are zero-padded to four digits. Months and +days are 0-padded to two digits. + +By default, the values are separated by a dash (-), but this can be +overridden by passing a value to the method. + +The `$dt->ymd()` method is also available as `$dt->date()`. + +### $dt->hour() + +Returns the hour of the day, from 0..23. + +### $dt->hour\_1() + +Returns the hour of the day, from 1..24. + +### $dt->hour\_12() + +Returns the hour of the day, from 1..12. + +### $dt->hour\_12\_0() + +Returns the hour of the day, from 0..11. + +### $dt->am\_or\_pm() + +Returns the appropriate localized abbreviation, depending on the +current hour. + +### $dt->minute() + +Returns the minute of the hour, from 0..59. + +Also available as `$dt->min()`. + +### $dt->second() + +Returns the second, from 0..61. The values 60 and 61 are used for +leap seconds. + +Also available as `$dt->sec()`. + +### $dt->fractional\_second() + +Returns the second, as a real number from 0.0 until 61.999999999 + +The values 60 and 61 are used for leap seconds. + +### $dt->millisecond() + +Returns the fractional part of the second as milliseconds (1E-3 seconds). + +Half a second is 500 milliseconds. + +This value will always be rounded down to the nearest integer. + +### $dt->microsecond() + +Returns the fractional part of the second as microseconds (1E-6 +seconds). + +Half a second is 500\_000 microseconds. + +This value will always be rounded down to the nearest integer. + +### $dt->nanosecond() + +Returns the fractional part of the second as nanoseconds (1E-9 seconds). + +Half a second is 500\_000\_000 nanoseconds. + +### $dt->hms( $optional\_separator ) + +Returns the hour, minute, and second, all zero-padded to two digits. +If no separator is specified, a colon (:) is used by default. + +Also available as `$dt->time()`. + +### $dt->datetime( $optional\_separator ) + +This method is equivalent to: + + $dt->ymd('-') . 'T' . $dt->hms(':') - $dt->nanosecond() +The `$optional_separator` parameter allows you to override the separator +between the date and time, for e.g. `$dt->datetime(q{ })`. - Returns the fractional part of the second as nanoseconds (1E-9 - seconds). +This method is also available as `$dt->iso8601()`, but it's not really a +very good ISO8601 format, as it lacks a time zone. If called as +`$dt->iso8601()` you cannot change the separator, as ISO8601 specifies +that "T" must be used to separate them. - Half a second is 500_000_000 nanoseconds. +### $dt->stringify() - $dt->hms( $optional_separator ) +This method returns a stringified version of the object. It is how +stringification overloading is implemented. If the object has a formatter, +then its `format_datetime()` method is used to produce a string. Otherwise, +this method calls `$dt->iso8601()` to produce a string. See ["Formatters +And Stringification"](#formatters-and-stringification) for details. - Returns the hour, minute, and second, all zero-padded to two digits. If - no separator is specified, a colon (:) is used by default. +### $dt->is\_leap\_year() - Also available as $dt->time(). +This method returns a true or false value indicating whether or not the +datetime object is in a leap year. - $dt->datetime() +### $dt->is\_last\_day\_of\_month() - This method is equivalent to: +This method returns a true or false value indicating whether or not the +datetime object is the last day of the month. - $dt->ymd('-') . 'T' . $dt->hms(':') +### $dt->month\_length() - This method is also available as $dt->iso8601(), but it's not really a - very good ISO8601 format, as it lacks a time zone. +This method returns the number of days in the current month. - $dt->is_leap_year() +### $dt->quarter\_length() - This method returns a true or false indicating whether or not the - datetime object is in a leap year. +This method returns the number of days in the current quarter. - $dt->week() +### $dt->year\_length() - ($week_year, $week_number) = $dt->week; +This method returns the number of days in the current year. - Returns information about the calendar week which contains this - datetime object. The values returned by this method are also available - separately through the week_year and week_number methods. +### $dt->week() - The first week of the year is defined by ISO as the one which contains - the fourth day of January, which is equivalent to saying that it's the - first week to overlap the new year by at least four days. + ($week_year, $week_number) = $dt->week; - Typically the week year will be the same as the year that the object is - in, but dates at the very beginning of a calendar year often end up in - the last week of the prior year, and similarly, the final few days of - the year may be placed in the first week of the next year. +Returns information about the calendar week which contains this +datetime object. The values returned by this method are also available +separately through the week\_year and week\_number methods. - $dt->week_year() +The first week of the year is defined by ISO as the one which contains +the fourth day of January, which is equivalent to saying that it's the +first week to overlap the new year by at least four days. - Returns the year of the week. See $dt->week() for details. +Typically the week year will be the same as the year that the object +is in, but dates at the very beginning of a calendar year often end up +in the last week of the prior year, and similarly, the final few days +of the year may be placed in the first week of the next year. - $dt->week_number() +### $dt->week\_year() - Returns the week of the year, from 1..53. See $dt->week() for details. +Returns the year of the week. See `$dt->week()` for details. - $dt->week_of_month() +### $dt->week\_number() - The week of the month, from 0..5. The first week of the month is the - first week that contains a Thursday. This is based on the ICU - definition of week of month, and correlates to the ISO8601 week of year - definition. A day in the week before the week with the first Thursday - will be week 0. +Returns the week of the year, from 1..53. See `$dt->week()` for details. - $dt->jd(), $dt->mjd() +### $dt->week\_of\_month() - These return the Julian Day and Modified Julian Day, respectively. The - value returned is a floating point number. The fractional portion of - the number represents the time portion of the datetime. +The week of the month, from 0..5. The first week of the month is the +first week that contains a Thursday. This is based on the ICU +definition of week of month, and correlates to the ISO8601 week of +year definition. A day in the week _before_ the week with the first +Thursday will be week 0. - $dt->time_zone() +### $dt->jd(), $dt->mjd() - This returns the DateTime::TimeZone object for the datetime object. +These return the Julian Day and Modified Julian Day, respectively. +The value returned is a floating point number. The fractional portion +of the number represents the time portion of the datetime. - $dt->offset() +### $dt->time\_zone() - This returns the offset from UTC, in seconds, of the datetime object - according to the time zone. +This returns the `DateTime::TimeZone` object for the datetime object. - $dt->is_dst() +### $dt->offset() - Returns a boolean indicating whether or not the datetime object is - currently in Daylight Saving Time or not. +This returns the offset from UTC, in seconds, of the datetime object +according to the time zone. - $dt->time_zone_long_name() +### $dt->is\_dst() - This is a shortcut for $dt->time_zone->name. It's provided so that one - can use "%{time_zone_long_name}" as a strftime format specifier. +Returns a boolean indicating whether or not the datetime object is +currently in Daylight Saving Time or not. - $dt->time_zone_short_name() +### $dt->time\_zone\_long\_name() - This method returns the time zone abbreviation for the current time - zone, such as "PST" or "GMT". These names are not definitive, and - should not be used in any application intended for general use by users - around the world. +This is a shortcut for `$dt->time_zone->name`. It's provided so +that one can use "%{time\_zone\_long\_name}" as a strftime format +specifier. - $dt->strftime( $format, ... ) +### $dt->time\_zone\_short\_name() - This method implements functionality similar to the strftime() method - in C. However, if given multiple format strings, then it will return - multiple scalars, one for each format string. +This method returns the time zone abbreviation for the current time +zone, such as "PST" or "GMT". These names are **not** definitive, and +should not be used in any application intended for general use by +users around the world. - See the "strftime Patterns" section for a list of all possible strftime - patterns. +### $dt->strftime( $format, ... ) - If you give a pattern that doesn't exist, then it is simply treated as - text. +This method implements functionality similar to the `strftime()` +method in C. However, if given multiple format strings, then it will +return multiple scalars, one for each format string. - $dt->format_cldr( $format, ... ) +See the ["strftime Patterns"](#strftime-patterns) section for a list of all possible +strftime patterns. - This method implements formatting based on the CLDR date patterns. If - given multiple format strings, then it will return multiple scalars, - one for each format string. +If you give a pattern that doesn't exist, then it is simply treated as +text. - See the "CLDR Patterns" section for a list of all possible CLDR - patterns. +### $dt->format\_cldr( $format, ... ) - If you give a pattern that doesn't exist, then it is simply treated as - text. +This method implements formatting based on the CLDR date patterns. If +given multiple format strings, then it will return multiple scalars, +one for each format string. - $dt->epoch() +See the ["CLDR Patterns"](#cldr-patterns) section for a list of all possible CLDR +patterns. - Return the UTC epoch value for the datetime object. Internally, this is - implemented using Time::Local, which uses the Unix epoch even on - machines with a different epoch (such as MacOS). Datetimes before the - start of the epoch will be returned as a negative number. +If you give a pattern that doesn't exist, then it is simply treated as +text. - The return value from this method is always an integer. +### $dt->epoch() - Since the epoch does not account for leap seconds, the epoch time for - 1972-12-31T23:59:60 (UTC) is exactly the same as that for - 1973-01-01T00:00:00. +Return the UTC epoch value for the datetime object. Datetimes before the start +of the epoch will be returned as a negative number. - This module uses Time::Local to calculate the epoch, which may or may - not handle epochs before 1904 or after 2038 (depending on the size of - your system's integers, and whether or not Perl was compiled with - 64-bit int support). +The return value from this method is always an integer. - $dt->hires_epoch() +Since the epoch does not account for leap seconds, the epoch time for +1972-12-31T23:59:60 (UTC) is exactly the same as that for +1973-01-01T00:00:00. - Returns the epoch as a floating point number. The floating point - portion of the value represents the nanosecond value of the object. - This method is provided for compatibility with the Time::HiRes module. +### $dt->hires\_epoch() - Note that this method suffers from the imprecision of floating point - numbers, and the result may end up rounded to an arbitrary degree - depending on your platform. +Returns the epoch as a floating point number. The floating point +portion of the value represents the nanosecond value of the object. +This method is provided for compatibility with the `Time::HiRes` +module. - my $dt = DateTime->new( year => 2012, nanosecond => 4 ); - say $dt->hires_epoch(); +Note that this method suffers from the imprecision of floating point numbers, +and the result may end up rounded to an arbitrary degree depending on your +platform. - On my system, this simply prints 1325376000 because adding 0.000000004 - to 1325376000 returns 1325376000. + my $dt = DateTime->new( year => 2012, nanosecond => 4 ); + say $dt->hires_epoch(); - $dt->is_finite(), $dt->is_infinite() +On my system, this simply prints `1325376000` because adding `0.000000004` +to `1325376000` returns `1325376000`. - These methods allow you to distinguish normal datetime objects from - infinite ones. Infinite datetime objects are documented in - DateTime::Infinite. +### $dt->is\_finite(), $dt->is\_infinite() - $dt->utc_rd_values() +These methods allow you to distinguish normal datetime objects from +infinite ones. Infinite datetime objects are documented in +[DateTime::Infinite](https://metacpan.org/pod/DateTime::Infinite). - Returns the current UTC Rata Die days, seconds, and nanoseconds as a - three element list. This exists primarily to allow other calendar - modules to create objects based on the values provided by this object. +### $dt->utc\_rd\_values() - $dt->local_rd_values() +Returns the current UTC Rata Die days, seconds, and nanoseconds as a +three element list. This exists primarily to allow other calendar +modules to create objects based on the values provided by this object. - Returns the current local Rata Die days, seconds, and nanoseconds as a - three element list. This exists for the benefit of other modules which - might want to use this information for date math, such as - DateTime::Event::Recurrence. +### $dt->local\_rd\_values() - $dt->leap_seconds() +Returns the current local Rata Die days, seconds, and nanoseconds as a +three element list. This exists for the benefit of other modules +which might want to use this information for date math, such as +`DateTime::Event::Recurrence`. - Returns the number of leap seconds that have happened up to the - datetime represented by the object. For floating datetimes, this always - returns 0. +### $dt->leap\_seconds() - $dt->utc_rd_as_seconds() +Returns the number of leap seconds that have happened up to the +datetime represented by the object. For floating datetimes, this +always returns 0. - Returns the current UTC Rata Die days and seconds purely as seconds. - This number ignores any fractional seconds stored in the object, as - well as leap seconds. +### $dt->utc\_rd\_as\_seconds() - $dt->locale() +Returns the current UTC Rata Die days and seconds purely as seconds. +This number ignores any fractional seconds stored in the object, +as well as leap seconds. - Returns the current locale object. +### $dt->locale() - $dt->formatter() +Returns the current locale object. - Returns current formatter object or class. See "Formatters And - Stringification" for details. +### $dt->formatter() - "Set" Methods +Returns current formatter object or class. See ["Formatters And +Stringification"](#formatters-and-stringification) for details. - The remaining methods provided by DateTime.pm, except where otherwise - specified, return the object itself, thus making method chaining - possible. For example: +## "Set" Methods - my $dt = DateTime->now->set_time_zone( 'Australia/Sydney' ); - - my $first = DateTime - ->last_day_of_month( year => 2003, month => 3 ) - ->add( days => 1 ) - ->subtract( seconds => 1 ); +The remaining methods provided by `DateTime.pm`, except where otherwise +specified, return the object itself, thus making method chaining +possible. For example: - $dt->set( .. ) + my $dt = DateTime->now->set_time_zone( 'Australia/Sydney' ); - This method can be used to change the local components of a date time, - or its locale. This method accepts any parameter allowed by the new() - method except for "time_zone". Time zones may be set using the - set_time_zone() method. + my $first = DateTime + ->last_day_of_month( year => 2003, month => 3 ) + ->add( days => 1 ) + ->subtract( seconds => 1 ); - This method performs parameters validation just as is done in the new() - method. +### $dt->set( .. ) - Do not use this method to do date math. Use the add() and subtract() - methods instead. +This method can be used to change the local components of a date time. This +method accepts any parameter allowed by the `new()` method except for +"locale" or "time\_zone". Use `set_locale()` and `set_time_zone()` for those +instead. - $dt->set_year(), $dt->set_month(), etc. +This method performs parameter validation just like the `new()` method. - DateTime has a set_* method for every item that can be passed to the - constructor: +**Do not use this method to do date math. Use the `add()` and `subtract()` +methods instead.** - * $dt->set_year() +### $dt->set\_year(), $dt->set\_month(), etc. - * $dt->set_month() +DateTime has a `set_*` method for every item that can be passed to the +constructor: - * $dt->set_day() +- $dt->set\_year() +- $dt->set\_month() +- $dt->set\_day() +- $dt->set\_hour() +- $dt->set\_minute() +- $dt->set\_second() +- $dt->set\_nanosecond() - * $dt->set_hour() +These are shortcuts to calling `set()` with a single key. They all +take a single parameter. - * $dt->set_minute() +### $dt->truncate( to => ... ) - * $dt->set_second() +This method allows you to reset some of the local time components in the +object to their "zero" values. The "to" parameter is used to specify which +values to truncate, and it may be one of "year", "quarter", "month", "week", +"local\_week", "day", "hour", "minute", or "second". - * $dt->set_nanosecond() +For example, if "month" is specified, then the local day becomes 1, and the +hour, minute, and second all become 0. - * $dt->set_locale() +If "week" is given, then the datetime is set to the Monday of the week in +which it occurs, and the time components are all set to 0. If you truncate to +"local\_week", then the first day of the week is locale-dependent. For example, +in the `en-US` locale, the first day of the week is Sunday. - These are shortcuts to calling set() with a single key. They all take a - single parameter. +### $dt->set\_locale( $locale ) - $dt->truncate( to => ... ) +Sets the object's locale. You can provide either a locale code like "en-US" or +an object returned by `DateTime::Locale->load`. - This method allows you to reset some of the local time components in - the object to their "zero" values. The "to" parameter is used to - specify which values to truncate, and it may be one of "year", "month", - "week", "local_week" "day", "hour", "minute", or "second". For example, - if "month" is specified, then the local day becomes 1, and the hour, - minute, and second all become 0. +### $dt->set\_time\_zone( $tz ) - If "week" is given, then the datetime is set to the Monday of the week - in which it occurs, and the time components are all set to 0. If you - truncate to "local_week", then the first day of the week is - locale-dependent. For example, in the en_US locale, the first day of - the week is Sunday. +This method accepts either a time zone object or a string that can be +passed as the "name" parameter to `DateTime::TimeZone->new()`. +If the new time zone's offset is different from the old time zone, +then the _local_ time is adjusted accordingly. - $dt->set_time_zone( $tz ) +For example: - This method accepts either a time zone object or a string that can be - passed as the "name" parameter to DateTime::TimeZone->new(). If the new - time zone's offset is different from the old time zone, then the local - time is adjusted accordingly. + my $dt = DateTime->new( + year => 2000, + month => 5, + day => 10, + hour => 15, + minute => 15, + time_zone => 'America/Los_Angeles', + ); - For example: + print $dt->hour; # prints 15 - my $dt = DateTime->new( - year => 2000, - month => 5, - day => 10, - hour => 15, - minute => 15, - time_zone => 'America/Los_Angeles', - ); - - print $dt->hour; # prints 15 - - $dt->set_time_zone( 'America/Chicago' ); - - print $dt->hour; # prints 17 + $dt->set_time_zone( 'America/Chicago' ); - If the old time zone was a floating time zone, then no adjustments to - the local time are made, except to account for leap seconds. If the new - time zone is floating, then the UTC time is adjusted in order to leave - the local time untouched. + print $dt->hour; # prints 17 - Fans of Tsai Ming-Liang's films will be happy to know that this does - work: +If the old time zone was a floating time zone, then no adjustments to +the local time are made, except to account for leap seconds. If the +new time zone is floating, then the _UTC_ time is adjusted in order +to leave the local time untouched. - my $dt = DateTime->now( time_zone => 'Asia/Taipei' ); - - $dt->set_time_zone( 'Europe/Paris' ); +Fans of Tsai Ming-Liang's films will be happy to know that this does +work: - Yes, now we can know "ni3 na4 bian1 ji2dian3?" + my $dt = DateTime->now( time_zone => 'Asia/Taipei' ); - $dt->set_formatter( $formatter ) + $dt->set_time_zone( 'Europe/Paris' ); - Set the formatter for the object. See "Formatters And Stringification" - for details. +Yes, now we can know "ni3 na4 bian1 ji2dian3?" - You can set this to undef to revert to the default formatter. +### $dt->set\_formatter( $formatter ) - Math Methods +Set the formatter for the object. See ["Formatters And +Stringification"](#formatters-and-stringification) for details. - Like the set methods, math related methods always return the object - itself, to allow for chaining: +You can set this to `undef` to revert to the default formatter. - $dt->add( days => 1 )->subtract( seconds => 1 ); +## Math Methods - $dt->duration_class() +Like the set methods, math related methods always return the object +itself, to allow for chaining: - This returns DateTime::Duration, but exists so that a subclass of - DateTime.pm can provide a different value. + $dt->add( days => 1 )->subtract( seconds => 1 ); - $dt->add_duration( $duration_object ) +### $dt->duration\_class() - This method adds a DateTime::Duration to the current datetime. See the - DateTime::Duration docs for more details. +This returns `DateTime::Duration`, but exists so that a subclass of +`DateTime.pm` can provide a different value. - $dt->add( DateTime::Duration->new parameters ) +### $dt->add\_duration( $duration\_object ) - This method is syntactic sugar around the add_duration() method. It - simply creates a new DateTime::Duration object using the parameters - given, and then calls the add_duration() method. +This method adds a `DateTime::Duration` to the current datetime. See +the [DateTime::Duration](https://metacpan.org/pod/DateTime::Duration) docs for more details. - $dt->subtract_duration( $duration_object ) +### $dt->add( parameters for DateTime::Duration ) - When given a DateTime::Duration object, this method simply calls - invert() on that object and passes that new duration to the - add_duration method. +This method is syntactic sugar around the `add_duration()` method. It +simply creates a new `DateTime::Duration` object using the parameters +given, and then calls the `add_duration()` method. - $dt->subtract( DateTime::Duration->new parameters ) +### $dt->add( $duration\_object ) - Like add(), this is syntactic sugar for the subtract_duration() method. +A synonym of `$dt->add_duration( $duration_object )`. - $dt->subtract_datetime( $datetime ) +### $dt->subtract\_duration( $duration\_object ) - This method returns a new DateTime::Duration object representing the - difference between the two dates. The duration is relative to the - object from which $datetime is subtracted. For example: +When given a `DateTime::Duration` object, this method simply calls +`invert()` on that object and passes that new duration to the +`add_duration` method. - 2003-03-15 00:00:00.00000000 - - 2003-02-15 00:00:00.00000000 - ------------------------------- - = 1 month +### $dt->subtract( DateTime::Duration->new parameters ) - Note that this duration is not an absolute measure of the amount of - time between the two datetimes, because the length of a month varies, - as well as due to the presence of leap seconds. +Like `add()`, this is syntactic sugar for the `subtract_duration()` +method. - The returned duration may have deltas for months, days, minutes, - seconds, and nanoseconds. +### $dt->subtract( $duration\_object ) - $dt->delta_md( $datetime ) +A synonym of `$dt->subtract_duration( $duration_object )`. - $dt->delta_days( $datetime ) +### $dt->subtract\_datetime( $datetime ) - Each of these methods returns a new DateTime::Duration object - representing some portion of the difference between two datetimes. The - delta_md() method returns a duration which contains only the month and - day portions of the duration is represented. The delta_days() method - returns a duration which contains only days. +This method returns a new `DateTime::Duration` object representing +the difference between the two dates. The duration is **relative** to +the object from which `$datetime` is subtracted. For example: - The delta_md and delta_days methods truncate the duration so that any - fractional portion of a day is ignored. Both of these methods operate - on the date portion of a datetime only, and so effectively ignore the - time zone. + 2003-03-15 00:00:00.00000000 + - 2003-02-15 00:00:00.00000000 + ------------------------------- + = 1 month - Unlike the subtraction methods, these methods always return a positive - (or zero) duration. +Note that this duration is not an absolute measure of the amount of +time between the two datetimes, because the length of a month varies, +as well as due to the presence of leap seconds. - $dt->delta_ms( $datetime ) +The returned duration may have deltas for months, days, minutes, +seconds, and nanoseconds. - Returns a duration which contains only minutes and seconds. Any day and - month differences to minutes are converted to minutes and seconds. This - method also always return a positive (or zero) duration. +### $dt->delta\_md( $datetime ) - $dt->subtract_datetime_absolute( $datetime ) +### $dt->delta\_days( $datetime ) - This method returns a new DateTime::Duration object representing the - difference between the two dates in seconds and nanoseconds. This is - the only way to accurately measure the absolute amount of time between - two datetimes, since units larger than a second do not represent a - fixed number of seconds. +Each of these methods returns a new `DateTime::Duration` object +representing some portion of the difference between two datetimes. +The `delta_md()` method returns a duration which contains only the +month and day portions of the duration is represented. The +`delta_days()` method returns a duration which contains only days. - Note that because of leap seconds, this may not return the same result - as doing this math based on the value returned by $dt->epoch(). +The `delta_md` and `delta_days` methods truncate the duration so +that any fractional portion of a day is ignored. Both of these +methods operate on the date portion of a datetime only, and so +effectively ignore the time zone. - Class Methods +Unlike the subtraction methods, **these methods always return a +positive (or zero) duration**. - DateTime->DefaultLocale( $locale ) +### $dt->delta\_ms( $datetime ) - This can be used to specify the default locale to be used when creating - DateTime objects. If unset, then "en_US" is used. +Returns a duration which contains only minutes and seconds. Any day +and month differences to minutes are converted to minutes and +seconds. This method also **always return a positive (or zero) +duration**. - DateTime->compare( $dt1, $dt2 ), DateTime->compare_ignore_floating( $dt1, - $dt2 ) +### $dt->subtract\_datetime\_absolute( $datetime ) - $cmp = DateTime->compare( $dt1, $dt2 ); - - $cmp = DateTime->compare_ignore_floating( $dt1, $dt2 ); +This method returns a new `DateTime::Duration` object representing +the difference between the two dates in seconds and nanoseconds. This +is the only way to accurately measure the absolute amount of time +between two datetimes, since units larger than a second do not +represent a fixed number of seconds. - Compare two DateTime objects. The semantics are compatible with Perl's - sort() function; it returns -1 if $dt1 < $dt2, 0 if $dt1 == $dt2, 1 if - $dt1 > $dt2. +Note that because of leap seconds, this may not return the same result as +doing this math based on the value returned by `$dt->epoch()`. - If one of the two DateTime objects has a floating time zone, it will - first be converted to the time zone of the other object. This is what - you want most of the time, but it can lead to inconsistent results when - you compare a number of DateTime objects, some of which are floating, - and some of which are in other time zones. +## Class Methods - If you want to have consistent results (because you want to sort a - number of objects, for example), you can use the - compare_ignore_floating() method: +### DateTime->DefaultLocale( $locale ) - @dates = sort { DateTime->compare_ignore_floating($a, $b) } @dates; +This can be used to specify the default locale to be used when +creating DateTime objects. If unset, then "en-US" is used. - In this case, objects with a floating time zone will be sorted as if - they were UTC times. +### DateTime->compare( $dt1, $dt2 ), DateTime->compare\_ignore\_floating( $dt1, $dt2 ) - Since DateTime objects overload comparison operators, this: + $cmp = DateTime->compare( $dt1, $dt2 ); - @dates = sort @dates; + $cmp = DateTime->compare_ignore_floating( $dt1, $dt2 ); - is equivalent to this: +Compare two DateTime objects. The semantics are compatible with Perl's +`sort()` function; it returns -1 if $dt1 < $dt2, 0 if $dt1 == $dt2, 1 if $dt1 +\> $dt2. - @dates = sort { DateTime->compare($a, $b) } @dates; +If one of the two DateTime objects has a floating time zone, it will +first be converted to the time zone of the other object. This is what +you want most of the time, but it can lead to inconsistent results +when you compare a number of DateTime objects, some of which are +floating, and some of which are in other time zones. - DateTime objects can be compared to any other calendar class that - implements the utc_rd_values() method. +If you want to have consistent results (because you want to sort a +number of objects, for example), you can use the +`compare_ignore_floating()` method: - Testing Code That Uses DateTime + @dates = sort { DateTime->compare_ignore_floating($a, $b) } @dates; - If you are trying to test code that calls uses DateTime, you may want - to be able to explicitly set the value returned by Perl's time() - builtin. This builtin is called by DateTime->now() and - DateTime->today(). +In this case, objects with a floating time zone will be sorted as if +they were UTC times. - You can override CORE::GLOBAL::time(), but this will only work if you - do this before loading DateTime. If doing this is inconvenient, you can - also override DateTime::_core_time(): +Since DateTime objects overload comparison operators, this: - no warnings 'redefine'; - local *DateTime::_core_time = sub { return 42 }; + @dates = sort @dates; - DateTime is guaranteed to call this subroutine to get the current - time() value. You can also override the _core_time() sub in a subclass - of DateTime and use that. +is equivalent to this: - How DateTime Math Works + @dates = sort { DateTime->compare($a, $b) } @dates; - It's important to have some understanding of how datetime math is - implemented in order to effectively use this module and - DateTime::Duration. +DateTime objects can be compared to any other calendar class that +implements the `utc_rd_values()` method. - Making Things Simple +## Testing Code That Uses DateTime - If you want to simplify your life and not have to think too hard about - the nitty-gritty of datetime math, I have several recommendations: +If you are trying to test code that calls uses DateTime, you may want to be +able to explicitly set the value returned by Perl's `time()` builtin. This +builtin is called by `DateTime->now()` and `DateTime->today()`. - * use the floating time zone +You can override `CORE::GLOBAL::time()`, but this will only work if you do +this **before** loading DateTime. If doing this is inconvenient, you can also +override `DateTime::_core_time()`: - If you do not care about time zones or leap seconds, use the - "floating" timezone: + no warnings 'redefine'; + local *DateTime::_core_time = sub { return 42 }; + +DateTime is guaranteed to call this subroutine to get the current `time()` +value. You can also override the `_core_time()` sub in a subclass of DateTime +and use that. + +## How DateTime Math Works + +It's important to have some understanding of how datetime math is +implemented in order to effectively use this module and +`DateTime::Duration`. + +### Making Things Simple + +If you want to simplify your life and not have to think too hard about +the nitty-gritty of datetime math, I have several recommendations: + +- use the floating time zone + + If you do not care about time zones or leap seconds, use the + "floating" timezone: my $dt = DateTime->now( time_zone => 'floating' ); - Math done on two objects in the floating time zone produces very - predictable results. + Math done on two objects in the floating time zone produces very + predictable results. - Note that in most cases you will want to start by creating an object - in a specific zone and then convert it to the floating time zone. - When an object goes from a real zone to the floating zone, the time - for the object remains the same. + Note that in most cases you will want to start by creating an object in a + specific zone and _then_ convert it to the floating time zone. When an object + goes from a real zone to the floating zone, the time for the object remains + the same. - This means that passing the floating zone to a constructor may not do - what you want. + This means that passing the floating zone to a constructor may not do what you + want. my $dt = DateTime->now( time_zone => 'floating' ); - is equivalent to + is equivalent to my $dt = DateTime->now( time_zone => 'UTC' )->set_time_zone('floating'); - This might not be what you wanted. Instead, you may prefer to do - this: + This might not be what you wanted. Instead, you may prefer to do this: my $dt = DateTime->now( time_zone => 'local' )->set_time_zone('floating'); - * use UTC for all calculations +- use UTC for all calculations - If you do care about time zones (particularly DST) or leap seconds, - try to use non-UTC time zones for presentation and user input only. - Convert to UTC immediately and convert back to the local time zone - for presentation: + If you do care about time zones (particularly DST) or leap seconds, + try to use non-UTC time zones for presentation and user input only. + Convert to UTC immediately and convert back to the local time zone for + presentation: my $dt = DateTime->new( %user_input, time_zone => $user_tz ); $dt->set_time_zone('UTC'); - + # do various operations - store it, retrieve it, add, subtract, etc. - + $dt->set_time_zone($user_tz); print $dt->datetime; - * math on non-UTC time zones +- math on non-UTC time zones - If you need to do date math on objects with non-UTC time zones, - please read the caveats below carefully. The results DateTime.pm - produces are predictable and correct, and mostly intuitive, but - datetime math gets very ugly when time zones are involved, and there - are a few strange corner cases involving subtraction of two datetimes - across a DST change. - - If you can always use the floating or UTC time zones, you can skip - ahead to Leap Seconds and Date Math - - * date vs datetime math - - If you only care about the date (calendar) portion of a datetime, you - should use either delta_md() or delta_days(), not - subtract_datetime(). This will give predictable, unsurprising - results, free from DST-related complications. - - * subtract_datetime() and add_duration() - - You must convert your datetime objects to the UTC time zone before - doing date math if you want to make sure that the following formulas - are always true: + If you need to do date math on objects with non-UTC time zones, please + read the caveats below carefully. The results `DateTime.pm` produces are + predictable and correct, and mostly intuitive, but datetime math gets + very ugly when time zones are involved, and there are a few strange + corner cases involving subtraction of two datetimes across a DST + change. + + If you can always use the floating or UTC time zones, you can skip + ahead to [Leap Seconds and Date Math](https://metacpan.org/pod/Leap Seconds and Date Math) + +- date vs datetime math + + If you only care about the date (calendar) portion of a datetime, you + should use either `delta_md()` or `delta_days()`, not + `subtract_datetime()`. This will give predictable, unsurprising + results, free from DST-related complications. + +- subtract\_datetime() and add\_duration() + + You must convert your datetime objects to the UTC time zone before + doing date math if you want to make sure that the following formulas + are always true: $dt2 - $dt1 = $dur $dt1 + $dur = $dt2 $dt2 - $dur = $dt1 - Note that using delta_days ensures that this formula always works, - regardless of the timezone of the objects involved, as does using - subtract_datetime_absolute(). Other methods of subtraction are not - always reversible. + Note that using `delta_days` ensures that this formula always works, + regardless of the timezone of the objects involved, as does using + `subtract_datetime_absolute()`. Other methods of subtraction are not + always reversible. - Adding a Duration to a Datetime +- never do math on two objects where only one is in the floating time zone - The parts of a duration can be broken down into five parts. These are - months, days, minutes, seconds, and nanoseconds. Adding one month to a - date is different than adding 4 weeks or 28, 29, 30, or 31 days. - Similarly, due to DST and leap seconds, adding a day can be different - than adding 86,400 seconds, and adding a minute is not exactly the same - as 60 seconds. + The date math code accounts for leap seconds whenever the `DateTime` object + is not in the floating time zone. If you try to do math where one object is in + the floating zone and the other isn't, the results will be confusing and + wrong. - We cannot convert between these units, except for seconds and - nanoseconds, because there is no fixed conversion between the two - units, because of things like leap seconds, DST changes, etc. +### Adding a Duration to a Datetime - DateTime.pm always adds (or subtracts) days, then months, minutes, and - then seconds and nanoseconds. If there are any boundary overflows, - these are normalized at each step. For the days and months the local - (not UTC) values are used. For minutes and seconds, the local values - are used. This generally just works. +The parts of a duration can be broken down into five parts. These are +months, days, minutes, seconds, and nanoseconds. Adding one month to +a date is different than adding 4 weeks or 28, 29, 30, or 31 days. +Similarly, due to DST and leap seconds, adding a day can be different +than adding 86,400 seconds, and adding a minute is not exactly the +same as 60 seconds. - This means that adding one month and one day to February 28, 2003 will - produce the date April 1, 2003, not March 29, 2003. +We cannot convert between these units, except for seconds and +nanoseconds, because there is no fixed conversion between the two +units, because of things like leap seconds, DST changes, etc. - my $dt = DateTime->new( year => 2003, month => 2, day => 28 ); - - $dt->add( months => 1, days => 1 ); - - # 2003-04-01 - the result +`DateTime.pm` always adds (or subtracts) days, then months, minutes, and then +seconds and nanoseconds. If there are any boundary overflows, these are +normalized at each step. For the days and months the local (not UTC) values +are used. For minutes and seconds, the local values are used. This generally +just works. - On the other hand, if we add months first, and then separately add - days, we end up with March 29, 2003: +This means that adding one month and one day to February 28, 2003 will +produce the date April 1, 2003, not March 29, 2003. - $dt->add( months => 1 )->add( days => 1 ); - - # 2003-03-29 + my $dt = DateTime->new( year => 2003, month => 2, day => 28 ); - We see similar strangeness when math crosses a DST boundary: + $dt->add( months => 1, days => 1 ); - my $dt = DateTime->new( - year => 2003, - month => 4, - day => 5, - hour => 1, - minute => 58, - time_zone => "America/Chicago", - ); - - $dt->add( days => 1, minutes => 3 ); - # 2003-04-06 02:01:00 - - $dt->add( minutes => 3 )->add( days => 1 ); - # 2003-04-06 03:01:00 + # 2003-04-01 - the result - Note that if you converted the datetime object to UTC first you would - get predictable results. +On the other hand, if we add months first, and then separately add +days, we end up with March 29, 2003: - If you want to know how many seconds a duration object represents, you - have to add it to a datetime to find out, so you could do: + $dt->add( months => 1 )->add( days => 1 ); - my $now = DateTime->now( time_zone => 'UTC' ); - my $later = $now->clone->add_duration($duration); - - my $seconds_dur = $later->subtract_datetime_absolute($now); + # 2003-03-29 - This returns a duration which only contains seconds and nanoseconds. +We see similar strangeness when math crosses a DST boundary: - If we were add the duration to a different datetime object we might get - a different number of seconds. + my $dt = DateTime->new( + year => 2003, + month => 4, + day => 5, + hour => 1, + minute => 58, + time_zone => "America/Chicago", + ); - DateTime::Duration supports three different end-of-month algorithms for - adding months. This comes into play when an addition results in a day - past the end of the month (for example, adding one month to January - 30). + $dt->add( days => 1, minutes => 3 ); + # 2003-04-06 02:01:00 - # 2010-08-31 + 1 month = 2010-10-01 - $dt->add( months => 1, end_of_month => 'wrap' ); - - # 2010-01-30 + 1 month = 2010-02-28 - $dt->add( months => 1, end_of_month => 'limit' ); - - # 2010-04-30 + 1 month = 2010-05-31 - $dt->add( months => 1, end_of_month => 'preserve' ); + $dt->add( minutes => 3 )->add( days => 1 ); + # 2003-04-06 03:01:00 - By default, it uses "wrap" for positive durations and "preserve" for - negative durations. See DateTime::Duration for a detailed explanation - of these algorithms. +Note that if you converted the datetime object to UTC first you would +get predictable results. - If you need to do lots of work with durations, take a look at Rick - Measham's DateTime::Format::Duration module, which lets you present - information from durations in many useful ways. +If you want to know how many seconds a duration object represents, you +have to add it to a datetime to find out, so you could do: - There are other subtract/delta methods in DateTime.pm to generate - different types of durations. These methods are subtract_datetime(), - subtract_datetime_absolute(), delta_md(), delta_days(), and delta_ms(). + my $now = DateTime->now( time_zone => 'UTC' ); + my $later = $now->clone->add_duration($duration); - Datetime Subtraction + my $seconds_dur = $later->subtract_datetime_absolute($now); - Date subtraction is done solely based on the two object's local - datetimes, with one exception to handle DST changes. Also, if the two - datetime objects are in different time zones, one of them is converted - to the other's time zone first before subtraction. This is best - explained through examples: +This returns a duration which only contains seconds and nanoseconds. - The first of these probably makes the most sense: +If we were add the duration to a different datetime object we might +get a different number of seconds. - my $dt1 = DateTime->new( - year => 2003, - month => 5, - day => 6, - time_zone => 'America/Chicago', - ); - - # not DST - - my $dt2 = DateTime->new( - year => 2003, - month => 11, - day => 6, - time_zone => 'America/Chicago', - ); - - # is DST - - my $dur = $dt2->subtract_datetime($dt1); - # 6 months +[DateTime::Duration](https://metacpan.org/pod/DateTime::Duration) supports three different end-of-month algorithms for +adding months. This comes into play when an addition results in a day past the +end of the month (for example, adding one month to January 30). - Nice and simple. + # 2010-08-31 + 1 month = 2010-10-01 + $dt->add( months => 1, end_of_month => 'wrap' ); - This one is a little trickier, but still fairly logical: + # 2010-01-30 + 1 month = 2010-02-28 + $dt->add( months => 1, end_of_month => 'limit' ); - my $dt1 = DateTime->new( - year => 2003, - month => 4, - day => 5, - hour => 1, - minute => 58, - time_zone => "America/Chicago", - ); - - # is DST - - my $dt2 = DateTime->new( - year => 2003, - month => 4, - day => 7, - hour => 2, - minute => 1, - time_zone => "America/Chicago", - ); - - # not DST - - my $dur = $dt2->subtract_datetime($dt1); - - # 2 days and 3 minutes + # 2010-04-30 + 1 month = 2010-05-31 + $dt->add( months => 1, end_of_month => 'preserve' ); - Which contradicts the result this one gives, even though they both make - sense: +By default, it uses "wrap" for positive durations and "preserve" for negative +durations. See [DateTime::Duration](https://metacpan.org/pod/DateTime::Duration) for a detailed explanation of these +algorithms. - my $dt1 = DateTime->new( - year => 2003, - month => 4, - day => 5, - hour => 1, - minute => 58, - time_zone => "America/Chicago", - ); - - # is DST - - my $dt2 = DateTime->new( - year => 2003, - month => 4, - day => 6, - hour => 3, - minute => 1, - time_zone => "America/Chicago", - ); - - # not DST - - my $dur = $dt2->subtract_datetime($dt1); - - # 1 day and 3 minutes +If you need to do lots of work with durations, take a look at Rick +Measham's `DateTime::Format::Duration` module, which lets you present +information from durations in many useful ways. - This last example illustrates the "DST" exception mentioned earlier. - The exception accounts for the fact 2003-04-06 only lasts 23 hours. +There are other subtract/delta methods in DateTime.pm to generate +different types of durations. These methods are +`subtract_datetime()`, `subtract_datetime_absolute()`, +`delta_md()`, `delta_days()`, and `delta_ms()`. - And finally: +### Datetime Subtraction - my $dt2 = DateTime->new( - year => 2003, - month => 10, - day => 26, - hour => 1, - time_zone => 'America/Chicago', - ); - - my $dt1 = $dt2->clone->subtract( hours => 1 ); - - my $dur = $dt2->subtract_datetime($dt1); - # 60 minutes +Date subtraction is done solely based on the two object's local +datetimes, with one exception to handle DST changes. Also, if the two +datetime objects are in different time zones, one of them is converted +to the other's time zone first before subtraction. This is best +explained through examples: - This seems obvious until you realize that subtracting 60 minutes from - $dt2 in the above example still leaves the clock time at "01:00:00". - This time we are accounting for a 25 hour day. +The first of these probably makes the most sense: - Reversibility + my $dt1 = DateTime->new( + year => 2003, + month => 5, + day => 6, + time_zone => 'America/Chicago', + ); - Date math operations are not always reversible. This is because of the - way that addition operations are ordered. As was discussed earlier, - adding 1 day and 3 minutes in one call to add() is not the same as - first adding 3 minutes and 1 day in two separate calls. + # not DST - If we take a duration returned from subtract_datetime() and then try to - add or subtract that duration from one of the datetimes we just used, - we sometimes get interesting results: + my $dt2 = DateTime->new( + year => 2003, + month => 11, + day => 6, + time_zone => 'America/Chicago', + ); - my $dt1 = DateTime->new( - year => 2003, - month => 4, - day => 5, - hour => 1, - minute => 58, - time_zone => "America/Chicago", - ); - - my $dt2 = DateTime->new( - year => 2003, - month => 4, - day => 6, - hour => 3, - minute => 1, - time_zone => "America/Chicago", - ); - - my $dur = $dt2->subtract_datetime($dt1); - # 1 day and 3 minutes - - $dt1->add_duration($dur); - # gives us $dt2 - - $dt2->subtract_duration($dur); - # gives us 2003-04-05 02:58:00 - 1 hour later than $dt1 + # is DST - The subtract_duration() operation gives us a (perhaps) unexpected - answer because it first subtracts one day to get 2003-04-05T03:01:00 - and then subtracts 3 minutes to get the final result. + my $dur = $dt2->subtract_datetime($dt1); + # 6 months - If we explicitly reverse the order we can get the original value of - $dt1. This can be facilitated by DateTime::Duration's - calendar_duration() and clock_duration() methods: +Nice and simple. - $dt2->subtract_duration( $dur->clock_duration ) - ->subtract_duration( $dur->calendar_duration ); +This one is a little trickier, but still fairly logical: - Leap Seconds and Date Math + my $dt1 = DateTime->new( + year => 2003, + month => 4, + day => 5, + hour => 1, + minute => 58, + time_zone => "America/Chicago", + ); - The presence of leap seconds can cause even more anomalies in date - math. For example, the following is a legal datetime: + # is DST - my $dt = DateTime->new( - year => 1972, - month => 12, - day => 31, - hour => 23, - minute => 59, - second => 60, - time_zone => 'UTC' - ); + my $dt2 = DateTime->new( + year => 2003, + month => 4, + day => 7, + hour => 2, + minute => 1, + time_zone => "America/Chicago", + ); - If we do the following: + # not DST - $dt->add( months => 1 ); + my $dur = $dt2->subtract_datetime($dt1); - Then the datetime is now "1973-02-01 00:00:00", because there is no - 23:59:60 on 1973-01-31. + # 2 days and 3 minutes - Leap seconds also force us to distinguish between minutes and seconds - during date math. Given the following datetime: +Which contradicts the result this one gives, even though they both +make sense: - my $dt = DateTime->new( - year => 1972, - month => 12, - day => 31, - hour => 23, - minute => 59, - second => 30, - time_zone => 'UTC' - ); + my $dt1 = DateTime->new( + year => 2003, + month => 4, + day => 5, + hour => 1, + minute => 58, + time_zone => "America/Chicago", + ); - we will get different results when adding 1 minute than we get if we - add 60 seconds. This is because in this case, the last minute of the - day, beginning at 23:59:00, actually contains 61 seconds. + # is DST - Here are the results we get: + my $dt2 = DateTime->new( + year => 2003, + month => 4, + day => 6, + hour => 3, + minute => 1, + time_zone => "America/Chicago", + ); - # 1972-12-31 23:59:30 - our starting datetime - - $dt->clone->add( minutes => 1 ); - # 1973-01-01 00:00:30 - one minute later - - $dt->clone->add( seconds => 60 ); - # 1973-01-01 00:00:29 - 60 seconds later - - $dt->clone->add( seconds => 61 ); - # 1973-01-01 00:00:30 - 61 seconds later + # not DST - Local vs. UTC and 24 hours vs. 1 day + my $dur = $dt2->subtract_datetime($dt1); - When math crosses a daylight saving boundary, a single day may have - more or less than 24 hours. + # 1 day and 3 minutes - For example, if you do this: +This last example illustrates the "DST" exception mentioned earlier. +The exception accounts for the fact 2003-04-06 only lasts 23 hours. - my $dt = DateTime->new( - year => 2003, - month => 4, - day => 5, - hour => 2, - time_zone => 'America/Chicago', - ); - - $dt->add( days => 1 ); +And finally: - then you will produce an invalid local time, and therefore an exception - will be thrown. + my $dt2 = DateTime->new( + year => 2003, + month => 10, + day => 26, + hour => 1, + time_zone => 'America/Chicago', + ); - However, this works: + my $dt1 = $dt2->clone->subtract( hours => 1 ); - my $dt = DateTime->new( - year => 2003, - month => 4, - day => 5, - hour => 2, - time_zone => 'America/Chicago', - ); - - $dt->add( hours => 24 ); + my $dur = $dt2->subtract_datetime($dt1); + # 60 minutes - and produces a datetime with the local time of "03:00". +This seems obvious until you realize that subtracting 60 minutes from +`$dt2` in the above example still leaves the clock time at +"01:00:00". This time we are accounting for a 25 hour day. - If all this makes your head hurt, there is a simple alternative. Just - convert your datetime object to the "UTC" time zone before doing date - math on it, and switch it back to the local time zone afterwards. This - avoids the possibility of having date math throw an exception, and - makes sure that 1 day equals 24 hours. Of course, this may not always - be desirable, so caveat user! +### Reversibility - Overloading +Date math operations are not always reversible. This is because of +the way that addition operations are ordered. As was discussed +earlier, adding 1 day and 3 minutes in one call to `add()` is not the +same as first adding 3 minutes and 1 day in two separate calls. - This module explicitly overloads the addition (+), subtraction (-), - string and numeric comparison operators. This means that the following - all do sensible things: +If we take a duration returned from `subtract_datetime()` and then +try to add or subtract that duration from one of the datetimes we just +used, we sometimes get interesting results: - my $new_dt = $dt + $duration_obj; - - my $new_dt = $dt - $duration_obj; - - my $duration_obj = $dt - $new_dt; - - foreach my $dt ( sort @dts ) { ... } + my $dt1 = DateTime->new( + year => 2003, + month => 4, + day => 5, + hour => 1, + minute => 58, + time_zone => "America/Chicago", + ); - Additionally, the fallback parameter is set to true, so other derivable - operators (+=, -=, etc.) will work properly. Do not expect increment - (++) or decrement (--) to do anything useful. + my $dt2 = DateTime->new( + year => 2003, + month => 4, + day => 6, + hour => 3, + minute => 1, + time_zone => "America/Chicago", + ); - The string comparison operators, eq or ne, will use the string value to - compare with non-DateTime objects. + my $dur = $dt2->subtract_datetime($dt1); + # 1 day and 3 minutes - DateTime objects do not have a numeric value, using == or <=> to - compare a DateTime object with a non-DateTime object will result in an - exception. To safely sort mixed DateTime and non-DateTime objects, use - sort { $a cmp $b } @dates. + $dt1->add_duration($dur); + # gives us $dt2 - The module also overloads stringification using the object's formatter, - defaulting to iso8601() method. See "Formatters And Stringification" - for details. + $dt2->subtract_duration($dur); + # gives us 2003-04-05 02:58:00 - 1 hour later than $dt1 - Formatters And Stringification +The `subtract_duration()` operation gives us a (perhaps) unexpected +answer because it first subtracts one day to get 2003-04-05T03:01:00 +and then subtracts 3 minutes to get the final result. - You can optionally specify a "formatter", which is usually a - DateTime::Format::* object/class, to control the stringification of the - DateTime object. +If we explicitly reverse the order we can get the original value of +`$dt1`. This can be facilitated by `DateTime::Duration`'s +`calendar_duration()` and `clock_duration()` methods: - Any of the constructor methods can accept a formatter argument: + $dt2->subtract_duration( $dur->clock_duration ) + ->subtract_duration( $dur->calendar_duration ); - my $formatter = DateTime::Format::Strptime->new(...); - my $dt = DateTime->new(year => 2004, formatter => $formatter); +### Leap Seconds and Date Math - Or, you can set it afterwards: +The presence of leap seconds can cause even more anomalies in date +math. For example, the following is a legal datetime: - $dt->set_formatter($formatter); - $formatter = $dt->formatter(); + my $dt = DateTime->new( + year => 1972, + month => 12, + day => 31, + hour => 23, + minute => 59, + second => 60, + time_zone => 'UTC' + ); - Once you set the formatter, the overloaded stringification method will - use the formatter. If unspecified, the iso8601() method is used. +If we do the following: - A formatter can be handy when you know that in your application you - want to stringify your DateTime objects into a special format all the - time, for example to a different language. + $dt->add( months => 1 ); - If you provide a formatter class name or object, it must implement a - format_datetime method. This method will be called with just the - DateTime object as its argument. +Then the datetime is now "1973-02-01 00:00:00", because there is no +23:59:60 on 1973-01-31. - CLDR Patterns +Leap seconds also force us to distinguish between minutes and seconds +during date math. Given the following datetime: - The CLDR pattern language is both more powerful and more complex than - strftime. Unlike strftime patterns, you often have to explicitly escape - text that you do not want formatted, as the patterns are simply letters - without any prefix. + my $dt = DateTime->new( + year => 1972, + month => 12, + day => 31, + hour => 23, + minute => 59, + second => 30, + time_zone => 'UTC' + ); - For example, "yyyy-MM-dd" is a valid CLDR pattern. If you want to - include any lower or upper case ASCII characters as-is, you can - surround them with single quotes ('). If you want to include a single - quote, you must escape it as two single quotes (''). +we will get different results when adding 1 minute than we get if we +add 60 seconds. This is because in this case, the last minute of the +day, beginning at 23:59:00, actually contains 61 seconds. - 'Today is ' EEEE - 'It is now' h 'o''clock' a +Here are the results we get: - Spaces and any non-letter text will always be passed through as-is. + # 1972-12-31 23:59:30 - our starting datetime - Many CLDR patterns which produce numbers will pad the number with - leading zeroes depending on the length of the format specifier. For - example, "h" represents the current hour from 1-12. If you specify "hh" - then the 1-9 will have a leading zero prepended. + $dt->clone->add( minutes => 1 ); + # 1973-01-01 00:00:30 - one minute later - However, CLDR often uses five of a letter to represent the narrow form - of a pattern. This inconsistency is necessary for backwards - compatibility. + $dt->clone->add( seconds => 60 ); + # 1973-01-01 00:00:29 - 60 seconds later - CLDR often distinguishes between the "format" and "stand-alone" forms - of a pattern. The format pattern is used when the thing in question is - being placed into a larger string. The stand-alone form is used when - displaying that item by itself, for example in a calendar. + $dt->clone->add( seconds => 61 ); + # 1973-01-01 00:00:30 - 61 seconds later - It also often provides three sizes for each item, wide (the full name), - abbreviated, and narrow. The narrow form is often just a single - character, for example "T" for "Tuesday", and may not be unique. +### Local vs. UTC and 24 hours vs. 1 day - CLDR provides a fairly complex system for localizing time zones that we - ignore entirely. The time zone patterns just use the information - provided by DateTime::TimeZone, and do not follow the CLDR spec. +When math crosses a daylight saving boundary, a single day may have +more or less than 24 hours. - The output of a CLDR pattern is always localized, when applicable. +For example, if you do this: - CLDR provides the following patterns: + my $dt = DateTime->new( + year => 2003, + month => 4, + day => 5, + hour => 2, + time_zone => 'America/Chicago', + ); - * G{1,3} + $dt->add( days => 1 ); - The abbreviated era (BC, AD). +then you will produce an _invalid_ local time, and therefore an +exception will be thrown. - * GGGG +However, this works: - The wide era (Before Christ, Anno Domini). + my $dt = DateTime->new( + year => 2003, + month => 4, + day => 5, + hour => 2, + time_zone => 'America/Chicago', + ); - * GGGGG + $dt->add( hours => 24 ); - The narrow era, if it exists (and it mostly doesn't). +and produces a datetime with the local time of "03:00". - * y and y{3,} +If all this makes your head hurt, there is a simple alternative. Just +convert your datetime object to the "UTC" time zone before doing date +math on it, and switch it back to the local time zone afterwards. +This avoids the possibility of having date math throw an exception, +and makes sure that 1 day equals 24 hours. Of course, this may not +always be desirable, so caveat user! - The year, zero-prefixed as needed. Negative years will start with a - "-", and this will be included in the length calculation. +## Overloading - In other, words the "yyyyy" pattern will format year -1234 as - "-1234", not "-01234". +This module explicitly overloads the addition (+), subtraction (-), +string and numeric comparison operators. This means that the +following all do sensible things: - * yy + my $new_dt = $dt + $duration_obj; - This is a special case. It always produces a two-digit year, so - "1976" becomes "76". Negative years will start with a "-", making - them one character longer. + my $new_dt = $dt - $duration_obj; - * Y{1,} + my $duration_obj = $dt - $new_dt; - The year in "week of the year" calendars, from $dt->week_year(). + foreach my $dt ( sort @dts ) { ... } - * u{1,} +Additionally, the fallback parameter is set to true, so other +derivable operators (+=, -=, etc.) will work properly. Do not expect +increment (++) or decrement (--) to do anything useful. - Same as "y" except that "uu" is not a special case. +The string comparison operators, `eq` or `ne`, will use the string +value to compare with non-DateTime objects. - * Q{1,2} +DateTime objects do not have a numeric value, using `==` or `<=>` to compare a DateTime object with a non-DateTime object will result +in an exception. To safely sort mixed DateTime and non-DateTime +objects, use `sort { $a cmp $b } @dates`. - The quarter as a number (1..4). +The module also overloads stringification using the object's +formatter, defaulting to `iso8601()` method. See ["Formatters And +Stringification"](#formatters-and-stringification) for details. - * QQQ +## Formatters And Stringification - The abbreviated format form for the quarter. +You can optionally specify a "formatter", which is usually a +DateTime::Format::\* object/class, to control the stringification of +the DateTime object. - * QQQQ +Any of the constructor methods can accept a formatter argument: - The wide format form for the quarter. + my $formatter = DateTime::Format::Strptime->new(...); + my $dt = DateTime->new(year => 2004, formatter => $formatter); - * q{1,2} +Or, you can set it afterwards: - The quarter as a number (1..4). + $dt->set_formatter($formatter); + $formatter = $dt->formatter(); - * qqq +Once you set the formatter, the overloaded stringification method will +use the formatter. If unspecified, the `iso8601()` method is used. - The abbreviated stand-alone form for the quarter. +A formatter can be handy when you know that in your application you +want to stringify your DateTime objects into a special format all the +time, for example to a different language. - * qqqq +If you provide a formatter class name or object, it must implement a +`format_datetime` method. This method will be called with just the +DateTime object as its argument. - The wide stand-alone form for the quarter. +## CLDR Patterns - * M{1,2] +The CLDR pattern language is both more powerful and more complex than +strftime. Unlike strftime patterns, you often have to explicitly +escape text that you do not want formatted, as the patterns are simply +letters without any prefix. - The numerical month. +For example, "yyyy-MM-dd" is a valid CLDR pattern. If you want to +include any lower or upper case ASCII characters as-is, you can +surround them with single quotes ('). If you want to include a single +quote, you must escape it as two single quotes (''). - * MMM + 'Today is ' EEEE + 'It is now' h 'o''clock' a - The abbreviated format form for the month. +Spaces and any non-letter text will always be passed through as-is. - * MMMM +Many CLDR patterns which produce numbers will pad the number with +leading zeroes depending on the length of the format specifier. For +example, "h" represents the current hour from 1-12. If you specify +"hh" then the 1-9 will have a leading zero prepended. - The wide format form for the month. +However, CLDR often uses five of a letter to represent the narrow form +of a pattern. This inconsistency is necessary for backwards +compatibility. - * MMMMM +CLDR often distinguishes between the "format" and "stand-alone" forms +of a pattern. The format pattern is used when the thing in question is +being placed into a larger string. The stand-alone form is used when +displaying that item by itself, for example in a calendar. - The narrow format form for the month. +It also often provides three sizes for each item, wide (the full +name), abbreviated, and narrow. The narrow form is often just a single +character, for example "T" for "Tuesday", and may not be unique. - * L{1,2] +CLDR provides a fairly complex system for localizing time zones that +we ignore entirely. The time zone patterns just use the information +provided by `DateTime::TimeZone`, and _do not follow the CLDR spec_. - The numerical month. +The output of a CLDR pattern is always localized, when applicable. - * LLL +CLDR provides the following patterns: - The abbreviated stand-alone form for the month. +- G{1,3} - * LLLL + The abbreviated era (BC, AD). - The wide stand-alone form for the month. +- GGGG - * LLLLL + The wide era (Before Christ, Anno Domini). - The narrow stand-alone form for the month. +- GGGGG - * w{1,2} + The narrow era, if it exists (and it mostly doesn't). - The week of the year, from $dt->week_number(). +- y and y{3,} - * W + The year, zero-prefixed as needed. Negative years will start with a "-", + and this will be included in the length calculation. - The week of the month, from $dt->week_of_month(). + In other, words the "yyyyy" pattern will format year -1234 as "-1234", not + "-01234". - * d{1,2} +- yy - The numeric day of the month. + This is a special case. It always produces a two-digit year, so "1976" becomes + "76". Negative years will start with a "-", making them one character longer. - * D{1,3} +- Y{1,} - The numeric day of the year. + The year in "week of the year" calendars, from `$dt->week_year()`. - * F +- u{1,} - The day of the week in the month, from $dt->weekday_of_month(). + Same as "y" except that "uu" is not a special case. - * g{1,} +- Q{1,2} - The modified Julian day, from $dt->mjd(). + The quarter as a number (1..4). - * E{1,3} and eee +- QQQ - The abbreviated format form for the day of the week. + The abbreviated format form for the quarter. - * EEEE and eeee +- QQQQ - The wide format form for the day of the week. + The wide format form for the quarter. - * EEEEE and eeeee +- q{1,2} - The narrow format form for the day of the week. + The quarter as a number (1..4). - * e{1,2} +- qqq - The local numeric day of the week, from 1 to 7. This number depends - on what day is considered the first day of the week, which varies by - locale. For example, in the US, Sunday is the first day of the week, - so this returns 2 for Monday. + The abbreviated stand-alone form for the quarter. - * c +- qqqq - The numeric day of the week from 1 to 7, treating Monday as the first - of the week, regardless of locale. + The wide stand-alone form for the quarter. - * ccc +- M{1,2\] - The abbreviated stand-alone form for the day of the week. + The numerical month. - * cccc +- MMM - The wide stand-alone form for the day of the week. + The abbreviated format form for the month. - * ccccc +- MMMM - The narrow format form for the day of the week. + The wide format form for the month. - * a +- MMMMM - The localized form of AM or PM for the time. + The narrow format form for the month. - * h{1,2} +- L{1,2\] - The hour from 1-12. + The numerical month. - * H{1,2} +- LLL - The hour from 0-23. + The abbreviated stand-alone form for the month. - * K{1,2} +- LLLL - The hour from 0-11. + The wide stand-alone form for the month. - * k{1,2} +- LLLLL - The hour from 1-24. + The narrow stand-alone form for the month. - * j{1,2} +- w{1,2} - The hour, in 12 or 24 hour form, based on the preferred form for the - locale. In other words, this is equivalent to either "h{1,2}" or - "H{1,2}". + The week of the year, from `$dt->week_number()`. - * m{1,2} +- W - The minute. + The week of the month, from `$dt->week_of_month()`. - * s{1,2} +- d{1,2} - The second. + The numeric day of the month. - * S{1,} +- D{1,3} - The fractional portion of the seconds, rounded based on the length of - the specifier. This returned without a leading decimal point, but may - have leading or trailing zeroes. + The numeric day of the year. - * A{1,} +- F - The millisecond of the day, based on the current time. In other - words, if it is 12:00:00.00, this returns 43200000. + The day of the week in the month, from `$dt->weekday_of_month()`. - * z{1,3} +- g{1,} - The time zone short name. + The modified Julian day, from `$dt->mjd()`. - * zzzz +- E{1,3} and eee - The time zone long name. + The abbreviated format form for the day of the week. - * Z{1,3} +- EEEE and eeee - The time zone offset. + The wide format form for the day of the week. - * ZZZZ +- EEEEE and eeeee - The time zone short name and the offset as one string, so something - like "CDT-0500". + The narrow format form for the day of the week. - * ZZZZZ +- e{1,2} - The time zone offset as a sexagesimal number, so something like - "-05:00". (This is useful for W3C format.) + The _local_ numeric day of the week, from 1 to 7. This number depends + on what day is considered the first day of the week, which varies by + locale. For example, in the US, Sunday is the first day of the week, + so this returns 2 for Monday. - * v{1,3} +- c - The time zone short name. + The numeric day of the week from 1 to 7, treating Monday as the first + of the week, regardless of locale. - * vvvv +- ccc - The time zone long name. + The abbreviated stand-alone form for the day of the week. - * V{1,3} +- cccc - The time zone short name. + The wide stand-alone form for the day of the week. - * VVVV +- ccccc - The time zone long name. + The narrow format form for the day of the week. - CLDR "Available Formats" +- a - The CLDR data includes pre-defined formats for various patterns such as - "month and day" or "time of day". Using these formats lets you render - information about a datetime in the most natural way for users from a - given locale. + The localized form of AM or PM for the time. - These formats are indexed by a key that is itself a CLDR pattern. When - you look these up, you get back a different CLDR pattern suitable for - the locale. +- h{1,2} - Let's look at some example We'll use 2008-02-05T18:30:30 as our example - datetime value, and see how this is rendered for the en_US and fr_FR - locales. + The hour from 1-12. - * MMMd +- H{1,2} - The abbreviated month and day as number. For en_US, we get the - pattern MMM d, which renders as Feb 5. For fr_FR, we get the pattern - d MMM, which renders as 5 févr.. + The hour from 0-23. - * yQQQ +- K{1,2} - The year and abbreviated quarter of year. For en_US, we get the - pattern QQQ y, which renders as Q1 2008. For fr_FR, we get the same - pattern, QQQ y, which renders as T1 2008. + The hour from 0-11. - * hm +- k{1,2} - The 12-hour time of day without seconds. For en_US, we get the - pattern h:mm a, which renders as 6:30 PM. For fr_FR, we get the exact - same pattern and rendering. + The hour from 1-24. - The available format for each locale are documented in the POD for that - locale. To get back the format, you use the $locale->format_for method. - For example: +- j{1,2} - say $dt->format_cldr( $dt->locale->format_for('MMMd') ); + The hour, in 12 or 24 hour form, based on the preferred form for the + locale. In other words, this is equivalent to either "h{1,2}" or + "H{1,2}". - strftime Patterns +- m{1,2} - The following patterns are allowed in the format string given to the - $dt->strftime() method: + The minute. - * %a +- s{1,2} - The abbreviated weekday name. + The second. - * %A +- S{1,} - The full weekday name. + The fractional portion of the seconds, rounded based on the length of + the specifier. This returned _without_ a leading decimal point, but + may have leading or trailing zeroes. - * %b +- A{1,} - The abbreviated month name. + The millisecond of the day, based on the current time. In other words, + if it is 12:00:00.00, this returns 43200000. - * %B +- z{1,3} - The full month name. + The time zone short name. - * %c +- zzzz - The default datetime format for the object's locale. + The time zone long name. - * %C +- Z{1,3} - The century number (year/100) as a 2-digit integer. + The time zone offset. - * %d +- ZZZZ - The day of the month as a decimal number (range 01 to 31). + The time zone short name and the offset as one string, so something + like "CDT-0500". - * %D +- ZZZZZ - Equivalent to %m/%d/%y. This is not a good standard format if you - want folks from both the United States and the rest of the world to - understand the date! + The time zone offset as a sexagesimal number, so something like "-05:00". + (This is useful for W3C format.) - * %e +- v{1,3} - Like %d, the day of the month as a decimal number, but a leading zero - is replaced by a space. + The time zone short name. - * %F +- vvvv - Equivalent to %Y-%m-%d (the ISO 8601 date format) + The time zone long name. - * %G +- V{1,3} - The ISO 8601 year with century as a decimal number. The 4-digit year - corresponding to the ISO week number (see %V). This has the same - format and value as %Y, except that if the ISO week number belongs to - the previous or next year, that year is used instead. (TZ) + The time zone short name. - * %g +- VVVV - Like %G, but without century, i.e., with a 2-digit year (00-99). + The time zone long name. - * %h +### CLDR "Available Formats" - Equivalent to %b. +The CLDR data includes pre-defined formats for various patterns such as "month +and day" or "time of day". Using these formats lets you render information +about a datetime in the most natural way for users from a given locale. - * %H +These formats are indexed by a key that is itself a CLDR pattern. When you +look these up, you get back a different CLDR pattern suitable for the locale. - The hour as a decimal number using a 24-hour clock (range 00 to 23). +Let's look at some example We'll use `2008-02-05T18:30:30` as our example +datetime value, and see how this is rendered for the `en-US` and `fr-FR` +locales. - * %I +- `MMMd` - The hour as a decimal number using a 12-hour clock (range 01 to 12). + The abbreviated month and day as number. For `en-US`, we get the pattern + `MMM d`, which renders as `Feb 5`. For `fr-FR`, we get the pattern + `d MMM`, which renders as `5 févr.`. - * %j +- `yQQQ` - The day of the year as a decimal number (range 001 to 366). + The year and abbreviated quarter of year. For `en-US`, we get the pattern + `QQQ y`, which renders as `Q1 2008`. For `fr-FR`, we get the same pattern, + `QQQ y`, which renders as `T1 2008`. - * %k +- `hm` - The hour (24-hour clock) as a decimal number (range 0 to 23); single - digits are preceded by a blank. (See also %H.) + The 12-hour time of day without seconds. For `en-US`, we get the pattern + `h:mm a`, which renders as `6:30 PM`. For `fr-FR`, we get the exact same + pattern and rendering. - * %l +The available formats for each locale are documented in the POD for that +locale. To get back the format, you use the `$locale->format_for` +method. For example: - The hour (12-hour clock) as a decimal number (range 1 to 12); single - digits are preceded by a blank. (See also %I.) + say $dt->format_cldr( $dt->locale->format_for('MMMd') ); - * %m +## strftime Patterns - The month as a decimal number (range 01 to 12). +The following patterns are allowed in the format string given to the +`$dt->strftime()` method: - * %M +- %a - The minute as a decimal number (range 00 to 59). + The abbreviated weekday name. - * %n +- %A - A newline character. + The full weekday name. - * %N +- %b - The fractional seconds digits. Default is 9 digits (nanoseconds). + The abbreviated month name. - %3N milliseconds (3 digits) - %6N microseconds (6 digits) - %9N nanoseconds (9 digits) +- %B + + The full month name. + +- %c + + The default datetime format for the object's locale. + +- %C + + The century number (year/100) as a 2-digit integer. + +- %d + + The day of the month as a decimal number (range 01 to 31). + +- %D + + Equivalent to %m/%d/%y. This is not a good standard format if you + want folks from both the United States and the rest of the world to + understand the date! + +- %e + + Like %d, the day of the month as a decimal number, but a leading zero + is replaced by a space. - This value will always be rounded down to the nearest integer. +- %F - * %p + Equivalent to %Y-%m-%d (the ISO 8601 date format) - Either `AM' or `PM' according to the given time value, or the - corresponding strings for the current locale. Noon is treated as `pm' - and midnight as `am'. +- %G - * %P + The ISO 8601 year with century as a decimal number. The 4-digit year + corresponding to the ISO week number (see %V). This has the same + format and value as %Y, except that if the ISO week number belongs to + the previous or next year, that year is used instead. (TZ) - Like %p but in lowercase: `am' or `pm' or a corresponding string for - the current locale. +- %g - * %r + Like %G, but without century, i.e., with a 2-digit year (00-99). - The time in a.m. or p.m. notation. In the POSIX locale this is - equivalent to `%I:%M:%S %p'. +- %h - * %R + Equivalent to %b. - The time in 24-hour notation (%H:%M). (SU) For a version including - the seconds, see %T below. +- %H - * %s + The hour as a decimal number using a 24-hour clock (range 00 to 23). + +- %I + + The hour as a decimal number using a 12-hour clock (range 01 to 12). + +- %j + + The day of the year as a decimal number (range 001 to 366). + +- %k + + The hour (24-hour clock) as a decimal number (range 0 to 23); single + digits are preceded by a blank. (See also %H.) + +- %l + + The hour (12-hour clock) as a decimal number (range 1 to 12); single + digits are preceded by a blank. (See also %I.) + +- %m + + The month as a decimal number (range 01 to 12). + +- %M + + The minute as a decimal number (range 00 to 59). + +- %n + + A newline character. + +- %N + + The fractional seconds digits. Default is 9 digits (nanoseconds). + + %3N milliseconds (3 digits) + %6N microseconds (6 digits) + %9N nanoseconds (9 digits) + + This value will always be rounded down to the nearest integer. - The number of seconds since the epoch. +- %p - * %S + Either \`AM' or \`PM' according to the given time value, or the + corresponding strings for the current locale. Noon is treated as \`pm' + and midnight as \`am'. - The second as a decimal number (range 00 to 61). +- %P - * %t + Like %p but in lowercase: \`am' or \`pm' or a corresponding string for + the current locale. - A tab character. +- %r - * %T + The time in a.m. or p.m. notation. In the POSIX locale this is + equivalent to \`%I:%M:%S %p'. - The time in 24-hour notation (%H:%M:%S). +- %R - * %u + The time in 24-hour notation (%H:%M). (SU) For a version including the + seconds, see %T below. - The day of the week as a decimal, range 1 to 7, Monday being 1. See - also %w. +- %s - * %U + The number of seconds since the epoch. - The week number of the current year as a decimal number, range 00 to - 53, starting with the first Sunday as the first day of week 01. See - also %V and %W. +- %S - * %V + The second as a decimal number (range 00 to 61). - The ISO 8601:1988 week number of the current year as a decimal - number, range 01 to 53, where week 1 is the first week that has at - least 4 days in the current year, and with Monday as the first day of - the week. See also %U and %W. +- %t - * %w + A tab character. - The day of the week as a decimal, range 0 to 6, Sunday being 0. See - also %u. +- %T - * %W + The time in 24-hour notation (%H:%M:%S). - The week number of the current year as a decimal number, range 00 to - 53, starting with the first Monday as the first day of week 01. +- %u - * %x + The day of the week as a decimal, range 1 to 7, Monday being 1. See + also %w. - The default date format for the object's locale. +- %U - * %X + The week number of the current year as a decimal number, range 00 to + 53, starting with the first Sunday as the first day of week 01. See + also %V and %W. - The default time format for the object's locale. +- %V - * %y + The ISO 8601:1988 week number of the current year as a decimal number, + range 01 to 53, where week 1 is the first week that has at least 4 + days in the current year, and with Monday as the first day of the + week. See also %U and %W. - The year as a decimal number without a century (range 00 to 99). +- %w - * %Y + The day of the week as a decimal, range 0 to 6, Sunday being 0. See + also %u. - The year as a decimal number including the century. +- %W - * %z + The week number of the current year as a decimal number, range 00 to + 53, starting with the first Monday as the first day of week 01. - The time-zone as hour offset from UTC. Required to emit - RFC822-conformant dates (using "%a, %d %b %Y %H:%M:%S %z"). +- %x - * %Z + The default date format for the object's locale. - The time zone or name or abbreviation. +- %X - * %% + The default time format for the object's locale. - A literal `%' character. +- %y - * %{method} + The year as a decimal number without a century (range 00 to 99). - Any method name may be specified using the format %{method} name - where "method" is a valid DateTime.pm object method. +- %Y - DateTime.pm and Storable + The year as a decimal number including the century. - DateTime implements Storable hooks in order to reduce the size of a - serialized DateTime object. +- %z -THE DATETIME PROJECT ECOSYSTEM + The time-zone as hour offset from UTC. Required to emit + RFC822-conformant dates (using "%a, %d %b %Y %H:%M:%S %z"). - This module is part of a larger ecosystem of modules in the DateTime - family. +- %Z - DateTime::Set + The time zone or name or abbreviation. - The DateTime::Set module represents sets (including recurrences) of - datetimes. Many modules return sets or recurrences. +- %% - Format Modules + A literal \`%' character. - The various format modules exist to parse and format datetimes. For - example, DateTime::Format::HTTP parses dates according to the RFC 1123 - format: +- %{method} - my $datetime - = DateTime::Format::HTTP->parse_datetime('Thu Feb 3 17:03:55 GMT 1994'); - - print DateTime::Format::HTTP->format_datetime($datetime); + Any method name may be specified using the format `%{method}` name + where "method" is a valid `DateTime.pm` object method. - Most format modules are suitable for use as a formatter with a DateTime - object. +## DateTime.pm and Storable - All format modules start with DateTime::Format::. +DateTime implements Storable hooks in order to reduce the size of a +serialized DateTime object. - Calendar Modules +# THE DATETIME PROJECT ECOSYSTEM - There are a number of modules on CPAN that implement non-Gregorian - calendars, such as the Chinese, Mayan, and Julian calendars. +This module is part of a larger ecosystem of modules in the DateTime +family. - All calendar modules start with DateTime::Calendar::. +## [DateTime::Set](https://metacpan.org/pod/DateTime::Set) - Event Modules +The [DateTime::Set](https://metacpan.org/pod/DateTime::Set) module represents sets (including recurrences) of +datetimes. Many modules return sets or recurrences. - There are a number of modules that calculate the dates for events, such - as Easter, Sunrise, etc. +## Format Modules - All event modules start with DateTime::Event::. +The various format modules exist to parse and format datetimes. For example, +[DateTime::Format::HTTP](https://metacpan.org/pod/DateTime::Format::HTTP) parses dates according to the RFC 1123 format: - Others + my $datetime + = DateTime::Format::HTTP->parse_datetime('Thu Feb 3 17:03:55 GMT 1994'); - There are many other modules that work with DateTime, including modules - in the DateTimeX namespace, as well as others. + print DateTime::Format::HTTP->format_datetime($datetime); - See the datetime wiki and search.cpan.org - for more - details. +Most format modules are suitable for use as a `formatter` with a DateTime +object. -KNOWN BUGS +All format modules start with `DateTime::Format::`. - The tests in 20infinite.t seem to fail on some machines, particularly - on Win32. This appears to be related to Perl's internal handling of - IEEE infinity and NaN, and seems to be highly platform/compiler/phase - of moon dependent. +## Calendar Modules - If you don't plan to use infinite datetimes you can probably ignore - this. This will be fixed (perhaps) in future versions. +There are a number of modules on CPAN that implement non-Gregorian calendars, +such as the Chinese, Mayan, and Julian calendars. -SUPPORT +All calendar modules start with `DateTime::Calendar::`. - Support for this module is provided via the datetime@perl.org email - list. See http://datetime.perl.org/wiki/datetime/page/Mailing_List for - details. +## Event Modules - Please submit bugs to the CPAN RT system at - http://rt.cpan.org/NoAuth/Bugs.html?Dist=DateTime or via email at - bug-datetime@rt.cpan.org. +There are a number of modules that calculate the dates for events, such as +Easter, Sunrise, etc. -DONATIONS +All event modules start with `DateTime::Event::`. - If you'd like to thank me for the work I've done on this module, please - consider making a "donation" to me via PayPal. I spend a lot of free - time creating free software, and would appreciate any support you'd - care to offer. +## Others - Please note that I am not suggesting that you must do this in order for - me to continue working on this particular software. I will continue to - do so, inasmuch as I have in the past, for as long as it interests me. +There are many other modules that work with DateTime, including modules in the +`DateTimeX` namespace, as well as others. - Similarly, a donation made in this way will probably not make me work - on this software much more, unless I get so many donations that I can - consider working on free software full time, which seems unlikely at - best. +See the [datetime wiki](http://datetime.perl.org) and +[search.cpan.org](http://search.cpan.org/search?query=datetime&mode=dist) for +more details. - To donate, log into PayPal and send money to autarch@urth.org or use - the button on this page: http://www.urth.org/~autarch/fs-donation.html +# KNOWN BUGS -SEE ALSO +The tests in `20infinite.t` seem to fail on some machines, +particularly on Win32. This appears to be related to Perl's internal +handling of IEEE infinity and NaN, and seems to be highly +platform/compiler/phase of moon dependent. - A Date with Perl - - a talk - I've given at a few YAPCs. +If you don't plan to use infinite datetimes you can probably ignore +this. This will be fixed (perhaps) in future versions. - datetime@perl.org mailing list - +# SEE ALSO - http://datetime.perl.org/ +[A Date with +Perl](http://www.houseabsolute.com/presentations/a-date-with-perl/) - a talk +I've given at a few YAPCs. -AUTHOR +[datetime@perl.org mailing list](http://lists.perl.org/list/datetime.html) - Dave Rolsky +[http://datetime.perl.org/](http://datetime.perl.org/) -CONTRIBUTORS +# SUPPORT - * Ben Bennett +Bugs may be submitted at [https://github.com/houseabsolute/DateTime.pm/issues](https://github.com/houseabsolute/DateTime.pm/issues). - * Christian Hansen +There is a mailing list available for users of this distribution, +[mailto:datetime@perl.org](mailto:datetime@perl.org). - * Daisuke Maki +I am also usually active on IRC as 'autarch' on `irc://irc.perl.org`. - * David E. Wheeler +# SOURCE - * Doug Bell +The source code repository for DateTime can be found at [https://github.com/houseabsolute/DateTime.pm](https://github.com/houseabsolute/DateTime.pm). - * Flávio Soibelmann Glock +# DONATIONS - * Gregory Oschwald +If you'd like to thank me for the work I've done on this module, please +consider making a "donation" to me via PayPal. I spend a lot of free time +creating free software, and would appreciate any support you'd care to offer. - * Iain Truskett +Please note that **I am not suggesting that you must do this** in order for me +to continue working on this particular software. I will continue to do so, +inasmuch as I have in the past, for as long as it interests me. - * Jason McIntosh +Similarly, a donation made in this way will probably not make me work on this +software much more, unless I get so many donations that I can consider working +on free software full time (let's all have a chuckle at that together). - * Joshua Hoblitt +To donate, log into PayPal and send money to autarch@urth.org, or use the +button at [http://www.urth.org/~autarch/fs-donation.html](http://www.urth.org/~autarch/fs-donation.html). - * Nick Tonkin <1nickt@users.noreply.github.com> +# AUTHOR - * Ricardo Signes +Dave Rolsky - * Richard Bowen +# CONTRIBUTORS - * Ron Hill +- Ben Bennett +- Christian Hansen +- Daisuke Maki +- Dan Book +- Dan Stewart +- David E. Wheeler +- David Precious +- Doug Bell +- Flávio Soibelmann Glock +- Gianni Ceccarelli +- Gregory Oschwald +- Hauke D +- Iain Truskett <deceased> +- Jason McIntosh +- Joshua Hoblitt +- Karen Etheridge +- Michael Conrad +- Michael R. Davis +- M Somerville +- Nick Tonkin <1nickt@users.noreply.github.com> +- Olaf Alders +- Ovid <curtis\_ovid\_poe@yahoo.com> +- Philippe Bruhat (BooK) +- Ricardo Signes +- Richard Bowen +- Ron Hill +- Sam Kington +- viviparous <viviparous@prc> -COPYRIGHT AND LICENSE +# COPYRIGHT AND LICENSE - This software is Copyright (c) 2015 by Dave Rolsky. +This software is Copyright (c) 2003 - 2018 by Dave Rolsky. - This is free software, licensed under: +This is free software, licensed under: - The Artistic License 2.0 (GPL Compatible) + The Artistic License 2.0 (GPL Compatible) +The full text of the license can be found in the +`LICENSE` file included with this distribution. diff -Nru libdatetime-perl-1.21/t/00-report-prereqs.dd libdatetime-perl-1.46/t/00-report-prereqs.dd --- libdatetime-perl-1.21/t/00-report-prereqs.dd 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/00-report-prereqs.dd 2018-02-11 23:36:51.000000000 +0000 @@ -1,52 +1,72 @@ do { my $x = { - 'build' => { - 'requires' => { - 'Module::Build' => '0.28' - } - }, 'configure' => { 'requires' => { - 'Module::Build' => '0.28' + 'Dist::CheckConflicts' => '0.02', + 'ExtUtils::MakeMaker' => '0' + }, + 'suggests' => { + 'JSON::PP' => '2.27300' } }, 'develop' => { 'requires' => { - 'Code::TidyAll' => '0.24', + 'Code::TidyAll' => '0.56', + 'Code::TidyAll::Plugin::SortLines::Naturally' => '0.000003', + 'Code::TidyAll::Plugin::Test::Vars' => '0.02', + 'Cwd' => '0', + 'Devel::PPPort' => '3.23', 'Module::Implementation' => '0', - 'Perl::Critic' => '1.123', - 'Perl::Tidy' => '20140711', + 'Parallel::ForkManager' => '1.19', + 'Perl::Critic' => '1.126', + 'Perl::Tidy' => '20160302', 'Pod::Coverage::TrustPod' => '0', + 'Pod::Wordlist' => '0', + 'Storable' => '0', 'Test::CPAN::Changes' => '0.19', - 'Test::Code::TidyAll' => '0.24', + 'Test::CPAN::Meta::JSON' => '0.16', + 'Test::CleanNamespaces' => '0.15', + 'Test::Code::TidyAll' => '0.50', + 'Test::DependentModules' => '0', 'Test::EOL' => '0', + 'Test::Fatal' => '0', 'Test::Mojibake' => '0', - 'Test::More' => '0.88', + 'Test::More' => '0.96', 'Test::NoTabs' => '0', 'Test::Pod' => '1.41', 'Test::Pod::Coverage' => '1.08', - 'Test::Pod::LinkCheck' => '0', + 'Test::Portability::Files' => '0', 'Test::Spelling' => '0.12', - 'Test::Version' => '1', - 'autodie' => '0' + 'Test::Vars' => '0.009', + 'Test::Version' => '2.05', + 'Test::Warnings' => '0.005', + 'autodie' => '0', + 'utf8' => '0' } }, 'runtime' => { 'requires' => { 'Carp' => '0', - 'DateTime::Locale' => '0.41', - 'DateTime::TimeZone' => '1.74', + 'DateTime::Locale' => '1.06', + 'DateTime::TimeZone' => '2.02', + 'Dist::CheckConflicts' => '0.02', 'POSIX' => '0', - 'Params::Validate' => '1.03', + 'Params::ValidationCompiler' => '0.26', 'Scalar::Util' => '0', + 'Specio' => '0.18', + 'Specio::Declare' => '0', + 'Specio::Exporter' => '0', + 'Specio::Library::Builtins' => '0', + 'Specio::Library::Numeric' => '0', + 'Specio::Library::String' => '0', 'Try::Tiny' => '0', 'XSLoader' => '0', 'base' => '0', - 'constant' => '0', 'integer' => '0', + 'namespace::autoclean' => '0.19', 'overload' => '0', - 'perl' => '5.008001', + 'parent' => '0', + 'perl' => '5.008004', 'strict' => '0', - 'vars' => '0', 'warnings' => '0', 'warnings::register' => '0' } @@ -56,6 +76,8 @@ 'CPAN::Meta' => '2.120900' }, 'requires' => { + 'CPAN::Meta::Check' => '0.011', + 'CPAN::Meta::Requirements' => '0', 'ExtUtils::MakeMaker' => '0', 'File::Spec' => '0', 'Storable' => '0', diff -Nru libdatetime-perl-1.21/t/00-report-prereqs.t libdatetime-perl-1.46/t/00-report-prereqs.t --- libdatetime-perl-1.21/t/00-report-prereqs.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/00-report-prereqs.t 2018-02-11 23:36:51.000000000 +0000 @@ -3,7 +3,7 @@ use strict; use warnings; -# This test was generated by Dist::Zilla::Plugin::Test::ReportPrereqs 0.021 +# This test was generated by Dist::Zilla::Plugin::Test::ReportPrereqs 0.027 use Test::More tests => 1; @@ -68,7 +68,7 @@ ); # Add static prereqs to the included modules list -my $static_prereqs = do 't/00-report-prereqs.dd'; +my $static_prereqs = do './t/00-report-prereqs.dd'; # Merge all prereqs (either with ::Prereqs or a hashref) my $full_prereqs = _merge_prereqs( @@ -78,12 +78,14 @@ # Add dynamic prereqs to the included modules list (if we can) my ($source) = grep { -f } 'MYMETA.json', 'MYMETA.yml'; -if ( $source && $HAS_CPAN_META ) { - if ( my $meta = eval { CPAN::Meta->load_file($source) } ) { - $full_prereqs = _merge_prereqs($full_prereqs, $meta->prereqs); - } +my $cpan_meta_error; +if ( $source && $HAS_CPAN_META + && (my $meta = eval { CPAN::Meta->load_file($source) } ) +) { + $full_prereqs = _merge_prereqs($full_prereqs, $meta->prereqs); } else { + $cpan_meta_error = $@; # capture error from CPAN::Meta->load_file($source) $source = 'static metadata'; } @@ -169,10 +171,18 @@ diag "\nVersions for all modules listed in $source (including optional ones):\n\n", @full_reports; } +if ( $cpan_meta_error || @dep_errors ) { + diag "\n*** WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING ***\n"; +} + +if ( $cpan_meta_error ) { + my ($orig_source) = grep { -f } 'MYMETA.json', 'MYMETA.yml'; + diag "\nCPAN::Meta->load_file('$orig_source') failed with: $cpan_meta_error\n"; +} + if ( @dep_errors ) { diag join("\n", - "\n*** WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING ***\n", - "The following REQUIRED prerequisites were not satisfied:\n", + "\nThe following REQUIRED prerequisites were not satisfied:\n", @dep_errors, "\n" ); diff -Nru libdatetime-perl-1.21/t/01sanity.t libdatetime-perl-1.46/t/01sanity.t --- libdatetime-perl-1.21/t/01sanity.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/01sanity.t 2018-02-11 23:36:51.000000000 +0000 @@ -7,28 +7,28 @@ { my $dt = DateTime->new( - year => 1870, month => 10, day => 21, - hour => 12, minute => 10, second => 45, + year => 1870, month => 10, day => 21, + hour => 12, minute => 10, second => 45, nanosecond => 123456, time_zone => 'UTC' ); - is( $dt->year, '1870', "Year accessor, outside of the epoch" ); - is( $dt->month, '10', "Month accessor, outside the epoch" ); - is( $dt->day, '21', "Day accessor, outside the epoch" ); - is( $dt->hour, '12', "Hour accessor, outside the epoch" ); - is( $dt->minute, '10', "Minute accessor, outside the epoch" ); - is( $dt->second, '45', "Second accessor, outside the epoch" ); - is( $dt->nanosecond, '123456', "nanosecond accessor, outside the epoch" ); + is( $dt->year, '1870', 'Year accessor, outside of the epoch' ); + is( $dt->month, '10', 'Month accessor, outside the epoch' ); + is( $dt->day, '21', 'Day accessor, outside the epoch' ); + is( $dt->hour, '12', 'Hour accessor, outside the epoch' ); + is( $dt->minute, '10', 'Minute accessor, outside the epoch' ); + is( $dt->second, '45', 'Second accessor, outside the epoch' ); + is( $dt->nanosecond, '123456', 'nanosecond accessor, outside the epoch' ); $dt = DateTime->from_object( object => $dt ); - is( $dt->year, '1870', "Year should be identical" ); - is( $dt->month, '10', "Month should be identical" ); - is( $dt->day, '21', "Day should be identical" ); - is( $dt->hour, '12', "Hour should be identical" ); - is( $dt->minute, '10', "Minute should be identical" ); - is( $dt->second, '45', "Second should be identical" ); - is( $dt->nanosecond, '123456', "nanosecond should be identical" ); + is( $dt->year, '1870', 'Year should be identical' ); + is( $dt->month, '10', 'Month should be identical' ); + is( $dt->day, '21', 'Day should be identical' ); + is( $dt->hour, '12', 'Hour should be identical' ); + is( $dt->minute, '10', 'Minute should be identical' ); + is( $dt->second, '45', 'Second should be identical' ); + is( $dt->nanosecond, '123456', 'nanosecond should be identical' ); } { @@ -37,8 +37,8 @@ hour => 12, minute => 10, second => 45, time_zone => 'UTC' ); - is( $dt->minute, '10', "Minute accessor, outside the epoch" ); - is( $dt->second, '45', "Second accessor, outside the epoch" ); + is( $dt->minute, '10', 'Minute accessor, outside the epoch' ); + is( $dt->second, '45', 'Second accessor, outside the epoch' ); } done_testing(); diff -Nru libdatetime-perl-1.21/t/02last-day.t libdatetime-perl-1.46/t/02last-day.t --- libdatetime-perl-1.21/t/02last-day.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/02last-day.t 2018-02-11 23:36:51.000000000 +0000 @@ -1,13 +1,14 @@ use strict; use warnings; +use Test::Fatal; use Test::More; use DateTime; -my @last = ( 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ); -my @leap_last = @last; -$leap_last[1]++; +my @last_day = ( 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ); +my @leap_last_day = @last_day; +$leap_last_day[1]++; foreach my $month ( 1 .. 12 ) { my $dt = DateTime->last_day_of_month( @@ -16,9 +17,9 @@ time_zone => 'UTC', ); - is( $dt->year, 2001, 'check year' ); - is( $dt->month, $month, 'check month' ); - is( $dt->day, $last[ $month - 1 ], 'check day' ); + is( $dt->year, 2001, 'check year' ); + is( $dt->month, $month, 'check month' ); + is( $dt->day, $last_day[ $month - 1 ], 'check day' ); } foreach my $month ( 1 .. 12 ) { @@ -28,21 +29,21 @@ time_zone => 'UTC', ); - is( $dt->year, 2004, 'check year' ); - is( $dt->month, $month, 'check month' ); - is( $dt->day, $leap_last[ $month - 1 ], 'check day' ); + is( $dt->year, 2004, 'check year' ); + is( $dt->month, $month, 'check month' ); + is( $dt->day, $leap_last_day[ $month - 1 ], 'check day' ); } { - eval { - DateTime->last_day_of_month( - year => 2000, month => 1, - nanosecond => 2000 - ); - }; is( - $@, '', - "last_day_of_month should accept nanosecond" + exception { + DateTime->last_day_of_month( + year => 2000, month => 1, + nanosecond => 2000 + ); + }, + undef, + 'last_day_of_month should accept nanosecond' ); } diff -Nru libdatetime-perl-1.21/t/03components.t libdatetime-perl-1.46/t/03components.t --- libdatetime-perl-1.21/t/03components.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/03components.t 2018-02-11 23:36:51.000000000 +0000 @@ -4,116 +4,167 @@ use Test::More; use DateTime; +{ + my $d = DateTime->new( + year => 2001, + month => 7, + day => 5, + hour => 2, + minute => 12, + second => 50, + time_zone => 'UTC', + ); + + is( $d->year, 2001, '->year' ); + is( $d->ce_year, 2001, '->ce_year' ); + is( $d->month, 7, '->month' ); + is( $d->quarter, 3, '->quarter' ); + is( $d->month_0, 6, '->month_0' ); + is( $d->month_name, 'July', '->month_name' ); + is( $d->month_abbr, 'Jul', '->month_abbr' ); + is( $d->day_of_month, 5, '->day_of_month' ); + is( $d->day_of_month_0, 4, '->day_of_month_0' ); + is( $d->day, 5, '->day' ); + is( $d->day_0, 4, '->day_0' ); + is( $d->mday, 5, '->mday' ); + is( $d->mday_0, 4, '->mday_0' ); + is( $d->mday, 5, '->mday' ); + is( $d->mday_0, 4, '->mday_0' ); + is( $d->hour, 2, '->hour' ); + is( $d->hour_1, 2, '->hour_1' ); + is( $d->hour_12, 2, '->hour_12' ); + is( $d->hour_12_0, 2, '->hour_12_0' ); + is( $d->minute, 12, '->minute' ); + is( $d->min, 12, '->min' ); + is( $d->second, 50, '->second' ); + is( $d->sec, 50, '->sec' ); + + is( $d->day_of_year, 186, '->day_of_year' ); + is( $d->day_of_year_0, 185, '->day_of_year' ); + is( $d->day_of_quarter, 5, '->day_of_quarter' ); + is( $d->doq, 5, '->doq' ); + is( $d->day_of_quarter_0, 4, '->day_of_quarter_0' ); + is( $d->doq_0, 4, '->doq_0' ); + is( $d->day_of_week, 4, '->day_of_week' ); + is( $d->day_of_week_0, 3, '->day_of_week_0' ); + is( $d->week_of_month, 1, '->week_of_month' ); + is( $d->weekday_of_month, 1, '->weekday_of_month' ); + is( $d->wday, 4, '->wday' ); + is( $d->wday_0, 3, '->wday_0' ); + is( $d->dow, 4, '->dow' ); + is( $d->dow_0, 3, '->dow_0' ); + is( $d->day_name, 'Thursday', '->day_name' ); + is( $d->day_abbr, 'Thu', '->day_abrr' ); + + is( $d->ymd, '2001-07-05', '->ymd' ); + is( $d->ymd('!'), '2001!07!05', q{->ymd('!')} ); + is( $d->date, '2001-07-05', '->date' ); + is( $d->date('!'), '2001!07!05', q{->date('!')} ); + + is( $d->mdy, '07-05-2001', '->mdy' ); + is( $d->mdy('!'), '07!05!2001', q{->mdy('!')} ); + + is( $d->dmy, '05-07-2001', '->dmy' ); + is( $d->dmy('!'), '05!07!2001', q{->dmy('!')} ); + + is( $d->hms, '02:12:50', '->hms' ); + is( $d->hms('!'), '02!12!50', q{->hms('!')} ); + is( $d->time, '02:12:50', '->hms' ); + is( $d->time('!'), '02!12!50', q{->time('!')} ); + + is( $d->datetime, '2001-07-05T02:12:50', '->datetime' ); + is( $d->datetime(q{ }), '2001-07-05 02:12:50', q{->datetime(q{ }} ); + is( $d->iso8601, '2001-07-05T02:12:50', '->iso8601' ); + is( + $d->iso8601(q{ }), '2001-07-05T02:12:50', + '->iso8601 ignores arguments' + ); + + ok( !$d->is_leap_year, '->is_leap_year' ); + ok( !$d->is_last_day_of_month, '->is_last_day_of_month' ); + + is( $d->month_length, 31, '->month_length' ); + is( $d->quarter_length, 92, '->quarter_length' ); + is( $d->year_length, 365, '->year_length' ); + + is( $d->era_abbr, 'AD', '->era_abbr' ); + is( $d->era, $d->era_abbr, '->era (deprecated)' ); + is( $d->era_name, 'Anno Domini', '->era_abbr' ); + + is( $d->quarter_abbr, 'Q3', '->quarter_abbr' ); + is( $d->quarter_name, '3rd quarter', '->quarter_name' ); +} + +{ + my $leap_d = DateTime->new( + year => 2004, + month => 7, + day => 5, + hour => 2, + minute => 12, + second => 50, + time_zone => 'UTC', + ); -my $d = DateTime->new( - year => 2001, - month => 7, - day => 5, - hour => 2, - minute => 12, - second => 50, - time_zone => 'UTC', -); - -is( $d->year, 2001, '->year' ); -is( $d->ce_year, 2001, '->ce_year' ); -is( $d->month, 7, '->month' ); -is( $d->quarter, 3, '->quarter' ); -is( $d->month_0, 6, '->month_0' ); -is( $d->month_name, 'July', '->month_name' ); -is( $d->month_abbr, 'Jul', '->month_abbr' ); -is( $d->day_of_month, 5, '->day_of_month' ); -is( $d->day_of_month_0, 4, '->day_of_month_0' ); -is( $d->day, 5, '->day' ); -is( $d->day_0, 4, '->day_0' ); -is( $d->mday, 5, '->mday' ); -is( $d->mday_0, 4, '->mday_0' ); -is( $d->mday, 5, '->mday' ); -is( $d->mday_0, 4, '->mday_0' ); -is( $d->hour, 2, '->hour' ); -is( $d->hour_1, 2, '->hour_1' ); -is( $d->hour_12, 2, '->hour_12' ); -is( $d->hour_12_0, 2, '->hour_12_0' ); -is( $d->minute, 12, '->minute' ); -is( $d->min, 12, '->min' ); -is( $d->second, 50, '->second' ); -is( $d->sec, 50, '->sec' ); - -is( $d->day_of_year, 186, '->day_of_year' ); -is( $d->day_of_year_0, 185, '->day_of_year' ); -is( $d->day_of_quarter, 5, '->day_of_quarter' ); -is( $d->doq, 5, '->doq' ); -is( $d->day_of_quarter_0, 4, '->day_of_quarter_0' ); -is( $d->doq_0, 4, '->doq_0' ); -is( $d->day_of_week, 4, '->day_of_week' ); -is( $d->day_of_week_0, 3, '->day_of_week_0' ); -is( $d->week_of_month, 1, '->week_of_month' ); -is( $d->weekday_of_month, 1, '->weekday_of_month' ); -is( $d->wday, 4, '->wday' ); -is( $d->wday_0, 3, '->wday_0' ); -is( $d->dow, 4, '->dow' ); -is( $d->dow_0, 3, '->dow_0' ); -is( $d->day_name, 'Thursday', '->day_name' ); -is( $d->day_abbr, 'Thu', '->day_abrr' ); - -is( $d->ymd, '2001-07-05', '->ymd' ); -is( $d->ymd('!'), '2001!07!05', "->ymd('!')" ); -is( $d->date, '2001-07-05', '->ymd' ); - -is( $d->mdy, '07-05-2001', '->mdy' ); -is( $d->mdy('!'), '07!05!2001', "->mdy('!')" ); - -is( $d->dmy, '05-07-2001', '->dmy' ); -is( $d->dmy('!'), '05!07!2001', "->dmy('!')" ); - -is( $d->hms, '02:12:50', '->hms' ); -is( $d->hms('!'), '02!12!50', "->hms('!')" ); -is( $d->time, '02:12:50', '->hms' ); - -is( $d->datetime, '2001-07-05T02:12:50', '->datetime' ); -is( $d->iso8601, '2001-07-05T02:12:50', '->iso8601' ); - -is( $d->is_leap_year, 0, '->is_leap_year' ); - -is( $d->era_abbr, 'AD', '->era_abbr' ); -is( $d->era, $d->era_abbr, '->era (deprecated)' ); -is( $d->era_name, 'Anno Domini', '->era_abbr' ); - -is( $d->quarter_abbr, 'Q3', '->quarter_abbr' ); -is( $d->quarter_name, '3rd quarter', '->quarter_name' ); - -my $leap_d = DateTime->new( - year => 2004, - month => 7, - day => 5, - hour => 2, - minute => 12, - second => 50, - time_zone => 'UTC', -); - -is( $leap_d->is_leap_year, 1, '->is_leap_year' ); - -my $sunday = DateTime->new( - year => 2003, - month => 1, - day => 26, - time_zone => 'UTC', -); - -is( $sunday->day_of_week, 7, "Sunday is day 7" ); - -my $monday = DateTime->new( - year => 2003, - month => 1, - day => 27, - time_zone => 'UTC', -); + ok( $leap_d->is_leap_year, '->is_leap_year' ); + is( $leap_d->year_length, 366, '->year_length' ); +} -is( $monday->day_of_week, 1, "Monday is day 1" ); +{ + my @tests = ( + { year => 2017, month => 8, day => 19, expect => 0 }, + { year => 2017, month => 8, day => 31, expect => 1 }, + { year => 2017, month => 2, day => 28, expect => 1 }, + { year => 2016, month => 2, day => 28, expect => 0 }, + ); + + for my $t (@tests) { + my $expect = delete $t->{expect}; + + my $dt = DateTime->new($t); + + my $is = $dt->is_last_day_of_month; + ok( ( $expect ? $is : !$is ), '->is_last_day_of_month' ); + } +} { + my @tests = ( + { year => 2016, month => 2, day => 1, expect => 29 }, + { year => 2017, month => 2, day => 1, expect => 28 }, + ); + + for my $t (@tests) { + my $expect = delete $t->{expect}; + + my $dt = DateTime->new($t); + is( $dt->month_length, $expect, '->month_length' ); + } +} +{ + my $sunday = DateTime->new( + year => 2003, + month => 1, + day => 26, + time_zone => 'UTC', + ); + + is( $sunday->day_of_week, 7, 'Sunday is day 7' ); +} + +{ + my $monday = DateTime->new( + year => 2003, + month => 1, + day => 27, + time_zone => 'UTC', + ); + + is( $monday->day_of_week, 1, 'Monday is day 1' ); +} + +{ # time zone offset should not affect the values returned my $d = DateTime->new( year => 2001, @@ -138,8 +189,8 @@ { my $dt0 = DateTime->new( year => 1, time_zone => 'UTC' ); - is( $dt0->year, 1, "year 1 is year 1" ); - is( $dt0->ce_year, 1, "ce_year 1 is year 1" ); + is( $dt0->year, 1, 'year 1 is year 1' ); + is( $dt0->ce_year, 1, 'ce_year 1 is year 1' ); is( $dt0->era_abbr, 'AD', 'era is AD' ); is( $dt0->year_with_era, '1AD', 'year_with_era is 1AD' ); is( $dt0->christian_era, 'AD', 'christian_era is AD' ); @@ -152,8 +203,8 @@ $dt0->subtract( years => 1 ); - is( $dt0->year, 0, "year 1 minus 1 is year 0" ); - is( $dt0->ce_year, -1, "ce_year 1 minus 1 is year -1" ); + is( $dt0->year, 0, 'year 1 minus 1 is year 0' ); + is( $dt0->ce_year, -1, 'ce_year 1 minus 1 is year -1' ); is( $dt0->era_abbr, 'BC', 'era is BC' ); is( $dt0->year_with_era, '1BC', 'year_with_era is 1BC' ); is( $dt0->christian_era, 'BC', 'christian_era is BC' ); @@ -170,14 +221,14 @@ { my $dt_neg = DateTime->new( year => -10, time_zone => 'UTC', ); - is( $dt_neg->year, -10, "Year -10 is -10" ); - is( $dt_neg->ce_year, -11, "year -10 is ce_year -11" ); + is( $dt_neg->year, -10, 'Year -10 is -10' ); + is( $dt_neg->ce_year, -11, 'year -10 is ce_year -11' ); my $dt1 = $dt_neg + DateTime::Duration->new( years => 10 ); - is( $dt1->year, 0, "year is 0 after adding ten years to year -10" ); + is( $dt1->year, 0, 'year is 0 after adding ten years to year -10' ); is( $dt1->ce_year, -1, - "ce_year is -1 after adding ten years to year -10" + 'ce_year is -1 after adding ten years to year -10' ); } @@ -198,7 +249,7 @@ # test doy in leap year { my $dt = DateTime->new( - year => 2000, month => 1, day => 5, + year => 2000, month => 1, day => 5, time_zone => 'UTC', ); @@ -208,7 +259,7 @@ { my $dt = DateTime->new( - year => 2000, month => 2, day => 29, + year => 2000, month => 2, day => 29, time_zone => 'UTC', ); @@ -218,7 +269,7 @@ { my $dt = DateTime->new( - year => -6, month => 2, day => 25, + year => -6, month => 2, day => 25, time_zone => 'UTC', ); @@ -232,10 +283,43 @@ } { + my $dt = DateTime->new( year => 1995, month => 2, day => 1 ); + + is( $dt->quarter, 1, '->quarter is 1' ); + is( $dt->day_of_quarter, 32, '->day_of_quarter' ); + is( $dt->quarter_length, 90, '->quarter_length' ); +} + +{ + my $dt = DateTime->new( year => 1995, month => 5, day => 1 ); + + is( $dt->quarter, 2, '->quarter is 2' ); + is( $dt->day_of_quarter, 31, '->day_of_quarter' ); + is( $dt->quarter_length, 91, '->quarter_length' ); +} + +{ + my $dt = DateTime->new( year => 1995, month => 8, day => 1 ); + + is( $dt->quarter, 3, '->quarter is 3' ); + is( $dt->day_of_quarter, 32, '->day_of_quarter' ); + is( $dt->quarter_length, 92, '->quarter_length' ); +} + +{ + my $dt = DateTime->new( year => 1995, month => 11, day => 1 ); + + is( $dt->quarter, 4, '->quarter is 4' ); + is( $dt->day_of_quarter, 32, '->day_of_quarter' ); + is( $dt->quarter_length, 92, '->quarter_length' ); +} + +{ my $dt = DateTime->new( year => 1996, month => 2, day => 1 ); is( $dt->quarter, 1, '->quarter is 1' ); is( $dt->day_of_quarter, 32, '->day_of_quarter' ); + is( $dt->quarter_length, 91, '->quarter_length' ); } { @@ -243,6 +327,7 @@ is( $dt->quarter, 2, '->quarter is 2' ); is( $dt->day_of_quarter, 31, '->day_of_quarter' ); + is( $dt->quarter_length, 91, '->quarter_length' ); } { @@ -250,6 +335,7 @@ is( $dt->quarter, 3, '->quarter is 3' ); is( $dt->day_of_quarter, 32, '->day_of_quarter' ); + is( $dt->quarter_length, 92, '->quarter_length' ); } { @@ -257,6 +343,7 @@ is( $dt->quarter, 4, '->quarter is 4' ); is( $dt->day_of_quarter, 32, '->day_of_quarter' ); + is( $dt->quarter_length, 92, '->quarter_length' ); } # nano, micro, and milli seconds @@ -322,8 +409,9 @@ SKIP: { + ## no critic (BuiltinFunctions::ProhibitStringyEval) skip 'These tests require Test::Warn', 9 - unless eval "use Test::Warn; 1"; + unless eval 'use Test::Warn; 1'; my $dt = DateTime->new( year => 2000 ); warnings_like( diff -Nru libdatetime-perl-1.21/t/04epoch.t libdatetime-perl-1.46/t/04epoch.t --- libdatetime-perl-1.21/t/04epoch.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/04epoch.t 2018-02-11 23:36:51.000000000 +0000 @@ -2,6 +2,7 @@ use warnings; use Test::More; +use Test::Fatal; use DateTime; @@ -9,14 +10,14 @@ # Tests creating objects from epoch time my $t1 = DateTime->from_epoch( epoch => 0 ); - is( $t1->epoch, 0, "epoch should be 0" ); + is( $t1->epoch, 0, 'epoch should be 0' ); - is( $t1->second, 0, "seconds are correct on epoch 0" ); - is( $t1->minute, 0, "minutes are correct on epoch 0" ); - is( $t1->hour, 0, "hours are correct on epoch 0" ); - is( $t1->day, 1, "days are correct on epoch 0" ); - is( $t1->month, 1, "months are correct on epoch 0" ); - is( $t1->year, 1970, "year is correct on epoch 0" ); + is( $t1->second, 0, 'seconds are correct on epoch 0' ); + is( $t1->minute, 0, 'minutes are correct on epoch 0' ); + is( $t1->hour, 0, 'hours are correct on epoch 0' ); + is( $t1->day, 1, 'days are correct on epoch 0' ); + is( $t1->month, 1, 'months are correct on epoch 0' ); + is( $t1->year, 1970, 'year is correct on epoch 0' ); } { @@ -33,9 +34,9 @@ my $now = time; my $nowtest = DateTime->now(); my $nowtest2 = DateTime->from_epoch( epoch => $now ); - is( $nowtest->hour, $nowtest2->hour, "Hour: Create without args" ); - is( $nowtest->month, $nowtest2->month, "Month : Create without args" ); - is( $nowtest->minute, $nowtest2->minute, "Minute: Create without args" ); + is( $nowtest->hour, $nowtest2->hour, 'Hour: Create without args' ); + is( $nowtest->month, $nowtest2->month, 'Month : Create without args' ); + is( $nowtest->minute, $nowtest2->minute, 'Minute: Create without args' ); } { @@ -43,10 +44,10 @@ is( $epochtest->epoch, 997121000, - "epoch method returns correct value" + 'epoch method returns correct value' ); - is( $epochtest->hour, 18, "hour" ); - is( $epochtest->min, 3, "minute" ); + is( $epochtest->hour, 18, 'hour' ); + is( $epochtest->min, 3, 'minute' ); } { @@ -90,13 +91,13 @@ $epochtest->epoch, $expected, "epoch method returns correct value ($expected)" ); - is( $epochtest->hour, 1, "hour" ); - is( $epochtest->min, 30, "minute" ); + is( $epochtest->hour, 1, 'hour' ); + is( $epochtest->min, 30, 'minute' ); $epochtest->add( hours => 2 ); $expected += 2 * 60 * 60; - is( $epochtest->hour, 3, "adjusted hour" ); + is( $epochtest->hour, 3, 'adjusted hour' ); is( $epochtest->epoch, $expected, "epoch method returns correct adjusted value ($expected)" @@ -116,14 +117,46 @@ } { + my $dt = DateTime->from_epoch( epoch => -0.5 ); + is( + $dt->nanosecond, 500_000_000, + 'nanosecond should be 500,000,000 with -0.5 as epoch' + ); + + is( $dt->epoch, -1, 'epoch should be -1' ); + is( $dt->hires_epoch, -0.5, 'hires_epoch should be -0.5' ); +} + +{ + my $dt = DateTime->from_epoch( epoch => 1609459199.999999 ); + is( + $dt->nanosecond, 999999000, + 'nanosecond should be 999,999,000 with 1609459199.999999 as epoch' + ); + + is( $dt->epoch, 1609459199, 'epoch should be 1609459199' ); +} + +{ my $dt = DateTime->from_epoch( epoch => 0.1234567891 ); - is( $dt->nanosecond, 123_456_789, 'nanosecond should be an integer ' ); + is( + $dt->nanosecond, 123_457_000, + 'nanosecond should be rounded to 123,457,000 when given 0.1234567891' + ); +} + +{ + my $dt = DateTime->from_epoch( epoch => -0.1234567891 ); + is( + $dt->nanosecond, 876_543_000, + 'nanosecond should be rounded to 876,543,000 when given -0.1234567891' + ); } { is( DateTime->new( year => 1904 )->epoch, -2082844800, - "epoch should work back to at least 1904" + 'epoch should work back to at least 1904' ); my $dt = DateTime->from_epoch( epoch => -2082844800 ); @@ -138,7 +171,7 @@ [ 99 => -59042995200 ], [ 100 => -59011459200 ], [ 999 => -30641760000 ], - ) { + ) { my ( $year, $epoch ) = @{$pair}; @@ -153,7 +186,7 @@ package Number::Overloaded; use overload - "0+" => sub { $_[0]->{num} }, + '0+' => sub { $_[0]->{num} }, fallback => 1; sub new { bless { num => $_[1] }, $_[0] } @@ -185,10 +218,9 @@ ); for my $test (@tests) { - eval { DateTime->from_epoch( epoch => $test ); }; - like( - $@, qr/did not pass regex check/, + exception { DateTime->from_epoch( epoch => $test ) }, + qr/Validation failed for type named Num/, qq{'$test' is not a valid epoch value} ); } diff -Nru libdatetime-perl-1.21/t/05set.t libdatetime-perl-1.46/t/05set.t --- libdatetime-perl-1.21/t/05set.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/05set.t 2018-02-11 23:36:51.000000000 +0000 @@ -7,8 +7,8 @@ { my $dt = DateTime->new( - year => 1996, month => 11, day => 22, - hour => 18, minute => 30, second => 20, + year => 1996, month => 11, day => 22, + hour => 18, minute => 30, second => 20, time_zone => 'UTC', ); @@ -57,8 +57,8 @@ { my $dt = DateTime->new( - year => 1996, month => 11, day => 22, - hour => 18, minute => 30, second => 20, + year => 1996, month => 11, day => 22, + hour => 18, minute => 30, second => 20, time_zone => 'UTC', ); diff -Nru libdatetime-perl-1.21/t/06add.t libdatetime-perl-1.46/t/06add.t --- libdatetime-perl-1.21/t/06add.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/06add.t 2018-02-11 23:36:51.000000000 +0000 @@ -6,357 +6,436 @@ use DateTime; -my $dt = DateTime->new( - year => 1996, month => 11, day => 22, - hour => 18, minute => 30, second => 20, - time_zone => 'UTC', -); -$dt->add( weeks => 8 ); - -is( $dt->year, 1997, "year rollover" ); -is( $dt->month, 1, "month set on year rollover" ); -is( $dt->datetime, '1997-01-17T18:30:20', 'okay on year rollover' ); - -$dt->add( weeks => 2 ); -is( $dt->datetime, '1997-01-31T18:30:20', 'Adding weeks' ); - -$dt->add( seconds => 15 ); -is( $dt->datetime, '1997-01-31T18:30:35', 'Adding seconds' ); - -$dt->add( minutes => 12 ); -is( $dt->datetime, '1997-01-31T18:42:35', 'Adding minutes' ); - -$dt->add( minutes => 25, hours => 3, seconds => 7 ); -is( $dt->datetime, '1997-01-31T22:07:42', 'Adding h,m,s' ); - -# Now, test the adding of durations -$dt = DateTime->new( - year => 1986, month => 1, day => 28, - hour => 16, minute => 38, - time_zone => 'UTC' -); - -$dt->add( minutes => 1, seconds => 12 ); -is( - $dt->datetime, '1986-01-28T16:39:12', - "Adding durations with minutes and seconds works" -); - -$dt = DateTime->new( - year => 1986, month => 1, day => 28, - hour => 16, minute => 38, - time_zone => 'UTC' -); - -$dt->add( seconds => 30 ); -is( - $dt->datetime, '1986-01-28T16:38:30', - "Adding durations with seconds only works" -); - -$dt = DateTime->new( - year => 1986, month => 1, day => 28, - hour => 16, minute => 38, - time_zone => 'UTC' -); - -$dt->add( hours => 1, minutes => 10 ); -is( - $dt->datetime, '1986-01-28T17:48:00', - "Adding durations with hours and minutes works" -); - -$dt = DateTime->new( - year => 1986, month => 1, day => 28, - hour => 16, minute => 38, - time_zone => 'UTC' -); - -$dt->add( days => 3 ); -is( - $dt->datetime, '1986-01-31T16:38:00', - "Adding durations with days only works" -); - -$dt = DateTime->new( - year => 1986, month => 1, day => 28, - hour => 16, minute => 38, - time_zone => 'UTC' -); - -$dt->add( days => 3, hours => 2 ); -is( - $dt->datetime, '1986-01-31T18:38:00', - "Adding durations with days and hours works" -); - -$dt = DateTime->new( - year => 1986, month => 1, day => 28, - hour => 16, minute => 38, - time_zone => 'UTC' -); - -$dt->add( days => 3, hours => 2, minutes => 20, seconds => 15 ); -is( - $dt->datetime, '1986-01-31T18:58:15', - "Adding durations with days, hours, minutes, and seconds works" -); - -# Add 15M - this test failed at one point in N::I::Time -$dt = DateTime->new( - year => 2001, month => 4, day => 5, - hour => 16, - time_zone => 'UTC' -); - -$dt->add( minutes => 15 ); -is( - $dt->datetime, '2001-04-05T16:15:00', - "Adding minutes to an ical string" -); - -# Subtract a duration -$dt->add( minutes => -15 ); -is( $dt->datetime, '2001-04-05T16:00:00', "Back where we started" ); - -undef $dt; - -$dt = DateTime->new( - year => 1986, month => 1, day => 28, - hour => 16, minute => 38, - time_zone => 'UTC' -); - -$dt->add( seconds => 60 ); -is( - $dt->datetime, "1986-01-28T16:39:00", - "adding positive seconds with seconds works" -); -$dt->add( seconds => -120 ); -is( - $dt->datetime, "1986-01-28T16:37:00", - "adding negative seconds with seconds works" -); - -# test sub months -$dt = DateTime->new( - year => 2001, month => 1, day => 31, - time_zone => 'UTC', -); -$dt->add( days => 1 ); -is( $dt->date, '2001-02-01', 'february 1st' ); - -$dt = DateTime->new( - year => 2001, month => 2, day => 28, - time_zone => 'UTC', -); -$dt->add( days => 1 ); -is( $dt->date, '2001-03-01', 'march 1st' ); - -$dt = DateTime->new( - year => 2001, month => 3, day => 31, - time_zone => 'UTC', -); -$dt->add( days => 1 ); -is( $dt->date, '2001-04-01', 'april 1st' ); - -$dt = DateTime->new( - year => 2001, month => 4, day => 30, - time_zone => 'UTC', -); -$dt->add( days => 1 ); -is( $dt->date, '2001-05-01', 'may 1st' ); - -$dt = DateTime->new( - year => 2001, month => 5, day => 31, - time_zone => 'UTC', -); -$dt->add( days => 1 ); -is( $dt->date, '2001-06-01', 'june 1st' ); - -$dt = DateTime->new( - year => 2001, month => 6, day => 30, - time_zone => 'UTC', -); -$dt->add( days => 1 ); -is( $dt->date, '2001-07-01', 'july 1st' ); - -$dt = DateTime->new( - year => 2001, month => 7, day => 31, - time_zone => 'UTC', -); -$dt->add( days => 1 ); -is( $dt->date, '2001-08-01', 'august 1st' ); - -$dt = DateTime->new( - year => 2001, month => 8, day => 31, - time_zone => 'UTC', -); -$dt->add( days => 1 ); -is( $dt->date, '2001-09-01', 'september 1st' ); - -$dt = DateTime->new( - year => 2001, month => 9, day => 30, - time_zone => 'UTC', -); -$dt->add( days => 1 ); -is( $dt->date, '2001-10-01', 'october 1st' ); - -$dt = DateTime->new( - year => 2001, month => 10, day => 31, - time_zone => 'UTC', -); -$dt->add( days => 1 ); -is( $dt->date, '2001-11-01', 'november 1st' ); - -$dt = DateTime->new( - year => 2001, month => 11, day => 30, - time_zone => 'UTC', -); -$dt->add( days => 1 ); -is( $dt->date, '2001-12-01', 'december 1st' ); - -$dt = DateTime->new( - year => 2001, month => 12, day => 31, - time_zone => 'UTC', -); -$dt->add( days => 1 ); -is( $dt->date, '2002-01-01', 'january 1st' ); - -# Adding years - -# Before leap day, not a leap year ... -$dt = DateTime->new( - year => 2001, month => 2, day => 28, - time_zone => 'UTC', -); -$dt->add( years => 1 ); -is( $dt->date, '2002-02-28', 'Adding a year' ); -$dt->add( years => 17 ); -is( $dt->date, '2019-02-28', 'Adding 17 years' ); - -# After leap day, not a leap year ... -$dt = DateTime->new( - year => 2001, month => 3, day => 28, - time_zone => 'UTC', -); -$dt->add( years => 1 ); -is( $dt->date, '2002-03-28', 'Adding a year' ); -$dt->add( years => 17 ); -is( $dt->date, '2019-03-28', 'Adding 17 years' ); - -# On leap day, in a leap year ... -$dt = DateTime->new( - year => 2000, month => 2, day => 29, - time_zone => 'UTC', -); -$dt->add( years => 1 ); -is( $dt->date, '2001-03-01', 'Adding a year' ); -$dt->add( years => 17 ); -is( $dt->date, '2018-03-01', 'Adding 17 years' ); - -# Before leap day, in a leap year ... -$dt = DateTime->new( - year => 2000, month => 2, day => 28, - time_zone => 'UTC', -); -$dt->add( years => 1 ); -is( $dt->date, '2001-02-28', 'Adding a year' ); -$dt->add( years => 17 ); -is( $dt->date, '2018-02-28', 'Adding 17 years' ); - -# After leap day, in a leap year ... -$dt = DateTime->new( - year => 2000, month => 3, day => 28, - time_zone => 'UTC', -); -$dt->add( years => 1 ); -is( $dt->date, '2001-03-28', 'Adding a year' ); -$dt->add( years => 17 ); -is( $dt->date, '2018-03-28', 'Adding 17 years' ); - -# Test a bunch of years, before leap day -for ( 1 .. 99 ) { - $dt = DateTime->new( - year => 2000, month => 2, day => 28, - time_zone => 'UTC', - ); - $dt->add( years => $_ ); - my $x = sprintf '%02d', $_; - is( $dt->date, "20${x}-02-28", "Adding $_ years" ); -} - -# Test a bunch of years, after leap day -for ( 1 .. 99 ) { - $dt = DateTime->new( - year => 2000, month => 3, day => 28, - time_zone => 'UTC', - ); - $dt->add( years => $_ ); - my $x = sprintf '%02d', $_; - is( $dt->date, "20${x}-03-28", "Adding $_ years" ); +{ + my $dt = DateTime->new( + year => 1996, month => 11, day => 22, + hour => 18, minute => 30, second => 20, + time_zone => 'UTC', + ); + $dt->add( weeks => 8 ); + + is( $dt->year, 1997, 'year rollover' ); + is( $dt->month, 1, 'month set on year rollover' ); + is( $dt->datetime, '1997-01-17T18:30:20', 'okay on year rollover' ); + + $dt->add( weeks => 2 ); + is( $dt->datetime, '1997-01-31T18:30:20', 'Adding weeks' ); + + $dt->add( seconds => 15 ); + is( $dt->datetime, '1997-01-31T18:30:35', 'Adding seconds' ); + + $dt->add( minutes => 12 ); + is( $dt->datetime, '1997-01-31T18:42:35', 'Adding minutes' ); + + $dt->add( minutes => 25, hours => 3, seconds => 7 ); + is( $dt->datetime, '1997-01-31T22:07:42', 'Adding h,m,s' ); } -# And more of the same, starting on a non-leap year +{ + # Now, test the adding of durations + my $dt = DateTime->new( + year => 1986, month => 1, day => 28, + hour => 16, minute => 38, + time_zone => 'UTC' + ); + + $dt->add( minutes => 1, seconds => 12 ); + is( + $dt->datetime, '1986-01-28T16:39:12', + 'Adding durations with minutes and seconds works' + ); +} + +{ + my $dt = DateTime->new( + year => 1986, month => 1, day => 28, + hour => 16, minute => 38, + time_zone => 'UTC' + ); + + $dt->add( seconds => 30 ); + is( + $dt->datetime, '1986-01-28T16:38:30', + 'Adding durations with seconds only works' + ); +} + +{ + my $dt = DateTime->new( + year => 1986, month => 1, day => 28, + hour => 16, minute => 38, + time_zone => 'UTC' + ); + + $dt->add( hours => 1, minutes => 10 ); + is( + $dt->datetime, '1986-01-28T17:48:00', + 'Adding durations with hours and minutes works' + ); +} + +{ + my $dt = DateTime->new( + year => 1986, month => 1, day => 28, + hour => 16, minute => 38, + time_zone => 'UTC' + ); + + $dt->add( days => 3 ); + is( + $dt->datetime, '1986-01-31T16:38:00', + 'Adding durations with days only works' + ); +} + +{ + my $dt = DateTime->new( + year => 1986, month => 1, day => 28, + hour => 16, minute => 38, + time_zone => 'UTC' + ); + + $dt->add( days => 3, hours => 2 ); + is( + $dt->datetime, '1986-01-31T18:38:00', + 'Adding durations with days and hours works' + ); +} + +{ + my $dt = DateTime->new( + year => 1986, month => 1, day => 28, + hour => 16, minute => 38, + time_zone => 'UTC' + ); + + $dt->add( days => 3, hours => 2, minutes => 20, seconds => 15 ); + is( + $dt->datetime, '1986-01-31T18:58:15', + 'Adding durations with days, hours, minutes, and seconds works' + ); +} + +{ + # Add 15M - this test failed at one point in N::I::Time + my $dt = DateTime->new( + year => 2001, month => 4, day => 5, + hour => 16, + time_zone => 'UTC' + ); + + $dt->add( minutes => 15 ); + is( + $dt->datetime, '2001-04-05T16:15:00', + 'Adding minutes to an ical string' + ); + + # Subtract a duration + $dt->add( minutes => -15 ); + is( $dt->datetime, '2001-04-05T16:00:00', 'Back where we started' ); +} + +{ + # Syntactic sugar works as well + my $dt = DateTime->new( + year => 2016, month => 11, day => 11, + hour => 17, + time_zone => 'UTC' + ); + my $duration = DateTime::Duration->new( years => 1 ); + $dt->add($duration); + is( + $dt->datetime, '2017-11-11T17:00:00', + 'Adding a Duration object via ->add works', + ); + $duration = DateTime::Duration->new( months => 5, days => 1 ); + $dt->subtract($duration); + is( + $dt->datetime, '2017-06-10T17:00:00', + 'Subtracting a Duration object via ->subtract works', + ); +} + +{ + my $dt = DateTime->new( + year => 1986, month => 1, day => 28, + hour => 16, minute => 38, + time_zone => 'UTC' + ); + + $dt->add( seconds => 60 ); + is( + $dt->datetime, '1986-01-28T16:39:00', + 'adding positive seconds with seconds works' + ); + $dt->add( seconds => -120 ); + is( + $dt->datetime, '1986-01-28T16:37:00', + 'adding negative seconds with seconds works' + ); +} + +{ + # test sub months + my $dt = DateTime->new( + year => 2001, month => 1, day => 31, + time_zone => 'UTC', + ); + $dt->add( days => 1 ); + is( $dt->date, '2001-02-01', 'february 1st' ); +} + +{ + my $dt = DateTime->new( + year => 2001, month => 2, day => 28, + time_zone => 'UTC', + ); + $dt->add( days => 1 ); + is( $dt->date, '2001-03-01', 'march 1st' ); +} + +{ + my $dt = DateTime->new( + year => 2001, month => 3, day => 31, + time_zone => 'UTC', + ); + $dt->add( days => 1 ); + is( $dt->date, '2001-04-01', 'april 1st' ); +} + +{ + my $dt = DateTime->new( + year => 2001, month => 4, day => 30, + time_zone => 'UTC', + ); + $dt->add( days => 1 ); + is( $dt->date, '2001-05-01', 'may 1st' ); +} + +{ + my $dt = DateTime->new( + year => 2001, month => 5, day => 31, + time_zone => 'UTC', + ); + $dt->add( days => 1 ); + is( $dt->date, '2001-06-01', 'june 1st' ); +} + +{ + my $dt = DateTime->new( + year => 2001, month => 6, day => 30, + time_zone => 'UTC', + ); + $dt->add( days => 1 ); + is( $dt->date, '2001-07-01', 'july 1st' ); +} -# Test a bunch of years, before leap day -for ( 1 .. 97 ) { - $dt = DateTime->new( - year => 2002, month => 2, day => 28, +{ + my $dt = DateTime->new( + year => 2001, month => 7, day => 31, time_zone => 'UTC', ); - $dt->add( years => $_ ); - my $x = sprintf '%02d', $_ + 2; - is( $dt->date, "20${x}-02-28", "Adding $_ years" ); + $dt->add( days => 1 ); + is( $dt->date, '2001-08-01', 'august 1st' ); } -# Test a bunch of years, after leap day -for ( 1 .. 97 ) { - $dt = DateTime->new( - year => 2002, month => 3, day => 28, +{ + my $dt = DateTime->new( + year => 2001, month => 8, day => 31, time_zone => 'UTC', ); - $dt->add( years => $_ ); - my $x = sprintf '%02d', $_ + 2; - is( $dt->date, "20${x}-03-28", "Adding $_ years" ); + $dt->add( days => 1 ); + is( $dt->date, '2001-09-01', 'september 1st' ); } -# subtract years -for ( 1 .. 97 ) { - $dt = DateTime->new( - year => 1999, month => 3, day => 1, +{ + my $dt = DateTime->new( + year => 2001, month => 9, day => 30, + time_zone => 'UTC', + ); + $dt->add( days => 1 ); + is( $dt->date, '2001-10-01', 'october 1st' ); +} + +{ + my $dt = DateTime->new( + year => 2001, month => 10, day => 31, + time_zone => 'UTC', + ); + $dt->add( days => 1 ); + is( $dt->date, '2001-11-01', 'november 1st' ); +} + +{ + my $dt = DateTime->new( + year => 2001, month => 11, day => 30, + time_zone => 'UTC', + ); + $dt->add( days => 1 ); + is( $dt->date, '2001-12-01', 'december 1st' ); +} + +{ + my $dt = DateTime->new( + year => 2001, month => 12, day => 31, + time_zone => 'UTC', + ); + $dt->add( days => 1 ); + is( $dt->date, '2002-01-01', 'january 1st' ); +} + +{ + # Before leap day, not a leap year ... + my $dt = DateTime->new( + year => 2001, month => 2, day => 28, time_zone => 'UTC', ); - $dt->add( years => -$_ ); - my $x = sprintf '%02d', 99 - $_; - is( $dt->date, "19${x}-03-01", "Subtracting $_ years" ); + $dt->add( years => 1 ); + is( $dt->date, '2002-02-28', 'Adding a year' ); + $dt->add( years => 17 ); + is( $dt->date, '2019-02-28', 'Adding 17 years' ); +} + +{ + # After leap day, not a leap year ... + my $dt = DateTime->new( + year => 2001, month => 3, day => 28, + time_zone => 'UTC', + ); + $dt->add( years => 1 ); + is( $dt->date, '2002-03-28', 'Adding a year' ); + $dt->add( years => 17 ); + is( $dt->date, '2019-03-28', 'Adding 17 years' ); +} + +{ + # On leap day, in a leap year ... + my $dt = DateTime->new( + year => 2000, month => 2, day => 29, + time_zone => 'UTC', + ); + $dt->add( years => 1 ); + is( $dt->date, '2001-03-01', 'Adding a year' ); + $dt->add( years => 17 ); + is( $dt->date, '2018-03-01', 'Adding 17 years' ); +} + +{ + # Before leap day, in a leap year ... + my $dt = DateTime->new( + year => 2000, month => 2, day => 28, + time_zone => 'UTC', + ); + $dt->add( years => 1 ); + is( $dt->date, '2001-02-28', 'Adding a year' ); + $dt->add( years => 17 ); + is( $dt->date, '2018-02-28', 'Adding 17 years' ); +} + +{ + # After leap day, in a leap year ... + my $dt = DateTime->new( + year => 2000, month => 3, day => 28, + time_zone => 'UTC', + ); + $dt->add( years => 1 ); + is( $dt->date, '2001-03-28', 'Adding a year' ); + $dt->add( years => 17 ); + is( $dt->date, '2018-03-28', 'Adding 17 years' ); +} + +{ + # Test a bunch of years, before leap day + for ( 1 .. 99 ) { + my $dt = DateTime->new( + year => 2000, month => 2, day => 28, + time_zone => 'UTC', + ); + $dt->add( years => $_ ); + my $x = sprintf '%02d', $_; + is( $dt->date, "20${x}-02-28", "Adding $_ years" ); + } + + # Test a bunch of years, after leap day + for ( 1 .. 99 ) { + my $dt = DateTime->new( + year => 2000, month => 3, day => 28, + time_zone => 'UTC', + ); + $dt->add( years => $_ ); + my $x = sprintf '%02d', $_; + is( $dt->date, "20${x}-03-28", "Adding $_ years" ); + } +} + +# And more of the same, starting on a non-leap year + +{ + # Test a bunch of years, before leap day + for ( 1 .. 97 ) { + my $dt = DateTime->new( + year => 2002, month => 2, day => 28, + time_zone => 'UTC', + ); + $dt->add( years => $_ ); + my $x = sprintf '%02d', $_ + 2; + is( $dt->date, "20${x}-02-28", "Adding $_ years" ); + } + + # Test a bunch of years, after leap day + for ( 1 .. 97 ) { + my $dt = DateTime->new( + year => 2002, month => 3, day => 28, + time_zone => 'UTC', + ); + $dt->add( years => $_ ); + my $x = sprintf '%02d', $_ + 2; + is( $dt->date, "20${x}-03-28", "Adding $_ years" ); + } +} + +{ + # subtract years + for ( 1 .. 97 ) { + my $dt = DateTime->new( + year => 1999, month => 3, day => 1, + time_zone => 'UTC', + ); + $dt->add( years => -$_ ); + my $x = sprintf '%02d', 99 - $_; + is( $dt->date, "19${x}-03-01", "Subtracting $_ years" ); + } } # test some old bugs -# bug adding months where current month + months added were > 25 -$dt = DateTime->new( - year => 1997, month => 12, day => 1, - time_zone => 'UTC', -); -$dt->add( months => 14 ); -is( $dt->date, '1999-02-01', 'Adding months--rollover year' ); - -# bug subtracting months with year rollover -$dt = DateTime->new( - year => 1997, month => 1, day => 1, - time_zone => 'UTC', -); -$dt->add( months => -1 ); -is( $dt->date, '1996-12-01', 'Subtracting months--rollover year' ); +{ + # bug adding months where current month + months added were > 25 + my $dt = DateTime->new( + year => 1997, month => 12, day => 1, + time_zone => 'UTC', + ); + $dt->add( months => 14 ); + is( $dt->date, '1999-02-01', 'Adding months--rollover year' ); +} -my $new = $dt + DateTime::Duration->new( years => 2 ); -is( $new->date, '1998-12-01', 'test + overloading' ); +{ + # bug subtracting months with year rollover + my $dt = DateTime->new( + year => 1997, month => 1, day => 1, + time_zone => 'UTC', + ); + $dt->add( months => -1 ); + is( $dt->date, '1996-12-01', 'Subtracting months--rollover year' ); + + my $new = $dt + DateTime::Duration->new( years => 2 ); + is( $new->date, '1998-12-01', 'test + overloading' ); +} { my $dt = DateTime->new( - year => 1997, month => 1, day => 1, - hour => 1, minute => 1, second => 59, + year => 1997, month => 1, day => 1, + hour => 1, minute => 1, second => 59, nanosecond => 500000000, time_zone => 'UTC', ); diff -Nru libdatetime-perl-1.21/t/07compare.t libdatetime-perl-1.46/t/07compare.t --- libdatetime-perl-1.21/t/07compare.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/07compare.t 2018-02-11 23:36:51.000000000 +0000 @@ -18,7 +18,7 @@ # make sure that comparing to itself eq 0 my $identity = $date1->compare($date2); -ok( $identity == 0, "Identity comparison" ); +ok( $identity == 0, 'Identity comparison' ); $date2 = DateTime->new( year => 1997, month => 10, day => 24, @@ -120,72 +120,72 @@ # comparison with floating time { - my $date1 = DateTime->new( + my $dt1 = DateTime->new( year => 1997, month => 10, day => 24, hour => 12, minute => 0, second => 0, time_zone => 'America/Chicago' ); - my $date2 = DateTime->new( + my $dt2 = DateTime->new( year => 1997, month => 10, day => 24, hour => 12, minute => 0, second => 0, time_zone => 'floating' ); is( - DateTime->compare( $date1, $date2 ), 0, + DateTime->compare( $dt1, $dt2 ), 0, 'Comparison with floating time (cmp)' ); - is( ( $date1 <=> $date2 ), 0, 'Comparison with floating time (<=>)' ); - is( ( $date1 cmp $date2 ), 0, 'Comparison with floating time (cmp)' ); + is( ( $dt1 <=> $dt2 ), 0, 'Comparison with floating time (<=>)' ); + is( ( $dt1 cmp $dt2 ), 0, 'Comparison with floating time (cmp)' ); is( - DateTime->compare_ignore_floating( $date1, $date2 ), 1, + DateTime->compare_ignore_floating( $dt1, $dt2 ), 1, 'Comparison with floating time (cmp)' ); } # sub-second { - my $date1 = DateTime->new( - year => 1997, month => 10, day => 24, - hour => 12, minute => 0, second => 0, + my $dt1 = DateTime->new( + year => 1997, month => 10, day => 24, + hour => 12, minute => 0, second => 0, nanosecond => 100, ); - my $date2 = DateTime->new( - year => 1997, month => 10, day => 24, - hour => 12, minute => 0, second => 0, + my $dt2 = DateTime->new( + year => 1997, month => 10, day => 24, + hour => 12, minute => 0, second => 0, nanosecond => 200, ); is( - DateTime->compare( $date1, $date2 ), -1, + DateTime->compare( $dt1, $dt2 ), -1, 'Comparison with floating time (cmp)' ); - is( ( $date1 <=> $date2 ), -1, 'Comparison with floating time (<=>)' ); - is( ( $date1 cmp $date2 ), -1, 'Comparison with floating time (cmp)' ); + is( ( $dt1 <=> $dt2 ), -1, 'Comparison with floating time (<=>)' ); + is( ( $dt1 cmp $dt2 ), -1, 'Comparison with floating time (cmp)' ); } { - my $date1 = DateTime->new( - year => 2000, month => 10, day => 24, - hour => 12, minute => 0, second => 0, + my $dt1 = DateTime->new( + year => 2000, month => 10, day => 24, + hour => 12, minute => 0, second => 0, nanosecond => 10000, ); - my $date2 = DateTime->new( - year => 2000, month => 10, day => 24, - hour => 12, minute => 0, second => 0, + my $dt2 = DateTime->new( + year => 2000, month => 10, day => 24, + hour => 12, minute => 0, second => 0, nanosecond => 10000, ); is( - DateTime->compare( $date1, $date2 ), 0, + DateTime->compare( $dt1, $dt2 ), 0, 'Comparison with floating time (cmp)' ); - is( ( $date1 <=> $date2 ), 0, 'Comparison with floating time (<=>)' ); - is( ( $date1 cmp $date2 ), 0, 'Comparison with floating time (cmp)' ); + is( ( $dt1 <=> $dt2 ), 0, 'Comparison with floating time (<=>)' ); + is( ( $dt1 cmp $dt2 ), 0, 'Comparison with floating time (cmp)' ); is( - DateTime->compare_ignore_floating( $date1, $date2 ), 0, + DateTime->compare_ignore_floating( $dt1, $dt2 ), 0, 'Comparison with compare_ignore_floating (cmp)' ); } @@ -194,7 +194,10 @@ package DT::Test; - sub new { shift; bless [@_] } + sub new { + my $class = shift; + return bless [@_], $class; + } sub utc_rd_values { @{ $_[0] } } } diff -Nru libdatetime-perl-1.21/t/09greg.t libdatetime-perl-1.46/t/09greg.t --- libdatetime-perl-1.21/t/09greg.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/09greg.t 2018-02-11 23:36:51.000000000 +0000 @@ -5,6 +5,8 @@ use DateTime; +## no critic (Subroutines::ProtectPrivateSubs) + # test _ymd2rd and _rd2ymd for various dates # 2 tests are performed for each date (on _ymd2rd and _rd2ymd) # dates are specified as [rd,year,month,day] @@ -27,7 +29,7 @@ [ 227015, 622, 7, 19 ], [ 654415, 1792, 9, 22 ], [ 673222, 1844, 3, 21 ] - ) { +) { is( join( '/', DateTime->_rd2ymd( $_->[0] ) ), join( '/', @{$_}[ 1 .. 3 ] ), @@ -46,13 +48,13 @@ [ -1753469, -4803, 39, 1 ], [ -1753105, -4796, -34, 28 ], [ -1753105, -4802, 38, 28 ] - ) { +) { is( DateTime->_ymd2rd( @{$_}[ 1 .. 3 ] ), $_->[0], join( '/', @{$_}[ 1 .. 3 ] ) . " \t=> " . $_->[0] - . " (normalization)" + . ' (normalization)' ); } @@ -113,6 +115,6 @@ } } -pass("greg torture test") if $y == 4801; +pass('greg torture test') if $y == 4801; done_testing(); diff -Nru libdatetime-perl-1.21/t/10subtract.t libdatetime-perl-1.46/t/10subtract.t --- libdatetime-perl-1.21/t/10subtract.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/10subtract.t 2018-02-11 23:36:51.000000000 +0000 @@ -7,15 +7,15 @@ { my $date1 = DateTime->new( - year => 2001, month => 5, day => 10, - hour => 4, minute => 3, second => 2, + year => 2001, month => 5, day => 10, + hour => 4, minute => 3, second => 2, nanosecond => 12, time_zone => 'UTC' ); my $date2 = DateTime->new( - year => 2001, month => 6, day => 12, - hour => 5, minute => 7, second => 23, + year => 2001, month => 6, day => 12, + hour => 5, minute => 7, second => 23, nanosecond => 7, time_zone => 'UTC' ); @@ -108,14 +108,14 @@ # based on bug report from Eric Cholet { my $dt1 = DateTime->new( - year => 2003, month => 2, day => 9, - hour => 0, minute => 0, second => 1, + year => 2003, month => 2, day => 9, + hour => 0, minute => 0, second => 1, time_zone => 'UTC', ); my $dt2 = DateTime->new( - year => 2003, month => 2, day => 7, - hour => 23, minute => 59, second => 59, + year => 2003, month => 2, day => 7, + hour => 23, minute => 59, second => 59, time_zone => 'UTC', ); @@ -162,15 +162,15 @@ # test for a bug when nanoseconds were greater in earlier datetime { my $dt1 = DateTime->new( - year => 2000, month => 1, day => 5, - hour => 0, minute => 10, second => 0, + year => 2000, month => 1, day => 5, + hour => 0, minute => 10, second => 0, nanosecond => 1, time_zone => 'UTC', ); my $dt2 = DateTime->new( - year => 2000, month => 1, day => 6, - hour => 0, minute => 10, second => 0, + year => 2000, month => 1, day => 6, + hour => 0, minute => 10, second => 0, nanosecond => 0, time_zone => 'UTC', ); @@ -188,15 +188,15 @@ { my $dt1 = DateTime->new( - year => 2000, month => 1, day => 5, - hour => 0, minute => 10, second => 0, + year => 2000, month => 1, day => 5, + hour => 0, minute => 10, second => 0, nanosecond => 20, time_zone => 'UTC', ); my $dt2 = DateTime->new( - year => 2000, month => 1, day => 5, - hour => 0, minute => 10, second => 0, + year => 2000, month => 1, day => 5, + hour => 0, minute => 10, second => 0, nanosecond => 10, time_zone => 'UTC', ); @@ -211,15 +211,15 @@ { my $dt1 = DateTime->new( - year => 2000, month => 1, day => 5, - hour => 0, minute => 11, second => 0, + year => 2000, month => 1, day => 5, + hour => 0, minute => 11, second => 0, nanosecond => 20, time_zone => 'UTC', ); my $dt2 = DateTime->new( - year => 2000, month => 1, day => 5, - hour => 0, minute => 10, second => 0, + year => 2000, month => 1, day => 5, + hour => 0, minute => 10, second => 0, nanosecond => 10, time_zone => 'UTC', ); @@ -235,15 +235,15 @@ { my $dt1 = DateTime->new( - year => 2000, month => 1, day => 5, - hour => 0, minute => 10, second => 0, + year => 2000, month => 1, day => 5, + hour => 0, minute => 10, second => 0, nanosecond => 20, time_zone => 'UTC', ); my $dt2 = DateTime->new( - year => 2000, month => 1, day => 5, - hour => 0, minute => 11, second => 0, + year => 2000, month => 1, day => 5, + hour => 0, minute => 11, second => 0, nanosecond => 10, time_zone => 'UTC', ); @@ -258,15 +258,15 @@ { my $dt1 = DateTime->new( - year => 2000, month => 1, day => 5, - hour => 0, minute => 11, second => 0, + year => 2000, month => 1, day => 5, + hour => 0, minute => 11, second => 0, nanosecond => 10, time_zone => 'UTC', ); my $dt2 = DateTime->new( - year => 2000, month => 1, day => 5, - hour => 0, minute => 10, second => 0, + year => 2000, month => 1, day => 5, + hour => 0, minute => 10, second => 0, nanosecond => 20, time_zone => 'UTC', ); @@ -284,8 +284,8 @@ { my $dt1 = DateTime->new( - year => 2000, month => 1, day => 5, - hour => 0, minute => 11, second => 0, + year => 2000, month => 1, day => 5, + hour => 0, minute => 11, second => 0, nanosecond => 20, time_zone => 'UTC', ); @@ -310,15 +310,15 @@ { my $date1 = DateTime->new( - year => 2001, month => 5, day => 10, - hour => 4, minute => 3, second => 2, + year => 2001, month => 5, day => 10, + hour => 4, minute => 3, second => 2, nanosecond => 12, time_zone => 'UTC' ); my $date2 = DateTime->new( - year => 2001, month => 6, day => 12, - hour => 5, minute => 7, second => 23, + year => 2001, month => 6, day => 12, + hour => 5, minute => 7, second => 23, nanosecond => 7, time_zone => 'UTC' ); @@ -373,27 +373,27 @@ [ $date3, $date4 ], [ $date5, $date6 ], [ $date7, $date8 ], - ) { + ) { my $pos_diff = $p->[1]->subtract_datetime( $p->[0] ); - is( $pos_diff->delta_days, 1, "1 day diff at end of month" ); - is( $pos_diff->delta_months, 0, "0 month diff at end of month" ); + is( $pos_diff->delta_days, 1, '1 day diff at end of month' ); + is( $pos_diff->delta_months, 0, '0 month diff at end of month' ); my $neg_diff = $p->[0]->subtract_datetime( $p->[1] ); - is( $neg_diff->delta_days, -1, "-1 day diff at end of month" ); - is( $neg_diff->delta_months, 0, "0 month diff at end of month" ); + is( $neg_diff->delta_days, -1, '-1 day diff at end of month' ); + is( $neg_diff->delta_months, 0, '0 month diff at end of month' ); } } { my $dt1 = DateTime->new( - year => 2005, month => 6, day => 11, + year => 2005, month => 6, day => 11, time_zone => 'UTC', ); my $dt2 = DateTime->new( - year => 2005, month => 11, day => 10, + year => 2005, month => 11, day => 10, time_zone => 'UTC', ); @@ -414,12 +414,12 @@ { my $dt1 = DateTime->new( - year => 2005, month => 6, day => 11, + year => 2005, month => 6, day => 11, time_zone => 'UTC', ); my $dt2 = DateTime->new( - year => 2005, month => 11, day => 10, + year => 2005, month => 11, day => 10, time_zone => 'UTC', ); diff -Nru libdatetime-perl-1.21/t/11duration.t libdatetime-perl-1.46/t/11duration.t --- libdatetime-perl-1.21/t/11duration.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/11duration.t 2018-02-11 23:36:51.000000000 +0000 @@ -1,6 +1,7 @@ use strict; use warnings; +use Test::Fatal; use Test::More; use DateTime; @@ -24,30 +25,30 @@ is( $dur->$unit(), $val, "$unit should be $val" ); } - is( $dur->delta_months, 14, "delta_months" ); - is( $dur->delta_days, 25, "delta_days" ); - is( $dur->delta_minutes, 367, "delta_minutes" ); - is( $dur->delta_seconds, 8, "delta_seconds" ); - is( $dur->delta_nanoseconds, 9, "delta_nanoseconds" ); - - is( $dur->in_units('months'), 14, "in_units months" ); - is( $dur->in_units('days'), 25, "in_units days" ); - is( $dur->in_units('minutes'), 367, "in_units minutes" ); - is( $dur->in_units('seconds'), 8, "in_units seconds" ); + is( $dur->delta_months, 14, 'delta_months' ); + is( $dur->delta_days, 25, 'delta_days' ); + is( $dur->delta_minutes, 367, 'delta_minutes' ); + is( $dur->delta_seconds, 8, 'delta_seconds' ); + is( $dur->delta_nanoseconds, 9, 'delta_nanoseconds' ); + + is( $dur->in_units('months'), 14, 'in_units months' ); + is( $dur->in_units('days'), 25, 'in_units days' ); + is( $dur->in_units('minutes'), 367, 'in_units minutes' ); + is( $dur->in_units('seconds'), 8, 'in_units seconds' ); is( $dur->in_units( 'nanoseconds', 'seconds' ), 9, - "in_units nanoseconds, seconds" + 'in_units nanoseconds, seconds' ); - is( $dur->in_units('years'), 1, "in_units years" ); - is( $dur->in_units( 'months', 'years' ), 2, "in_units months, years" ); - is( $dur->in_units('weeks'), 3, "in_units weeks" ); - is( $dur->in_units( 'days', 'weeks' ), 4, "in_units days, weeks" ); - is( $dur->in_units('hours'), 6, "in_units hours" ); - is( $dur->in_units( 'minutes', 'hours' ), 7, "in_units minutes, hours" ); + is( $dur->in_units('years'), 1, 'in_units years' ); + is( $dur->in_units( 'months', 'years' ), 2, 'in_units months, years' ); + is( $dur->in_units('weeks'), 3, 'in_units weeks' ); + is( $dur->in_units( 'days', 'weeks' ), 4, 'in_units days, weeks' ); + is( $dur->in_units('hours'), 6, 'in_units hours' ); + is( $dur->in_units( 'minutes', 'hours' ), 7, 'in_units minutes, hours' ); is( $dur->in_units('nanoseconds'), 8_000_000_009, - "in_units nanoseconds" + 'in_units nanoseconds' ); my ( @@ -59,20 +60,20 @@ minutes seconds nanoseconds ) ); - is( $years, 1, "in_units years, list context" ); - is( $months, 2, "in_units months, list context" ); - is( $weeks, 3, "in_units weeks, list context" ); - is( $days, 4, "in_units days, list context" ); - is( $hours, 6, "in_units hours, list context" ); - is( $minutes, 7, "in_units minutes, list context" ); - is( $seconds, 8, "in_units seconds, list context" ); - is( $nanoseconds, 9, "in_units nanoseconds, list context" ); - - ok( $dur->is_positive, "should be positive" ); - ok( !$dur->is_zero, "should not be zero" ); - ok( !$dur->is_negative, "should not be negative" ); + is( $years, 1, 'in_units years, list context' ); + is( $months, 2, 'in_units months, list context' ); + is( $weeks, 3, 'in_units weeks, list context' ); + is( $days, 4, 'in_units days, list context' ); + is( $hours, 6, 'in_units hours, list context' ); + is( $minutes, 7, 'in_units minutes, list context' ); + is( $seconds, 8, 'in_units seconds, list context' ); + is( $nanoseconds, 9, 'in_units nanoseconds, list context' ); + + ok( $dur->is_positive, 'should be positive' ); + ok( !$dur->is_zero, 'should not be zero' ); + ok( !$dur->is_negative, 'should not be negative' ); - ok( $dur->is_wrap_mode, "wrap mode" ); + ok( $dur->is_wrap_mode, 'wrap mode' ); } { my %pairs = ( @@ -89,36 +90,36 @@ my $dur = DateTime::Duration->new( %pairs, end_of_month => 'limit' ); my $calendar_dur = $dur->calendar_duration; - is( $calendar_dur->delta_months, 14, "date - delta_months is 14" ); - is( $calendar_dur->delta_minutes, 0, "date - delta_minutes is 0" ); - is( $calendar_dur->delta_seconds, 0, "date - delta_seconds is 0" ); + is( $calendar_dur->delta_months, 14, 'date - delta_months is 14' ); + is( $calendar_dur->delta_minutes, 0, 'date - delta_minutes is 0' ); + is( $calendar_dur->delta_seconds, 0, 'date - delta_seconds is 0' ); is( $calendar_dur->delta_nanoseconds, 0, - "date - delta_nanoseconds is 0" + 'date - delta_nanoseconds is 0' ); - ok( $calendar_dur->is_limit_mode, "limit mode" ); + ok( $calendar_dur->is_limit_mode, 'limit mode' ); my $clock_dur = $dur->clock_duration; - is( $clock_dur->delta_months, 0, "time - delta_months is 0" ); - is( $clock_dur->delta_minutes, 367, "time - delta_minutes is 367" ); - is( $clock_dur->delta_seconds, 8, "time - delta_seconds is 8" ); - is( $clock_dur->delta_nanoseconds, 9, "time - delta_nanoseconds is 9" ); - ok( $clock_dur->is_limit_mode, "limit mode" ); + is( $clock_dur->delta_months, 0, 'time - delta_months is 0' ); + is( $clock_dur->delta_minutes, 367, 'time - delta_minutes is 367' ); + is( $clock_dur->delta_seconds, 8, 'time - delta_seconds is 8' ); + is( $clock_dur->delta_nanoseconds, 9, 'time - delta_nanoseconds is 9' ); + ok( $clock_dur->is_limit_mode, 'limit mode' ); } { my $dur = DateTime::Duration->new( days => 1, end_of_month => 'limit' ); - ok( $dur->is_limit_mode, "limit mode" ); + ok( $dur->is_limit_mode, 'limit mode' ); } { my $dur = DateTime::Duration->new( days => 1, end_of_month => 'preserve' ); - ok( $dur->is_preserve_mode, "preserve mode" ); + ok( $dur->is_preserve_mode, 'preserve mode' ); } my $leap_day = DateTime->new( - year => 2004, month => 2, day => 29, + year => 2004, month => 2, day => 29, time_zone => 'UTC', ); @@ -128,7 +129,7 @@ end_of_month => 'wrap' ); - is( $new->date, '2005-03-01', "new date should be 2005-03-01" ); + is( $new->date, '2005-03-01', 'new date should be 2005-03-01' ); } { @@ -137,7 +138,7 @@ end_of_month => 'limit' ); - is( $new->date, '2005-02-28', "new date should be 2005-02-28" ); + is( $new->date, '2005-02-28', 'new date should be 2005-02-28' ); } { @@ -146,13 +147,13 @@ end_of_month => 'preserve' ); - is( $new->date, '2005-02-28', "new date should be 2005-02-28" ); + is( $new->date, '2005-02-28', 'new date should be 2005-02-28' ); my $new2 = $leap_day + DateTime::Duration->new( months => 1, end_of_month => 'preserve' ); - is( $new2->date, '2004-03-31', "new date should be 2004-03-31" ); + is( $new2->date, '2004-03-31', 'new date should be 2004-03-31' ); } { @@ -184,9 +185,9 @@ 'inverse delta seconds should be negative' ); - ok( $inverse->is_negative, "should be negative" ); - ok( !$inverse->is_zero, "should not be zero" ); - ok( !$inverse->is_positive, "should not be positivea" ); + ok( $inverse->is_negative, 'should be negative' ); + ok( !$inverse->is_zero, 'should not be zero' ); + ok( !$inverse->is_positive, 'should not be positivea' ); is( $inverse->end_of_month_mode(), 'preserve', @@ -274,6 +275,23 @@ } { + my $dur1 = DateTime::Duration->new( seconds => 1 ); + my $dur2 = DateTime::Duration->new( seconds => 1 ); + + $dur1->add($dur2); + is( + $dur1->delta_seconds, 2, + 'add method works with a duration object' + ); + + $dur1->subtract($dur2); + is( + $dur1->delta_seconds, 1, + 'subtract method works with a duration object' + ); +} + +{ my $dur = DateTime::Duration->new( nanoseconds => -10 ); is( $dur->nanoseconds, 10, 'nanoseconds is 10' ); is( $dur->delta_nanoseconds, -10, 'delta_nanoseconds is -10' ); @@ -289,11 +307,14 @@ } { - eval { - DateTime::Duration->new( months => 3 )->add( hours => -3 ) - ->add( minutes => 1 ); - }; - ok( !$@, 'method chaining should work' ); + is( + exception { + DateTime::Duration->new( months => 3 )->add( hours => -3 ) + ->add( minutes => 1 ); + }, + undef, + 'method chaining should work' + ); } { @@ -321,9 +342,9 @@ my $dur1 = DateTime::Duration->new( minutes => 10 ); my $dur2 = DateTime::Duration->new( minutes => 20 ); - eval { my $x = 1 if $dur1 <=> $dur2 }; like( - $@, qr/does not overload comparison/, + exception { 1 if $dur1 <=> $dur2 }, + qr/does not overload comparison/, 'check error for duration comparison overload' ); @@ -427,10 +448,9 @@ { local $TODO = 'reject fractional units in DateTime::Duration->new'; - eval { DateTime::Duration->new( minutes => 50.2 ) }; - like( - $@, qr/is an integer/, + exception { DateTime::Duration->new( minutes => 50.2 ) }, + qr/is an integer/, 'cannot create a duration with fractional units' ); } diff -Nru libdatetime-perl-1.21/t/12week.t libdatetime-perl-1.46/t/12week.t --- libdatetime-perl-1.21/t/12week.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/12week.t 2018-02-11 23:36:51.000000000 +0000 @@ -47,7 +47,7 @@ my ( $year, $week ) = $dt->week(); - is( "$year-W$week", "$results[0]-W$results[1]" ); + is( "$year-W$week", "$results[0]-W$results[1]", 'week for ' . $dt->ymd ); } done_testing(); diff -Nru libdatetime-perl-1.21/t/13strftime.t libdatetime-perl-1.46/t/13strftime.t --- libdatetime-perl-1.21/t/13strftime.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/13strftime.t 2018-02-11 23:36:51.000000000 +0000 @@ -126,8 +126,8 @@ '%% and %{method}', sub { my $dt = DateTime->new( - year => 2004, month => 8, day => 16, - hour => 15, minute => 30, nanosecond => 123456789, + year => 2004, month => 8, day => 16, + hour => 15, minute => 30, nanosecond => 123456789, locale => 'en', ); @@ -304,8 +304,6 @@ $c_format =~ s/\{0\}/'1:02:42 ' . $en_locale->am_pm_abbreviated->[1]/e; return { - '%y' => '99', - '%Y' => '1999', '%%' => '%', '%a' => $en_locale->day_format_abbreviated->[1], '%A' => $en_locale->day_format_wide->[1], @@ -354,8 +352,6 @@ sub de_tests { my $de_locale = DateTime::Locale->load('de'); return { - '%y' => '99', - '%Y' => '1999', '%%' => '%', '%a' => $de_locale->day_format_abbreviated->[1], '%A' => $de_locale->day_format_wide->[1], @@ -395,8 +391,6 @@ sub it_tests { my $it_locale = DateTime::Locale->load('it'); return { - '%y' => '99', - '%Y' => '1999', '%%' => '%', '%a' => $it_locale->day_format_abbreviated->[1], '%A' => $it_locale->day_format_wide->[1], diff -Nru libdatetime-perl-1.21/t/14locale.t libdatetime-perl-1.46/t/14locale.t --- libdatetime-perl-1.21/t/14locale.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/14locale.t 2018-02-11 23:36:51.000000000 +0000 @@ -1,27 +1,46 @@ use strict; use warnings; +use Test::Fatal; use Test::More; use DateTime; use DateTime::Locale; -eval { DateTime->new( year => 100, locale => 'en_US' ) }; -is( $@, '', 'make sure constructor accepts locale parameter' ); - -eval { DateTime->now( locale => 'en_US' ) }; -is( $@, '', 'make sure constructor accepts locale parameter' ); - -eval { DateTime->today( locale => 'en_US' ) }; -is( $@, '', 'make sure constructor accepts locale parameter' ); - -eval { DateTime->from_epoch( epoch => 1, locale => 'en_US' ) }; -is( $@, '', 'make sure constructor accepts locale parameter' ); - -eval { - DateTime->last_day_of_month( year => 100, month => 2, locale => 'en_US' ); -}; -is( $@, '', 'make sure constructor accepts locale parameter' ); +is( + exception { DateTime->new( year => 100, locale => 'en_US' ) }, + undef, + 'make sure new accepts locale parameter' +); + +is( + exception { DateTime->now( locale => 'en_US' ) }, + undef, + 'make sure now accepts locale parameter' +); + +is( + exception { DateTime->today( locale => 'en_US' ) }, + undef, + 'make sure today accepts locale parameter' +); + +is( + exception { DateTime->from_epoch( epoch => 1, locale => 'en_US' ) }, + undef, + 'make sure from_epoch accepts locale parameter' +); + +is( + exception { + DateTime->last_day_of_month( + year => 100, month => 2, + locale => 'en_US' + ); + }, + undef, + 'make sure last_day_of_month accepts locale parameter' +); { @@ -29,18 +48,28 @@ sub utc_rd_values { ( 0, 0 ) } } -eval { - DateTime->from_object( - object => ( bless {}, 'DT::Object' ), - locale => 'en_US' - ); -}; -is( $@, '', 'make sure constructor accepts locale parameter' ); - -eval { - DateTime->new( year => 100, locale => DateTime::Locale->load('en_US') ); -}; -is( $@, '', 'make sure constructor accepts locale parameter as object' ); +is( + exception { + DateTime->from_object( + object => ( bless {}, 'DT::Object' ), + locale => 'en_US' + ); + }, + undef, + , + 'make sure constructor accepts locale parameter' +); + +is( + exception { + DateTime->new( + year => 100, + locale => DateTime::Locale->load('en_US') + ); + }, + undef, + 'make sure constructor accepts locale parameter as object' +); DateTime->DefaultLocale('it'); is( DateTime->now->locale->id, 'it', 'default locale should now be "it"' ); diff -Nru libdatetime-perl-1.21/t/16truncate.t libdatetime-perl-1.46/t/16truncate.t --- libdatetime-perl-1.21/t/16truncate.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/16truncate.t 2018-02-11 23:36:51.000000000 +0000 @@ -1,3 +1,4 @@ +## no critic (Modules::ProhibitExcessMainComplexity) use strict; use warnings; @@ -117,15 +118,15 @@ 'truncate to week should always truncate to monday of week' ); } +} - { - my $dt = DateTime->new( year => 2003, month => 10, day => 2 ) - ->truncate( to => 'week' ); +{ + my $dt = DateTime->new( year => 2003, month => 10, day => 2 ) + ->truncate( to => 'week' ); - is( $dt->year, 2003, 'truncation to week across month boundary' ); - is( $dt->month, 9, 'truncation to week across month boundary' ); - is( $dt->day, 29, 'truncation to week across month boundary' ); - } + is( $dt->year, 2003, 'truncation to week across month boundary' ); + is( $dt->month, 9, 'truncation to week across month boundary' ); + is( $dt->day, 29, 'truncation to week across month boundary' ); } { @@ -153,26 +154,26 @@ 'truncate to local_week returns correct date - locale start is Monday' ); } +} - { - my $dt = DateTime->new( - year => 2013, month => 11, day => 2, - locale => 'fr_FR' - )->truncate( to => 'local_week' ); +{ + my $dt = DateTime->new( + year => 2013, month => 11, day => 2, + locale => 'fr_FR' + )->truncate( to => 'local_week' ); - is( - $dt->year, 2013, - 'truncation to local_week across month boundary - locale start is Monday' - ); - is( - $dt->month, 10, - 'truncation to local_week across month boundary - locale start is Monday' - ); - is( - $dt->day, 28, - 'truncation to local_week across month boundary - locale start is Monday' - ); - } + is( + $dt->year, 2013, + 'truncation to local_week across month boundary - locale start is Monday' + ); + is( + $dt->month, 10, + 'truncation to local_week across month boundary - locale start is Monday' + ); + is( + $dt->day, 28, + 'truncation to local_week across month boundary - locale start is Monday' + ); } { @@ -200,25 +201,95 @@ 'truncate to local_week returns correct date - locale start is Sunday' ); } +} - { - my $dt = DateTime->new( - year => 2013, month => 11, day => 2, - locale => 'en_US' - )->truncate( to => 'local_week' ); +{ + my $dt = DateTime->new( + year => 2013, month => 11, day => 2, + locale => 'en_US' + )->truncate( to => 'local_week' ); - is( - $dt->year, 2013, - 'truncation to local_week across month boundary - locale start is Sunday' - ); - is( - $dt->month, 10, - 'truncation to local_week across month boundary - locale start is Sunday' - ); - is( - $dt->day, 27, - 'truncation to local_week across month boundary - locale start is Sunday' - ); + is( + $dt->year, 2013, + 'truncation to local_week across month boundary - locale start is Sunday' + ); + is( + $dt->month, 10, + 'truncation to local_week across month boundary - locale start is Sunday' + ); + is( + $dt->day, 27, + 'truncation to local_week across month boundary - locale start is Sunday' + ); +} + +{ + my %months_to_quarter = ( + 1 => 1, + 2 => 1, + 3 => 1, + 4 => 4, + 5 => 4, + 6 => 4, + 7 => 7, + 8 => 7, + 9 => 7, + 10 => 10, + 11 => 10, + 12 => 10, + ); + + for my $year ( -1, 100, 2016 ) { + for my $month ( sort keys %months_to_quarter ) { + for my $day ( 1, 15, 27 ) { + my $dt = DateTime->new( + year => $year, + month => $month, + day => $day, + ); + subtest( + 'truncate to quarter - ' . $dt->ymd, + sub { + $dt->truncate( to => 'quarter' ); + is( + $dt->year, + $year, + 'year is unchanged' + ); + is( + $dt->month, + $months_to_quarter{$month}, + "month $month becomes month $months_to_quarter{$month}" + ); + is( + $dt->day, + 1, + 'day is always 1' + ); + is( + $dt->hour, + 0, + 'hour is always 0' + ); + is( + $dt->minute, + 0, + 'minute is always 0' + ); + is( + $dt->second, + 0, + 'second is always 0' + ); + is( + $dt->nanosecond, + 0, + 'nanosecond is always 0' + ); + } + ); + } + } } } @@ -228,7 +299,7 @@ for my $bad (qw( seconds minutes year_foo month_bar )) { like( exception { $dt->truncate( to => $bad ) }, - qr/\QThe 'to' parameter/, + qr/Validation failed for type named TruncationLevel/, "bad truncate parameter ($bad) throws an error" ); } diff -Nru libdatetime-perl-1.21/t/17set-return.t libdatetime-perl-1.46/t/17set-return.t --- libdatetime-perl-1.21/t/17set-return.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/17set-return.t 2018-02-11 23:36:51.000000000 +0000 @@ -13,25 +13,25 @@ my $p; $p = $dt->set( year => 1882 ); - is( DateTime->compare( $p, $dt ), 0, "set() returns self" ); + is( DateTime->compare( $p, $dt ), 0, 'set returns self' ); $p = $dt->set_time_zone('Australia/Sydney'); - is( DateTime->compare( $p, $dt ), 0, "set_time_zone() returns self" ); + is( DateTime->compare( $p, $dt ), 0, 'set_time_zone returns self' ); $p = $dt->add_duration($du); - is( DateTime->compare( $p, $dt ), 0, "add_duration() returns self" ); + is( DateTime->compare( $p, $dt ), 0, 'add_duration returns self' ); $p = $dt->add( years => 2 ); - is( DateTime->compare( $p, $dt ), 0, "add() returns self" ); + is( DateTime->compare( $p, $dt ), 0, 'add returns self' ); $p = $dt->subtract_duration($du); - is( DateTime->compare( $p, $dt ), 0, "subtract_duration() returns self" ); + is( DateTime->compare( $p, $dt ), 0, 'subtract_duration returns self' ); $p = $dt->subtract( years => 3 ); - is( DateTime->compare( $p, $dt ), 0, "subtract() returns self" ); + is( DateTime->compare( $p, $dt ), 0, 'subtract returns self' ); $p = $dt->truncate( to => 'day' ); - is( DateTime->compare( $p, $dt ), 0, "truncate() returns self" ); + is( DateTime->compare( $p, $dt ), 0, 'truncate returns self' ); } diff -Nru libdatetime-perl-1.21/t/19leap-second.t libdatetime-perl-1.46/t/19leap-second.t --- libdatetime-perl-1.21/t/19leap-second.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/19leap-second.t 2018-02-11 23:36:51.000000000 +0000 @@ -4,52 +4,53 @@ use Test::Fatal; use Test::More; use DateTime; +use DateTime::LeapSecond; # tests using UTC times { # 1972-06-30T23:58:20 UTC my $t = DateTime->new( - year => 1972, month => 6, day => 30, - hour => 23, minute => 58, second => 20, + year => 1972, month => 6, day => 30, + hour => 23, minute => 58, second => 20, time_zone => 'UTC', ); my $t1 = $t->clone; - is( $t->year, 1972, "year is 1972" ); - is( $t->minute, 58, "minute is 58" ); - is( $t->second, 20, "second is 20" ); + is( $t->year, 1972, 'year is 1972' ); + is( $t->minute, 58, 'minute is 58' ); + is( $t->second, 20, 'second is 20' ); # 1972-06-30T23:59:20 UTC $t->add( seconds => 60 ); - is( $t->year, 1972, "year is 1972" ); - is( $t->minute, 59, "minute is 59" ); - is( $t->second, 20, "second is 20" ); + is( $t->year, 1972, 'year is 1972' ); + is( $t->minute, 59, 'minute is 59' ); + is( $t->second, 20, 'second is 20' ); # 1972-07-01T00:00:19 UTC $t->add( seconds => 60 ); - is( $t->year, 1972, "year is 1972" ); - is( $t->minute, 0, "minute is 0" ); - is( $t->second, 19, "second is 19" ); + is( $t->year, 1972, 'year is 1972' ); + is( $t->minute, 0, 'minute is 0' ); + is( $t->second, 19, 'second is 19' ); # 1972-06-30T23:59:60 UTC $t->subtract( seconds => 20 ); - is( $t->year, 1972, "year is 1972" ); - is( $t->minute, 59, "minute is 59" ); - is( $t->second, 60, "second is 60" ); - is( $t->{utc_rd_secs}, 86400, "utc_rd_secs is 86400" ); + is( $t->year, 1972, 'year is 1972' ); + is( $t->minute, 59, 'minute is 59' ); + is( $t->second, 60, 'second is 60' ); + is( $t->{utc_rd_secs}, 86400, 'utc_rd_secs is 86400' ); # subtract_datetime my $t2 = DateTime->new( - year => 1972, month => 07, day => 1, - hour => 0, minute => 0, second => 20, + year => 1972, month => 7, day => 1, + hour => 0, minute => 0, second => 20, time_zone => 'UTC', ); my $dur = $t2->subtract_datetime_absolute($t1); - is( $dur->delta_seconds, 121, "delta_seconds is 121" ); + is( $dur->delta_seconds, 121, 'delta_seconds is 121' ); $dur = $t1->subtract_datetime_absolute($t2); - is( $dur->delta_seconds, -121, "delta_seconds is -121" ); + is( $dur->delta_seconds, -121, 'delta_seconds is -121' ); } { @@ -58,32 +59,32 @@ # a floating time has no leap seconds my $t = DateTime->new( - year => 1971, month => 12, day => 31, - hour => 23, minute => 58, second => 20, + year => 1971, month => 12, day => 31, + hour => 23, minute => 58, second => 20, time_zone => 'floating', ); my $t1 = $t->clone; $t->add( seconds => 60 ); - is( $t->minute, 59, "min" ); - is( $t->second, 20, "sec" ); + is( $t->minute, 59, 'min' ); + is( $t->second, 20, 'sec' ); $t->add( seconds => 60 ); - is( $t->minute, 0, "min" ); - is( $t->second, 20, "sec" ); + is( $t->minute, 0, 'min' ); + is( $t->second, 20, 'sec' ); # subtract_datetime, using floating times my $t2 = DateTime->new( - year => 1972, month => 1, day => 1, - hour => 0, minute => 0, second => 20, + year => 1972, month => 1, day => 1, + hour => 0, minute => 0, second => 20, time_zone => 'floating', ); my $dur = $t2->subtract_datetime_absolute($t1); - is( $dur->delta_seconds, 120, "delta_seconds is 120" ); + is( $dur->delta_seconds, 120, 'delta_seconds is 120' ); $dur = $t1->subtract_datetime_absolute($t2); - is( $dur->delta_seconds, -120, "delta_seconds is -120" ); + is( $dur->delta_seconds, -120, 'delta_seconds is -120' ); } { @@ -93,33 +94,33 @@ # 1972-06-30 20:58:20 -03:00 = 1972-06-30 23:58:20 UTC my $t = DateTime->new( - year => 1972, month => 6, day => 30, - hour => 20, minute => 58, second => 20, + year => 1972, month => 6, day => 30, + hour => 20, minute => 58, second => 20, time_zone => 'America/Sao_Paulo', ); $t->add( seconds => 60 ); - is( $t->datetime, '1972-06-30T20:59:20', "normal add" ); - is( $t->minute, 59, "min" ); - is( $t->second, 20, "sec" ); + is( $t->datetime, '1972-06-30T20:59:20', 'normal add' ); + is( $t->minute, 59, 'min' ); + is( $t->second, 20, 'sec' ); $t->add( seconds => 60 ); - is( $t->datetime, '1972-06-30T21:00:19', "add over a leap second" ); - is( $t->minute, 0, "min" ); - is( $t->second, 19, "sec" ); + is( $t->datetime, '1972-06-30T21:00:19', 'add over a leap second' ); + is( $t->minute, 0, 'min' ); + is( $t->second, 19, 'sec' ); $t->subtract( seconds => 20 ); - is( $t->datetime, '1972-06-30T20:59:60', "subtract over a leap second" ); - is( $t->minute, 59, "min" ); - is( $t->second, 60, "sec" ); - is( $t->{utc_rd_secs}, 86400, "rd_sec" ); + is( $t->datetime, '1972-06-30T20:59:60', 'subtract over a leap second' ); + is( $t->minute, 59, 'min' ); + is( $t->second, 60, 'sec' ); + is( $t->{utc_rd_secs}, 86400, 'rd_sec' ); } # test that we can set second to 60 (negative offset) { my $t = DateTime->new( - year => 1972, month => 6, day => 30, - hour => 20, minute => 59, second => 60, + year => 1972, month => 6, day => 30, + hour => 20, minute => 59, second => 60, time_zone => 'America/Sao_Paulo', ); @@ -128,8 +129,8 @@ { my $t = DateTime->new( - year => 1972, month => 6, day => 30, - hour => 21, minute => 0, second => 0, + year => 1972, month => 6, day => 30, + hour => 21, minute => 0, second => 0, time_zone => 'America/Sao_Paulo', ); @@ -138,8 +139,8 @@ { my $t = DateTime->new( - year => 1972, month => 6, day => 30, - hour => 21, minute => 0, second => 1, + year => 1972, month => 6, day => 30, + hour => 21, minute => 0, second => 1, time_zone => 'America/Sao_Paulo', ); @@ -148,51 +149,48 @@ # test that we can set second to 60 (negative offset) { - eval { - my $t = DateTime->new( - year => 1972, month => 6, day => 30, - hour => 22, minute => 59, second => 60, - time_zone => '-0100', - ); - - is( - $t->second, 60, - 'second set to 60 in constructor, negative TZ offset' - ); - }; - - if ($@) { - ok( 0, "Error setting second to 60 in constructor: $@" ); - } + is( + exception { + my $t = DateTime->new( + year => 1972, month => 6, day => 30, + hour => 22, minute => 59, second => 60, + time_zone => '-0100', + ); + + is( + $t->second, 60, + 'second set to 60 in constructor, negative TZ offset' + ); + }, + undef, + 'can set second to 60 in constructor' + ); } # test that we can set second to 60 (positive offset) { - eval { - my $t = DateTime->new( - year => 1972, month => 7, day => 1, - hour => 0, minute => 59, second => 60, - time_zone => '+0100', - ); - - is( - $t->second, 60, - 'second set to 60 in constructor, positive TZ offset' - ); - }; - - if ($@) { - ok( - 0, - "Error setting second to 60 in constructor, positive TZ offset: $@" - ); - } + is( + exception { + my $t = DateTime->new( + year => 1972, month => 7, day => 1, + hour => 0, minute => 59, second => 60, + time_zone => '+0100', + ); + + is( + $t->second, 60, + 'second set to 60 in constructor, positive TZ offset' + ); + }, + undef, + 'can set second to 60 with positive TZ offset' + ); } { my $t = DateTime->new( - year => 1972, month => 7, day => 1, - hour => 0, minute => 59, second => 59, + year => 1972, month => 7, day => 1, + hour => 0, minute => 59, second => 59, time_zone => '+0100', ); @@ -201,8 +199,8 @@ { my $t = DateTime->new( - year => 1972, month => 7, day => 1, - hour => 1, minute => 0, second => 0, + year => 1972, month => 7, day => 1, + hour => 1, minute => 0, second => 0, time_zone => '+0100', ); @@ -211,8 +209,8 @@ { my $t = DateTime->new( - year => 1972, month => 7, day => 1, - hour => 1, minute => 0, second => 1, + year => 1972, month => 7, day => 1, + hour => 1, minute => 0, second => 1, time_zone => '+0100', ); @@ -221,8 +219,8 @@ { my $t = DateTime->new( - year => 1972, month => 7, day => 1, - hour => 0, minute => 0, second => 29, + year => 1972, month => 7, day => 1, + hour => 0, minute => 0, second => 29, time_zone => '+00:00:30', ); @@ -235,8 +233,8 @@ { my $t = DateTime->new( - year => 1972, month => 6, day => 30, - hour => 20, minute => 59, second => 60, + year => 1972, month => 6, day => 30, + hour => 20, minute => 59, second => 60, time_zone => 'America/Sao_Paulo', ); @@ -262,8 +260,8 @@ { my $t = DateTime->new( - year => 1972, month => 6, day => 30, - hour => 23, minute => 59, second => 59, + year => 1972, month => 6, day => 30, + hour => 23, minute => 59, second => 59, time_zone => 'UTC', ); @@ -349,44 +347,50 @@ } { - eval { - DateTime->new( - year => 1972, month => 12, day => 31, - hour => 23, minute => 59, second => 61, - time_zone => 'UTC', - ); - }; - ok( $@, "Cannot give second of 61 except when it matches a leap second" ); - - eval { - DateTime->new( - year => 1972, month => 12, day => 31, - hour => 23, minute => 58, second => 60, - time_zone => 'UTC', - ); - }; - ok( $@, "Cannot give second of 60 except when it matches a leap second" ); - - eval { - DateTime->new( - year => 1972, month => 12, day => 31, - hour => 23, minute => 59, second => 60, - time_zone => 'floating', - ); - }; - ok( $@, "Cannot give second of 60 with floating time zone" ); + ok( + exception { + DateTime->new( + year => 1972, month => 12, day => 31, + hour => 23, minute => 59, second => 61, + time_zone => 'UTC', + ); + }, + 'Cannot give second of 61 except when it matches a leap second' + ); + + ok( + exception { + DateTime->new( + year => 1972, month => 12, day => 31, + hour => 23, minute => 58, second => 60, + time_zone => 'UTC', + ); + }, + 'Cannot give second of 60 except when it matches a leap second' + ); + + ok( + exception { + DateTime->new( + year => 1972, month => 12, day => 31, + hour => 23, minute => 59, second => 60, + time_zone => 'floating', + ); + }, + 'Cannot give second of 60 with floating time zone' + ); } { my $dt1 = DateTime->new( - year => 1998, month => 12, day => 31, - hour => 23, minute => 59, second => 60, + year => 1998, month => 12, day => 31, + hour => 23, minute => 59, second => 60, time_zone => 'UTC', ); my $dt2 = DateTime->new( - year => 1998, month => 12, day => 31, - hour => 23, minute => 58, second => 50, + year => 1998, month => 12, day => 31, + hour => 23, minute => 58, second => 50, time_zone => 'UTC', ); @@ -403,14 +407,14 @@ { my $dt1 = DateTime->new( - year => 1998, month => 12, day => 31, - hour => 23, minute => 59, second => 55, + year => 1998, month => 12, day => 31, + hour => 23, minute => 59, second => 55, time_zone => 'UTC', ); my $dt2 = DateTime->new( - year => 1998, month => 12, day => 31, - hour => 23, minute => 58, second => 50, + year => 1998, month => 12, day => 31, + hour => 23, minute => 58, second => 50, time_zone => 'UTC', ); @@ -427,14 +431,14 @@ { my $dt1 = DateTime->new( - year => 1998, month => 12, day => 31, - hour => 23, minute => 59, second => 55, + year => 1998, month => 12, day => 31, + hour => 23, minute => 59, second => 55, time_zone => 'UTC', ); my $dt2 = DateTime->new( - year => 1999, month => 1, day => 1, - hour => 0, minute => 0, second => 30, + year => 1999, month => 1, day => 1, + hour => 0, minute => 0, second => 30, time_zone => 'UTC', ); @@ -452,15 +456,15 @@ # catch off-by-one when carrying a leap second { my $dt1 = DateTime->new( - year => 1998, month => 12, day => 31, - hour => 23, minute => 59, second => 0, + year => 1998, month => 12, day => 31, + hour => 23, minute => 59, second => 0, nanosecond => 1, time_zone => 'UTC', ); my $dt2 = DateTime->new( - year => 1999, month => 1, day => 1, - hour => 0, minute => 0, second => 0, + year => 1999, month => 1, day => 1, + hour => 0, minute => 0, second => 0, time_zone => 'UTC', ); @@ -476,8 +480,8 @@ { my $dt = DateTime->new( - year => 1972, month => 6, day => 30, - hour => 23, minute => 58, second => 20, + year => 1972, month => 6, day => 30, + hour => 23, minute => 58, second => 20, time_zone => 'UTC', ); @@ -485,15 +489,15 @@ is( $dt->datetime, '1972-07-02T23:58:20', - "add two days crossing a leap second (UTC)" + 'add two days crossing a leap second (UTC)' ); } # a bunch of tests that math works across a leap second for various time zones { my $dt = DateTime->new( - year => 1972, month => 6, day => 30, - hour => 20, minute => 58, second => 20, + year => 1972, month => 6, day => 30, + hour => 20, minute => 58, second => 20, time_zone => '-0300', ); @@ -501,14 +505,14 @@ is( $dt->datetime, '1972-07-02T20:58:20', - "add two days crossing a leap second (-0300)" + 'add two days crossing a leap second (-0300)' ); } { my $dt = DateTime->new( - year => 1972, month => 7, day => 1, - hour => 2, minute => 58, second => 20, + year => 1972, month => 7, day => 1, + hour => 2, minute => 58, second => 20, time_zone => '+0300', ); @@ -516,14 +520,14 @@ is( $dt->datetime, '1972-07-03T02:58:20', - "add two days crossing a leap second (+0300)" + 'add two days crossing a leap second (+0300)' ); } { my $dt = DateTime->new( - year => 1972, month => 6, day => 30, - hour => 23, minute => 58, second => 20, + year => 1972, month => 6, day => 30, + hour => 23, minute => 58, second => 20, time_zone => 'UTC', ); @@ -531,14 +535,14 @@ is( $dt->datetime, '1972-07-02T23:58:20', - "add 48 hours crossing a leap second (UTC)" + 'add 48 hours crossing a leap second (UTC)' ); } { my $dt = DateTime->new( - year => 1972, month => 6, day => 30, - hour => 20, minute => 58, second => 20, + year => 1972, month => 6, day => 30, + hour => 20, minute => 58, second => 20, time_zone => '-0300', ); @@ -546,14 +550,14 @@ is( $dt->datetime, '1972-07-02T20:58:20', - "add 48 hours crossing a leap second (-0300)" + 'add 48 hours crossing a leap second (-0300)' ); } { my $dt = DateTime->new( - year => 1972, month => 7, day => 1, - hour => 2, minute => 58, second => 20, + year => 1972, month => 7, day => 1, + hour => 2, minute => 58, second => 20, time_zone => '+0300', ); @@ -561,14 +565,14 @@ is( $dt->datetime, '1972-07-03T02:58:20', - "add 48 hours crossing a leap second (+0300)" + 'add 48 hours crossing a leap second (+0300)' ); } { my $dt = DateTime->new( - year => 1972, month => 6, day => 30, - hour => 23, minute => 58, second => 20, + year => 1972, month => 6, day => 30, + hour => 23, minute => 58, second => 20, time_zone => 'UTC', ); @@ -576,14 +580,14 @@ is( $dt->datetime, '1972-07-02T23:58:20', - "add 2880 minutes crossing a leap second (UTC)" + 'add 2880 minutes crossing a leap second (UTC)' ); } { my $dt = DateTime->new( - year => 1972, month => 6, day => 30, - hour => 20, minute => 58, second => 20, + year => 1972, month => 6, day => 30, + hour => 20, minute => 58, second => 20, time_zone => '-0300', ); @@ -591,14 +595,14 @@ is( $dt->datetime, '1972-07-02T20:58:20', - "add 2880 minutes crossing a leap second (-0300)" + 'add 2880 minutes crossing a leap second (-0300)' ); } { my $dt = DateTime->new( - year => 1972, month => 7, day => 1, - hour => 2, minute => 58, second => 20, + year => 1972, month => 7, day => 1, + hour => 2, minute => 58, second => 20, time_zone => '+0300', ); @@ -606,14 +610,14 @@ is( $dt->datetime, '1972-07-03T02:58:20', - "add 2880 minutes crossing a leap second (+0300)" + 'add 2880 minutes crossing a leap second (+0300)' ); } { my $dt = DateTime->new( - year => 1972, month => 6, day => 30, - hour => 23, minute => 58, second => 20, + year => 1972, month => 6, day => 30, + hour => 23, minute => 58, second => 20, time_zone => 'UTC', ); @@ -621,14 +625,14 @@ is( $dt->datetime, '1972-07-02T23:58:20', - "add 172801 seconds crossing a leap second (UTC)" + 'add 172801 seconds crossing a leap second (UTC)' ); } { my $dt = DateTime->new( - year => 1972, month => 6, day => 30, - hour => 20, minute => 58, second => 20, + year => 1972, month => 6, day => 30, + hour => 20, minute => 58, second => 20, time_zone => '-0300', ); @@ -636,14 +640,14 @@ is( $dt->datetime, '1972-07-02T20:58:20', - "add 172801 seconds crossing a leap second (-0300)" + 'add 172801 seconds crossing a leap second (-0300)' ); } { my $dt = DateTime->new( - year => 1972, month => 7, day => 1, - hour => 2, minute => 58, second => 20, + year => 1972, month => 7, day => 1, + hour => 2, minute => 58, second => 20, time_zone => '+0300', ); @@ -651,14 +655,14 @@ is( $dt->datetime, '1972-07-03T02:58:20', - "add 172801 seconds crossing a leap second (+0300)" + 'add 172801 seconds crossing a leap second (+0300)' ); } { my $dt = DateTime->new( - year => 1972, month => 7, day => 2, - hour => 23, minute => 58, second => 20, + year => 1972, month => 7, day => 2, + hour => 23, minute => 58, second => 20, time_zone => 'UTC', ); @@ -666,14 +670,14 @@ is( $dt->datetime, '1972-06-30T23:58:20', - "subtract two days crossing a leap second (UTC)" + 'subtract two days crossing a leap second (UTC)' ); } { my $dt = DateTime->new( - year => 1972, month => 7, day => 2, - hour => 20, minute => 58, second => 20, + year => 1972, month => 7, day => 2, + hour => 20, minute => 58, second => 20, time_zone => '-0300', ); @@ -681,14 +685,14 @@ is( $dt->datetime, '1972-06-30T20:58:20', - "subtract two days crossing a leap second (-0300)" + 'subtract two days crossing a leap second (-0300)' ); } { my $dt = DateTime->new( - year => 1972, month => 7, day => 3, - hour => 2, minute => 58, second => 20, + year => 1972, month => 7, day => 3, + hour => 2, minute => 58, second => 20, time_zone => '+0300', ); @@ -696,14 +700,14 @@ is( $dt->datetime, '1972-07-01T02:58:20', - "subtract two days crossing a leap second (+0300)" + 'subtract two days crossing a leap second (+0300)' ); } { my $dt = DateTime->new( - year => 1972, month => 7, day => 2, - hour => 23, minute => 58, second => 20, + year => 1972, month => 7, day => 2, + hour => 23, minute => 58, second => 20, time_zone => 'UTC', ); @@ -711,14 +715,14 @@ is( $dt->datetime, '1972-06-30T23:58:20', - "subtract 48 hours crossing a leap second (UTC)" + 'subtract 48 hours crossing a leap second (UTC)' ); } { my $dt = DateTime->new( - year => 1972, month => 7, day => 2, - hour => 20, minute => 58, second => 20, + year => 1972, month => 7, day => 2, + hour => 20, minute => 58, second => 20, time_zone => '-0300', ); @@ -726,14 +730,14 @@ is( $dt->datetime, '1972-06-30T20:58:20', - "subtract 48 hours crossing a leap second (-0300)" + 'subtract 48 hours crossing a leap second (-0300)' ); } { my $dt = DateTime->new( - year => 1972, month => 7, day => 3, - hour => 2, minute => 58, second => 20, + year => 1972, month => 7, day => 3, + hour => 2, minute => 58, second => 20, time_zone => '+0300', ); @@ -741,14 +745,14 @@ is( $dt->datetime, '1972-07-01T02:58:20', - "subtract 48 hours crossing a leap second (+0300)" + 'subtract 48 hours crossing a leap second (+0300)' ); } { my $dt = DateTime->new( - year => 1972, month => 7, day => 2, - hour => 23, minute => 58, second => 20, + year => 1972, month => 7, day => 2, + hour => 23, minute => 58, second => 20, time_zone => 'UTC', ); @@ -756,14 +760,14 @@ is( $dt->datetime, '1972-06-30T23:58:20', - "subtract 2880 minutes crossing a leap second (UTC)" + 'subtract 2880 minutes crossing a leap second (UTC)' ); } { my $dt = DateTime->new( - year => 1972, month => 7, day => 2, - hour => 20, minute => 58, second => 20, + year => 1972, month => 7, day => 2, + hour => 20, minute => 58, second => 20, time_zone => '-0300', ); @@ -771,14 +775,14 @@ is( $dt->datetime, '1972-06-30T20:58:20', - "subtract 2880 minutes crossing a leap second (-0300)" + 'subtract 2880 minutes crossing a leap second (-0300)' ); } { my $dt = DateTime->new( - year => 1972, month => 7, day => 3, - hour => 2, minute => 58, second => 20, + year => 1972, month => 7, day => 3, + hour => 2, minute => 58, second => 20, time_zone => '+0300', ); @@ -786,14 +790,14 @@ is( $dt->datetime, '1972-07-01T02:58:20', - "subtract 2880 minutes crossing a leap second (+0300)" + 'subtract 2880 minutes crossing a leap second (+0300)' ); } { my $dt = DateTime->new( - year => 1972, month => 7, day => 2, - hour => 23, minute => 58, second => 20, + year => 1972, month => 7, day => 2, + hour => 23, minute => 58, second => 20, time_zone => 'UTC', ); @@ -801,14 +805,14 @@ is( $dt->datetime, '1972-06-30T23:58:20', - "subtract 172801 seconds crossing a leap second (UTC)" + 'subtract 172801 seconds crossing a leap second (UTC)' ); } { my $dt = DateTime->new( - year => 1972, month => 7, day => 2, - hour => 20, minute => 58, second => 20, + year => 1972, month => 7, day => 2, + hour => 20, minute => 58, second => 20, time_zone => '-0300', ); @@ -816,14 +820,14 @@ is( $dt->datetime, '1972-06-30T20:58:20', - "subtract 172801 seconds crossing a leap second (-0300)" + 'subtract 172801 seconds crossing a leap second (-0300)' ); } { my $dt = DateTime->new( - year => 1972, month => 7, day => 3, - hour => 2, minute => 58, second => 20, + year => 1972, month => 7, day => 3, + hour => 2, minute => 58, second => 20, time_zone => '+0300', ); @@ -831,14 +835,14 @@ is( $dt->datetime, '1972-07-01T02:58:20', - "subtract 172801 seconds crossing a leap second (+0300)" + 'subtract 172801 seconds crossing a leap second (+0300)' ); } { my $dt = DateTime->new( - year => 1972, month => 7, day => 1, - hour => 12, minute => 58, second => 20, + year => 1972, month => 7, day => 1, + hour => 12, minute => 58, second => 20, time_zone => '+1200', ); @@ -846,14 +850,14 @@ is( $dt->datetime, '1972-06-30T12:58:20', - "24 hour time zone change near leap second" + '24 hour time zone change near leap second' ); } { my $dt = DateTime->new( - year => 1972, month => 6, day => 30, - hour => 12, minute => 58, second => 20, + year => 1972, month => 6, day => 30, + hour => 12, minute => 58, second => 20, time_zone => '-1200', ); @@ -861,7 +865,7 @@ is( $dt->datetime, '1972-07-01T12:58:20', - "24 hour time zone change near leap second" + '24 hour time zone change near leap second' ); } @@ -1085,8 +1089,8 @@ { my $dt = DateTime->new( - year => 2005, month => 12, day => 31, - hour => 23, minute => 59, second => 59, + year => 2005, month => 12, day => 31, + hour => 23, minute => 59, second => 59, time_zone => 'UTC', ); @@ -1101,8 +1105,8 @@ # and never rolled over to the following day { my $dt = DateTime->new( - year => 2005, month => 12, day => 31, - hour => 23, minute => 59, second => 59, + year => 2005, month => 12, day => 31, + hour => 23, minute => 59, second => 59, time_zone => 'UTC', ); @@ -1117,8 +1121,8 @@ # _non-leapsecond_ second addition { my $dt = DateTime->new( - year => 2005, month => 12, day => 30, - hour => 23, minute => 59, second => 58, + year => 2005, month => 12, day => 30, + hour => 23, minute => 59, second => 58, time_zone => 'UTC', ); @@ -1157,12 +1161,14 @@ [ 2008, 12, 31 ], [ 2012, 6, 30 ], [ 2015, 6, 30 ], - ) { + [ 2016, 12, 31 ], + ) { my $formatted = join '-', map { sprintf( '%02d', $_ ) } @{$date}; + my $dt; is( exception { - DateTime->new( + $dt = DateTime->new( year => $date->[0], month => $date->[1], day => $date->[2], @@ -1175,6 +1181,12 @@ undef, "We can make a DateTime object for the leap second on $formatted" ); + + is( + DateTime::LeapSecond::day_length( ( $dt->utc_rd_values )[0] ), + 86401, + "DateTime::LeapSecond::day_length returns 86401 for $formatted" + ); } } diff -Nru libdatetime-perl-1.21/t/20infinite.t libdatetime-perl-1.46/t/20infinite.t --- libdatetime-perl-1.21/t/20infinite.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/20infinite.t 2018-02-11 23:36:51.000000000 +0000 @@ -19,6 +19,25 @@ ok( !$pos->is_finite, 'positive infinity should not be finite' ); ok( !$neg->is_finite, 'negative infinity should not be finite' ); + # These methods produce numbers or strings - we want to make sure they all + # return Inf or -Inf as expected. + my @ification_methods = qw( + ymd mdy dmy hms time iso8601 datetime + year ce_year month day day_of_week + quarter + hour hour_1 hour_12 hour_12_0 minute second + fractional_second + week week_year week_number + mjd jd + nanosecond millisecond microsecond + epoch + ); + + for my $meth (@ification_methods) { + is( $pos->$meth, $posinf, "+Infinity $meth returns $posinf" ); + is( $neg->$meth, $neginf, "-Infinity $meth returns $neginf" ); + } + # that's a long time ago! my $long_ago = DateTime->new( year => -100_000 ); @@ -69,7 +88,7 @@ # NaN != NaN (but should stringify the same) is( - $deltas{$_} . '', $nan_string, + $deltas{$_} . q{}, $nan_string, "infinity - infinity = nan ($_)" ); } @@ -77,43 +96,43 @@ my $new_pos = $pos->clone->add( days => 10 ); ok( $new_pos == $pos, - "infinity + normal duration = infinity" + 'infinity + normal duration = infinity' ); my $new_pos2 = $pos->clone->subtract( days => 10 ); ok( $new_pos2 == $pos, - "infinity - normal duration = infinity" + 'infinity - normal duration = infinity' ); ok( $pos == $posinf, - "infinity (datetime) == infinity (number)" + 'infinity (datetime) == infinity (number)' ); ok( $neg == $neginf, - "neg infinity (datetime) == neg infinity (number)" + 'neg infinity (datetime) == neg infinity (number)' ); } # This could vary across platforms -my $pos_as_string = $posinf . ''; -my $neg_as_string = $neginf . ''; +my $pos_as_string = $posinf . q{}; +my $neg_as_string = $neginf . q{}; # formatting { foreach my $m ( qw( year month day hour minute second microsecond millisecond nanosecond ) - ) { + ) { is( - $pos->$m() . '', $pos_as_string, + $pos->$m() . q{}, $pos_as_string, "pos $m is $pos_as_string" ); is( - $neg->$m() . '', $neg_as_string, + $neg->$m() . q{}, $neg_as_string, "neg $m is $pos_as_string" ); } @@ -138,7 +157,7 @@ ok( $pos == $pos2, - "infinity (datetime) == infinity (datetime)" + 'infinity (datetime) == infinity (datetime)' ); } @@ -148,7 +167,7 @@ ok( $neg == $neg2, - "-infinity (datetime) == -infinity (datetime)" + '-infinity (datetime) == -infinity (datetime)' ); } diff -Nru libdatetime-perl-1.21/t/21bad-params.t libdatetime-perl-1.46/t/21bad-params.t --- libdatetime-perl-1.21/t/21bad-params.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/21bad-params.t 2018-02-11 23:36:51.000000000 +0000 @@ -1,6 +1,7 @@ use strict; use warnings; +use Test::Fatal; use Test::More; use DateTime; @@ -16,49 +17,57 @@ { year => 2000, month => 12, day => 10, hour => 12, minute => 60 }, { year => 2000, month => 12, day => 10, hour => 12, second => -1 }, { year => 2000, month => 12, day => 10, hour => 12, second => 62 }, - ) { - eval { DateTime->new(%$p) }; +) { like( - $@, qr/did not pass/, - "Parameters outside valid range should fail in call to new()" + exception { DateTime->new(%$p) }, + qr/Validation failed/, + 'Parameters outside valid range should fail in call to new()' ); - eval { DateTime->new( year => 2000 )->set(%$p) }; like( - $@, qr/did not pass/, - "Parameters outside valid range should fail in call to set()" + exception { DateTime->new( year => 2000 )->set(%$p) }, + qr/Validation failed/, + 'Parameters outside valid range should fail in call to set()' ); } { - eval { DateTime->last_day_of_month( year => 2000, month => 13 ) }; like( - $@, qr/did not pass/, - "Parameters outside valid range should fail in call to last_day_of_month()" + exception { + DateTime->last_day_of_month( + year => 2000, + month => 13, + ); + }, + qr/Validation failed/, + 'Parameters outside valid range should fail in call to last_day_of_month()' ); - eval { DateTime->last_day_of_month( year => 2000, month => 0 ) }; like( - $@, qr/did not pass/, - "Parameters outside valid range should fail in call to last_day_of_month()" + exception { DateTime->last_day_of_month( year => 2000, month => 0 ) }, + qr/Validation failed/, + 'Parameters outside valid range should fail in call to last_day_of_month()' ); } { - eval { DateTime->new( year => 2000, month => 4, day => 31 ) }; like( - $@, qr/valid day of month/i, - "Day past last day of month should fail" + exception { DateTime->new( year => 2000, month => 4, day => 31 ) }, + qr/valid day of month/i, + 'Day past last day of month should fail' ); - eval { DateTime->new( year => 2001, month => 2, day => 29 ) }; like( - $@, qr/valid day of month/i, - "Day past last day of month should fail" + exception { DateTime->new( year => 2001, month => 2, day => 29 ) }, + qr/valid day of month/i, + 'Day past last day of month should fail' ); - eval { DateTime->new( year => 2000, month => 2, day => 29 ) }; - ok( !$@, "February 29 should be valid in leap years" ); + is( + exception { DateTime->new( year => 2000, month => 2, day => 29 ) }, + undef, + 'February 29 should be valid in leap years' + ); } done_testing(); diff -Nru libdatetime-perl-1.21/t/22from-doy.t libdatetime-perl-1.46/t/22from-doy.t --- libdatetime-perl-1.21/t/22from-doy.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/22from-doy.t 2018-02-11 23:36:51.000000000 +0000 @@ -1,18 +1,19 @@ use strict; use warnings; +use Test::Fatal; use Test::More; use DateTime; -my @last = ( 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ); -my @leap_last = @last; -$leap_last[1]++; +my @last_day = ( 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ); +my @leap_last_day = @last_day; +$leap_last_day[1]++; { my $doy = 15; foreach my $month ( 1 .. 12 ) { - $doy += $last[ $month - 2 ] if $month > 1; + $doy += $last_day[ $month - 2 ] if $month > 1; my $dt = DateTime->from_day_of_year( year => 2001, @@ -30,7 +31,7 @@ { my $doy = 15; foreach my $month ( 1 .. 12 ) { - $doy += $leap_last[ $month - 2 ] if $month > 1; + $doy += $leap_last_day[ $month - 2 ] if $month > 1; my $dt = DateTime->from_day_of_year( year => 2004, @@ -46,14 +47,21 @@ } { - eval { DateTime->from_day_of_year( year => 2001, day_of_year => 366 ) }; like( - $@, qr/2001 is not a leap year/, - "Cannot give day of year 366 in non-leap years" + exception { + DateTime->from_day_of_year( year => 2001, day_of_year => 366 ) + }, + qr/2001 is not a leap year/, + 'Cannot give day of year 366 in non-leap years' ); - eval { DateTime->from_day_of_year( year => 2004, day_of_year => 366 ) }; - ok( !$@, "Day of year 366 should work in leap years" ); + is( + exception { + DateTime->from_day_of_year( year => 2004, day_of_year => 366 ) + }, + undef, + 'Day of year 366 should work in leap years' + ); } done_testing(); diff -Nru libdatetime-perl-1.21/t/23storable.t libdatetime-perl-1.46/t/23storable.t --- libdatetime-perl-1.21/t/23storable.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/23storable.t 2018-02-11 23:36:51.000000000 +0000 @@ -16,7 +16,7 @@ hour => 1, nanosecond => 1, time_zone => 'America/Chicago', - language => 'German' + locale => 'de' ), DateTime::Infinite::Past->new, DateTime::Infinite::Future->new, diff -Nru libdatetime-perl-1.21/t/24from-object.t libdatetime-perl-1.46/t/24from-object.t --- libdatetime-perl-1.21/t/24from-object.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/24from-object.t 2018-02-11 23:36:51.000000000 +0000 @@ -1,3 +1,4 @@ +## no critic (Modules::ProhibitMultiplePackages) use strict; use warnings; @@ -60,6 +61,17 @@ ); } +{ + for my $class (qw( DateTime::Infinite::Past DateTime::Infinite::Future )) + { + isa_ok( + DateTime->from_object( object => $class->new ), + $class, + "from_object($class)" + ); + } +} + done_testing(); # Set up two simple test packages diff -Nru libdatetime-perl-1.21/t/27delta.t libdatetime-perl-1.46/t/27delta.t --- libdatetime-perl-1.21/t/27delta.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/27delta.t 2018-02-11 23:36:51.000000000 +0000 @@ -7,15 +7,15 @@ { my $date1 = DateTime->new( - year => 2001, month => 5, day => 10, - hour => 4, minute => 3, second => 2, + year => 2001, month => 5, day => 10, + hour => 4, minute => 3, second => 2, nanosecond => 12, time_zone => 'UTC' ); my $date2 = DateTime->new( - year => 2001, month => 6, day => 12, - hour => 5, minute => 7, second => 23, + year => 2001, month => 6, day => 12, + hour => 5, minute => 7, second => 23, nanosecond => 7, time_zone => 'UTC' ); diff -Nru libdatetime-perl-1.21/t/28dow.t libdatetime-perl-1.46/t/28dow.t --- libdatetime-perl-1.21/t/28dow.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/28dow.t 2018-02-11 23:36:51.000000000 +0000 @@ -51,7 +51,7 @@ DateTime->from_day_of_year( year => $year, day_of_year => $doy, - )->day_of_week, + )->day_of_week, $dow, "day of week for day $doy of year $year is $dow" ); diff -Nru libdatetime-perl-1.21/t/29overload.t libdatetime-perl-1.46/t/29overload.t --- libdatetime-perl-1.21/t/29overload.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/29overload.t 2018-02-11 23:36:51.000000000 +0000 @@ -1,6 +1,7 @@ use strict; use warnings; +use Test::Fatal; use Test::More; use Test::Warnings 0.005 ':all'; @@ -50,10 +51,10 @@ my $after_od = Other::Date->new($after_string); my $before_od = Other::Date->new($before_string); - ok( $dt eq $same_od, "DateTime eq non-DateTime overloaded object true" ); - ok( !( $dt eq $after_od ), " eq false" ); - ok( $dt ne $after_od, " ne true" ); - ok( !( $dt ne $same_od ), " ne false" ); + ok( $dt eq $same_od, 'DateTime eq non-DateTime overloaded object true' ); + ok( !( $dt eq $after_od ), ' eq false' ); + ok( $dt ne $after_od, ' ne true' ); + ok( !( $dt ne $same_od ), ' ne false' ); is( $dt cmp $same_od, 0, 'cmp overloading' ); is( $dt cmp $after_od, -1, ' lt overloading' ); @@ -70,56 +71,54 @@ map { $_ . ' - ' . ( ref $_ || 'no ref' ) } $before_string, $before_od, $same_string, $dt, $same_od, $after_string, $after_od ], - "eq sort" + 'eq sort' ); - eval { my $x = $dt + 1 }; like( - $@, qr/Cannot add 1 to a DateTime object/, + exception { my $x = $dt + 1 }, + qr/Cannot add 1 to a DateTime object/, 'Cannot add plain scalar to a DateTime object' ); - eval { my $x = $dt + bless {}, 'FooBar' }; like( - $@, qr/Cannot add FooBar=HASH\([^\)]+\) to a DateTime object/, + exception { my $x = $dt + bless {}, 'FooBar' }, + qr/Cannot add FooBar=HASH\([^\)]+\) to a DateTime object/, 'Cannot add plain FooBar object to a DateTime object' ); - eval { my $x = $dt - 1 }; like( - $@, qr/Cannot subtract 1 from a DateTime object/, + exception { my $x = $dt - 1 }, + qr/Cannot subtract 1 from a DateTime object/, 'Cannot subtract plain scalar from a DateTime object' ); - eval { my $x = $dt - bless {}, 'FooBar' }; like( - $@, qr/Cannot subtract FooBar=HASH\([^\)]+\) from a DateTime object/, + exception { my $x = $dt - bless {}, 'FooBar' }, + qr/Cannot subtract FooBar=HASH\([^\)]+\) from a DateTime object/, 'Cannot subtract plain FooBar object from a DateTime object' ); - eval { my $x = $dt > 1 }; like( - $@, + exception { my $x = $dt > 1 }, qr/A DateTime object can only be compared to another DateTime object/, 'Cannot compare a DateTime object to a scalar' ); - eval { my $x = $dt > bless {}, 'FooBar' }; like( - $@, + exception { my $x = $dt > bless {}, 'FooBar' }, qr/A DateTime object can only be compared to another DateTime object/, 'Cannot compare a DateTime object to a FooBar object' ); like( warning { my $x = undef; $dt > $x; }, - qr/uninitialized value in numeric gt .+ at .*t.(release-pp-)?29overload\.t/, + qr/uninitialized value in numeric gt .+ at .*x?t.(author.pp.)?29overload\.t/, 'Comparing undef to a DateTime object generates a Perl warning at the right spot ($dt > undef)' ); like( warning { my $x = undef; $x > $dt; }, - qr/uninitialized value in numeric gt .+ at .*t.(release-pp-)?29overload\.t/, + qr/uninitialized value in numeric gt .+ at .*x?t.(author.pp.)?29overload\.t/, 'Comparing undef to a DateTime object generates a Perl warning at the right spot (undef > $dt)' ); diff -Nru libdatetime-perl-1.21/t/30future-tz.t libdatetime-perl-1.46/t/30future-tz.t --- libdatetime-perl-1.21/t/30future-tz.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/30future-tz.t 2018-02-11 23:36:51.000000000 +0000 @@ -18,24 +18,24 @@ # Each iteration needs to use a different zone, because if it # works once, the generated spans are cached. for my $add ( - [ years => 50, 1, 'America/New_York' ], - [ days => 50, 365, 'America/Chicago' ], - [ minutes => 50, 365 * 1440, 'America/Denver', ], + [ years => 50, 1, 'America/New_York' ], + [ days => 50, 365, 'America/Chicago' ], + [ minutes => 50, 365 * 1440, 'America/Denver', ], [ seconds => 50, 365 * 1440 * 60, 'America/Los_Angeles' ], [ nanoseconds => 50, 365 * 1440 * 60 * 1_000_000_000, 'America/North_Dakota/Center' ], - [ years => 750, 1, 'Europe/Paris' ], - [ days => 750, 365, 'Europe/London' ], - [ minutes => 750, 365 * 1440, 'Europe/Brussels', ], + [ years => 750, 1, 'Europe/Paris' ], + [ days => 750, 365, 'Europe/London' ], + [ minutes => 750, 365 * 1440, 'Europe/Brussels', ], [ seconds => 750, 365 * 1440 * 60, 'Europe/Vienna' ], [ nanoseconds => 750, 365 * 1440 * 60 * 1_000_000_000, 'Europe/Prague' ], - ) { + ) { my $dt = DateTime->now->set( hour => 12 )->set_time_zone( $add->[3] ); diff -Nru libdatetime-perl-1.21/t/31formatter.t libdatetime-perl-1.46/t/31formatter.t --- libdatetime-perl-1.21/t/31formatter.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/31formatter.t 2018-02-11 23:36:51.000000000 +0000 @@ -1,6 +1,7 @@ use strict; use warnings; +use Test::Fatal; use Test::More; use DateTime; @@ -19,11 +20,36 @@ my $formatter = Formatter->new(); -my $dt = DateTime->from_epoch( epoch => time(), formatter => $formatter ); -ok( $dt, "Constructor (from_epoch) : $@" ); +{ + is( + exception { + DateTime->from_epoch( epoch => time(), formatter => $formatter ) + }, + undef, + 'passed formatter to from_epoch' + ); +} + +{ + is( + exception { + DateTime->new( + year => 2004, + month => 9, + day => 2, + hour => 13, + minute => 23, + second => 34, + formatter => $formatter + ); + }, + undef, + 'passed formatter to new' + ); +} -$dt = eval { - DateTime->new( +{ + my $from = DateTime->new( year => 2004, month => 9, day => 2, @@ -32,42 +58,54 @@ second => 34, formatter => $formatter ); -}; -ok( $dt, "Constructor (new) : $@" ); + my $dt; + is( + exception { + $dt = DateTime->from_object( + object => $from, + formatter => $formatter + ); + }, + undef, + 'passed formatter to from_object' + ); + + is( + $dt->formatter, $formatter, + 'check from_object copies formatter' + ); + + is( $dt->stringify(), '20040902 13:23:34', 'Format datetime' ); + + # check stringification (with formatter) + is( $dt->stringify, "$dt", 'Stringification (with formatter)' ); + + # check that set() and truncate() don't lose formatter + $dt->set( hour => 3 ); + is( + $dt->stringify, '20040902 03:23:34', + 'formatter is preserved after set()' + ); -$dt - = eval { DateTime->from_object( object => $dt, formatter => $formatter ) }; -ok( $dt, "Constructor (from_object) : $@" ); - -is( $dt->formatter, $formatter, "check from_object copies formatter" ); - -is( $dt->_stringify(), '20040902 13:23:34', 'Format datetime' ); - -# check stringification (with formatter) -is( $dt->_stringify, "$dt", "Stringification (with formatter)" ); - -# check that set() and truncate() don't lose formatter -$dt->set( hour => 3 ); -is( - $dt->_stringify, '20040902 03:23:34', - 'formatter is preserved after set()' -); - -$dt->truncate( to => 'minute' ); -is( - $dt->_stringify, '20040902 03:23:00', - 'formatter is preserved after truncate()' -); - -# check if the default behavior works -$dt->set_formatter(undef); -is( $dt->_stringify(), $dt->iso8601, 'Default iso8601 works' ); - -# check stringification (default) -is( - $dt->_stringify, "$dt", - "Stringification (no formatter -> format_datetime)" -); -is( $dt->iso8601, "$dt", "Stringification (no formatter -> iso8601)" ); + $dt->truncate( to => 'minute' ); + is( + $dt->stringify, '20040902 03:23:00', + 'formatter is preserved after truncate()' + ); + + # check if the default behavior works + $dt->set_formatter(undef); + is( $dt->stringify(), $dt->iso8601, 'Default iso8601 works' ); + + # check stringification (default) + is( + $dt->stringify, "$dt", + 'Stringification (no formatter -> format_datetime)' + ); + is( + $dt->iso8601, "$dt", + 'Stringification (no formatter -> iso8601)' + ); +} done_testing(); diff -Nru libdatetime-perl-1.21/t/32leap-second2.t libdatetime-perl-1.46/t/32leap-second2.t --- libdatetime-perl-1.21/t/32leap-second2.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/32leap-second2.t 2018-02-11 23:36:51.000000000 +0000 @@ -7,8 +7,8 @@ { my $t = DateTime->new( - year => 1972, month => 7, day => 1, - hour => 0, minute => 59, second => 58, + year => 1972, month => 7, day => 1, + hour => 0, minute => 59, second => 58, time_zone => '+0100', ); @@ -35,8 +35,8 @@ { my $t = DateTime->new( - year => 1972, month => 7, day => 1, - hour => 0, minute => 59, second => 59, + year => 1972, month => 7, day => 1, + hour => 0, minute => 59, second => 59, time_zone => '+0100', ); @@ -63,8 +63,8 @@ { my $t = eval { DateTime->new( - year => 1972, month => 7, day => 1, - hour => 0, minute => 59, second => 60, + year => 1972, month => 7, day => 1, + hour => 0, minute => 59, second => 60, time_zone => '+0100', ); }; @@ -99,8 +99,8 @@ { my $t = DateTime->new( - year => 1972, month => 7, day => 1, - hour => 1, minute => 0, second => 0, + year => 1972, month => 7, day => 1, + hour => 1, minute => 0, second => 0, time_zone => '+0100', ); @@ -126,8 +126,8 @@ { my $t = DateTime->new( - year => 1972, month => 7, day => 1, - hour => 1, minute => 0, second => 1, + year => 1972, month => 7, day => 1, + hour => 1, minute => 0, second => 1, time_zone => '+0100', ); @@ -153,8 +153,8 @@ { my $t = DateTime->new( - year => 1972, month => 7, day => 1, - hour => 23, minute => 59, second => 59, + year => 1972, month => 7, day => 1, + hour => 23, minute => 59, second => 59, time_zone => '+0100', ); @@ -180,8 +180,8 @@ { my $t = DateTime->new( - year => 1972, month => 6, day => 30, - hour => 22, minute => 59, second => 58, + year => 1972, month => 6, day => 30, + hour => 22, minute => 59, second => 58, time_zone => '-0100', ); @@ -208,8 +208,8 @@ { my $t = DateTime->new( - year => 1972, month => 6, day => 30, - hour => 22, minute => 59, second => 59, + year => 1972, month => 6, day => 30, + hour => 22, minute => 59, second => 59, time_zone => '-0100', ); @@ -237,8 +237,8 @@ { my $t = eval { DateTime->new( - year => 1972, month => 6, day => 30, - hour => 22, minute => 59, second => 60, + year => 1972, month => 6, day => 30, + hour => 22, minute => 59, second => 60, time_zone => '-0100', ); }; @@ -274,8 +274,8 @@ { my $t = DateTime->new( - year => 1972, month => 6, day => 30, - hour => 23, minute => 0, second => 0, + year => 1972, month => 6, day => 30, + hour => 23, minute => 0, second => 0, time_zone => '-0100', ); @@ -302,8 +302,8 @@ { my $t = DateTime->new( - year => 1972, month => 6, day => 30, - hour => 23, minute => 0, second => 1, + year => 1972, month => 6, day => 30, + hour => 23, minute => 0, second => 1, time_zone => '-0100', ); diff -Nru libdatetime-perl-1.21/t/34set-tz.t libdatetime-perl-1.46/t/34set-tz.t --- libdatetime-perl-1.21/t/34set-tz.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/34set-tz.t 2018-02-11 23:36:51.000000000 +0000 @@ -21,8 +21,8 @@ # DT::TZ { my $dt = DateTime->new( - year => 1922, month => 8, day => 31, - hour => 23, minute => 59, second => 59, + year => 1922, month => 8, day => 31, + hour => 23, minute => 59, second => 59, time_zone => 'UTC', ); $dt->set_time_zone('Africa/Accra'); diff -Nru libdatetime-perl-1.21/t/36invalid-local.t libdatetime-perl-1.46/t/36invalid-local.t --- libdatetime-perl-1.21/t/36invalid-local.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/36invalid-local.t 2018-02-11 23:36:51.000000000 +0000 @@ -1,6 +1,7 @@ use strict; use warnings; +use Test::Fatal; use Test::More; use DateTime; @@ -8,43 +9,54 @@ my $badlt_rx = qr/Invalid local time|local time [0-9\-:T]+ does not exist/; { - eval { - DateTime->new( - year => 2003, month => 4, day => 6, - hour => 2, time_zone => 'America/Chicago', - ); - }; - - like( $@, $badlt_rx, 'exception for invalid time' ); - - eval { - DateTime->new( - year => 2003, month => 4, day => 6, - hour => 2, minute => 59, second => 59, - time_zone => 'America/Chicago', - ); - }; - like( $@, $badlt_rx, 'exception for invalid time' ); + like( + exception { + DateTime->new( + year => 2003, month => 4, day => 6, + hour => 2, time_zone => 'America/Chicago', + ); + }, + $badlt_rx, + 'exception for invalid time' + ); + + like( + exception { + DateTime->new( + year => 2003, month => 4, day => 6, + hour => 2, minute => 59, second => 59, + time_zone => 'America/Chicago', + ); + }, + $badlt_rx, + 'exception for invalid time' + ); } { - eval { - DateTime->new( - year => 2003, month => 4, day => 6, - hour => 1, minute => 59, second => 59, - time_zone => 'America/Chicago', - ); - }; - ok( !$@, 'no exception for valid time' ); + is( + exception { + DateTime->new( + year => 2003, month => 4, day => 6, + hour => 1, minute => 59, second => 59, + time_zone => 'America/Chicago', + ); + }, + undef, + 'no exception for valid time' + ); my $dt = DateTime->new( - year => 2003, month => 4, day => 5, - hour => 2, + year => 2003, month => 4, day => 5, + hour => 2, time_zone => 'America/Chicago', ); - eval { $dt->add( days => 1 ) }; - like( $@, $badlt_rx, 'exception for invalid time produced via add' ); + like( + exception { $dt->add( days => 1 ) }, + $badlt_rx, + 'exception for invalid time produced via add' + ); } done_testing(); diff -Nru libdatetime-perl-1.21/t/37local-add.t libdatetime-perl-1.46/t/37local-add.t --- libdatetime-perl-1.21/t/37local-add.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/37local-add.t 2018-02-11 23:36:51.000000000 +0000 @@ -1,6 +1,7 @@ use strict; use warnings; +use Test::Fatal; use Test::More; use DateTime; @@ -12,7 +13,7 @@ # say?" this means it acts on the UTC components. { my $dt = DateTime->new( - year => 2003, month => 4, day => 6, + year => 2003, month => 4, day => 6, time_zone => 'America/Chicago', ); @@ -22,8 +23,11 @@ 'add one hour to midnight, get 1 am' ); - eval { $dt->add( hours => 1 ) }; - is( $@, '', 'no error adding 1 hour just before DST leap forward' ); + is( + exception { $dt->add( hours => 1 ) }, + undef, + 'no error adding 1 hour just before DST leap forward' + ); is( $dt->datetime, '2003-04-06T03:00:00', 'add one hour to 1 am, get 3 am' @@ -44,7 +48,7 @@ { my $dt = DateTime->new( - year => 2003, month => 10, day => 26, + year => 2003, month => 10, day => 26, time_zone => 'America/Chicago', ); @@ -89,7 +93,7 @@ # portion". this means it acts on local components { my $dt = DateTime->new( - year => 2003, month => 4, day => 6, + year => 2003, month => 4, day => 6, time_zone => 'America/Chicago', ); @@ -120,7 +124,7 @@ { my $dt = DateTime->new( - year => 2003, month => 10, day => 26, + year => 2003, month => 10, day => 26, time_zone => 'America/Chicago', ); @@ -153,7 +157,7 @@ # First we do date, then time. { my $dt = DateTime->new( - year => 2003, month => 4, day => 5, + year => 2003, month => 4, day => 5, time_zone => 'America/Chicago', ); @@ -180,7 +184,7 @@ { my $dt = DateTime->new( - year => 2003, month => 10, day => 25, + year => 2003, month => 10, day => 25, time_zone => 'America/Chicago', ); @@ -206,8 +210,8 @@ # an example from the docs { my $dt = DateTime->new( - year => 2003, month => 4, day => 5, - hour => 2, + year => 2003, month => 4, day => 5, + hour => 2, time_zone => 'America/Chicago', ); diff -Nru libdatetime-perl-1.21/t/38local-subtract.t libdatetime-perl-1.46/t/38local-subtract.t --- libdatetime-perl-1.21/t/38local-subtract.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/38local-subtract.t 2018-02-11 23:36:51.000000000 +0000 @@ -10,12 +10,12 @@ { my $dt1 = DateTime->new( - year => 2003, month => 5, day => 6, + year => 2003, month => 5, day => 6, time_zone => 'America/Chicago', ); my $dt2 = DateTime->new( - year => 2003, month => 11, day => 6, + year => 2003, month => 11, day => 6, time_zone => 'America/Chicago', ); @@ -84,12 +84,12 @@ # are handled correctly. { my $dt1 = DateTime->new( - year => 2003, month => 5, day => 6, hour => 18, + year => 2003, month => 5, day => 6, hour => 18, time_zone => 'America/Chicago', ); my $dt2 = DateTime->new( - year => 2003, month => 11, day => 6, hour => 18, + year => 2003, month => 11, day => 6, hour => 18, time_zone => 'America/Chicago', ); @@ -106,12 +106,12 @@ # where we lose an hour { my $dt1 = DateTime->new( - year => 2003, month => 11, day => 6, + year => 2003, month => 11, day => 6, time_zone => 'America/Chicago', ); my $dt2 = DateTime->new( - year => 2004, month => 5, day => 6, + year => 2004, month => 5, day => 6, time_zone => 'America/Chicago', ); @@ -136,12 +136,12 @@ # the docs say use UTC to guarantee reversibility { my $dt1 = DateTime->new( - year => 2003, month => 5, day => 6, + year => 2003, month => 5, day => 6, time_zone => 'America/Chicago', ); my $dt2 = DateTime->new( - year => 2003, month => 11, day => 6, + year => 2003, month => 11, day => 6, time_zone => 'America/Chicago', ); @@ -165,12 +165,12 @@ # of subtraction done. { my $dt1 = DateTime->new( - year => 2003, month => 5, day => 6, + year => 2003, month => 5, day => 6, time_zone => 'America/Chicago', ); my $dt2 = DateTime->new( - year => 2003, month => 11, day => 6, + year => 2003, month => 11, day => 6, time_zone => 'America/Chicago', ); @@ -213,14 +213,14 @@ { my $dt1 = DateTime->new( - year => 2003, month => 4, day => 6, - hour => 1, minute => 58, + year => 2003, month => 4, day => 6, + hour => 1, minute => 58, time_zone => 'America/Chicago', ); my $dt2 = DateTime->new( - year => 2003, month => 4, day => 6, - hour => 3, minute => 1, + year => 2003, month => 4, day => 6, + hour => 3, minute => 1, time_zone => 'America/Chicago', ); @@ -245,14 +245,14 @@ { my $dt1 = DateTime->new( - year => 2003, month => 4, day => 5, - hour => 1, minute => 58, + year => 2003, month => 4, day => 5, + hour => 1, minute => 58, time_zone => 'America/Chicago', ); my $dt2 = DateTime->new( - year => 2003, month => 4, day => 6, - hour => 3, minute => 1, + year => 2003, month => 4, day => 6, + hour => 3, minute => 1, time_zone => 'America/Chicago', ); @@ -320,14 +320,14 @@ # they're the smaller operand { my $dt1 = DateTime->new( - year => 2003, month => 4, day => 6, - hour => 3, minute => 1, + year => 2003, month => 4, day => 6, + hour => 3, minute => 1, time_zone => 'America/Chicago', ); my $dt2 = DateTime->new( - year => 2003, month => 4, day => 7, - hour => 3, minute => 2, + year => 2003, month => 4, day => 7, + hour => 3, minute => 2, time_zone => 'America/Chicago', ); @@ -353,14 +353,14 @@ { my $dt1 = DateTime->new( - year => 2003, month => 4, day => 5, - hour => 1, minute => 58, + year => 2003, month => 4, day => 5, + hour => 1, minute => 58, time_zone => 'America/Chicago', ); my $dt2 = DateTime->new( - year => 2003, month => 4, day => 7, - hour => 2, minute => 1, + year => 2003, month => 4, day => 7, + hour => 2, minute => 1, time_zone => 'America/Chicago', ); @@ -386,12 +386,12 @@ # from example in docs { my $dt1 = DateTime->new( - year => 2003, month => 5, day => 6, + year => 2003, month => 5, day => 6, time_zone => 'America/Chicago', ); my $dt2 = DateTime->new( - year => 2003, month => 11, day => 6, + year => 2003, month => 11, day => 6, time_zone => 'America/Chicago', ); @@ -418,12 +418,12 @@ { my $dt1 = DateTime->new( - year => 2005, month => 8, + year => 2005, month => 8, time_zone => 'Europe/London', ); my $dt2 = DateTime->new( - year => 2005, month => 11, + year => 2005, month => 11, time_zone => 'Europe/London', ); @@ -443,12 +443,12 @@ # same as previous but without hours overflow { my $dt1 = DateTime->new( - year => 2005, month => 8, hour => 12, + year => 2005, month => 8, hour => 12, time_zone => 'Europe/London', ); my $dt2 = DateTime->new( - year => 2005, month => 11, hour => 12, + year => 2005, month => 11, hour => 12, time_zone => 'Europe/London', ); @@ -468,8 +468,8 @@ # another docs example { my $dt2 = DateTime->new( - year => 2003, month => 10, day => 26, - hour => 1, + year => 2003, month => 10, day => 26, + hour => 1, time_zone => 'America/Chicago', ); @@ -500,12 +500,12 @@ { my $dt1 = DateTime->new( - year => 2003, month => 5, day => 6, + year => 2003, month => 5, day => 6, time_zone => 'America/New_York', ); my $dt2 = DateTime->new( - year => 2003, month => 5, day => 6, + year => 2003, month => 5, day => 6, time_zone => 'America/Chicago', ); diff -Nru libdatetime-perl-1.21/t/39no-so.t libdatetime-perl-1.46/t/39no-so.t --- libdatetime-perl-1.21/t/39no-so.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/39no-so.t 2018-02-11 23:36:51.000000000 +0000 @@ -1,10 +1,13 @@ # no pp test +# HARNESS-NO-PRELOAD use strict; use warnings; +use Test::Fatal; use Test::More; +## no critic (TestingAndDebugging::ProhibitNoWarnings) no warnings 'once', 'redefine'; require XSLoader; @@ -22,8 +25,11 @@ *XSLoader::load = $sub; -eval { require DateTime }; -is( $@, '', 'No error loading DateTime without DateTime.so file' ); +is( + exception { require DateTime }, + undef,, 'No error loading DateTime without DateTime.so file' +); +## no critic (Variables::ProhibitPackageVars) ok( $DateTime::IsPurePerl, '$DateTime::IsPurePerl is true' ); ok( diff -Nru libdatetime-perl-1.21/t/40leap-years.t libdatetime-perl-1.46/t/40leap-years.t --- libdatetime-perl-1.21/t/40leap-years.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/40leap-years.t 2018-02-11 23:36:51.000000000 +0000 @@ -5,6 +5,7 @@ use DateTime; +## no critic (Subroutines::ProtectPrivateSubs) for my $y ( 0, 400, 2000, 2004 ) { ok( DateTime->_is_leap_year($y), "$y is a leap year" ); } diff -Nru libdatetime-perl-1.21/t/41cldr-format.t libdatetime-perl-1.46/t/41cldr-format.t --- libdatetime-perl-1.21/t/41cldr-format.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/41cldr-format.t 2018-02-11 23:36:51.000000000 +0000 @@ -6,9 +6,14 @@ use DateTime; -binmode $_, ':encoding(UTF-8)' for Test::Builder->new()->output(), - Test::Builder->new()->failure_output(), - Test::Builder->new()->todo_output(); +for my $o ( + Test::Builder->new->output, + Test::Builder->new->failure_output, + Test::Builder->new->todo_output +) { + + binmode $o, ':encoding(UTF-8)' or die $!; +} { my $dt = DateTime->new( @@ -113,7 +118,6 @@ 'KK' => '06', 'K' => '6', 'kk' => '18', - 'kk' => '18', 'j' => '6', 'jj' => '06', @@ -298,4 +302,24 @@ } } +{ + my $dt = DateTime->new( + year => 1976, + month => 10, + day => 20, + hour => 18, + minute => 34, + second => 55, + nanosecond => 999_999_999, + locale => 'en', + time_zone => 'UTC', + ); + + is( + $dt->format_cldr('ss,SSS'), + '55,999', + 'milliseconds are rounded down', + ); +} + done_testing(); diff -Nru libdatetime-perl-1.21/t/42duration-class.t libdatetime-perl-1.46/t/42duration-class.t --- libdatetime-perl-1.21/t/42duration-class.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/42duration-class.t 2018-02-11 23:36:51.000000000 +0000 @@ -1,3 +1,4 @@ +## no critic (Modules::ProhibitMultiplePackages) use strict; use warnings; @@ -5,7 +6,6 @@ use DateTime; { - package DateTime::MySubclass; use base 'DateTime'; diff -Nru libdatetime-perl-1.21/t/43new-params.t libdatetime-perl-1.46/t/43new-params.t --- libdatetime-perl-1.21/t/43new-params.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/43new-params.t 2018-02-11 23:36:51.000000000 +0000 @@ -8,24 +8,24 @@ like( exception { DateTime->new( year => 10.5 ) }, - qr/is an integer/, + qr/Validation failed for type named Year/, 'year must be an integer' ); like( exception { DateTime->new( year => -10.5 ) }, - qr/is an integer/, + qr/Validation failed for type named Year/, 'year must be an integer' ); like( exception { DateTime->new( year => 10, month => 2.5 ) }, - qr/an integer/, + qr/Validation failed for type named Month/, 'month must be an integer' ); like( exception { DateTime->new( year => 10, month => 2, day => 12.4 ) }, - qr/an integer/, + qr/Validation failed for type named DayOfMonth/, 'day must be an integer' ); @@ -33,7 +33,7 @@ exception { DateTime->new( year => 10, month => 2, day => 12, hour => 4.1 ); }, - qr/an integer/, + qr/Validation failed for type named Hour/, 'hour must be an integer' ); @@ -47,7 +47,7 @@ minute => 12.2 ); }, - qr/an integer/, + qr/Validation failed for type named Minute/, 'minute must be an integer' ); @@ -62,7 +62,7 @@ second => 51.8 ); }, - qr/an integer/, + qr/Validation failed for type named Second/, 'second must be an integer' ); @@ -78,7 +78,7 @@ nanosecond => 124512.12412 ); }, - qr/positive integer/, + qr/Validation failed for type named Nanosecond/, 'nanosecond must be an integer' ); diff -Nru libdatetime-perl-1.21/t/44set-formatter.t libdatetime-perl-1.46/t/44set-formatter.t --- libdatetime-perl-1.21/t/44set-formatter.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/44set-formatter.t 2018-02-11 23:36:51.000000000 +0000 @@ -11,14 +11,15 @@ like( exception { $dt->set_formatter('Invalid::Formatter') }, - qr/can format_datetime/, + qr/\QValidation failed for type named Maybe[Formatter]/, 'set_format is validated' ); SKIP: { + ## no critic (BuiltinFunctions::ProhibitStringyEval) skip 'This test requires DateTime::Format::Strptime 1.2000+', 1 - unless eval "use DateTime::Format::Strptime 1.2000"; + unless eval 'use DateTime::Format::Strptime 1.2000; 1;'; my $formatter = DateTime::Format::Strptime->new( pattern => '%Y%m%d %T', diff -Nru libdatetime-perl-1.21/t/45core-time.t libdatetime-perl-1.46/t/45core-time.t --- libdatetime-perl-1.21/t/45core-time.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/45core-time.t 2018-02-11 23:36:51.000000000 +0000 @@ -6,6 +6,7 @@ use DateTime; no warnings 'redefine'; +## no critic (Variables::ProtectPrivateVars) local *DateTime::_core_time = sub {0}; my $dt = DateTime->now; diff -Nru libdatetime-perl-1.21/t/46warnings.t libdatetime-perl-1.46/t/46warnings.t --- libdatetime-perl-1.21/t/46warnings.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/46warnings.t 2018-02-11 23:36:51.000000000 +0000 @@ -8,10 +8,12 @@ my $year_5001_epoch = 95649120000; +## no critic (TestingAndDebugging::ProhibitNoWarnings) SKIP: { + my $year = ( gmtime($year_5001_epoch) )[5]; skip 'These tests require a 64-bit Perl', 2 - unless ( gmtime($year_5001_epoch) )[5] == 3101; + unless defined $year && $year == 3101; { like( diff -Nru libdatetime-perl-1.21/t/47default-time-zone.t libdatetime-perl-1.46/t/47default-time-zone.t --- libdatetime-perl-1.21/t/47default-time-zone.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/t/47default-time-zone.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,90 @@ +use strict; +use warnings; + +use Test::More; + +use DateTime; + +{ + my $dt = DateTime->new( year => 2000, month => 2, day => 21 ); + is( + $dt->time_zone->name, 'floating', + 'Time zones for new DateTime objects should default to floating' + ); + is( + DateTime->last_day_of_month( year => 2000, month => 2 ) + ->time_zone->name, + 'floating', + 'last_day_of_month time zone also should default to floating' + ); + is( + DateTime->from_day_of_year( year => 2000, day_of_year => 212 ) + ->time_zone->name, + 'floating', + 'from_day_of_year time zone also should default to floating' + ); + is( + DateTime->now->time_zone->name, 'UTC', + '... except for constructors which assume UTC' + ); + is( + DateTime->from_epoch( epoch => time() )->time_zone->name, 'UTC', + '... except for constructors which assume UTC' + ); +} + +{ + my $dt1 = DateTime->new( year => 1970, hour => 1, nanosecond => 100 ); + my $dt2 = DateTime->from_object( object => $dt1 ); + is( + $dt2->time_zone->name, 'floating', + 'Copying DateTime objects from other DateTime objects should retain the timezone' + ); +} + +{ + my $dt = DateTime->new( year => 2000, month => 2, day => 21 ); + local $ENV{PERL_DATETIME_DEFAULT_TZ} = 'America/Los_Angeles'; + is( + $dt->time_zone->name, 'floating', + 'Setting PERL_DATETIME_DEFAULT_TZ env should not impact existing objects' + ); + $dt = DateTime->new( year => 2000, month => 2, day => 21 ); + is( + $dt->time_zone->name, $ENV{PERL_DATETIME_DEFAULT_TZ}, + '... but new objects should no longer default to the floating time zone' + ); + is( + DateTime->last_day_of_month( year => 2000, month => 2 ) + ->time_zone->name, + $ENV{PERL_DATETIME_DEFAULT_TZ}, + 'last_day_of_month time zone also should default to floating' + ); + is( + DateTime->from_day_of_year( year => 2000, day_of_year => 212 ) + ->time_zone->name, + $ENV{PERL_DATETIME_DEFAULT_TZ}, + 'from_day_of_year time zone also should default to floating' + ); + is( + DateTime->now->time_zone->name, 'UTC', + '... and constructors which assume UTC should remain unchanged' + ); + + my $dt1 = DateTime->new( year => 1970, hour => 1, nanosecond => 100 ); + my $dt2 = DateTime->from_object( object => $dt1 ); + is( + $dt2->time_zone->name, $ENV{PERL_DATETIME_DEFAULT_TZ}, + 'Copying DateTime objects from other DateTime objects should retain the timezone' + ); +} + +{ + my $dt = DateTime->new( year => 2000, month => 2, day => 21 ); + is( + $dt->time_zone->name, 'floating', + 'Default time zone should revert to "floating" when PERL_DATETIME_DEFAULT_TZ no longer set' + ); +} + +done_testing(); diff -Nru libdatetime-perl-1.21/t/48rt-115983.t libdatetime-perl-1.46/t/48rt-115983.t --- libdatetime-perl-1.21/t/48rt-115983.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/t/48rt-115983.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,25 @@ +use strict; +use warnings; + +use Test::Fatal; +use Test::More; + +use DateTime; + +# The bug here is that if DateTime doesn't clean it's namespace, it ends up +# having a catch method that is getting called here and being passed a hashref +# containing the return value of $dt->truncate. See +# https://rt.cpan.org/Ticket/Display.html?id=115983 + +my $dt = DateTime->now; +like( + exception { + try { } catch { + $dt->truncate( to => 'hour' ); + }; + }, + qr/Can\'t locate object method "catch"/, + 'DateTime does not have a catch method' +); + +done_testing(); diff -Nru libdatetime-perl-1.21/t/author-eol.t libdatetime-perl-1.46/t/author-eol.t --- libdatetime-perl-1.21/t/author-eol.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/author-eol.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,133 +0,0 @@ - -BEGIN { - unless ($ENV{AUTHOR_TESTING}) { - require Test::More; - Test::More::plan(skip_all => 'these tests are for testing by the author'); - } -} - -use strict; -use warnings; - -# this test was generated with Dist::Zilla::Plugin::Test::EOL 0.18 - -use Test::More 0.88; -use Test::EOL; - -my @files = ( - 'lib/DateTime.pm', - 'lib/DateTime/Duration.pm', - 'lib/DateTime/Helpers.pm', - 'lib/DateTime/Infinite.pm', - 'lib/DateTime/LeapSecond.pm', - 'lib/DateTime/PP.pm', - 'lib/DateTime/PPExtra.pm', - 't/00-report-prereqs.dd', - 't/00-report-prereqs.t', - 't/00load.t', - 't/01sanity.t', - 't/02last-day.t', - 't/03components.t', - 't/04epoch.t', - 't/05set.t', - 't/06add.t', - 't/07compare.t', - 't/09greg.t', - 't/10subtract.t', - 't/11duration.t', - 't/12week.t', - 't/13strftime.t', - 't/14locale.t', - 't/15jd.t', - 't/16truncate.t', - 't/17set-return.t', - 't/18today.t', - 't/19leap-second.t', - 't/20infinite.t', - 't/21bad-params.t', - 't/22from-doy.t', - 't/23storable.t', - 't/24from-object.t', - 't/25add-subtract.t', - 't/26dt-leapsecond-pm.t', - 't/27delta.t', - 't/28dow.t', - 't/29overload.t', - 't/30future-tz.t', - 't/31formatter.t', - 't/32leap-second2.t', - 't/33seconds-offset.t', - 't/34set-tz.t', - 't/35rd-values.t', - 't/36invalid-local.t', - 't/37local-add.t', - 't/38local-subtract.t', - 't/39no-so.t', - 't/40leap-years.t', - 't/41cldr-format.t', - 't/42duration-class.t', - 't/43new-params.t', - 't/44set-formatter.t', - 't/45core-time.t', - 't/46warnings.t', - 't/author-eol.t', - 't/author-mojibake.t', - 't/author-no-tabs.t', - 't/author-pod-spell.t', - 't/author-test-all-my-deps.t', - 't/author-test-version.t', - 't/release-cpan-changes.t', - 't/release-load-is-xs.t', - 't/release-pod-coverage.t', - 't/release-pod-linkcheck.t', - 't/release-pod-syntax.t', - 't/release-portability.t', - 't/release-pp-00load.t', - 't/release-pp-01sanity.t', - 't/release-pp-02last-day.t', - 't/release-pp-03components.t', - 't/release-pp-04epoch.t', - 't/release-pp-05set.t', - 't/release-pp-06add.t', - 't/release-pp-07compare.t', - 't/release-pp-09greg.t', - 't/release-pp-10subtract.t', - 't/release-pp-11duration.t', - 't/release-pp-12week.t', - 't/release-pp-13strftime.t', - 't/release-pp-14locale.t', - 't/release-pp-15jd.t', - 't/release-pp-16truncate.t', - 't/release-pp-17set-return.t', - 't/release-pp-18today.t', - 't/release-pp-19leap-second.t', - 't/release-pp-20infinite.t', - 't/release-pp-21bad-params.t', - 't/release-pp-22from-doy.t', - 't/release-pp-23storable.t', - 't/release-pp-24from-object.t', - 't/release-pp-25add-subtract.t', - 't/release-pp-27delta.t', - 't/release-pp-28dow.t', - 't/release-pp-29overload.t', - 't/release-pp-30future-tz.t', - 't/release-pp-31formatter.t', - 't/release-pp-32leap-second2.t', - 't/release-pp-33seconds-offset.t', - 't/release-pp-34set-tz.t', - 't/release-pp-35rd-values.t', - 't/release-pp-36invalid-local.t', - 't/release-pp-37local-add.t', - 't/release-pp-38local-subtract.t', - 't/release-pp-40leap-years.t', - 't/release-pp-41cldr-format.t', - 't/release-pp-42duration-class.t', - 't/release-pp-43new-params.t', - 't/release-pp-44set-formatter.t', - 't/release-pp-45core-time.t', - 't/release-pp-46warnings.t', - 't/release-tidyall.t' -); - -eol_unix_ok($_, { trailing_whitespace => 1 }) foreach @files; -done_testing; diff -Nru libdatetime-perl-1.21/t/author-mojibake.t libdatetime-perl-1.46/t/author-mojibake.t --- libdatetime-perl-1.21/t/author-mojibake.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/author-mojibake.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,17 +0,0 @@ -#!perl - -BEGIN { - unless ($ENV{AUTHOR_TESTING}) { - require Test::More; - Test::More::plan(skip_all => 'these tests are for testing by the author'); - } -} - - -use strict; -use warnings qw(all); - -use Test::More; -use Test::Mojibake; - -all_files_encoding_ok(); diff -Nru libdatetime-perl-1.21/t/author-no-tabs.t libdatetime-perl-1.46/t/author-no-tabs.t --- libdatetime-perl-1.21/t/author-no-tabs.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/author-no-tabs.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,133 +0,0 @@ - -BEGIN { - unless ($ENV{AUTHOR_TESTING}) { - require Test::More; - Test::More::plan(skip_all => 'these tests are for testing by the author'); - } -} - -use strict; -use warnings; - -# this test was generated with Dist::Zilla::Plugin::Test::NoTabs 0.15 - -use Test::More 0.88; -use Test::NoTabs; - -my @files = ( - 'lib/DateTime.pm', - 'lib/DateTime/Duration.pm', - 'lib/DateTime/Helpers.pm', - 'lib/DateTime/Infinite.pm', - 'lib/DateTime/LeapSecond.pm', - 'lib/DateTime/PP.pm', - 'lib/DateTime/PPExtra.pm', - 't/00-report-prereqs.dd', - 't/00-report-prereqs.t', - 't/00load.t', - 't/01sanity.t', - 't/02last-day.t', - 't/03components.t', - 't/04epoch.t', - 't/05set.t', - 't/06add.t', - 't/07compare.t', - 't/09greg.t', - 't/10subtract.t', - 't/11duration.t', - 't/12week.t', - 't/13strftime.t', - 't/14locale.t', - 't/15jd.t', - 't/16truncate.t', - 't/17set-return.t', - 't/18today.t', - 't/19leap-second.t', - 't/20infinite.t', - 't/21bad-params.t', - 't/22from-doy.t', - 't/23storable.t', - 't/24from-object.t', - 't/25add-subtract.t', - 't/26dt-leapsecond-pm.t', - 't/27delta.t', - 't/28dow.t', - 't/29overload.t', - 't/30future-tz.t', - 't/31formatter.t', - 't/32leap-second2.t', - 't/33seconds-offset.t', - 't/34set-tz.t', - 't/35rd-values.t', - 't/36invalid-local.t', - 't/37local-add.t', - 't/38local-subtract.t', - 't/39no-so.t', - 't/40leap-years.t', - 't/41cldr-format.t', - 't/42duration-class.t', - 't/43new-params.t', - 't/44set-formatter.t', - 't/45core-time.t', - 't/46warnings.t', - 't/author-eol.t', - 't/author-mojibake.t', - 't/author-no-tabs.t', - 't/author-pod-spell.t', - 't/author-test-all-my-deps.t', - 't/author-test-version.t', - 't/release-cpan-changes.t', - 't/release-load-is-xs.t', - 't/release-pod-coverage.t', - 't/release-pod-linkcheck.t', - 't/release-pod-syntax.t', - 't/release-portability.t', - 't/release-pp-00load.t', - 't/release-pp-01sanity.t', - 't/release-pp-02last-day.t', - 't/release-pp-03components.t', - 't/release-pp-04epoch.t', - 't/release-pp-05set.t', - 't/release-pp-06add.t', - 't/release-pp-07compare.t', - 't/release-pp-09greg.t', - 't/release-pp-10subtract.t', - 't/release-pp-11duration.t', - 't/release-pp-12week.t', - 't/release-pp-13strftime.t', - 't/release-pp-14locale.t', - 't/release-pp-15jd.t', - 't/release-pp-16truncate.t', - 't/release-pp-17set-return.t', - 't/release-pp-18today.t', - 't/release-pp-19leap-second.t', - 't/release-pp-20infinite.t', - 't/release-pp-21bad-params.t', - 't/release-pp-22from-doy.t', - 't/release-pp-23storable.t', - 't/release-pp-24from-object.t', - 't/release-pp-25add-subtract.t', - 't/release-pp-27delta.t', - 't/release-pp-28dow.t', - 't/release-pp-29overload.t', - 't/release-pp-30future-tz.t', - 't/release-pp-31formatter.t', - 't/release-pp-32leap-second2.t', - 't/release-pp-33seconds-offset.t', - 't/release-pp-34set-tz.t', - 't/release-pp-35rd-values.t', - 't/release-pp-36invalid-local.t', - 't/release-pp-37local-add.t', - 't/release-pp-38local-subtract.t', - 't/release-pp-40leap-years.t', - 't/release-pp-41cldr-format.t', - 't/release-pp-42duration-class.t', - 't/release-pp-43new-params.t', - 't/release-pp-44set-formatter.t', - 't/release-pp-45core-time.t', - 't/release-pp-46warnings.t', - 't/release-tidyall.t' -); - -notabs_ok($_) foreach @files; -done_testing; diff -Nru libdatetime-perl-1.21/t/author-pod-spell.t libdatetime-perl-1.46/t/author-pod-spell.t --- libdatetime-perl-1.21/t/author-pod-spell.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/author-pod-spell.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,154 +0,0 @@ - -BEGIN { - unless ($ENV{AUTHOR_TESTING}) { - require Test::More; - Test::More::plan(skip_all => 'these tests are for testing by the author'); - } -} - -use strict; -use warnings; -use Test::More; - -# generated by Dist::Zilla::Plugin::Test::PodSpelling 2.006009 -use Test::Spelling 0.12; -use Pod::Wordlist; - - -add_stopwords(); -all_pod_files_spelling_ok( qw( bin lib ) ); -__DATA__ -DROLSKY -DROLSKY's -PayPal -Rolsky -Rolsky's -Anno -BCE -CLDR -CPAN -DATETIME -DateTime -DateTimes -Datetime -Datetimes -Domini -EEEE -EEEEE -Flávio -Formatters -GGGG -GGGGG -Glock -IEEE -LLL -LLLL -LLLLL -Liang -Liang's -MMM -MMMM -MMMMM -Measham -Measham's -POSIX -QQQ -QQQQ -Rata -SU -Soibelmann -Storable -TZ -Tsai -UTC -VVVV -YAPCs -ZZZZ -ZZZZZ -afterwards -bian -ccc -cccc -ccccc -conformant -datetime -datetime's -datetimes -decrement -dian -durations -eee -eeee -eeeee -fallback -formatter -hh -iCal -ji -mutiplication -na -namespace -ni -nitty -other's -proleptic -qqq -qqqq -sexagesimal -subclasses -uu -vvvv -wiki -yy -yyyy -yyyyy -zzzz -Dave -autarch -Ben -Bennett -fiji -Christian -Hansen -chansen -Daisuke -Maki -dmaki -David -Wheeler -david -Doug -Bell -madcityzen -fglock -Gregory -Oschwald -oschwald -Iain -Truskett -deceased -Jason -McIntosh -jmac -Joshua -Hoblitt -jhoblitt -Nick -Tonkin -1nickt -Ricardo -Signes -rjbs -Richard -Bowen -bowen -Ron -Hill -rkhill -lib -Duration -Helpers -Infinite -LeapSecond -PP -PPExtra diff -Nru libdatetime-perl-1.21/t/author-test-all-my-deps.t libdatetime-perl-1.46/t/author-test-all-my-deps.t --- libdatetime-perl-1.21/t/author-test-all-my-deps.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/author-test-all-my-deps.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ - -BEGIN { - unless ($ENV{AUTHOR_TESTING}) { - require Test::More; - Test::More::plan(skip_all => 'these tests are for testing by the author'); - } -} - -use strict; -use warnings; - -use Cwd qw( abs_path ); -use Test::More; - -BEGIN { - plan skip_all => - 'Must set DATETIME_TEST_DEPS to true in order to run these tests' - unless $ENV{DATETIME_TEST_DEPS}; -} - -use Test::DependentModules qw( test_all_dependents ); - -$ENV{PERL_TEST_DM_LOG_DIR} = abs_path('.'); - -my $exclude = $ENV{DATETIME_TEST_DEPS} eq 'all' - ? qr/(?:^App-) - | - ^(?: - Archive-RPM - | - Video-Xine - )$ - /x - : qr/^(?!DateTime-)/; - -test_all_dependents( 'DateTime', { exclude => $exclude } ); diff -Nru libdatetime-perl-1.21/t/author-test-version.t libdatetime-perl-1.46/t/author-test-version.t --- libdatetime-perl-1.21/t/author-test-version.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/author-test-version.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,32 +0,0 @@ - -BEGIN { - unless ($ENV{AUTHOR_TESTING}) { - require Test::More; - Test::More::plan(skip_all => 'these tests are for testing by the author'); - } -} - -use strict; -use warnings; -use Test::More; - -# generated by Dist::Zilla::Plugin::Test::Version 1.05 -use Test::Version; - -my @imports = qw( version_all_ok ); - -my $params = { - is_strict => 1, - has_version => 1, - multiple => 0, - -}; - -push @imports, $params - if version->parse( $Test::Version::VERSION ) >= version->parse('1.002'); - - -Test::Version->import(@imports); - -version_all_ok; -done_testing; diff -Nru libdatetime-perl-1.21/t/release-cpan-changes.t libdatetime-perl-1.46/t/release-cpan-changes.t --- libdatetime-perl-1.21/t/release-cpan-changes.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-cpan-changes.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,19 +0,0 @@ -#!perl - -BEGIN { - unless ($ENV{RELEASE_TESTING}) { - require Test::More; - Test::More::plan(skip_all => 'these tests are for release candidate testing'); - } -} - - -use strict; -use warnings; - -use Test::More 0.96 tests => 2; -use_ok('Test::CPAN::Changes'); -subtest 'changes_ok' => sub { - changes_file_ok('Changes'); -}; -done_testing(); diff -Nru libdatetime-perl-1.21/t/release-load-is-xs.t libdatetime-perl-1.46/t/release-load-is-xs.t --- libdatetime-perl-1.21/t/release-load-is-xs.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-load-is-xs.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ - -BEGIN { - unless ($ENV{RELEASE_TESTING}) { - require Test::More; - Test::More::plan(skip_all => 'these tests are for release candidate testing'); - } -} - -use strict; -use warnings; - -use Test::More; - -use DateTime; - -ok( !$DateTime::IsPurePerl, 'Loading DateTime loaded the XS version' ); - -done_testing(); diff -Nru libdatetime-perl-1.21/t/release-pod-coverage.t libdatetime-perl-1.46/t/release-pod-coverage.t --- libdatetime-perl-1.21/t/release-pod-coverage.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pod-coverage.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,79 +0,0 @@ -#!perl - -BEGIN { - unless ($ENV{RELEASE_TESTING}) { - require Test::More; - Test::More::plan(skip_all => 'these tests are for release candidate testing'); - } -} - -# This file was automatically generated by Dist::Zilla::Plugin::Test::Pod::Coverage::Configurable. - -use Test::Pod::Coverage 1.08; -use Test::More 0.88; - -BEGIN { - if ( $] <= 5.008008 ) { - plan skip_all => 'These tests require Pod::Coverage::TrustPod, which only works with Perl 5.8.9+'; - } -} -use Pod::Coverage::TrustPod; - -my %skip = map { $_ => 1 } qw( DateTime::Helpers DateTime::PP DateTime::PPExtra ); - -my @modules; -for my $module ( all_modules() ) { - next if $skip{$module}; - - push @modules, $module; -} - -plan skip_all => 'All the modules we found were excluded from POD coverage test.' - unless @modules; - -plan tests => scalar @modules; - -my %trustme = ( - 'DateTime::Infinite' => [ - qr/^STORABLE/, - qr/^set/, - qr/^is(?:in)?finite/, - qr/^truncate/ - ], - 'DateTime' => [ - qr/0$/, - qr/^STORABLE/, - qr/^utc_year$/, - qr/^timegm$/, - qr/^day_of_month$/, - qr/^doq$/, - qr/^dow$/, - qr/^doy$/, - qr/^iso8601$/, - qr/^local_rd_as_seconds$/, - qr/^mday$/, - qr/^min$/, - qr/^mon$/, - qr/^sec$/, - qr/^wday$/, - qr/^DefaultLanguage$/, - qr/^era$/, - qr/^language$/ - ] - ); - -my @also_private; - -for my $module ( sort @modules ) { - pod_coverage_ok( - $module, - { - coverage_class => 'Pod::Coverage::TrustPod', - also_private => \@also_private, - trustme => $trustme{$module} || [], - }, - "pod coverage for $module" - ); -} - -done_testing(); diff -Nru libdatetime-perl-1.21/t/release-pod-linkcheck.t libdatetime-perl-1.46/t/release-pod-linkcheck.t --- libdatetime-perl-1.21/t/release-pod-linkcheck.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pod-linkcheck.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,28 +0,0 @@ -#!perl - -BEGIN { - unless ($ENV{RELEASE_TESTING}) { - require Test::More; - Test::More::plan(skip_all => 'these tests are for release candidate testing'); - } -} - - -use strict; -use warnings; -use Test::More; - -foreach my $env_skip ( qw( - SKIP_POD_LINKCHECK -) ){ - plan skip_all => "\$ENV{$env_skip} is set, skipping" - if $ENV{$env_skip}; -} - -eval "use Test::Pod::LinkCheck"; -if ( $@ ) { - plan skip_all => 'Test::Pod::LinkCheck required for testing POD'; -} -else { - Test::Pod::LinkCheck->new->all_pod_ok; -} diff -Nru libdatetime-perl-1.21/t/release-pod-syntax.t libdatetime-perl-1.46/t/release-pod-syntax.t --- libdatetime-perl-1.21/t/release-pod-syntax.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pod-syntax.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ -#!perl - -BEGIN { - unless ($ENV{RELEASE_TESTING}) { - require Test::More; - Test::More::plan(skip_all => 'these tests are for release candidate testing'); - } -} - -# This file was automatically generated by Dist::Zilla::Plugin::PodSyntaxTests. -use Test::More; -use Test::Pod 1.41; - -all_pod_files_ok(); diff -Nru libdatetime-perl-1.21/t/release-portability.t libdatetime-perl-1.46/t/release-portability.t --- libdatetime-perl-1.21/t/release-portability.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-portability.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,20 +0,0 @@ -#!perl - -BEGIN { - unless ($ENV{RELEASE_TESTING}) { - require Test::More; - Test::More::plan(skip_all => 'these tests are for release candidate testing'); - } -} - - -use strict; -use warnings; - -use Test::More; - -eval 'use Test::Portability::Files'; -plan skip_all => 'Test::Portability::Files required for testing portability' - if $@; - -run_tests(); diff -Nru libdatetime-perl-1.21/t/release-pp-00load.t libdatetime-perl-1.46/t/release-pp-00load.t --- libdatetime-perl-1.21/t/release-pp-00load.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-00load.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -use strict; -use warnings; - -use Test::More 0.88; - -use_ok('DateTime'); - -done_testing(); - diff -Nru libdatetime-perl-1.21/t/release-pp-01sanity.t libdatetime-perl-1.46/t/release-pp-01sanity.t --- libdatetime-perl-1.21/t/release-pp-01sanity.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-01sanity.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,57 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -use strict; -use warnings; - -use Test::More; - -use DateTime; - -{ - my $dt = DateTime->new( - year => 1870, month => 10, day => 21, - hour => 12, minute => 10, second => 45, - nanosecond => 123456, - time_zone => 'UTC' - ); - - is( $dt->year, '1870', "Year accessor, outside of the epoch" ); - is( $dt->month, '10', "Month accessor, outside the epoch" ); - is( $dt->day, '21', "Day accessor, outside the epoch" ); - is( $dt->hour, '12', "Hour accessor, outside the epoch" ); - is( $dt->minute, '10', "Minute accessor, outside the epoch" ); - is( $dt->second, '45', "Second accessor, outside the epoch" ); - is( $dt->nanosecond, '123456', "nanosecond accessor, outside the epoch" ); - - $dt = DateTime->from_object( object => $dt ); - is( $dt->year, '1870', "Year should be identical" ); - is( $dt->month, '10', "Month should be identical" ); - is( $dt->day, '21', "Day should be identical" ); - is( $dt->hour, '12', "Hour should be identical" ); - is( $dt->minute, '10', "Minute should be identical" ); - is( $dt->second, '45', "Second should be identical" ); - is( $dt->nanosecond, '123456', "nanosecond should be identical" ); -} - -{ - my $dt = DateTime->new( - year => 1870, month => 10, day => 21, - hour => 12, minute => 10, second => 45, - time_zone => 'UTC' - ); - is( $dt->minute, '10', "Minute accessor, outside the epoch" ); - is( $dt->second, '45', "Second accessor, outside the epoch" ); -} - -done_testing(); - diff -Nru libdatetime-perl-1.21/t/release-pp-02last-day.t libdatetime-perl-1.46/t/release-pp-02last-day.t --- libdatetime-perl-1.21/t/release-pp-02last-day.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-02last-day.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,62 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -use strict; -use warnings; - -use Test::More; - -use DateTime; - -my @last = ( 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ); -my @leap_last = @last; -$leap_last[1]++; - -foreach my $month ( 1 .. 12 ) { - my $dt = DateTime->last_day_of_month( - year => 2001, - month => $month, - time_zone => 'UTC', - ); - - is( $dt->year, 2001, 'check year' ); - is( $dt->month, $month, 'check month' ); - is( $dt->day, $last[ $month - 1 ], 'check day' ); -} - -foreach my $month ( 1 .. 12 ) { - my $dt = DateTime->last_day_of_month( - year => 2004, - month => $month, - time_zone => 'UTC', - ); - - is( $dt->year, 2004, 'check year' ); - is( $dt->month, $month, 'check month' ); - is( $dt->day, $leap_last[ $month - 1 ], 'check day' ); -} - -{ - eval { - DateTime->last_day_of_month( - year => 2000, month => 1, - nanosecond => 2000 - ); - }; - is( - $@, '', - "last_day_of_month should accept nanosecond" - ); -} - -done_testing(); - diff -Nru libdatetime-perl-1.21/t/release-pp-03components.t libdatetime-perl-1.46/t/release-pp-03components.t --- libdatetime-perl-1.21/t/release-pp-03components.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-03components.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,380 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -use strict; -use warnings; - -use Test::More; - -use DateTime; - -my $d = DateTime->new( - year => 2001, - month => 7, - day => 5, - hour => 2, - minute => 12, - second => 50, - time_zone => 'UTC', -); - -is( $d->year, 2001, '->year' ); -is( $d->ce_year, 2001, '->ce_year' ); -is( $d->month, 7, '->month' ); -is( $d->quarter, 3, '->quarter' ); -is( $d->month_0, 6, '->month_0' ); -is( $d->month_name, 'July', '->month_name' ); -is( $d->month_abbr, 'Jul', '->month_abbr' ); -is( $d->day_of_month, 5, '->day_of_month' ); -is( $d->day_of_month_0, 4, '->day_of_month_0' ); -is( $d->day, 5, '->day' ); -is( $d->day_0, 4, '->day_0' ); -is( $d->mday, 5, '->mday' ); -is( $d->mday_0, 4, '->mday_0' ); -is( $d->mday, 5, '->mday' ); -is( $d->mday_0, 4, '->mday_0' ); -is( $d->hour, 2, '->hour' ); -is( $d->hour_1, 2, '->hour_1' ); -is( $d->hour_12, 2, '->hour_12' ); -is( $d->hour_12_0, 2, '->hour_12_0' ); -is( $d->minute, 12, '->minute' ); -is( $d->min, 12, '->min' ); -is( $d->second, 50, '->second' ); -is( $d->sec, 50, '->sec' ); - -is( $d->day_of_year, 186, '->day_of_year' ); -is( $d->day_of_year_0, 185, '->day_of_year' ); -is( $d->day_of_quarter, 5, '->day_of_quarter' ); -is( $d->doq, 5, '->doq' ); -is( $d->day_of_quarter_0, 4, '->day_of_quarter_0' ); -is( $d->doq_0, 4, '->doq_0' ); -is( $d->day_of_week, 4, '->day_of_week' ); -is( $d->day_of_week_0, 3, '->day_of_week_0' ); -is( $d->week_of_month, 1, '->week_of_month' ); -is( $d->weekday_of_month, 1, '->weekday_of_month' ); -is( $d->wday, 4, '->wday' ); -is( $d->wday_0, 3, '->wday_0' ); -is( $d->dow, 4, '->dow' ); -is( $d->dow_0, 3, '->dow_0' ); -is( $d->day_name, 'Thursday', '->day_name' ); -is( $d->day_abbr, 'Thu', '->day_abrr' ); - -is( $d->ymd, '2001-07-05', '->ymd' ); -is( $d->ymd('!'), '2001!07!05', "->ymd('!')" ); -is( $d->date, '2001-07-05', '->ymd' ); - -is( $d->mdy, '07-05-2001', '->mdy' ); -is( $d->mdy('!'), '07!05!2001', "->mdy('!')" ); - -is( $d->dmy, '05-07-2001', '->dmy' ); -is( $d->dmy('!'), '05!07!2001', "->dmy('!')" ); - -is( $d->hms, '02:12:50', '->hms' ); -is( $d->hms('!'), '02!12!50', "->hms('!')" ); -is( $d->time, '02:12:50', '->hms' ); - -is( $d->datetime, '2001-07-05T02:12:50', '->datetime' ); -is( $d->iso8601, '2001-07-05T02:12:50', '->iso8601' ); - -is( $d->is_leap_year, 0, '->is_leap_year' ); - -is( $d->era_abbr, 'AD', '->era_abbr' ); -is( $d->era, $d->era_abbr, '->era (deprecated)' ); -is( $d->era_name, 'Anno Domini', '->era_abbr' ); - -is( $d->quarter_abbr, 'Q3', '->quarter_abbr' ); -is( $d->quarter_name, '3rd quarter', '->quarter_name' ); - -my $leap_d = DateTime->new( - year => 2004, - month => 7, - day => 5, - hour => 2, - minute => 12, - second => 50, - time_zone => 'UTC', -); - -is( $leap_d->is_leap_year, 1, '->is_leap_year' ); - -my $sunday = DateTime->new( - year => 2003, - month => 1, - day => 26, - time_zone => 'UTC', -); - -is( $sunday->day_of_week, 7, "Sunday is day 7" ); - -my $monday = DateTime->new( - year => 2003, - month => 1, - day => 27, - time_zone => 'UTC', -); - -is( $monday->day_of_week, 1, "Monday is day 1" ); - -{ - - # time zone offset should not affect the values returned - my $d = DateTime->new( - year => 2001, - month => 7, - day => 5, - hour => 2, - minute => 12, - second => 50, - time_zone => '-0124', - ); - - is( $d->year, 2001, '->year' ); - is( $d->ce_year, 2001, '->ce_year' ); - is( $d->month, 7, '->month' ); - is( $d->day_of_month, 5, '->day_of_month' ); - is( $d->hour, 2, '->hour' ); - is( $d->hour_1, 2, '->hour_1' ); - is( $d->minute, 12, '->minute' ); - is( $d->second, 50, '->second' ); -} - -{ - my $dt0 = DateTime->new( year => 1, time_zone => 'UTC' ); - - is( $dt0->year, 1, "year 1 is year 1" ); - is( $dt0->ce_year, 1, "ce_year 1 is year 1" ); - is( $dt0->era_abbr, 'AD', 'era is AD' ); - is( $dt0->year_with_era, '1AD', 'year_with_era is 1AD' ); - is( $dt0->christian_era, 'AD', 'christian_era is AD' ); - is( - $dt0->year_with_christian_era, '1AD', - 'year_with_christian_era is 1AD' - ); - is( $dt0->secular_era, 'CE', 'secular_era is CE' ); - is( $dt0->year_with_secular_era, '1CE', 'year_with_secular_era is 1CE' ); - - $dt0->subtract( years => 1 ); - - is( $dt0->year, 0, "year 1 minus 1 is year 0" ); - is( $dt0->ce_year, -1, "ce_year 1 minus 1 is year -1" ); - is( $dt0->era_abbr, 'BC', 'era is BC' ); - is( $dt0->year_with_era, '1BC', 'year_with_era is 1BC' ); - is( $dt0->christian_era, 'BC', 'christian_era is BC' ); - is( - $dt0->year_with_christian_era, '1BC', - 'year_with_christian_era is 1BC' - ); - is( $dt0->secular_era, 'BCE', 'secular_era is BCE' ); - is( - $dt0->year_with_secular_era, '1BCE', - 'year_with_secular_era is 1BCE' - ); -} - -{ - my $dt_neg = DateTime->new( year => -10, time_zone => 'UTC', ); - is( $dt_neg->year, -10, "Year -10 is -10" ); - is( $dt_neg->ce_year, -11, "year -10 is ce_year -11" ); - - my $dt1 = $dt_neg + DateTime::Duration->new( years => 10 ); - is( $dt1->year, 0, "year is 0 after adding ten years to year -10" ); - is( - $dt1->ce_year, -1, - "ce_year is -1 after adding ten years to year -10" - ); -} - -{ - my $dt = DateTime->new( - year => 50, month => 2, - hour => 3, minute => 20, second => 5, - time_zone => 'UTC', - ); - - is( $dt->ymd('%s'), '0050%s02%s01', 'use %s as separator in ymd' ); - is( $dt->mdy('%s'), '02%s01%s0050', 'use %s as separator in mdy' ); - is( $dt->dmy('%s'), '01%s02%s0050', 'use %s as separator in dmy' ); - - is( $dt->hms('%s'), '03%s20%s05', 'use %s as separator in hms' ); -} - -# test doy in leap year -{ - my $dt = DateTime->new( - year => 2000, month => 1, day => 5, - time_zone => 'UTC', - ); - - is( $dt->day_of_year, 5, 'doy for 2000-01-05 should be 5' ); - is( $dt->day_of_year_0, 4, 'doy_0 for 2000-01-05 should be 4' ); -} - -{ - my $dt = DateTime->new( - year => 2000, month => 2, day => 29, - time_zone => 'UTC', - ); - - is( $dt->day_of_year, 60, 'doy for 2000-02-29 should be 60' ); - is( $dt->day_of_year_0, 59, 'doy_0 for 2000-02-29 should be 59' ); -} - -{ - my $dt = DateTime->new( - year => -6, month => 2, day => 25, - time_zone => 'UTC', - ); - - is( $dt->ymd, '-0006-02-25', 'ymd is -0006-02-25' ); - is( - $dt->iso8601, '-0006-02-25T00:00:00', - 'iso8601 is -0005-02-25T00:00:00' - ); - is( $dt->year, -6, 'year is -6' ); - is( $dt->ce_year, -7, 'ce_year is -7' ); -} - -{ - my $dt = DateTime->new( year => 1996, month => 2, day => 1 ); - - is( $dt->quarter, 1, '->quarter is 1' ); - is( $dt->day_of_quarter, 32, '->day_of_quarter' ); -} - -{ - my $dt = DateTime->new( year => 1996, month => 5, day => 1 ); - - is( $dt->quarter, 2, '->quarter is 2' ); - is( $dt->day_of_quarter, 31, '->day_of_quarter' ); -} - -{ - my $dt = DateTime->new( year => 1996, month => 8, day => 1 ); - - is( $dt->quarter, 3, '->quarter is 3' ); - is( $dt->day_of_quarter, 32, '->day_of_quarter' ); -} - -{ - my $dt = DateTime->new( year => 1996, month => 11, day => 1 ); - - is( $dt->quarter, 4, '->quarter is 4' ); - is( $dt->day_of_quarter, 32, '->day_of_quarter' ); -} - -# nano, micro, and milli seconds -{ - my $dt = DateTime->new( year => 1996, nanosecond => 500_000_000 ); - - is( $dt->nanosecond, 500_000_000, 'nanosecond is 500,000,000' ); - is( $dt->microsecond, 500_000, 'microsecond is 500,000' ); - is( $dt->millisecond, 500, 'millisecond is 500' ); - - $dt->set( nanosecond => 500_000_500 ); - - is( $dt->nanosecond, 500_000_500, 'nanosecond is 500,000,500' ); - is( $dt->microsecond, 500_000, 'microsecond is 500,000' ); - is( $dt->millisecond, 500, 'millisecond is 500' ); - - $dt->set( nanosecond => 499_999_999 ); - - is( $dt->nanosecond, 499_999_999, 'nanosecond is 499,999,999' ); - is( $dt->microsecond, 499_999, 'microsecond is 499,999' ); - is( $dt->millisecond, 499, 'millisecond is 499' ); - - $dt->set( nanosecond => 450_000_001 ); - - is( $dt->nanosecond, 450_000_001, 'nanosecond is 450,000,001' ); - is( $dt->microsecond, 450_000, 'microsecond is 450,000' ); - is( $dt->millisecond, 450, 'millisecond is 450' ); - - $dt->set( nanosecond => 450_500_000 ); - - is( $dt->nanosecond, 450_500_000, 'nanosecond is 450,500,000' ); - is( $dt->microsecond, 450_500, 'microsecond is 450,500' ); - is( $dt->millisecond, 450, 'millisecond is 450' ); -} - -{ - my $dt = DateTime->new( year => 2003, month => 5, day => 7 ); - is( $dt->weekday_of_month, 1, '->weekday_of_month' ); - is( $dt->week_of_month, 2, '->week_of_month' ); -} - -{ - my $dt = DateTime->new( year => 2003, month => 5, day => 8 ); - is( $dt->weekday_of_month, 2, '->weekday_of_month' ); - is( $dt->week_of_month, 2, '->week_of_month' ); -} - -{ - my $dt = DateTime->new( year => 1000, hour => 23 ); - is( $dt->hour, 23, '->hour' ); - is( $dt->hour_1, 23, '->hour_1' ); - is( $dt->hour_12, 11, '->hour_12' ); - is( $dt->hour_12_0, 11, '->hour_12_0' ); -} - -{ - my $dt = DateTime->new( year => 1000, hour => 0 ); - is( $dt->hour, 0, '->hour' ); - is( $dt->hour_1, 24, '->hour_1' ); - is( $dt->hour_12, 12, '->hour_12' ); - is( $dt->hour_12_0, 0, '->hour_12_0' ); -} - -SKIP: -{ - skip 'These tests require Test::Warn', 9 - unless eval "use Test::Warn; 1"; - - my $dt = DateTime->new( year => 2000 ); - warnings_like( - sub { $dt->year(2001) }, qr/is a read-only/, - 'year() is read-only' - ); - warnings_like( - sub { $dt->month(5) }, qr/is a read-only/, - 'month() is read-only' - ); - warnings_like( - sub { $dt->day(5) }, qr/is a read-only/, - 'day() is read-only' - ); - warnings_like( - sub { $dt->hour(5) }, qr/is a read-only/, - 'hour() is read-only' - ); - warnings_like( - sub { $dt->minute(5) }, qr/is a read-only/, - 'minute() is read-only' - ); - warnings_like( - sub { $dt->second(5) }, qr/is a read-only/, - 'second() is read-only' - ); - warnings_like( - sub { $dt->nanosecond(5) }, qr/is a read-only/, - 'nanosecond() is read-only' - ); - warnings_like( - sub { $dt->time_zone('America/Chicago') }, qr/is a read-only/, - 'time_zone() is read-only' - ); - warnings_like( - sub { $dt->locale('en_US') }, qr/is a read-only/, - 'locale() is read-only' - ); -} - -done_testing(); - diff -Nru libdatetime-perl-1.21/t/release-pp-04epoch.t libdatetime-perl-1.46/t/release-pp-04epoch.t --- libdatetime-perl-1.21/t/release-pp-04epoch.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-04epoch.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,210 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -use strict; -use warnings; - -use Test::More; - -use DateTime; - -{ - - # Tests creating objects from epoch time - my $t1 = DateTime->from_epoch( epoch => 0 ); - is( $t1->epoch, 0, "epoch should be 0" ); - - is( $t1->second, 0, "seconds are correct on epoch 0" ); - is( $t1->minute, 0, "minutes are correct on epoch 0" ); - is( $t1->hour, 0, "hours are correct on epoch 0" ); - is( $t1->day, 1, "days are correct on epoch 0" ); - is( $t1->month, 1, "months are correct on epoch 0" ); - is( $t1->year, 1970, "year is correct on epoch 0" ); -} - -{ - my $dt = DateTime->from_epoch( epoch => '3600' ); - is( - $dt->epoch, 3600, - 'creation test from epoch = 3600 (compare to epoch)' - ); -} - -{ - - # these tests could break if the time changed during the next three lines - my $now = time; - my $nowtest = DateTime->now(); - my $nowtest2 = DateTime->from_epoch( epoch => $now ); - is( $nowtest->hour, $nowtest2->hour, "Hour: Create without args" ); - is( $nowtest->month, $nowtest2->month, "Month : Create without args" ); - is( $nowtest->minute, $nowtest2->minute, "Minute: Create without args" ); -} - -{ - my $epochtest = DateTime->from_epoch( epoch => '997121000' ); - - is( - $epochtest->epoch, 997121000, - "epoch method returns correct value" - ); - is( $epochtest->hour, 18, "hour" ); - is( $epochtest->min, 3, "minute" ); -} - -{ - my $dt = DateTime->from_epoch( epoch => 3600 ); - $dt->set_time_zone('+0100'); - - is( $dt->epoch, 3600, 'epoch is 3600' ); - is( $dt->hour, 2, 'hour is 2' ); -} - -{ - - my $dt = DateTime->new( - year => 1970, - month => 1, - day => 1, - hour => 0, - time_zone => '-0100', - ); - - is( $dt->epoch, 3600, 'epoch is 3600' ); -} - -{ - - my $dt = DateTime->from_epoch( - epoch => 0, - time_zone => '-0100', - ); - - is( $dt->offset, -3600, 'offset should be -3600' ); - is( $dt->epoch, 0, 'epoch is 0' ); -} - -# Adding/subtracting should affect epoch -{ - my $expected = 1049160602; - my $epochtest = DateTime->from_epoch( epoch => $expected ); - - is( - $epochtest->epoch, $expected, - "epoch method returns correct value ($expected)" - ); - is( $epochtest->hour, 1, "hour" ); - is( $epochtest->min, 30, "minute" ); - - $epochtest->add( hours => 2 ); - $expected += 2 * 60 * 60; - - is( $epochtest->hour, 3, "adjusted hour" ); - is( - $epochtest->epoch, $expected, - "epoch method returns correct adjusted value ($expected)" - ); - -} - -{ - my $dt = DateTime->from_epoch( epoch => 0.5 ); - is( - $dt->nanosecond, 500_000_000, - 'nanosecond should be 500,000,000 with 0.5 as epoch' - ); - - is( $dt->epoch, 0, 'epoch should be 0' ); - is( $dt->hires_epoch, 0.5, 'hires_epoch should be 0.5' ); -} - -{ - my $dt = DateTime->from_epoch( epoch => 0.1234567891 ); - is( $dt->nanosecond, 123_456_789, 'nanosecond should be an integer ' ); -} - -{ - is( - DateTime->new( year => 1904 )->epoch, -2082844800, - "epoch should work back to at least 1904" - ); - - my $dt = DateTime->from_epoch( epoch => -2082844800 ); - is( $dt->year, 1904, 'year should be 1904' ); - is( $dt->month, 1, 'month should be 1904' ); - is( $dt->day, 1, 'day should be 1904' ); -} - -{ - for my $pair ( - [ 1 => -62135596800 ], - [ 99 => -59042995200 ], - [ 100 => -59011459200 ], - [ 999 => -30641760000 ], - ) { - - my ( $year, $epoch ) = @{$pair}; - - is( - DateTime->new( year => $year )->epoch, $epoch, - "epoch for $year is $epoch" - ); - } -} - -{ - - package Number::Overloaded; - use overload - "0+" => sub { $_[0]->{num} }, - fallback => 1; - - sub new { bless { num => $_[1] }, $_[0] } -} - -{ - my $time = Number::Overloaded->new(12345); - - my $dt = DateTime->from_epoch( epoch => $time ); - is( $dt->epoch, 12345, 'can pass overloaded object to from_epoch' ); - - $time = Number::Overloaded->new(12345.1234); - $dt = DateTime->from_epoch( epoch => $time ); - is( $dt->epoch, 12345, 'decimal epoch in overloaded object' ); -} - -{ - my $time = Number::Overloaded->new(-12345); - my $dt = DateTime->from_epoch( epoch => $time ); - - is( $dt->epoch, -12345, 'negative epoch in overloaded object' ); -} - -{ - my @tests = ( - 'asldkjlkjd', - '1234 foo', - 'adlkj 1234', - ); - - for my $test (@tests) { - eval { DateTime->from_epoch( epoch => $test ); }; - - like( - $@, qr/did not pass regex check/, - qq{'$test' is not a valid epoch value} - ); - } -} - -done_testing(); - diff -Nru libdatetime-perl-1.21/t/release-pp-05set.t libdatetime-perl-1.46/t/release-pp-05set.t --- libdatetime-perl-1.21/t/release-pp-05set.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-05set.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,103 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -use strict; -use warnings; - -use Test::More; - -use DateTime; - -{ - my $dt = DateTime->new( - year => 1996, month => 11, day => 22, - hour => 18, minute => 30, second => 20, - time_zone => 'UTC', - ); - - is( $dt->month, 11, 'check month' ); - - $dt->set( month => 5 ); - is( $dt->year, 1996, 'check year after setting month' ); - is( $dt->month, 5, 'check month after setting it' ); - is( $dt->day, 22, 'check day after setting month' ); - is( $dt->hour, 18, 'check hour after setting month' ); - is( $dt->minute, 30, 'check minute after setting month' ); - is( $dt->second, 20, 'check second after setting month' ); - - $dt->set_time_zone('-060001'); - is( $dt->year, 1996, 'check year after setting time zone' ); - is( $dt->month, 5, 'check month after setting time zone' ); - is( $dt->day, 22, 'check day after setting time zone' ); - is( $dt->hour, 12, 'check hour after setting time zone' ); - is( $dt->minute, 30, 'check minute after setting time zone' ); - is( $dt->second, 19, 'check second after setting time zone' ); - is( - $dt->offset, -21601, - 'check time zone offset after setting new time zone' - ); - - $dt->set_time_zone('+0100'); - is( $dt->year, 1996, 'check year after setting time zone' ); - is( $dt->month, 5, 'check month after setting time zone' ); - is( $dt->day, 22, 'check day after setting time zone' ); - is( $dt->hour, 19, 'check hour after setting time zone' ); - is( $dt->minute, 30, 'check minute after setting time zone' ); - is( $dt->second, 20, 'check second after setting time zone' ); - is( - $dt->offset, 3600, - 'check time zone offset after setting new time zone' - ); - - $dt->set( hour => 17 ); - is( $dt->year, 1996, 'check year after setting hour' ); - is( $dt->month, 5, 'check month after setting hour' ); - is( $dt->day, 22, 'check day after setting hour' ); - is( $dt->hour, 17, 'check hour after setting hour' ); - is( $dt->minute, 30, 'check minute after setting hour' ); - is( $dt->second, 20, 'check second after setting hour' ); -} - -{ - my $dt = DateTime->new( - year => 1996, month => 11, day => 22, - hour => 18, minute => 30, second => 20, - time_zone => 'UTC', - ); - - $dt->set_year(2000); - is( $dt->year, 2000, 'check year after set_year' ); - - $dt->set_month(5); - is( $dt->month, 5, 'check month after set_month' ); - - $dt->set_day(6); - is( $dt->day, 6, 'check day after set_day' ); - - $dt->set_hour(7); - is( $dt->hour, 7, 'check hour after set_hour' ); - - $dt->set_minute(8); - is( $dt->minute, 8, 'check minute after set_minute' ); - - $dt->set_second(9); - is( $dt->second, 9, 'check second after set_second' ); - - $dt->set_nanosecond(9999); - is( $dt->nanosecond, 9999, 'check nanosecond after set_nanosecond' ); - - $dt->set_locale('fr_FR'); - is( $dt->month_name, 'mai', 'check month name after set_locale' ); -} - -done_testing(); - diff -Nru libdatetime-perl-1.21/t/release-pp-06add.t libdatetime-perl-1.46/t/release-pp-06add.t --- libdatetime-perl-1.21/t/release-pp-06add.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-06add.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,429 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -use strict; -use warnings; - -use Test::More; -use Test::Fatal; - -use DateTime; - -my $dt = DateTime->new( - year => 1996, month => 11, day => 22, - hour => 18, minute => 30, second => 20, - time_zone => 'UTC', -); -$dt->add( weeks => 8 ); - -is( $dt->year, 1997, "year rollover" ); -is( $dt->month, 1, "month set on year rollover" ); -is( $dt->datetime, '1997-01-17T18:30:20', 'okay on year rollover' ); - -$dt->add( weeks => 2 ); -is( $dt->datetime, '1997-01-31T18:30:20', 'Adding weeks' ); - -$dt->add( seconds => 15 ); -is( $dt->datetime, '1997-01-31T18:30:35', 'Adding seconds' ); - -$dt->add( minutes => 12 ); -is( $dt->datetime, '1997-01-31T18:42:35', 'Adding minutes' ); - -$dt->add( minutes => 25, hours => 3, seconds => 7 ); -is( $dt->datetime, '1997-01-31T22:07:42', 'Adding h,m,s' ); - -# Now, test the adding of durations -$dt = DateTime->new( - year => 1986, month => 1, day => 28, - hour => 16, minute => 38, - time_zone => 'UTC' -); - -$dt->add( minutes => 1, seconds => 12 ); -is( - $dt->datetime, '1986-01-28T16:39:12', - "Adding durations with minutes and seconds works" -); - -$dt = DateTime->new( - year => 1986, month => 1, day => 28, - hour => 16, minute => 38, - time_zone => 'UTC' -); - -$dt->add( seconds => 30 ); -is( - $dt->datetime, '1986-01-28T16:38:30', - "Adding durations with seconds only works" -); - -$dt = DateTime->new( - year => 1986, month => 1, day => 28, - hour => 16, minute => 38, - time_zone => 'UTC' -); - -$dt->add( hours => 1, minutes => 10 ); -is( - $dt->datetime, '1986-01-28T17:48:00', - "Adding durations with hours and minutes works" -); - -$dt = DateTime->new( - year => 1986, month => 1, day => 28, - hour => 16, minute => 38, - time_zone => 'UTC' -); - -$dt->add( days => 3 ); -is( - $dt->datetime, '1986-01-31T16:38:00', - "Adding durations with days only works" -); - -$dt = DateTime->new( - year => 1986, month => 1, day => 28, - hour => 16, minute => 38, - time_zone => 'UTC' -); - -$dt->add( days => 3, hours => 2 ); -is( - $dt->datetime, '1986-01-31T18:38:00', - "Adding durations with days and hours works" -); - -$dt = DateTime->new( - year => 1986, month => 1, day => 28, - hour => 16, minute => 38, - time_zone => 'UTC' -); - -$dt->add( days => 3, hours => 2, minutes => 20, seconds => 15 ); -is( - $dt->datetime, '1986-01-31T18:58:15', - "Adding durations with days, hours, minutes, and seconds works" -); - -# Add 15M - this test failed at one point in N::I::Time -$dt = DateTime->new( - year => 2001, month => 4, day => 5, - hour => 16, - time_zone => 'UTC' -); - -$dt->add( minutes => 15 ); -is( - $dt->datetime, '2001-04-05T16:15:00', - "Adding minutes to an ical string" -); - -# Subtract a duration -$dt->add( minutes => -15 ); -is( $dt->datetime, '2001-04-05T16:00:00', "Back where we started" ); - -undef $dt; - -$dt = DateTime->new( - year => 1986, month => 1, day => 28, - hour => 16, minute => 38, - time_zone => 'UTC' -); - -$dt->add( seconds => 60 ); -is( - $dt->datetime, "1986-01-28T16:39:00", - "adding positive seconds with seconds works" -); -$dt->add( seconds => -120 ); -is( - $dt->datetime, "1986-01-28T16:37:00", - "adding negative seconds with seconds works" -); - -# test sub months -$dt = DateTime->new( - year => 2001, month => 1, day => 31, - time_zone => 'UTC', -); -$dt->add( days => 1 ); -is( $dt->date, '2001-02-01', 'february 1st' ); - -$dt = DateTime->new( - year => 2001, month => 2, day => 28, - time_zone => 'UTC', -); -$dt->add( days => 1 ); -is( $dt->date, '2001-03-01', 'march 1st' ); - -$dt = DateTime->new( - year => 2001, month => 3, day => 31, - time_zone => 'UTC', -); -$dt->add( days => 1 ); -is( $dt->date, '2001-04-01', 'april 1st' ); - -$dt = DateTime->new( - year => 2001, month => 4, day => 30, - time_zone => 'UTC', -); -$dt->add( days => 1 ); -is( $dt->date, '2001-05-01', 'may 1st' ); - -$dt = DateTime->new( - year => 2001, month => 5, day => 31, - time_zone => 'UTC', -); -$dt->add( days => 1 ); -is( $dt->date, '2001-06-01', 'june 1st' ); - -$dt = DateTime->new( - year => 2001, month => 6, day => 30, - time_zone => 'UTC', -); -$dt->add( days => 1 ); -is( $dt->date, '2001-07-01', 'july 1st' ); - -$dt = DateTime->new( - year => 2001, month => 7, day => 31, - time_zone => 'UTC', -); -$dt->add( days => 1 ); -is( $dt->date, '2001-08-01', 'august 1st' ); - -$dt = DateTime->new( - year => 2001, month => 8, day => 31, - time_zone => 'UTC', -); -$dt->add( days => 1 ); -is( $dt->date, '2001-09-01', 'september 1st' ); - -$dt = DateTime->new( - year => 2001, month => 9, day => 30, - time_zone => 'UTC', -); -$dt->add( days => 1 ); -is( $dt->date, '2001-10-01', 'october 1st' ); - -$dt = DateTime->new( - year => 2001, month => 10, day => 31, - time_zone => 'UTC', -); -$dt->add( days => 1 ); -is( $dt->date, '2001-11-01', 'november 1st' ); - -$dt = DateTime->new( - year => 2001, month => 11, day => 30, - time_zone => 'UTC', -); -$dt->add( days => 1 ); -is( $dt->date, '2001-12-01', 'december 1st' ); - -$dt = DateTime->new( - year => 2001, month => 12, day => 31, - time_zone => 'UTC', -); -$dt->add( days => 1 ); -is( $dt->date, '2002-01-01', 'january 1st' ); - -# Adding years - -# Before leap day, not a leap year ... -$dt = DateTime->new( - year => 2001, month => 2, day => 28, - time_zone => 'UTC', -); -$dt->add( years => 1 ); -is( $dt->date, '2002-02-28', 'Adding a year' ); -$dt->add( years => 17 ); -is( $dt->date, '2019-02-28', 'Adding 17 years' ); - -# After leap day, not a leap year ... -$dt = DateTime->new( - year => 2001, month => 3, day => 28, - time_zone => 'UTC', -); -$dt->add( years => 1 ); -is( $dt->date, '2002-03-28', 'Adding a year' ); -$dt->add( years => 17 ); -is( $dt->date, '2019-03-28', 'Adding 17 years' ); - -# On leap day, in a leap year ... -$dt = DateTime->new( - year => 2000, month => 2, day => 29, - time_zone => 'UTC', -); -$dt->add( years => 1 ); -is( $dt->date, '2001-03-01', 'Adding a year' ); -$dt->add( years => 17 ); -is( $dt->date, '2018-03-01', 'Adding 17 years' ); - -# Before leap day, in a leap year ... -$dt = DateTime->new( - year => 2000, month => 2, day => 28, - time_zone => 'UTC', -); -$dt->add( years => 1 ); -is( $dt->date, '2001-02-28', 'Adding a year' ); -$dt->add( years => 17 ); -is( $dt->date, '2018-02-28', 'Adding 17 years' ); - -# After leap day, in a leap year ... -$dt = DateTime->new( - year => 2000, month => 3, day => 28, - time_zone => 'UTC', -); -$dt->add( years => 1 ); -is( $dt->date, '2001-03-28', 'Adding a year' ); -$dt->add( years => 17 ); -is( $dt->date, '2018-03-28', 'Adding 17 years' ); - -# Test a bunch of years, before leap day -for ( 1 .. 99 ) { - $dt = DateTime->new( - year => 2000, month => 2, day => 28, - time_zone => 'UTC', - ); - $dt->add( years => $_ ); - my $x = sprintf '%02d', $_; - is( $dt->date, "20${x}-02-28", "Adding $_ years" ); -} - -# Test a bunch of years, after leap day -for ( 1 .. 99 ) { - $dt = DateTime->new( - year => 2000, month => 3, day => 28, - time_zone => 'UTC', - ); - $dt->add( years => $_ ); - my $x = sprintf '%02d', $_; - is( $dt->date, "20${x}-03-28", "Adding $_ years" ); -} - -# And more of the same, starting on a non-leap year - -# Test a bunch of years, before leap day -for ( 1 .. 97 ) { - $dt = DateTime->new( - year => 2002, month => 2, day => 28, - time_zone => 'UTC', - ); - $dt->add( years => $_ ); - my $x = sprintf '%02d', $_ + 2; - is( $dt->date, "20${x}-02-28", "Adding $_ years" ); -} - -# Test a bunch of years, after leap day -for ( 1 .. 97 ) { - $dt = DateTime->new( - year => 2002, month => 3, day => 28, - time_zone => 'UTC', - ); - $dt->add( years => $_ ); - my $x = sprintf '%02d', $_ + 2; - is( $dt->date, "20${x}-03-28", "Adding $_ years" ); -} - -# subtract years -for ( 1 .. 97 ) { - $dt = DateTime->new( - year => 1999, month => 3, day => 1, - time_zone => 'UTC', - ); - $dt->add( years => -$_ ); - my $x = sprintf '%02d', 99 - $_; - is( $dt->date, "19${x}-03-01", "Subtracting $_ years" ); -} - -# test some old bugs - -# bug adding months where current month + months added were > 25 -$dt = DateTime->new( - year => 1997, month => 12, day => 1, - time_zone => 'UTC', -); -$dt->add( months => 14 ); -is( $dt->date, '1999-02-01', 'Adding months--rollover year' ); - -# bug subtracting months with year rollover -$dt = DateTime->new( - year => 1997, month => 1, day => 1, - time_zone => 'UTC', -); -$dt->add( months => -1 ); -is( $dt->date, '1996-12-01', 'Subtracting months--rollover year' ); - -my $new = $dt + DateTime::Duration->new( years => 2 ); -is( $new->date, '1998-12-01', 'test + overloading' ); - -{ - my $dt = DateTime->new( - year => 1997, month => 1, day => 1, - hour => 1, minute => 1, second => 59, - nanosecond => 500000000, - time_zone => 'UTC', - ); - - $dt->add( nanoseconds => 500000000 ); - is( $dt->second, 0, 'fractional second rollover' ); - $dt->add( nanoseconds => 123000000 ); - is( $dt->fractional_second, 0.123, 'as fractional_second' ); -} - -{ - my $dt = DateTime->new( year => 2003, month => 2, day => 28 ); - $dt->add( months => 1, days => 1 ); - - is( $dt->ymd, '2003-04-01', 'order of units in date math' ); -} - -{ - my $dt = DateTime->new( year => 2003, hour => 12, minute => 1 ); - $dt->add( minutes => 30, seconds => -1 ); - - is( $dt->hour, 12, 'hour is 12' ); - is( $dt->minute, 30, 'minute is 30' ); - is( $dt->second, 59, 'second is 59' ); -} - -{ - my $dt = DateTime->new( - year => 2014, - month => 7, - day => 1, - time_zone => 'floating', - ); - - $dt->add( days => 2 ); - is( $dt->date, '2014-07-03', 'adding 2 days to a floating datetime' ); -} - -{ - my $dt = DateTime->new( year => 0, month => 1, day => 1 ); - my $dt2; - is( - exception { $dt2 = $dt->clone->add( days => 268_526_345 ) }, - undef, - 'no exception adding 268,526,345 days to 0000-01-01' - ); - - if ($dt2) { - is( - $dt2->ymd(), - '735200-02-29', - 'adding 268,526,345 days produces 735200-02-29' - ); - } -} - -done_testing(); - diff -Nru libdatetime-perl-1.21/t/release-pp-07compare.t libdatetime-perl-1.46/t/release-pp-07compare.t --- libdatetime-perl-1.21/t/release-pp-07compare.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-07compare.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,232 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -use strict; -use warnings; - -use Test::More; - -use DateTime; - -my $date1 = DateTime->new( - year => 1997, month => 10, day => 24, - hour => 12, minute => 0, second => 0, - time_zone => 'UTC' -); -my $date2 = DateTime->new( - year => 1997, month => 10, day => 24, - hour => 12, minute => 0, second => 0, - time_zone => 'UTC' -); - -# make sure that comparing to itself eq 0 -my $identity = $date1->compare($date2); -ok( $identity == 0, "Identity comparison" ); - -$date2 = DateTime->new( - year => 1997, month => 10, day => 24, - hour => 12, minute => 0, second => 1, - time_zone => 'UTC' -); -ok( $date1->compare($date2) == -1, 'Comparison $a < $b, 1 second diff' ); - -$date2 = DateTime->new( - year => 1997, month => 10, day => 24, - hour => 12, minute => 1, second => 0, - time_zone => 'UTC' -); -ok( $date1->compare($date2) == -1, 'Comparison $a < $b, 1 minute diff' ); - -$date2 = DateTime->new( - year => 1997, month => 10, day => 24, - hour => 13, minute => 0, second => 0, - time_zone => 'UTC' -); -ok( $date1->compare($date2) == -1, 'Comparison $a < $b, 1 hour diff' ); - -$date2 = DateTime->new( - year => 1997, month => 10, day => 25, - hour => 12, minute => 0, second => 0, - time_zone => 'UTC' -); -ok( $date1->compare($date2) == -1, 'Comparison $a < $b, 1 day diff' ); - -$date2 = DateTime->new( - year => 1997, month => 11, day => 24, - hour => 12, minute => 0, second => 0, - time_zone => 'UTC' -); -ok( $date1->compare($date2) == -1, 'Comparison $a < $b, 1 month diff' ); - -$date2 = DateTime->new( - year => 1998, month => 10, day => 24, - hour => 12, minute => 0, second => 0, - time_zone => 'UTC' -); -ok( $date1->compare($date2) == -1, 'Comparison $a < $b, 1 year diff' ); - -# $a > $b tests - -$date2 = DateTime->new( - year => 1997, month => 10, day => 24, - hour => 11, minute => 59, second => 59, - time_zone => 'UTC' -); -ok( $date1->compare($date2) == 1, 'Comparison $a > $b, 1 second diff' ); - -$date2 = DateTime->new( - year => 1997, month => 10, day => 24, - hour => 11, minute => 59, second => 0, - time_zone => 'UTC' -); -ok( $date1->compare($date2) == 1, 'Comparison $a > $b, 1 minute diff' ); - -$date2 = DateTime->new( - year => 1997, month => 10, day => 24, - hour => 11, minute => 0, second => 0, - time_zone => 'UTC' -); -ok( $date1->compare($date2) == 1, 'Comparison $a > $b, 1 hour diff' ); - -$date2 = DateTime->new( - year => 1997, month => 10, day => 23, - hour => 12, minute => 0, second => 0, - time_zone => 'UTC' -); -ok( $date1->compare($date2) == 1, 'Comparison $a > $b, 1 day diff' ); - -$date2 = DateTime->new( - year => 1997, month => 9, day => 24, - hour => 12, minute => 0, second => 0, - time_zone => 'UTC' -); -ok( $date1->compare($date2) == 1, 'Comparison $a > $b, 1 month diff' ); - -$date2 = DateTime->new( - year => 1996, month => 10, day => 24, - hour => 12, minute => 0, second => 0, - time_zone => 'UTC' -); -ok( $date1->compare($date2) == 1, 'Comparison $a > $b, 1 year diff' ); - -my $infinity = DateTime::INFINITY; - -ok( $date1->compare($infinity) == -1, 'Comparison $a < inf' ); - -ok( $date1->compare( -$infinity ) == 1, 'Comparison $a > -inf' ); - -# comparison overloading, and infinity - -ok( ( $date1 <=> $infinity ) == -1, 'Comparison overload $a <=> inf' ); - -ok( ( $infinity <=> $date1 ) == 1, 'Comparison overload $inf <=> $a' ); - -# comparison with floating time -{ - my $date1 = DateTime->new( - year => 1997, month => 10, day => 24, - hour => 12, minute => 0, second => 0, - time_zone => 'America/Chicago' - ); - my $date2 = DateTime->new( - year => 1997, month => 10, day => 24, - hour => 12, minute => 0, second => 0, - time_zone => 'floating' - ); - - is( - DateTime->compare( $date1, $date2 ), 0, - 'Comparison with floating time (cmp)' - ); - is( ( $date1 <=> $date2 ), 0, 'Comparison with floating time (<=>)' ); - is( ( $date1 cmp $date2 ), 0, 'Comparison with floating time (cmp)' ); - is( - DateTime->compare_ignore_floating( $date1, $date2 ), 1, - 'Comparison with floating time (cmp)' - ); -} - -# sub-second -{ - my $date1 = DateTime->new( - year => 1997, month => 10, day => 24, - hour => 12, minute => 0, second => 0, - nanosecond => 100, - ); - - my $date2 = DateTime->new( - year => 1997, month => 10, day => 24, - hour => 12, minute => 0, second => 0, - nanosecond => 200, - ); - - is( - DateTime->compare( $date1, $date2 ), -1, - 'Comparison with floating time (cmp)' - ); - is( ( $date1 <=> $date2 ), -1, 'Comparison with floating time (<=>)' ); - is( ( $date1 cmp $date2 ), -1, 'Comparison with floating time (cmp)' ); -} - -{ - my $date1 = DateTime->new( - year => 2000, month => 10, day => 24, - hour => 12, minute => 0, second => 0, - nanosecond => 10000, - ); - - my $date2 = DateTime->new( - year => 2000, month => 10, day => 24, - hour => 12, minute => 0, second => 0, - nanosecond => 10000, - ); - - is( - DateTime->compare( $date1, $date2 ), 0, - 'Comparison with floating time (cmp)' - ); - is( ( $date1 <=> $date2 ), 0, 'Comparison with floating time (<=>)' ); - is( ( $date1 cmp $date2 ), 0, 'Comparison with floating time (cmp)' ); - is( - DateTime->compare_ignore_floating( $date1, $date2 ), 0, - 'Comparison with compare_ignore_floating (cmp)' - ); -} - -{ - - package DT::Test; - - sub new { shift; bless [@_] } - - sub utc_rd_values { @{ $_[0] } } -} - -{ - my $dt = DateTime->new( year => 1950 ); - my @values = $dt->utc_rd_values; - - $values[2] += 50; - - my $dt_test1 = DT::Test->new(@values); - - ok( $dt < $dt_test1, 'comparison works across different classes' ); - - $values[0] -= 1; - - my $dt_test2 = DT::Test->new(@values); - - ok( $dt > $dt_test2, 'comparison works across different classes' ); -} - -done_testing(); - diff -Nru libdatetime-perl-1.21/t/release-pp-09greg.t libdatetime-perl-1.46/t/release-pp-09greg.t --- libdatetime-perl-1.21/t/release-pp-09greg.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-09greg.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,131 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -use strict; -use warnings; - -use Test::More; - -use DateTime; - -# test _ymd2rd and _rd2ymd for various dates -# 2 tests are performed for each date (on _ymd2rd and _rd2ymd) -# dates are specified as [rd,year,month,day] -for ( # min and max supported days (for 32-bit system) - [ -( 2**28 ), -734951, 9, 7 ], - [ 2**28, 734952, 4, 25 ], - - # some miscellaneous dates (these are actually epoch dates for - # various calendars from Calendrical Calculations (1st ed) Table - # 1.1) - [ -1721425, -4713, 11, 24 ], - [ -1373427, -3760, 9, 7 ], - [ -1137142, -3113, 8, 11 ], - [ -1132959, -3101, 1, 23 ], - [ -963099, -2636, 2, 15 ], - [ -1, 0, 12, 30 ], [ 1, 1, 1, 1 ], - [ 2796, 8, 8, 27 ], - [ 103605, 284, 8, 29 ], - [ 226896, 622, 3, 22 ], - [ 227015, 622, 7, 19 ], - [ 654415, 1792, 9, 22 ], - [ 673222, 1844, 3, 21 ] - ) { - is( - join( '/', DateTime->_rd2ymd( $_->[0] ) ), - join( '/', @{$_}[ 1 .. 3 ] ), - $_->[0] . " \t=> " . join '/', @{$_}[ 1 .. 3 ] - ); - - is( - DateTime->_ymd2rd( @{$_}[ 1 .. 3 ] ), $_->[0], - join( '/', @{$_}[ 1 .. 3 ] ) . " \t=> " . $_->[0] - ); -} - -# normalization tests -for ( - [ -1753469, -4797, -33, 1 ], - [ -1753469, -4803, 39, 1 ], - [ -1753105, -4796, -34, 28 ], - [ -1753105, -4802, 38, 28 ] - ) { - is( - DateTime->_ymd2rd( @{$_}[ 1 .. 3 ] ), $_->[0], - join( '/', @{$_}[ 1 .. 3 ] ) - . " \t=> " - . $_->[0] - . " (normalization)" - ); -} - -# test first and last day of each month from Jan -4800..Dec 4800 -# this test bails after the first failure with a not ok. -# if it completes successfully, only one ok is issued. - -my @mlen = ( 0, 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ); -my ( $dno, $y, $m, $dno2, $y2, $m2, $d2, $mlen ) = ( -1753530, -4800, 1 ); - -while ( $y <= 4800 ) { - - # test $y,$m,1 - ++$dno; - $dno2 = DateTime->_ymd2rd( $y, $m, 1 ); - if ( $dno != $dno2 ) { - is( - $dno2, $dno, - "greg torture test: _ymd2rd($y,$m,1) should be $dno" - ); - last; - } - ( $y2, $m2, $d2 ) = DateTime->_rd2ymd($dno); - - if ( $y2 != $y || $m2 != $m || $d2 != 1 ) { - is( - "$y2/$m2/$d2", "$y/$m/1", - "greg torture test: _rd2ymd($dno) should be $y/$m/1" - ); - last; - } - - # test $y,$m,$mlen - $mlen = $mlen[$m] || ( $y % 4 ? 28 : $y % 100 ? 29 : $y % 400 ? 28 : 29 ); - $dno += $mlen - 1; - $dno2 = DateTime->_ymd2rd( $y, $m, $mlen ); - if ( $dno != $dno2 ) { - is( - $dno2, $dno, - "greg torture test: _ymd2rd($y,$m,$mlen) should be $dno" - ); - last; - } - ( $y2, $m2, $d2 ) = DateTime->_rd2ymd($dno); - - if ( $y2 != $y || $m2 != $m || $d2 != $mlen ) { - is( - "$y2/$m2/$d2", "$y/$m/$mlen", - "greg torture test: _rd2ymd($dno) should be $y/$m/$mlen" - ); - last; - } - - # and on to the next month... - if ( ++$m > 12 ) { - $m = 1; - ++$y; - } -} - -pass("greg torture test") if $y == 4801; - -done_testing(); - diff -Nru libdatetime-perl-1.21/t/release-pp-10subtract.t libdatetime-perl-1.46/t/release-pp-10subtract.t --- libdatetime-perl-1.21/t/release-pp-10subtract.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-10subtract.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,497 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -use strict; -use warnings; - -use Test::More; - -use DateTime; - -{ - my $date1 = DateTime->new( - year => 2001, month => 5, day => 10, - hour => 4, minute => 3, second => 2, - nanosecond => 12, - time_zone => 'UTC' - ); - - my $date2 = DateTime->new( - year => 2001, month => 6, day => 12, - hour => 5, minute => 7, second => 23, - nanosecond => 7, - time_zone => 'UTC' - ); - - my $dur = $date2 - $date1; - - is( $dur->delta_months, 1, 'delta_months should be 1' ); - is( $dur->delta_days, 2, 'delta_days should be 2' ); - is( $dur->delta_minutes, 64, 'delta_minutes should be 64' ); - is( $dur->delta_seconds, 20, 'delta_seconds should be 20' ); - is( - $dur->delta_nanoseconds, 999_999_995, - 'delta_nanoseconds should be 999,999,995' - ); - - is( $dur->years, 0, 'Years' ); - is( $dur->months, 1, 'Months' ); - is( $dur->weeks, 0, 'Weeks' ); - is( $dur->days, 2, 'Days' ); - is( $dur->hours, 1, 'Hours' ); - is( $dur->minutes, 4, 'Minutes' ); - is( $dur->seconds, 20, 'Seconds' ); - is( $dur->nanoseconds, 999_999_995, 'Nanoseconds' ); -} - -{ - my $date1 = DateTime->new( - year => 2001, month => 5, day => 10, - hour => 4, minute => 3, second => 2, - time_zone => 'UTC' - ); - - my $date2 = DateTime->new( - year => 2001, month => 6, day => 12, - hour => 5, minute => 7, second => 23, - time_zone => 'UTC' - ); - - my $dur = $date1 - $date2; - - is( $dur->delta_months, -1, 'delta_months should be -1' ); - is( $dur->delta_days, -2, 'delta_days should be -2' ); - is( $dur->delta_minutes, -64, 'delta_minutes should be 64' ); - is( $dur->delta_seconds, -21, 'delta_seconds should be 20' ); - is( $dur->delta_nanoseconds, 0, 'delta_nanoseconds should be 0' ); - - is( $dur->years, 0, 'Years' ); - is( $dur->months, 1, 'Months' ); - is( $dur->weeks, 0, 'Weeks' ); - is( $dur->days, 2, 'Days' ); - is( $dur->hours, 1, 'Hours' ); - is( $dur->minutes, 4, 'Minutes' ); - is( $dur->seconds, 21, 'Seconds' ); - is( $dur->nanoseconds, 0, 'Nanoseconds' ); - - $dur = $date1 - $date1; - is( $dur->delta_days, 0, 'date minus itself should have no delta days' ); - is( - $dur->delta_seconds, 0, - 'date minus itself should have no delta seconds' - ); - - my $new = $date1 - DateTime::Duration->new( years => 2 ); - is( $new->datetime, '1999-05-10T04:03:02', 'test - overloading' ); -} - -{ - my $d = DateTime->new( - year => 2001, month => 10, day => 19, - hour => 5, minute => 1, second => 1, - time_zone => 'UTC' - ); - - my $d2 = $d->clone; - $d2->subtract( - weeks => 1, - days => 1, - hours => 1, - minutes => 1, - seconds => 1, - ); - - ok( defined $d2, 'Defined' ); - is( - $d2->datetime, '2001-10-11T04:00:00', - 'Subtract and get the right thing' - ); -} - -# based on bug report from Eric Cholet -{ - my $dt1 = DateTime->new( - year => 2003, month => 2, day => 9, - hour => 0, minute => 0, second => 1, - time_zone => 'UTC', - ); - - my $dt2 = DateTime->new( - year => 2003, month => 2, day => 7, - hour => 23, minute => 59, second => 59, - time_zone => 'UTC', - ); - - my $dur1 = $dt1->subtract_datetime($dt2); - - is( $dur1->delta_days, 1, 'delta_days should be 1' ); - is( $dur1->delta_seconds, 2, 'delta_seconds should be 2' ); - - my $dt3 = $dt2 + $dur1; - - is( - DateTime->compare( $dt1, $dt3 ), 0, - 'adding difference back to dt1 should give same datetime' - ); - - my $dur2 = $dt2->subtract_datetime($dt1); - - is( $dur2->delta_days, -1, 'delta_days should be -1' ); - is( $dur2->delta_seconds, -2, 'delta_seconds should be -2' ); - - my $dt4 = $dt1 + $dur2; - - is( - DateTime->compare( $dt2, $dt4 ), 0, - 'adding difference back to dt2 should give same datetime' - ); -} - -# test if the day changes because of a nanosecond subtract -{ - my $dt = DateTime->new( - year => 2001, month => 6, day => 12, - hour => 0, minute => 0, second => 0, - time_zone => 'UTC' - ); - $dt->subtract( nanoseconds => 1 ); - is( $dt->nanosecond, 999999999, 'negative nanoseconds normalize ok' ); - is( $dt->second, 59, 'seconds normalize ok' ); - is( $dt->minute, 59, 'minutes normalize ok' ); - is( $dt->hour, 23, 'hours normalize ok' ); - is( $dt->day, 11, 'days normalize ok' ); -} - -# test for a bug when nanoseconds were greater in earlier datetime -{ - my $dt1 = DateTime->new( - year => 2000, month => 1, day => 5, - hour => 0, minute => 10, second => 0, - nanosecond => 1, - time_zone => 'UTC', - ); - - my $dt2 = DateTime->new( - year => 2000, month => 1, day => 6, - hour => 0, minute => 10, second => 0, - nanosecond => 0, - time_zone => 'UTC', - ); - my $dur = $dt2 - $dt1; - - is( $dur->delta_days, 0, 'delta_days is 0' ); - is( $dur->delta_minutes, 1439, 'delta_minutes is 1439' ); - is( $dur->delta_seconds, 59, 'delta_seconds is 59' ); - is( - $dur->delta_nanoseconds, 999_999_999, - 'delta_nanoseconds is 999,999,999' - ); - ok( $dur->is_positive, 'duration is positive' ); -} - -{ - my $dt1 = DateTime->new( - year => 2000, month => 1, day => 5, - hour => 0, minute => 10, second => 0, - nanosecond => 20, - time_zone => 'UTC', - ); - - my $dt2 = DateTime->new( - year => 2000, month => 1, day => 5, - hour => 0, minute => 10, second => 0, - nanosecond => 10, - time_zone => 'UTC', - ); - - my $dur = $dt2 - $dt1; - - is( $dur->delta_days, 0, 'days is 0' ); - is( $dur->delta_seconds, 0, 'seconds is 0' ); - is( $dur->delta_nanoseconds, -10, 'nanoseconds is -10' ); - ok( $dur->is_negative, 'duration is negative' ); -} - -{ - my $dt1 = DateTime->new( - year => 2000, month => 1, day => 5, - hour => 0, minute => 11, second => 0, - nanosecond => 20, - time_zone => 'UTC', - ); - - my $dt2 = DateTime->new( - year => 2000, month => 1, day => 5, - hour => 0, minute => 10, second => 0, - nanosecond => 10, - time_zone => 'UTC', - ); - - my $dur = $dt2 - $dt1; - - is( $dur->delta_days, 0, 'delta_days is 0' ); - is( $dur->delta_minutes, -1, 'delta_minutes is -1' ); - is( $dur->delta_seconds, 0, 'delta_seconds is 0' ); - is( $dur->delta_nanoseconds, -10, 'nanoseconds is -10' ); - ok( $dur->is_negative, 'duration is negative' ); -} - -{ - my $dt1 = DateTime->new( - year => 2000, month => 1, day => 5, - hour => 0, minute => 10, second => 0, - nanosecond => 20, - time_zone => 'UTC', - ); - - my $dt2 = DateTime->new( - year => 2000, month => 1, day => 5, - hour => 0, minute => 11, second => 0, - nanosecond => 10, - time_zone => 'UTC', - ); - - my $dur = $dt2 - $dt1; - - is( $dur->delta_days, 0, 'days is 0' ); - is( $dur->delta_seconds, 59, 'seconds is 59' ); - is( $dur->delta_nanoseconds, 999_999_990, 'nanoseconds is 999,999,990' ); - ok( $dur->is_positive, 'duration is positive' ); -} - -{ - my $dt1 = DateTime->new( - year => 2000, month => 1, day => 5, - hour => 0, minute => 11, second => 0, - nanosecond => 10, - time_zone => 'UTC', - ); - - my $dt2 = DateTime->new( - year => 2000, month => 1, day => 5, - hour => 0, minute => 10, second => 0, - nanosecond => 20, - time_zone => 'UTC', - ); - - my $dur = $dt2 - $dt1; - - is( $dur->delta_days, 0, 'days is 0' ); - is( $dur->delta_seconds, -59, 'seconds is -59' ); - is( - $dur->delta_nanoseconds, -999_999_990, - 'nanoseconds is -999,999,990' - ); - ok( $dur->is_negative, 'duration is negative' ); -} - -{ - my $dt1 = DateTime->new( - year => 2000, month => 1, day => 5, - hour => 0, minute => 11, second => 0, - nanosecond => 20, - time_zone => 'UTC', - ); - - my $dur = $dt1 - $dt1; - - is( $dur->delta_days, 0, 'days is 0' ); - is( $dur->delta_seconds, 0, 'seconds is 0' ); - is( $dur->delta_nanoseconds, 0, 'nanoseconds is 0' ); - ok( !$dur->is_positive, 'not positive' ); - ok( !$dur->is_negative, 'not negative' ); -} - -{ - my $dt1 = DateTime->new( year => 2003, month => 12, day => 31 ); - my $dt2 = $dt1->clone->subtract( months => 1 ); - - is( $dt2->year, 2003, '2003-12-31 - 1 month = 2003-11-30' ); - is( $dt2->month, 11, '2003-12-31 - 1 month = 2003-11-30' ); - is( $dt2->day, 30, '2003-12-31 - 1 month = 2003-11-30' ); -} - -{ - my $date1 = DateTime->new( - year => 2001, month => 5, day => 10, - hour => 4, minute => 3, second => 2, - nanosecond => 12, - time_zone => 'UTC' - ); - - my $date2 = DateTime->new( - year => 2001, month => 6, day => 12, - hour => 5, minute => 7, second => 23, - nanosecond => 7, - time_zone => 'UTC' - ); - - my $dur = $date2->subtract_datetime_absolute($date1); - - is( $dur->delta_months, 0, 'delta_months is 0' ); - is( $dur->delta_minutes, 0, 'delta_minutes is 0' ); - is( $dur->delta_seconds, 2_855_060, 'delta_seconds is 2,855,060' ); - is( - $dur->delta_nanoseconds, 999_999_995, - 'delta_seconds is 999,999,995' - ); -} - -{ - my $date1 = DateTime->new( - year => 2001, month => 5, day => 10, - hour => 4, minute => 3, second => 2, - time_zone => 'UTC' - ); - - my $date2 = DateTime->new( - year => 2001, month => 6, day => 12, - hour => 5, minute => 7, second => 23, - time_zone => 'UTC' - ); - - my $dur = $date1->subtract_datetime_absolute($date2); - - is( $dur->delta_months, 0, 'delta_months is 0' ); - is( $dur->delta_minutes, 0, 'delta_minutes is 0' ); - is( $dur->delta_seconds, -2_855_061, 'delta_seconds is -2,855,061' ); - is( $dur->delta_nanoseconds, 0, 'delta_nanoseconds is 0' ); -} - -{ - my $date1 = DateTime->new( year => 2003, month => 9, day => 30 ); - my $date2 = DateTime->new( year => 2003, month => 10, day => 1 ); - - my $date3 = DateTime->new( year => 2003, month => 10, day => 31 ); - my $date4 = DateTime->new( year => 2003, month => 11, day => 1 ); - - my $date5 = DateTime->new( year => 2003, month => 2, day => 28 ); - my $date6 = DateTime->new( year => 2003, month => 3, day => 1 ); - - my $date7 = DateTime->new( year => 2003, month => 1, day => 31 ); - my $date8 = DateTime->new( year => 2003, month => 2, day => 1 ); - - foreach my $p ( - [ $date1, $date2 ], - [ $date3, $date4 ], - [ $date5, $date6 ], - [ $date7, $date8 ], - ) { - my $pos_diff = $p->[1]->subtract_datetime( $p->[0] ); - - is( $pos_diff->delta_days, 1, "1 day diff at end of month" ); - is( $pos_diff->delta_months, 0, "0 month diff at end of month" ); - - my $neg_diff = $p->[0]->subtract_datetime( $p->[1] ); - - is( $neg_diff->delta_days, -1, "-1 day diff at end of month" ); - is( $neg_diff->delta_months, 0, "0 month diff at end of month" ); - } -} - -{ - my $dt1 = DateTime->new( - year => 2005, month => 6, day => 11, - time_zone => 'UTC', - ); - - my $dt2 = DateTime->new( - year => 2005, month => 11, day => 10, - time_zone => 'UTC', - ); - - my $dur = $dt2->subtract_datetime($dt1); - my %deltas = $dur->deltas; - is( $deltas{months}, 4, '4 months - smaller day > bigger day' ); - is( $deltas{days}, 29, '29 days - smaller day > bigger day' ); - is( $deltas{minutes}, 0, '0 minutes - smaller day > bigger day' ); - - is( - DateTime->compare( $dt1->clone->add_duration($dur), $dt2 ), 0, - '$dt1 + $dur == $dt2' - ); - - # XXX - this does not work, nor will it ever work - # is( $dt2->clone->subtract_duration($dur), $dt1, '$dt2 - $dur == $dt1' ); -} - -{ - my $dt1 = DateTime->new( - year => 2005, month => 6, day => 11, - time_zone => 'UTC', - ); - - my $dt2 = DateTime->new( - year => 2005, month => 11, day => 10, - time_zone => 'UTC', - ); - - my $dur = $dt2->delta_days($dt1); - my %deltas = $dur->deltas; - is( $deltas{months}, 0, '30 months - smaller day > bigger day' ); - is( $deltas{days}, 152, '152 days - smaller day > bigger day' ); - is( $deltas{minutes}, 0, '0 minutes - smaller day > bigger day' ); - - is( - DateTime->compare( $dt1->clone->add_duration($dur), $dt2 ), 0, - '$dt1 + $dur == $dt2' - ); - is( - DateTime->compare( $dt2->clone->subtract_duration($dur), $dt1 ), 0, - '$dt2 - $dur == $dt1' - ); -} - -{ - my $dt = DateTime->new( - year => 2012, - month => 6, - day => 30, - time_zone => 'floating', - ); - - my $default = $dt->clone()->subtract( months => 1 ); - is( - $default->format_cldr('yyyy-MM-dd'), - '2012-05-31', - 'default subtract uses preserve end_of_month mode' - ); - - my $with_mode = $dt->clone()->subtract( - months => 1, - end_of_month => 'limit', - ); - is( - $with_mode->format_cldr('yyyy-MM-dd'), - '2012-05-30', - 'set end_of_month mode to limit in call to subtract()' - ); - -} - -{ - my $dt = DateTime->new( - year => 2014, - month => 7, - day => 3, - time_zone => 'floating', - ); - - $dt->subtract( days => 2 ); - is( - $dt->date, '2014-07-01', - 'subtracting 2 days from a floating datetime' - ); -} - -done_testing(); - diff -Nru libdatetime-perl-1.21/t/release-pp-11duration.t libdatetime-perl-1.46/t/release-pp-11duration.t --- libdatetime-perl-1.21/t/release-pp-11duration.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-11duration.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,451 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -use strict; -use warnings; - -use Test::More; - -use DateTime; -use DateTime::Duration; - -{ - my %pairs = ( - years => 1, - months => 2, - weeks => 3, - days => 4, - hours => 6, - minutes => 7, - seconds => 8, - nanoseconds => 9, - ); - - my $dur = DateTime::Duration->new(%pairs); - - while ( my ( $unit, $val ) = each %pairs ) { - is( $dur->$unit(), $val, "$unit should be $val" ); - } - - is( $dur->delta_months, 14, "delta_months" ); - is( $dur->delta_days, 25, "delta_days" ); - is( $dur->delta_minutes, 367, "delta_minutes" ); - is( $dur->delta_seconds, 8, "delta_seconds" ); - is( $dur->delta_nanoseconds, 9, "delta_nanoseconds" ); - - is( $dur->in_units('months'), 14, "in_units months" ); - is( $dur->in_units('days'), 25, "in_units days" ); - is( $dur->in_units('minutes'), 367, "in_units minutes" ); - is( $dur->in_units('seconds'), 8, "in_units seconds" ); - is( - $dur->in_units( 'nanoseconds', 'seconds' ), 9, - "in_units nanoseconds, seconds" - ); - - is( $dur->in_units('years'), 1, "in_units years" ); - is( $dur->in_units( 'months', 'years' ), 2, "in_units months, years" ); - is( $dur->in_units('weeks'), 3, "in_units weeks" ); - is( $dur->in_units( 'days', 'weeks' ), 4, "in_units days, weeks" ); - is( $dur->in_units('hours'), 6, "in_units hours" ); - is( $dur->in_units( 'minutes', 'hours' ), 7, "in_units minutes, hours" ); - is( - $dur->in_units('nanoseconds'), 8_000_000_009, - "in_units nanoseconds" - ); - - my ( - $years, $months, $weeks, $days, $hours, - $minutes, $seconds, $nanoseconds - ) - = $dur->in_units( - qw( years months weeks days hours - minutes seconds nanoseconds ) - ); - - is( $years, 1, "in_units years, list context" ); - is( $months, 2, "in_units months, list context" ); - is( $weeks, 3, "in_units weeks, list context" ); - is( $days, 4, "in_units days, list context" ); - is( $hours, 6, "in_units hours, list context" ); - is( $minutes, 7, "in_units minutes, list context" ); - is( $seconds, 8, "in_units seconds, list context" ); - is( $nanoseconds, 9, "in_units nanoseconds, list context" ); - - ok( $dur->is_positive, "should be positive" ); - ok( !$dur->is_zero, "should not be zero" ); - ok( !$dur->is_negative, "should not be negative" ); - - ok( $dur->is_wrap_mode, "wrap mode" ); -} -{ - my %pairs = ( - years => 1, - months => 2, - weeks => 3, - days => 4, - hours => 6, - minutes => 7, - seconds => 8, - nanoseconds => 9, - ); - - my $dur = DateTime::Duration->new( %pairs, end_of_month => 'limit' ); - - my $calendar_dur = $dur->calendar_duration; - is( $calendar_dur->delta_months, 14, "date - delta_months is 14" ); - is( $calendar_dur->delta_minutes, 0, "date - delta_minutes is 0" ); - is( $calendar_dur->delta_seconds, 0, "date - delta_seconds is 0" ); - is( - $calendar_dur->delta_nanoseconds, 0, - "date - delta_nanoseconds is 0" - ); - ok( $calendar_dur->is_limit_mode, "limit mode" ); - - my $clock_dur = $dur->clock_duration; - is( $clock_dur->delta_months, 0, "time - delta_months is 0" ); - is( $clock_dur->delta_minutes, 367, "time - delta_minutes is 367" ); - is( $clock_dur->delta_seconds, 8, "time - delta_seconds is 8" ); - is( $clock_dur->delta_nanoseconds, 9, "time - delta_nanoseconds is 9" ); - ok( $clock_dur->is_limit_mode, "limit mode" ); -} - -{ - my $dur = DateTime::Duration->new( days => 1, end_of_month => 'limit' ); - ok( $dur->is_limit_mode, "limit mode" ); -} - -{ - my $dur - = DateTime::Duration->new( days => 1, end_of_month => 'preserve' ); - ok( $dur->is_preserve_mode, "preserve mode" ); -} - -my $leap_day = DateTime->new( - year => 2004, month => 2, day => 29, - time_zone => 'UTC', -); - -{ - my $new = $leap_day + DateTime::Duration->new( - years => 1, - end_of_month => 'wrap' - ); - - is( $new->date, '2005-03-01', "new date should be 2005-03-01" ); -} - -{ - my $new = $leap_day + DateTime::Duration->new( - years => 1, - end_of_month => 'limit' - ); - - is( $new->date, '2005-02-28', "new date should be 2005-02-28" ); -} - -{ - my $new = $leap_day + DateTime::Duration->new( - years => 1, - end_of_month => 'preserve' - ); - - is( $new->date, '2005-02-28', "new date should be 2005-02-28" ); - - my $new2 = $leap_day + DateTime::Duration->new( - months => 1, - end_of_month => 'preserve' - ); - is( $new2->date, '2004-03-31', "new date should be 2004-03-31" ); -} - -{ - my $inverse = DateTime::Duration->new( - years => 1, months => 1, - weeks => 1, days => 1, - hours => 1, minutes => 2, seconds => 3, - )->inverse; - - is( $inverse->years, 1, 'inverse years should be positive' ); - is( $inverse->months, 1, 'inverse months should be positive' ); - is( $inverse->weeks, 1, 'inverse weeks should be positive' ); - is( $inverse->days, 1, 'inverse days should be positive' ); - is( $inverse->hours, 1, 'inverse hours should be positive' ); - is( $inverse->minutes, 2, 'inverse minutes should be positive' ); - is( $inverse->seconds, 3, 'inverse minutes should be positive' ); - - is( - $inverse->delta_months, -13, - 'inverse delta months should be negative' - ); - is( $inverse->delta_days, -8, 'inverse delta months should be negative' ); - is( - $inverse->delta_minutes, -62, - 'inverse delta minutes should be negative' - ); - is( - $inverse->delta_seconds, -3, - 'inverse delta seconds should be negative' - ); - - ok( $inverse->is_negative, "should be negative" ); - ok( !$inverse->is_zero, "should not be zero" ); - ok( !$inverse->is_positive, "should not be positivea" ); - - is( - $inverse->end_of_month_mode(), 'preserve', - 'inverse method uses default end_of_month_mode without explicit parameter' - ); - - my $inverse2 = DateTime::Duration->new( years => 1 ) - ->inverse( end_of_month => 'limit' ); - - is( - $inverse2->end_of_month_mode(), 'limit', - 'inverse method allows setting end_of_month_mode' - ); -} - -{ - my $dur1 = DateTime::Duration->new( months => 6, days => 10 ); - - my $dur2 = DateTime::Duration->new( months => 3, days => 7 ); - - my $new1 = $dur1 + $dur2; - is( $new1->delta_months, 9, 'test + overloading' ); - is( $new1->delta_days, 17, 'test + overloading' ); - - my $new2 = $dur1 - $dur2; - is( $new2->delta_months, 3, 'test - overloading' ); - is( $new2->delta_days, 3, 'test - overloading' ); - - my $new3 = $dur2 - $dur1; - is( $new3->delta_months, -3, 'test - overloading' ); - is( $new3->delta_days, -3, 'test - overloading' ); -} - -{ - my $dur1 = DateTime::Duration->new( months => 6, days => 10 ); - - my $new1 = $dur1 * 4; - is( $new1->delta_months, 24, 'test * overloading' ); - is( $new1->delta_days, 40, 'test * overloading' ); - - $dur1->multiply(4); - is( $dur1->delta_months, 24, 'test multiply' ); - is( $dur1->delta_days, 40, 'test multiply' ); -} - -{ - my $dur1 = DateTime::Duration->new( - months => 6, days => 10, seconds => 3, - nanoseconds => 1_200_300_400 - ); - - my $dur2 - = DateTime::Duration->new( seconds => 1, nanoseconds => 500_000_000 ); - - is( $dur1->delta_seconds, 4, 'test nanoseconds overflow' ); - is( $dur1->delta_nanoseconds, 200_300_400, 'test nanoseconds remainder' ); - - my $new1 = $dur1 - $dur2; - - is( $new1->delta_seconds, 2, 'seconds is positive' ); - is( - $new1->delta_nanoseconds, 700_300_400, - 'nanoseconds remainder is negative' - ); - - $new1->add( nanoseconds => 500_000_000 ); - is( $new1->delta_seconds, 3, 'seconds are unaffected' ); - is( $new1->delta_nanoseconds, 200_300_400, 'nanoseconds are back' ); - - my $new2 = $dur1 - $dur2; - $new2->add( nanoseconds => 1_500_000_000 ); - is( $new2->delta_seconds, 4, 'seconds go up' ); - is( $new2->delta_nanoseconds, 200_300_400, 'nanoseconds are normalized' ); - - $new2->subtract( nanoseconds => 100_000_000 ); - is( $new2->delta_nanoseconds, 100_300_400, 'sub nanoseconds works' ); - - my $new3 = $dur2 * 3; - - is( $new3->delta_seconds, 4, 'seconds normalized after multiplication' ); - is( - $new3->delta_nanoseconds, 500_000_000, - 'nanoseconds normalized after multiplication' - ); -} - -{ - my $dur = DateTime::Duration->new( nanoseconds => -10 ); - is( $dur->nanoseconds, 10, 'nanoseconds is 10' ); - is( $dur->delta_nanoseconds, -10, 'delta_nanoseconds is -10' ); - ok( $dur->is_negative, 'duration is negative' ); -} - -{ - my $dur = DateTime::Duration->new( days => 0 ); - is( $dur->delta_days, 0, 'delta_days is 0' ); - ok( !$dur->is_positive, 'not positive' ); - ok( $dur->is_zero, 'is zero' ); - ok( !$dur->is_negative, 'not negative' ); -} - -{ - eval { - DateTime::Duration->new( months => 3 )->add( hours => -3 ) - ->add( minutes => 1 ); - }; - ok( !$@, 'method chaining should work' ); -} - -{ - my $min_1 = DateTime::Duration->new( minutes => 1 ); - my $hour_1 = DateTime::Duration->new( hours => 1 ); - - my $min_59 = $hour_1 - $min_1; - - is( $min_59->delta_months, 0, 'delta_months is 0' ); - is( $min_59->delta_days, 0, 'delta_days is 0' ); - is( $min_59->delta_minutes, 59, 'delta_minutes is 59' ); - is( $min_59->delta_seconds, 0, 'delta_seconds is 0' ); - is( $min_59->delta_nanoseconds, 0, 'delta_nanoseconds is 0' ); - - my $min_neg_59 = $min_1 - $hour_1; - - is( $min_neg_59->delta_months, 0, 'delta_months is 0' ); - is( $min_neg_59->delta_days, 0, 'delta_days is 0' ); - is( $min_neg_59->delta_minutes, -59, 'delta_minutes is -59' ); - is( $min_neg_59->delta_seconds, 0, 'delta_seconds is 0' ); - is( $min_neg_59->delta_nanoseconds, 0, 'delta_nanoseconds is 0' ); -} - -{ - my $dur1 = DateTime::Duration->new( minutes => 10 ); - my $dur2 = DateTime::Duration->new( minutes => 20 ); - - eval { my $x = 1 if $dur1 <=> $dur2 }; - like( - $@, qr/does not overload comparison/, - 'check error for duration comparison overload' - ); - - is( - DateTime::Duration->compare( $dur1, $dur2 ), -1, - '20 minutes is greater than 10 minutes' - ); - - is( - DateTime::Duration->compare( - $dur1, $dur2, DateTime->new( year => 1 ) - ), - -1, - '20 minutes is greater than 10 minutes' - ); -} - -{ - my $dur1 = DateTime::Duration->new( days => 29 ); - my $dur2 = DateTime::Duration->new( months => 1 ); - - my $base = DateTime->new( year => 2004 ); - is( - DateTime::Duration->compare( $dur1, $dur2, $base ), -1, - '29 days is less than 1 month with base of 2004-01-01' - ); - - $base = DateTime->new( year => 2004, month => 2 ); - is( - DateTime::Duration->compare( $dur1, $dur2, $base ), 0, - '29 days is equal to 1 month with base of 2004-02-01' - ); - - $base = DateTime->new( year => 2005, month => 2 ); - is( - DateTime::Duration->compare( $dur1, $dur2, $base ), 1, - '29 days is greater than 1 month with base of 2005-02-01' - ); -} - -{ - my $dur1 = DateTime::Duration->new( - nanoseconds => 1_000, - seconds => 1, - ); - - my $dur2 = $dur1->clone->subtract( nanoseconds => 5_000 ); - - is( $dur2->delta_seconds, 0, 'normalize nanoseconds to positive' ); - is( - $dur2->delta_nanoseconds, 999_996_000, - 'normalize nanoseconds to positive' - ); - - my $dur3 = $dur1->clone->subtract( nanoseconds => 6_000 ) - ->subtract( nanoseconds => 999_999_000 ); - - is( $dur3->delta_seconds, 0, 'normalize nanoseconds to negative' ); - is( - $dur3->delta_nanoseconds, -4_000, - 'normalize nanoseconds to negative' - ); - - my $dur4 = DateTime::Duration->new( - seconds => -1, - nanoseconds => -2_500_000_000 - ); - - is( $dur4->delta_seconds, -3, 'normalize many negative nanoseconds' ); - is( - $dur4->delta_nanoseconds, -500_000_000, - 'normalize many negative nanoseconds' - ); -} - -{ - my $dur = DateTime::Duration->new( - minutes => 30, - seconds => -1, - ); - - ok( !$dur->is_positive, 'is not positive' ); - ok( !$dur->is_zero, 'is not zero' ); - ok( !$dur->is_negative, 'is not negative' ); -} - -{ - my $dur = DateTime::Duration->new( minutes => 50 ); - - is( $dur->in_units('years'), 0, 'in_units returns 0 for years' ); - is( $dur->in_units('months'), 0, 'in_units returns 0 for months' ); - is( $dur->in_units('days'), 0, 'in_units returns 0 for days' ); - is( $dur->in_units('hours'), 0, 'in_units returns 0 for hours' ); - is( $dur->in_units('seconds'), 0, 'in_units returns 0 for seconds' ); - is( - $dur->in_units('nanoseconds'), 0, - 'in_units returns 0 for nanoseconds' - ); -} - -{ - local $TODO = 'reject fractional units in DateTime::Duration->new'; - - eval { DateTime::Duration->new( minutes => 50.2 ) }; - - like( - $@, qr/is an integer/, - 'cannot create a duration with fractional units' - ); -} - -done_testing(); - diff -Nru libdatetime-perl-1.21/t/release-pp-12week.t libdatetime-perl-1.46/t/release-pp-12week.t --- libdatetime-perl-1.21/t/release-pp-12week.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-12week.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,66 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -use strict; -use warnings; - -use Test::More; - -use DateTime; - -my @tests = ( - [ [ 1964, 12, 31 ], [ 1964, 53 ] ], - [ [ 1965, 1, 1 ], [ 1964, 53 ] ], - [ [ 1971, 9, 7 ], [ 1971, 36 ] ], - [ [ 1971, 10, 25 ], [ 1971, 43 ] ], - [ [ 1995, 1, 1 ], [ 1994, 52 ] ], - [ [ 1995, 11, 18 ], [ 1995, 46 ] ], - [ [ 1995, 12, 31 ], [ 1995, 52 ] ], - [ [ 1996, 12, 31 ], [ 1997, 1 ] ], - [ [ 2001, 4, 28 ], [ 2001, 17 ] ], - [ [ 2001, 8, 2 ], [ 2001, 31 ] ], - [ [ 2001, 9, 11 ], [ 2001, 37 ] ], - [ [ 2002, 12, 25 ], [ 2002, 52 ] ], - [ [ 2002, 12, 31 ], [ 2003, 1 ] ], - [ [ 2003, 1, 1 ], [ 2003, 1 ] ], - [ [ 2003, 12, 31 ], [ 2004, 1 ] ], - [ [ 2004, 1, 1 ], [ 2004, 1 ] ], - [ [ 2004, 12, 31 ], [ 2004, 53 ] ], - [ [ 2005, 1, 1 ], [ 2004, 53 ] ], - [ [ 2005, 12, 31 ], [ 2005, 52 ] ], - [ [ 2006, 1, 1 ], [ 2005, 52 ] ], - [ [ 2006, 12, 31 ], [ 2006, 52 ] ], - [ [ 2007, 1, 1 ], [ 2007, 1 ] ], - [ [ 2007, 12, 31 ], [ 2008, 1 ] ], - [ [ 2008, 1, 1 ], [ 2008, 1 ] ], - [ [ 2008, 12, 31 ], [ 2009, 1 ] ], - [ [ 2009, 1, 1 ], [ 2009, 1 ] ], -); - -foreach my $test (@tests) { - my @args = @{ $test->[0] }; - my @results = @{ $test->[1] }; - - my $dt = DateTime->new( - year => $args[0], - month => $args[1], - day => $args[2], - time_zone => 'UTC', - ); - - my ( $year, $week ) = $dt->week(); - - is( "$year-W$week", "$results[0]-W$results[1]" ); -} - -done_testing(); - diff -Nru libdatetime-perl-1.21/t/release-pp-13strftime.t libdatetime-perl-1.46/t/release-pp-13strftime.t --- libdatetime-perl-1.21/t/release-pp-13strftime.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-13strftime.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,447 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -# test suite stolen shamelessly from TimeDate distro -use strict; -use warnings; -use utf8; - -use Test::More 0.96; - -use DateTime; -use DateTime::Locale; - -test_strftime_for_locale( 'en-US', en_tests() ); -test_strftime_for_locale( 'de', de_tests() ); -test_strftime_for_locale( 'it', it_tests() ); - -subtest( - 'strftime with multiple params', - sub { - my $dt = DateTime->new( - year => 1800, - month => 1, - day => 10, - time_zone => 'UTC', - ); - - my ( $y, $d ) = $dt->strftime( '%Y', '%d' ); - is( $y, 1800, 'first value is year' ); - is( $d, 10, 'second value is day' ); - - $y = $dt->strftime( '%Y', '%d' ); - is( $y, 1800, 'scalar context returns year' ); - } -); - -subtest( - 'hour formatting', - sub { - my $dt = DateTime->new( - year => 2003, - hour => 0, - minute => 0 - ); - - is( - $dt->strftime('%I %M %p'), '12 00 AM', - 'formatting of hours as 1-12' - ); - is( - $dt->strftime('%l %M %p'), '12 00 AM', - 'formatting of hours as 1-12' - ); - - $dt->set( hour => 1 ); - is( - $dt->strftime('%I %M %p'), '01 00 AM', - 'formatting of hours as 1-12' - ); - is( - $dt->strftime('%l %M %p'), ' 1 00 AM', - 'formatting of hours as 1-12' - ); - - $dt->set( hour => 11 ); - is( - $dt->strftime('%I %M %p'), '11 00 AM', - 'formatting of hours as 1-12' - ); - is( - $dt->strftime('%l %M %p'), '11 00 AM', - 'formatting of hours as 1-12' - ); - - $dt->set( hour => 12 ); - is( - $dt->strftime('%I %M %p'), '12 00 PM', - 'formatting of hours as 1-12' - ); - is( - $dt->strftime('%l %M %p'), '12 00 PM', - 'formatting of hours as 1-12' - ); - - $dt->set( hour => 13 ); - is( - $dt->strftime('%I %M %p'), '01 00 PM', - 'formatting of hours as 1-12' - ); - is( - $dt->strftime('%l %M %p'), ' 1 00 PM', - 'formatting of hours as 1-12' - ); - - $dt->set( hour => 23 ); - is( - $dt->strftime('%I %M %p'), '11 00 PM', - 'formatting of hours as 1-12' - ); - is( - $dt->strftime('%l %M %p'), '11 00 PM', - 'formatting of hours as 1-12' - ); - - $dt->set( hour => 0 ); - is( - $dt->strftime('%I %M %p'), '12 00 AM', - 'formatting of hours as 1-12' - ); - is( - $dt->strftime('%l %M %p'), '12 00 AM', - 'formatting of hours as 1-12' - ); - } -); - -subtest( - '%V', - sub { - is( - DateTime->new( year => 2003, month => 1, day => 1 ) - ->strftime('%V'), - '01', '%V is 01' - ); - } -); - -subtest( - '%% and %{method}', - sub { - my $dt = DateTime->new( - year => 2004, month => 8, day => 16, - hour => 15, minute => 30, nanosecond => 123456789, - locale => 'en', - ); - - # Should print '%{day_name}', prints '30onday'! - is( - $dt->strftime('%%{day_name}%n'), "%{day_name}\n", - '%%{day_name}%n bug' - ); - - # Should print '%6N', prints '123456' - is( $dt->strftime('%%6N%n'), "%6N\n", '%%6N%n bug' ); - } -); - -subtest( - 'nanosecond formatting', - sub { - subtest( - 'nanosecond floating point rounding', - sub { - # Internally this becomes 119999885 nanoseconds (floating point math is awesome) - my $epoch = 1297777805.12; - my $dt = DateTime->from_epoch( epoch => $epoch ); - - my @vals = ( - 1, - 12, - 120, - 1200, - 12000, - 120000, - 1200000, - 12000000, - 120000000, - 1200000000, - ); - - my $x = 1; - for my $val (@vals) { - my $spec = '%' . $x++ . 'N'; - is( - $dt->strftime($spec), $val, - "strftime($spec) for $epoch == $val" - ); - } - } - ); - subtest( - 'nanosecond rounding in strftime', - sub { - my $dt = DateTime->new( - 'year' => 1999, - month => 9, - day => 7, - hour => 13, - minute => 2, - second => 42, - nanosecond => 12345678, - ); - - my %tests = ( - '%N' => '012345678', - '%3N' => '012', - '%6N' => '012345', - '%10N' => '0123456780', - ); - for my $fmt ( sort keys %tests ) { - is( - $dt->strftime($fmt), $tests{$fmt}, - "$fmt is $tests{$fmt}" - ); - } - } - ); - } -); - -subtest( - '0 nanoseconds', - sub { - my $dt = DateTime->new( year => 2011 ); - - for my $i ( 1 .. 9 ) { - my $spec = '%' . $i . 'N'; - my $expect = '0' x $i; - - is( - $dt->strftime($spec), $expect, - "strftime $spec with 0 nanoseconds" - ); - } - } -); - -subtest( - 'week-year formatting', - sub { - my $dt = DateTime->new( 'year' => 2012, month => 1, day => 1 ); - subtest( - $dt->ymd, - sub { - my %tests = ( - '%U' => '01', - '%W' => '00', - '%j' => '001', - ); - for my $fmt ( sort keys %tests ) { - is( - $dt->strftime($fmt), $tests{$fmt}, - "$fmt is $tests{$fmt}" - ); - } - } - ); - - $dt = DateTime->new( 'year' => 2012, month => 1, day => 10 ); - subtest( - $dt->ymd, - sub { - my %tests = ( - '%U' => '02', - '%W' => '02', - '%j' => '010', - ); - for my $fmt ( sort keys %tests ) { - is( - $dt->strftime($fmt), $tests{$fmt}, - "$fmt is $tests{$fmt}" - ); - } - } - ); - } -); - -done_testing(); - -sub test_strftime_for_locale { - my $locale = shift; - my $tests = shift; - - my $dt = DateTime->new( - year => 1999, - month => 9, - day => 7, - hour => 13, - minute => 2, - second => 42, - nanosecond => 123456789, - time_zone => 'UTC', - locale => $locale, - ); - - subtest( - $locale, - sub { - for my $fmt ( sort keys %{$tests} ) { - is( - $dt->strftime($fmt), - $tests->{$fmt}, - "$fmt is $tests->{$fmt}" - ); - } - } - ); -} - -sub en_tests { - my $en_locale = DateTime::Locale->load('en-US'); - - my $c_format = $en_locale->datetime_format; - $c_format - =~ s/\{1\}/$en_locale->month_format_abbreviated->[8] . ' 7, 1999'/e; - $c_format =~ s/\{0\}/'1:02:42 ' . $en_locale->am_pm_abbreviated->[1]/e; - - return { - '%y' => '99', - '%Y' => '1999', - '%%' => '%', - '%a' => $en_locale->day_format_abbreviated->[1], - '%A' => $en_locale->day_format_wide->[1], - '%b' => $en_locale->month_format_abbreviated->[8], - '%B' => $en_locale->month_format_wide->[8], - '%C' => '19', - '%d' => '07', - '%e' => ' 7', - '%D' => '09/07/99', - '%h' => $en_locale->month_format_abbreviated->[8], - '%H' => '13', - '%I' => '01', - '%j' => '250', - '%k' => '13', - '%l' => ' 1', - '%m' => '09', - '%M' => '02', - '%N' => '123456789', - '%3N' => '123', - '%6N' => '123456', - '%10N' => '1234567890', - '%p' => $en_locale->am_pm_abbreviated->[1], - '%r' => '01:02:42 ' . $en_locale->am_pm_abbreviated->[1], - '%R' => '13:02', - '%s' => '936709362', - '%S' => '42', - '%T' => '13:02:42', - '%U' => '36', - '%V' => '36', - '%w' => '2', - '%W' => '36', - '%y' => '99', - '%Y' => '1999', - '%Z' => 'UTC', - '%z' => '+0000', - '%E' => '%E', - '%{foobar}' => '%{foobar}', - '%{month}' => '9', - '%{year}' => '1999', - '%x' => $en_locale->month_format_abbreviated->[8] . ' 7, 1999', - '%X' => '1:02:42 ' . $en_locale->am_pm_abbreviated->[1], - '%c' => $c_format, - }; -} - -sub de_tests { - my $de_locale = DateTime::Locale->load('de'); - return { - '%y' => '99', - '%Y' => '1999', - '%%' => '%', - '%a' => $de_locale->day_format_abbreviated->[1], - '%A' => $de_locale->day_format_wide->[1], - '%b' => $de_locale->month_format_abbreviated->[8], - '%B' => $de_locale->month_format_wide->[8], - '%C' => '19', - '%d' => '07', - '%e' => ' 7', - '%D' => '09/07/99', - '%b' => $de_locale->month_format_abbreviated->[8], - '%H' => '13', - '%I' => '01', - '%j' => '250', - '%k' => '13', - '%l' => ' 1', - '%m' => '09', - '%M' => '02', - '%p' => $de_locale->am_pm_abbreviated->[1], - '%r' => '01:02:42 ' . $de_locale->am_pm_abbreviated->[1], - '%R' => '13:02', - '%s' => '936709362', - '%S' => '42', - '%T' => '13:02:42', - '%U' => '36', - '%V' => '36', - '%w' => '2', - '%W' => '36', - '%y' => '99', - '%Y' => '1999', - '%Z' => 'UTC', - '%z' => '+0000', - '%{month}' => '9', - '%{year}' => '1999', - }; -} - -sub it_tests { - my $it_locale = DateTime::Locale->load('it'); - return { - '%y' => '99', - '%Y' => '1999', - '%%' => '%', - '%a' => $it_locale->day_format_abbreviated->[1], - '%A' => $it_locale->day_format_wide->[1], - '%b' => $it_locale->month_format_abbreviated->[8], - '%B' => $it_locale->month_format_wide->[8], - '%C' => '19', - '%d' => '07', - '%e' => ' 7', - '%D' => '09/07/99', - '%b' => $it_locale->month_format_abbreviated->[8], - '%H' => '13', - '%I' => '01', - '%j' => '250', - '%k' => '13', - '%l' => ' 1', - '%m' => '09', - '%M' => '02', - '%p' => $it_locale->am_pm_abbreviated->[1], - '%r' => '01:02:42 ' . $it_locale->am_pm_abbreviated->[1], - '%R' => '13:02', - '%s' => '936709362', - '%S' => '42', - '%T' => '13:02:42', - '%U' => '36', - '%V' => '36', - '%w' => '2', - '%W' => '36', - '%y' => '99', - '%Y' => '1999', - '%Z' => 'UTC', - '%z' => '+0000', - '%{month}' => '9', - '%{year}' => '1999', - }; -} - diff -Nru libdatetime-perl-1.21/t/release-pp-14locale.t libdatetime-perl-1.46/t/release-pp-14locale.t --- libdatetime-perl-1.21/t/release-pp-14locale.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-14locale.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,85 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -use strict; -use warnings; - -use Test::More; - -use DateTime; -use DateTime::Locale; - -eval { DateTime->new( year => 100, locale => 'en_US' ) }; -is( $@, '', 'make sure constructor accepts locale parameter' ); - -eval { DateTime->now( locale => 'en_US' ) }; -is( $@, '', 'make sure constructor accepts locale parameter' ); - -eval { DateTime->today( locale => 'en_US' ) }; -is( $@, '', 'make sure constructor accepts locale parameter' ); - -eval { DateTime->from_epoch( epoch => 1, locale => 'en_US' ) }; -is( $@, '', 'make sure constructor accepts locale parameter' ); - -eval { - DateTime->last_day_of_month( year => 100, month => 2, locale => 'en_US' ); -}; -is( $@, '', 'make sure constructor accepts locale parameter' ); - -{ - - package DT::Object; - sub utc_rd_values { ( 0, 0 ) } -} - -eval { - DateTime->from_object( - object => ( bless {}, 'DT::Object' ), - locale => 'en_US' - ); -}; -is( $@, '', 'make sure constructor accepts locale parameter' ); - -eval { - DateTime->new( year => 100, locale => DateTime::Locale->load('en_US') ); -}; -is( $@, '', 'make sure constructor accepts locale parameter as object' ); - -DateTime->DefaultLocale('it'); -is( DateTime->now->locale->id, 'it', 'default locale should now be "it"' ); - -{ - my $dt = DateTime->new( - year => 2013, month => 10, day => 27, hour => 0, - time_zone => 'UTC' - ); - - my $after_zone = $dt->clone()->set_time_zone('Europe/Rome'); - - is( - $after_zone->offset(), - '7200', - 'offset is 7200 after set_time_zone()' - ); - - my $after_locale - = $dt->clone()->set_time_zone('Europe/Rome')->set_locale('en_GB'); - - is( - $after_locale->offset(), - '7200', - 'offset is 7200 after set_time_zone() and set_locale()' - ); -} - -done_testing(); - diff -Nru libdatetime-perl-1.21/t/release-pp-15jd.t libdatetime-perl-1.46/t/release-pp-15jd.t --- libdatetime-perl-1.21/t/release-pp-15jd.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-15jd.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,112 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -use strict; -use warnings; - -use Test::More; - -use DateTime; - -# Borrowed from Matt Sergeant's Time::Piece - -# A table of MJD and components -my @mjd = ( - '51603.524' => { - year => 2000, - month => 2, - day => 29, - hour => 12, - minute => 34, - second => 56, - }, - - '40598.574' => { - year => 1970, - month => 1, - day => 12, - hour => 13, - minute => 46, - second => 51, - }, - - '52411.140' => { - year => 2002, - month => 5, - day => 17, - hour => 3, - minute => 21, - second => 43, - }, - - '53568.547' => { - year => 2005, - month => 7, - day => 17, - hour => 13, - minute => 8, - second => 23, - }, - - '52295.218' => { - year => 2002, - month => 1, - day => 21, - hour => 5, - minute => 13, - second => 20, - }, - - '52295.399' => { - year => 2002, - month => 1, - day => 21, - hour => 9, - minute => 35, - second => 3, - }, - - # beginning of MJD - '0.000' => { - year => 1858, - month => 11, - day => 17, - hour => 0, - minute => 0, - second => 0, - }, - - # beginning of JD - '-2400000.500' => { - year => -4713, - month => 11, - day => 24, - hour => 12, - minute => 0, - second => 0, - }, -); - -while ( my ( $mjd, $comps ) = splice @mjd, 0, 2 ) { - my $dt = DateTime->new( - %$comps, - time_zone => 'UTC', - ); - - is( sprintf( '%.3f', $dt->mjd ), $mjd, "MJD should be $mjd" ); - - my $jd = sprintf( '%.3f', $mjd + 2_400_000.5 ); - is( sprintf( '%.3f', $dt->jd ), $jd, "JD should be $jd" ); -} - -done_testing(); - diff -Nru libdatetime-perl-1.21/t/release-pp-16truncate.t libdatetime-perl-1.46/t/release-pp-16truncate.t --- libdatetime-perl-1.21/t/release-pp-16truncate.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-16truncate.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,287 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -use strict; -use warnings; - -use Test::Fatal; -use Test::More 0.88; - -use DateTime; -use Try::Tiny; - -my %vals = ( - year => 50, - month => 3, - day => 15, - hour => 10, - minute => 55, - second => 17, - nanosecond => 1234, -); - -{ - my $dt = DateTime->new(%vals); - $dt->truncate( to => 'second' ); - foreach my $f (qw( year month day hour minute second )) { - is( $dt->$f(), $vals{$f}, "$f should be $vals{$f}" ); - } - - foreach my $f (qw( nanosecond )) { - is( $dt->$f(), 0, "$f should be 0" ); - } -} - -{ - my $dt = DateTime->new(%vals); - $dt->truncate( to => 'minute' ); - foreach my $f (qw( year month day hour minute )) { - is( $dt->$f(), $vals{$f}, "$f should be $vals{$f}" ); - } - - foreach my $f (qw( second nanosecond )) { - is( $dt->$f(), 0, "$f should be 0" ); - } -} - -{ - my $dt = DateTime->new(%vals); - $dt->truncate( to => 'hour' ); - foreach my $f (qw( year month day hour )) { - is( $dt->$f(), $vals{$f}, "$f should be $vals{$f}" ); - } - - foreach my $f (qw( minute second nanosecond )) { - is( $dt->$f(), 0, "$f should be 0" ); - } -} - -{ - my $dt = DateTime->new(%vals); - $dt->truncate( to => 'day' ); - foreach my $f (qw( year month day )) { - is( $dt->$f(), $vals{$f}, "$f should be $vals{$f}" ); - } - - foreach my $f (qw( hour minute second nanosecond )) { - is( $dt->$f(), 0, "$f should be 0" ); - } -} - -{ - my $dt = DateTime->new(%vals); - $dt->truncate( to => 'month' ); - foreach my $f (qw( year month )) { - is( $dt->$f(), $vals{$f}, "$f should be $vals{$f}" ); - } - - foreach my $f (qw( day )) { - is( $dt->$f(), 1, "$f should be 1" ); - } - - foreach my $f (qw( hour minute second nanosecond )) { - is( $dt->$f(), 0, "$f should be 0" ); - } -} - -{ - my $dt = DateTime->new(%vals); - $dt->truncate( to => 'year' ); - foreach my $f (qw( year )) { - is( $dt->$f(), $vals{$f}, "$f should be $vals{$f}" ); - } - - foreach my $f (qw( month day )) { - is( $dt->$f(), 1, "$f should be 1" ); - } - - foreach my $f (qw( hour minute second nanosecond )) { - is( $dt->$f(), 0, "$f should be 0" ); - } -} - -{ - my $dt = DateTime->new( year => 2003, month => 11, day => 17 ); - - for ( 1 .. 6 ) { - my $trunc = $dt->clone->add( days => $_ )->truncate( to => 'week' ); - - is( - $trunc->day, 17, - 'truncate to week should always truncate to monday of week' - ); - } - - { - my $trunc = $dt->clone->add( days => 7 )->truncate( to => 'week' ); - - is( - $trunc->day, 24, - 'truncate to week should always truncate to monday of week' - ); - } - - { - my $dt = DateTime->new( year => 2003, month => 10, day => 2 ) - ->truncate( to => 'week' ); - - is( $dt->year, 2003, 'truncation to week across month boundary' ); - is( $dt->month, 9, 'truncation to week across month boundary' ); - is( $dt->day, 29, 'truncation to week across month boundary' ); - } -} - -{ - my $dt = DateTime->new( - year => 2013, month => 12, day => 16, - locale => 'fr_FR' - ); - - for ( 1 .. 6 ) { - my $trunc - = $dt->clone->add( days => $_ )->truncate( to => 'local_week' ); - - is( - $trunc->day, 16, - 'truncate to local_week returns correct date - locale start is Monday' - ); - } - - { - my $trunc - = $dt->clone->add( days => 7 )->truncate( to => 'local_week' ); - - is( - $trunc->day, 23, - 'truncate to local_week returns correct date - locale start is Monday' - ); - } - - { - my $dt = DateTime->new( - year => 2013, month => 11, day => 2, - locale => 'fr_FR' - )->truncate( to => 'local_week' ); - - is( - $dt->year, 2013, - 'truncation to local_week across month boundary - locale start is Monday' - ); - is( - $dt->month, 10, - 'truncation to local_week across month boundary - locale start is Monday' - ); - is( - $dt->day, 28, - 'truncation to local_week across month boundary - locale start is Monday' - ); - } -} - -{ - my $dt = DateTime->new( - year => 2013, month => 12, day => 15, - locale => 'en_US' - ); - - for ( 1 .. 6 ) { - my $trunc - = $dt->clone->add( days => $_ )->truncate( to => 'local_week' ); - - is( - $trunc->day, 15, - 'truncate to local_week returns correct date - locale start is Sunday' - ); - } - - { - my $trunc - = $dt->clone->add( days => 7 )->truncate( to => 'local_week' ); - - is( - $trunc->day, 22, - 'truncate to local_week returns correct date - locale start is Sunday' - ); - } - - { - my $dt = DateTime->new( - year => 2013, month => 11, day => 2, - locale => 'en_US' - )->truncate( to => 'local_week' ); - - is( - $dt->year, 2013, - 'truncation to local_week across month boundary - locale start is Sunday' - ); - is( - $dt->month, 10, - 'truncation to local_week across month boundary - locale start is Sunday' - ); - is( - $dt->day, 27, - 'truncation to local_week across month boundary - locale start is Sunday' - ); - } -} - -{ - my $dt = DateTime->new(%vals); - - for my $bad (qw( seconds minutes year_foo month_bar )) { - like( - exception { $dt->truncate( to => $bad ) }, - qr/\QThe 'to' parameter/, - "bad truncate parameter ($bad) throws an error" - ); - } -} - -{ - my $dt = DateTime->new( - year => 2010, - month => 3, - day => 25, - hour => 1, - minute => 5, - time_zone => 'Asia/Tehran', - ); - - is( - $dt->day_of_week(), - 4, - 'day of week is Thursday' - ); - - my $error; - try { - $dt->truncate( to => 'week' ); - } - catch { - $error = $_; - }; - - like( - $error, - qr/Invalid local time for date/, - 'truncate operation threw an error because of an invalid local datetime' - ); - - is( - $dt->day_of_week(), - 4, - 'day of week does not change after failed truncate() call' - ); -} - -done_testing(); - diff -Nru libdatetime-perl-1.21/t/release-pp-17set-return.t libdatetime-perl-1.46/t/release-pp-17set-return.t --- libdatetime-perl-1.21/t/release-pp-17set-return.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-17set-return.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,51 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -use strict; -use warnings; - -use Test::More; - -use DateTime; -use DateTime::Duration; - -{ - my $dt = DateTime->new( year => 2008, month => 2, day => 28 ); - my $du = DateTime::Duration->new( years => 1 ); - - my $p; - - $p = $dt->set( year => 1882 ); - is( DateTime->compare( $p, $dt ), 0, "set() returns self" ); - - $p = $dt->set_time_zone('Australia/Sydney'); - is( DateTime->compare( $p, $dt ), 0, "set_time_zone() returns self" ); - - $p = $dt->add_duration($du); - is( DateTime->compare( $p, $dt ), 0, "add_duration() returns self" ); - - $p = $dt->add( years => 2 ); - is( DateTime->compare( $p, $dt ), 0, "add() returns self" ); - - $p = $dt->subtract_duration($du); - is( DateTime->compare( $p, $dt ), 0, "subtract_duration() returns self" ); - - $p = $dt->subtract( years => 3 ); - is( DateTime->compare( $p, $dt ), 0, "subtract() returns self" ); - - $p = $dt->truncate( to => 'day' ); - is( DateTime->compare( $p, $dt ), 0, "truncate() returns self" ); - -} - -done_testing(); - diff -Nru libdatetime-perl-1.21/t/release-pp-18today.t libdatetime-perl-1.46/t/release-pp-18today.t --- libdatetime-perl-1.21/t/release-pp-18today.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-18today.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,34 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -use strict; -use warnings; - -use Test::More; - -use DateTime; - -{ - my $now = DateTime->now; - my $today = DateTime->today; - - is( $today->year, $now->year, 'today->year' ); - is( $today->month, $now->month, 'today->month' ); - is( $today->day, $now->day, 'today->day' ); - - is( $today->hour, 0, 'today->hour' ); - is( $today->minute, 0, 'today->hour' ); - is( $today->second, 0, 'today->hour' ); -} - -done_testing(); - diff -Nru libdatetime-perl-1.21/t/release-pp-19leap-second.t libdatetime-perl-1.46/t/release-pp-19leap-second.t --- libdatetime-perl-1.21/t/release-pp-19leap-second.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-19leap-second.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,1194 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -use strict; -use warnings; - -use Test::Fatal; -use Test::More; -use DateTime; - -# tests using UTC times -{ - - # 1972-06-30T23:58:20 UTC - my $t = DateTime->new( - year => 1972, month => 6, day => 30, - hour => 23, minute => 58, second => 20, - time_zone => 'UTC', - ); - my $t1 = $t->clone; - - is( $t->year, 1972, "year is 1972" ); - is( $t->minute, 58, "minute is 58" ); - is( $t->second, 20, "second is 20" ); - - # 1972-06-30T23:59:20 UTC - $t->add( seconds => 60 ); - is( $t->year, 1972, "year is 1972" ); - is( $t->minute, 59, "minute is 59" ); - is( $t->second, 20, "second is 20" ); - - # 1972-07-01T00:00:19 UTC - $t->add( seconds => 60 ); - is( $t->year, 1972, "year is 1972" ); - is( $t->minute, 0, "minute is 0" ); - is( $t->second, 19, "second is 19" ); - - # 1972-06-30T23:59:60 UTC - $t->subtract( seconds => 20 ); - is( $t->year, 1972, "year is 1972" ); - is( $t->minute, 59, "minute is 59" ); - is( $t->second, 60, "second is 60" ); - is( $t->{utc_rd_secs}, 86400, "utc_rd_secs is 86400" ); - - # subtract_datetime - my $t2 = DateTime->new( - year => 1972, month => 07, day => 1, - hour => 0, minute => 0, second => 20, - time_zone => 'UTC', - ); - my $dur = $t2->subtract_datetime_absolute($t1); - is( $dur->delta_seconds, 121, "delta_seconds is 121" ); - - $dur = $t1->subtract_datetime_absolute($t2); - is( $dur->delta_seconds, -121, "delta_seconds is -121" ); -} - -{ - - # tests using floating times - # a floating time has no leap seconds - - my $t = DateTime->new( - year => 1971, month => 12, day => 31, - hour => 23, minute => 58, second => 20, - time_zone => 'floating', - ); - my $t1 = $t->clone; - - $t->add( seconds => 60 ); - is( $t->minute, 59, "min" ); - is( $t->second, 20, "sec" ); - - $t->add( seconds => 60 ); - is( $t->minute, 0, "min" ); - is( $t->second, 20, "sec" ); - - # subtract_datetime, using floating times - - my $t2 = DateTime->new( - year => 1972, month => 1, day => 1, - hour => 0, minute => 0, second => 20, - time_zone => 'floating', - ); - my $dur = $t2->subtract_datetime_absolute($t1); - is( $dur->delta_seconds, 120, "delta_seconds is 120" ); - - $dur = $t1->subtract_datetime_absolute($t2); - is( $dur->delta_seconds, -120, "delta_seconds is -120" ); -} - -{ - - # tests using time zones - # leap seconds occur during _UTC_ midnight - - # 1972-06-30 20:58:20 -03:00 = 1972-06-30 23:58:20 UTC - my $t = DateTime->new( - year => 1972, month => 6, day => 30, - hour => 20, minute => 58, second => 20, - time_zone => 'America/Sao_Paulo', - ); - - $t->add( seconds => 60 ); - is( $t->datetime, '1972-06-30T20:59:20', "normal add" ); - is( $t->minute, 59, "min" ); - is( $t->second, 20, "sec" ); - - $t->add( seconds => 60 ); - is( $t->datetime, '1972-06-30T21:00:19', "add over a leap second" ); - is( $t->minute, 0, "min" ); - is( $t->second, 19, "sec" ); - - $t->subtract( seconds => 20 ); - is( $t->datetime, '1972-06-30T20:59:60', "subtract over a leap second" ); - is( $t->minute, 59, "min" ); - is( $t->second, 60, "sec" ); - is( $t->{utc_rd_secs}, 86400, "rd_sec" ); -} - -# test that we can set second to 60 (negative offset) -{ - my $t = DateTime->new( - year => 1972, month => 6, day => 30, - hour => 20, minute => 59, second => 60, - time_zone => 'America/Sao_Paulo', - ); - - is( $t->second, 60, 'second set to 60 in constructor' ); -} - -{ - my $t = DateTime->new( - year => 1972, month => 6, day => 30, - hour => 21, minute => 0, second => 0, - time_zone => 'America/Sao_Paulo', - ); - - is( $t->second, 0, 'datetime just after leap second' ); -} - -{ - my $t = DateTime->new( - year => 1972, month => 6, day => 30, - hour => 21, minute => 0, second => 1, - time_zone => 'America/Sao_Paulo', - ); - - is( $t->second, 1, 'datetime two seconds after leap second' ); -} - -# test that we can set second to 60 (negative offset) -{ - eval { - my $t = DateTime->new( - year => 1972, month => 6, day => 30, - hour => 22, minute => 59, second => 60, - time_zone => '-0100', - ); - - is( - $t->second, 60, - 'second set to 60 in constructor, negative TZ offset' - ); - }; - - if ($@) { - ok( 0, "Error setting second to 60 in constructor: $@" ); - } -} - -# test that we can set second to 60 (positive offset) -{ - eval { - my $t = DateTime->new( - year => 1972, month => 7, day => 1, - hour => 0, minute => 59, second => 60, - time_zone => '+0100', - ); - - is( - $t->second, 60, - 'second set to 60 in constructor, positive TZ offset' - ); - }; - - if ($@) { - ok( - 0, - "Error setting second to 60 in constructor, positive TZ offset: $@" - ); - } -} - -{ - my $t = DateTime->new( - year => 1972, month => 7, day => 1, - hour => 0, minute => 59, second => 59, - time_zone => '+0100', - ); - - is( $t->second, 59, 'datetime just before leap second' ); -} - -{ - my $t = DateTime->new( - year => 1972, month => 7, day => 1, - hour => 1, minute => 0, second => 0, - time_zone => '+0100', - ); - - is( $t->second, 0, 'datetime just after leap second' ); -} - -{ - my $t = DateTime->new( - year => 1972, month => 7, day => 1, - hour => 1, minute => 0, second => 1, - time_zone => '+0100', - ); - - is( $t->second, 1, 'datetime two seconds after leap second' ); -} - -{ - my $t = DateTime->new( - year => 1972, month => 7, day => 1, - hour => 0, minute => 0, second => 29, - time_zone => '+00:00:30', - ); - - is( - $t->second, 29, - 'time zone +00:00:30 and leap seconds, second value' - ); - is( $t->minute, 0, 'time zone +00:00:30 and leap seconds, minute value' ); -} - -{ - my $t = DateTime->new( - year => 1972, month => 6, day => 30, - hour => 20, minute => 59, second => 60, - time_zone => 'America/Sao_Paulo', - ); - - $t->set_time_zone('UTC'); - is( $t->second, 60, 'second after setting time zone' ); - is( $t->hour, 23, 'hour after setting time zone' ); - - $t->add( days => 1 ); - is( - $t->datetime, '1972-07-02T00:00:00', - 'add 1 day starting on leap second' - ); - - $t->subtract( days => 1 ); - - is( - $t->datetime, '1972-07-01T00:00:00', - 'add and subtract 1 day starting on leap second' - ); - - is( $t->leap_seconds, 1, 'datetime has 1 leap second' ); -} - -{ - my $t = DateTime->new( - year => 1972, month => 6, day => 30, - hour => 23, minute => 59, second => 59, - time_zone => 'UTC', - ); - - is( - $t->epoch, 78796799, - 'epoch just before first leap second is 78796799' - ); - - $t->add( seconds => 1 ); - - is( $t->epoch, 78796800, 'epoch of first leap second is 78796800' ); - - $t->add( seconds => 1 ); - - is( - $t->epoch, 78796800, - 'epoch of first second after first leap second is 78796700' - ); -} - -{ - my $dt = DateTime->new( year => 2003, time_zone => 'UTC' ); - - is( $dt->leap_seconds, 22, 'datetime has 22 leap seconds' ); -} - -{ - my $dt = DateTime->new( year => 2003, time_zone => 'floating' ); - - is( $dt->leap_seconds, 0, 'floating datetime has 0 leap seconds' ); -} - -# date math across leap seconds distinguishes between minutes and second -{ - my $t = DateTime->new( - year => 1972, month => 12, day => 31, - hour => 23, minute => 59, second => 30, - time_zone => 'UTC' - ); - - $t->add( minutes => 1 ); - - is( $t->year, 1973, '+1 minute, year == 1973' ); - is( $t->month, 1, '+1 minute, month == 1' ); - is( $t->day, 1, '+1 minute, day == 1' ); - is( $t->hour, 0, '+1 minute, hour == 0' ); - is( $t->minute, 0, '+1 minute, minute == 0' ); - is( $t->second, 30, '+1 minute, second == 30' ); -} - -{ - my $t = DateTime->new( - year => 1972, month => 12, day => 31, - hour => 23, minute => 59, second => 30, - time_zone => 'UTC' - ); - - $t->add( seconds => 60 ); - - is( $t->year, 1973, '+60 seconds, year == 1973' ); - is( $t->month, 1, '+60 seconds, month == 1' ); - is( $t->day, 1, '+60 seconds, day == 1' ); - is( $t->hour, 0, '+60 seconds, hour == 0' ); - is( $t->minute, 0, '+60 seconds, minute == 0' ); - is( $t->second, 29, '+60 seconds, second == 29' ); -} - -{ - my $t = DateTime->new( - year => 1972, month => 12, day => 31, - hour => 23, minute => 59, second => 30, - time_zone => 'UTC' - ); - - $t->add( minutes => 1, seconds => 1 ); - - is( $t->year, 1973, '+1 minute & 1 second, year == 1973' ); - is( $t->month, 1, '+1 minute & 1 second, month == 1' ); - is( $t->day, 1, '+1 minute & 1 second, day == 1' ); - is( $t->hour, 0, '+1 minute & 1 second, hour == 0' ); - is( $t->minute, 0, '+1 minute & 1 second, minute == 0' ); - is( $t->second, 31, '+1 minute & 1 second, second == 31' ); -} - -{ - eval { - DateTime->new( - year => 1972, month => 12, day => 31, - hour => 23, minute => 59, second => 61, - time_zone => 'UTC', - ); - }; - ok( $@, "Cannot give second of 61 except when it matches a leap second" ); - - eval { - DateTime->new( - year => 1972, month => 12, day => 31, - hour => 23, minute => 58, second => 60, - time_zone => 'UTC', - ); - }; - ok( $@, "Cannot give second of 60 except when it matches a leap second" ); - - eval { - DateTime->new( - year => 1972, month => 12, day => 31, - hour => 23, minute => 59, second => 60, - time_zone => 'floating', - ); - }; - ok( $@, "Cannot give second of 60 with floating time zone" ); -} - -{ - my $dt1 = DateTime->new( - year => 1998, month => 12, day => 31, - hour => 23, minute => 59, second => 60, - time_zone => 'UTC', - ); - - my $dt2 = DateTime->new( - year => 1998, month => 12, day => 31, - hour => 23, minute => 58, second => 50, - time_zone => 'UTC', - ); - - my $pos_dur = $dt1 - $dt2; - - is( $pos_dur->delta_minutes, 1, 'delta_minutes is 1' ); - is( $pos_dur->delta_seconds, 10, 'delta_seconds is 10' ); - - my $neg_dur = $dt2 - $dt1; - - is( $neg_dur->delta_minutes, -1, 'delta_minutes is -1' ); - is( $neg_dur->delta_seconds, -10, 'delta_seconds is -10' ); -} - -{ - my $dt1 = DateTime->new( - year => 1998, month => 12, day => 31, - hour => 23, minute => 59, second => 55, - time_zone => 'UTC', - ); - - my $dt2 = DateTime->new( - year => 1998, month => 12, day => 31, - hour => 23, minute => 58, second => 50, - time_zone => 'UTC', - ); - - my $pos_dur = $dt1 - $dt2; - - is( $pos_dur->delta_minutes, 1, 'delta_minutes is 1' ); - is( $pos_dur->delta_seconds, 5, 'delta_seconds is 5' ); - - my $neg_dur = $dt2 - $dt1; - - is( $neg_dur->delta_minutes, -1, 'delta_minutes is -1' ); - is( $neg_dur->delta_seconds, -5, 'delta_seconds is -5' ); -} - -{ - my $dt1 = DateTime->new( - year => 1998, month => 12, day => 31, - hour => 23, minute => 59, second => 55, - time_zone => 'UTC', - ); - - my $dt2 = DateTime->new( - year => 1999, month => 1, day => 1, - hour => 0, minute => 0, second => 30, - time_zone => 'UTC', - ); - - my $pos_dur = $dt2 - $dt1; - - is( $pos_dur->delta_minutes, 0, 'delta_minutes is 0' ); - is( $pos_dur->delta_seconds, 36, 'delta_seconds is 36' ); - - my $neg_dur = $dt1 - $dt2; - - is( $neg_dur->delta_minutes, 0, 'delta_minutes is 0' ); - is( $neg_dur->delta_seconds, -36, 'delta_seconds is -36' ); -} - -# catch off-by-one when carrying a leap second -{ - my $dt1 = DateTime->new( - year => 1998, month => 12, day => 31, - hour => 23, minute => 59, second => 0, - nanosecond => 1, - time_zone => 'UTC', - ); - - my $dt2 = DateTime->new( - year => 1999, month => 1, day => 1, - hour => 0, minute => 0, second => 0, - time_zone => 'UTC', - ); - - my $pos_dur = $dt2 - $dt1; - - is( $pos_dur->delta_minutes, 0, 'delta_minutes is 0' ); - is( $pos_dur->delta_seconds, 60, 'delta_seconds is 60' ); - is( - $pos_dur->delta_nanoseconds, 999999999, - 'delta_nanoseconds is 999...' - ); -} - -{ - my $dt = DateTime->new( - year => 1972, month => 6, day => 30, - hour => 23, minute => 58, second => 20, - time_zone => 'UTC', - ); - - $dt->add( days => 2 ); - - is( - $dt->datetime, '1972-07-02T23:58:20', - "add two days crossing a leap second (UTC)" - ); -} - -# a bunch of tests that math works across a leap second for various time zones -{ - my $dt = DateTime->new( - year => 1972, month => 6, day => 30, - hour => 20, minute => 58, second => 20, - time_zone => '-0300', - ); - - $dt->add( days => 2 ); - - is( - $dt->datetime, '1972-07-02T20:58:20', - "add two days crossing a leap second (-0300)" - ); -} - -{ - my $dt = DateTime->new( - year => 1972, month => 7, day => 1, - hour => 2, minute => 58, second => 20, - time_zone => '+0300', - ); - - $dt->add( days => 2 ); - - is( - $dt->datetime, '1972-07-03T02:58:20', - "add two days crossing a leap second (+0300)" - ); -} - -{ - my $dt = DateTime->new( - year => 1972, month => 6, day => 30, - hour => 23, minute => 58, second => 20, - time_zone => 'UTC', - ); - - $dt->add( hours => 48 ); - - is( - $dt->datetime, '1972-07-02T23:58:20', - "add 48 hours crossing a leap second (UTC)" - ); -} - -{ - my $dt = DateTime->new( - year => 1972, month => 6, day => 30, - hour => 20, minute => 58, second => 20, - time_zone => '-0300', - ); - - $dt->add( hours => 48 ); - - is( - $dt->datetime, '1972-07-02T20:58:20', - "add 48 hours crossing a leap second (-0300)" - ); -} - -{ - my $dt = DateTime->new( - year => 1972, month => 7, day => 1, - hour => 2, minute => 58, second => 20, - time_zone => '+0300', - ); - - $dt->add( hours => 48 ); - - is( - $dt->datetime, '1972-07-03T02:58:20', - "add 48 hours crossing a leap second (+0300)" - ); -} - -{ - my $dt = DateTime->new( - year => 1972, month => 6, day => 30, - hour => 23, minute => 58, second => 20, - time_zone => 'UTC', - ); - - $dt->add( minutes => 2880 ); - - is( - $dt->datetime, '1972-07-02T23:58:20', - "add 2880 minutes crossing a leap second (UTC)" - ); -} - -{ - my $dt = DateTime->new( - year => 1972, month => 6, day => 30, - hour => 20, minute => 58, second => 20, - time_zone => '-0300', - ); - - $dt->add( minutes => 2880 ); - - is( - $dt->datetime, '1972-07-02T20:58:20', - "add 2880 minutes crossing a leap second (-0300)" - ); -} - -{ - my $dt = DateTime->new( - year => 1972, month => 7, day => 1, - hour => 2, minute => 58, second => 20, - time_zone => '+0300', - ); - - $dt->add( minutes => 2880 ); - - is( - $dt->datetime, '1972-07-03T02:58:20', - "add 2880 minutes crossing a leap second (+0300)" - ); -} - -{ - my $dt = DateTime->new( - year => 1972, month => 6, day => 30, - hour => 23, minute => 58, second => 20, - time_zone => 'UTC', - ); - - $dt->add( seconds => 172801 ); - - is( - $dt->datetime, '1972-07-02T23:58:20', - "add 172801 seconds crossing a leap second (UTC)" - ); -} - -{ - my $dt = DateTime->new( - year => 1972, month => 6, day => 30, - hour => 20, minute => 58, second => 20, - time_zone => '-0300', - ); - - $dt->add( seconds => 172801 ); - - is( - $dt->datetime, '1972-07-02T20:58:20', - "add 172801 seconds crossing a leap second (-0300)" - ); -} - -{ - my $dt = DateTime->new( - year => 1972, month => 7, day => 1, - hour => 2, minute => 58, second => 20, - time_zone => '+0300', - ); - - $dt->add( seconds => 172801 ); - - is( - $dt->datetime, '1972-07-03T02:58:20', - "add 172801 seconds crossing a leap second (+0300)" - ); -} - -{ - my $dt = DateTime->new( - year => 1972, month => 7, day => 2, - hour => 23, minute => 58, second => 20, - time_zone => 'UTC', - ); - - $dt->subtract( days => 2 ); - - is( - $dt->datetime, '1972-06-30T23:58:20', - "subtract two days crossing a leap second (UTC)" - ); -} - -{ - my $dt = DateTime->new( - year => 1972, month => 7, day => 2, - hour => 20, minute => 58, second => 20, - time_zone => '-0300', - ); - - $dt->subtract( days => 2 ); - - is( - $dt->datetime, '1972-06-30T20:58:20', - "subtract two days crossing a leap second (-0300)" - ); -} - -{ - my $dt = DateTime->new( - year => 1972, month => 7, day => 3, - hour => 2, minute => 58, second => 20, - time_zone => '+0300', - ); - - $dt->subtract( days => 2 ); - - is( - $dt->datetime, '1972-07-01T02:58:20', - "subtract two days crossing a leap second (+0300)" - ); -} - -{ - my $dt = DateTime->new( - year => 1972, month => 7, day => 2, - hour => 23, minute => 58, second => 20, - time_zone => 'UTC', - ); - - $dt->subtract( hours => 48 ); - - is( - $dt->datetime, '1972-06-30T23:58:20', - "subtract 48 hours crossing a leap second (UTC)" - ); -} - -{ - my $dt = DateTime->new( - year => 1972, month => 7, day => 2, - hour => 20, minute => 58, second => 20, - time_zone => '-0300', - ); - - $dt->subtract( hours => 48 ); - - is( - $dt->datetime, '1972-06-30T20:58:20', - "subtract 48 hours crossing a leap second (-0300)" - ); -} - -{ - my $dt = DateTime->new( - year => 1972, month => 7, day => 3, - hour => 2, minute => 58, second => 20, - time_zone => '+0300', - ); - - $dt->subtract( hours => 48 ); - - is( - $dt->datetime, '1972-07-01T02:58:20', - "subtract 48 hours crossing a leap second (+0300)" - ); -} - -{ - my $dt = DateTime->new( - year => 1972, month => 7, day => 2, - hour => 23, minute => 58, second => 20, - time_zone => 'UTC', - ); - - $dt->subtract( minutes => 2880 ); - - is( - $dt->datetime, '1972-06-30T23:58:20', - "subtract 2880 minutes crossing a leap second (UTC)" - ); -} - -{ - my $dt = DateTime->new( - year => 1972, month => 7, day => 2, - hour => 20, minute => 58, second => 20, - time_zone => '-0300', - ); - - $dt->subtract( minutes => 2880 ); - - is( - $dt->datetime, '1972-06-30T20:58:20', - "subtract 2880 minutes crossing a leap second (-0300)" - ); -} - -{ - my $dt = DateTime->new( - year => 1972, month => 7, day => 3, - hour => 2, minute => 58, second => 20, - time_zone => '+0300', - ); - - $dt->subtract( minutes => 2880 ); - - is( - $dt->datetime, '1972-07-01T02:58:20', - "subtract 2880 minutes crossing a leap second (+0300)" - ); -} - -{ - my $dt = DateTime->new( - year => 1972, month => 7, day => 2, - hour => 23, minute => 58, second => 20, - time_zone => 'UTC', - ); - - $dt->subtract( seconds => 172801 ); - - is( - $dt->datetime, '1972-06-30T23:58:20', - "subtract 172801 seconds crossing a leap second (UTC)" - ); -} - -{ - my $dt = DateTime->new( - year => 1972, month => 7, day => 2, - hour => 20, minute => 58, second => 20, - time_zone => '-0300', - ); - - $dt->subtract( seconds => 172801 ); - - is( - $dt->datetime, '1972-06-30T20:58:20', - "subtract 172801 seconds crossing a leap second (-0300)" - ); -} - -{ - my $dt = DateTime->new( - year => 1972, month => 7, day => 3, - hour => 2, minute => 58, second => 20, - time_zone => '+0300', - ); - - $dt->subtract( seconds => 172801 ); - - is( - $dt->datetime, '1972-07-01T02:58:20', - "subtract 172801 seconds crossing a leap second (+0300)" - ); -} - -{ - my $dt = DateTime->new( - year => 1972, month => 7, day => 1, - hour => 12, minute => 58, second => 20, - time_zone => '+1200', - ); - - $dt->set_time_zone('-1200'); - - is( - $dt->datetime, '1972-06-30T12:58:20', - "24 hour time zone change near leap second" - ); -} - -{ - my $dt = DateTime->new( - year => 1972, month => 6, day => 30, - hour => 12, minute => 58, second => 20, - time_zone => '-1200', - ); - - $dt->set_time_zone('+1200'); - - is( - $dt->datetime, '1972-07-01T12:58:20', - "24 hour time zone change near leap second" - ); -} - -{ - my $dt = DateTime->new( - year => 1997, month => 7, day => 1, - hour => 0, minute => 59, second => 59, - time_zone => '+0100' - ); - - is( $dt->datetime, '1997-07-01T00:59:59', '+0100 time leap second T-1' ); - - $dt->set_time_zone('UTC'); - - is( $dt->datetime, '1997-06-30T23:59:59', 'UTC time leap second T-1' ); -} - -{ - my $dt = DateTime->new( - year => 1997, month => 7, day => 1, - hour => 0, minute => 59, second => 60, - time_zone => '+0100' - ); - - is( $dt->datetime, '1997-07-01T00:59:60', 'local time leap second T-0' ); - - $dt->set_time_zone('UTC'); - - is( $dt->datetime, '1997-06-30T23:59:60', 'UTC time leap second T-0' ); -} - -{ - my $dt = DateTime->new( - year => 1997, month => 7, day => 1, - hour => 1, minute => 0, second => 0, - time_zone => '+0100' - ); - - is( $dt->datetime, '1997-07-01T01:00:00', 'local time leap second T+1' ); - - $dt->set_time_zone('UTC'); - - is( $dt->datetime, '1997-07-01T00:00:00', 'UTC time leap second T+1' ); -} - -{ - my $dt = DateTime->new( - year => 1997, month => 7, day => 1, - hour => 23, minute => 59, second => 59, - time_zone => '+0100' - ); - - is( - $dt->datetime, '1997-07-01T23:59:59', - 'local time end of leap second day' - ); - - $dt->set_time_zone('UTC'); - - is( - $dt->datetime, '1997-07-01T22:59:59', - 'UTC time end of leap second day' - ); -} - -{ - my $dt = DateTime->new( - year => 1997, month => 6, day => 30, - hour => 22, minute => 59, second => 59, - time_zone => '-0100' - ); - - is( $dt->datetime, '1997-06-30T22:59:59', '-0100 time leap second T-1' ); - - $dt->set_time_zone('UTC'); - - is( $dt->datetime, '1997-06-30T23:59:59', 'UTC time leap second T-1' ); -} - -{ - my $dt = DateTime->new( - year => 1997, month => 6, day => 30, - hour => 22, minute => 59, second => 60, - time_zone => '-0100' - ); - - is( $dt->datetime, '1997-06-30T22:59:60', '-0100 time leap second T-0' ); - - $dt->set_time_zone('UTC'); - - is( $dt->datetime, '1997-06-30T23:59:60', 'UTC time leap second T-0' ); -} - -{ - my $dt = DateTime->new( - year => 1997, month => 6, day => 30, - hour => 23, minute => 0, second => 0, - time_zone => '-0100' - ); - - is( $dt->datetime, '1997-06-30T23:00:00', '-0100 time leap second T+1' ); - - $dt->set_time_zone('UTC'); - - is( $dt->datetime, '1997-07-01T00:00:00', 'UTC time leap second T+1' ); -} - -{ - my $dt = DateTime->new( - year => 1997, month => 6, day => 30, - hour => 23, minute => 59, second => 59, - time_zone => 'UTC' - ); - - is( $dt->datetime, '1997-06-30T23:59:59', 'UTC time leap second T-1' ); - - $dt->set_time_zone('+0100'); - - is( $dt->datetime, '1997-07-01T00:59:59', '+0100 time leap second T-1' ); -} - -{ - my $dt = DateTime->new( - year => 1997, month => 6, day => 30, - hour => 23, minute => 59, second => 60, - time_zone => 'UTC' - ); - - is( $dt->datetime, '1997-06-30T23:59:60', 'UTC time leap second T-0' ); - - $dt->set_time_zone('+0100'); - - is( $dt->datetime, '1997-07-01T00:59:60', '+0100 time leap second T-0' ); -} - -{ - my $dt = DateTime->new( - year => 1997, month => 7, day => 1, - hour => 0, minute => 0, second => 0, - time_zone => 'UTC' - ); - - is( $dt->datetime, '1997-07-01T00:00:00', 'UTC time leap second T+1' ); - - $dt->set_time_zone('+0100'); - - is( $dt->datetime, '1997-07-01T01:00:00', '+0100 time leap second T+1' ); -} - -{ - my $dt = DateTime->new( - year => 1997, month => 6, day => 30, - hour => 23, minute => 59, second => 59, - time_zone => 'UTC' - ); - - is( - $dt->datetime, '1997-06-30T23:59:59', - 'UTC time end of leap second day' - ); - - $dt->set_time_zone('+0100'); - - is( - $dt->datetime, '1997-07-01T00:59:59', - '+0100 time end of leap second day' - ); -} - -{ - my $dt = DateTime->new( - year => 1997, month => 6, day => 30, - hour => 23, minute => 59, second => 59, - time_zone => 'UTC' - ); - - is( $dt->datetime, '1997-06-30T23:59:59', 'UTC time leap second T-1' ); - - $dt->set_time_zone('-0100'); - - is( $dt->datetime, '1997-06-30T22:59:59', '-0100 time leap second T-1' ); -} - -{ - my $dt = DateTime->new( - year => 1997, month => 6, day => 30, - hour => 23, minute => 59, second => 60, - time_zone => 'UTC' - ); - - is( $dt->datetime, '1997-06-30T23:59:60', 'UTC time leap second T-0' ); - - $dt->set_time_zone('-0100'); - - is( $dt->datetime, '1997-06-30T22:59:60', '-0100 time leap second T-0' ); -} - -{ - my $dt = DateTime->new( - year => 1997, month => 7, day => 1, - hour => 0, minute => 0, second => 0, - time_zone => 'UTC' - ); - - is( $dt->datetime, '1997-07-01T00:00:00', 'UTC time leap second T+1' ); - - $dt->set_time_zone('-0100'); - - is( $dt->datetime, '1997-06-30T23:00:00', '-0100 time leap second T+1' ); -} - -{ - my $dt = DateTime->new( - year => 2005, month => 12, day => 31, - hour => 23, minute => 59, second => 60, - time_zone => 'UTC' - ); - - is( $dt->second, 60, 'leap second at end of 2005 is allowed' ); -} - -{ - my $dt = DateTime->new( - year => 2005, month => 12, day => 31, - hour => 23, minute => 59, second => 59, - time_zone => 'UTC', - ); - - $dt->add( seconds => 1 ); - is( $dt->datetime, '2005-12-31T23:59:60', 'dt is 2005-12-31T23:59:60' ); - - $dt->add( seconds => 1 ); - is( $dt->datetime, '2006-01-01T00:00:00', 'dt is 2006-01-01T00:00:00' ); -} - -# bug reported by Mike Schilli - addition got "stuck" at 60 seconds -# and never rolled over to the following day -{ - my $dt = DateTime->new( - year => 2005, month => 12, day => 31, - hour => 23, minute => 59, second => 59, - time_zone => 'UTC', - ); - - $dt->add( seconds => 1 ); - is( $dt->datetime, '2005-12-31T23:59:60', 'dt is 2005-12-31T23:59:60' ); - - $dt->add( seconds => 1 ); - is( $dt->datetime, '2006-01-01T00:00:00', 'dt is 2006-01-01T00:00:00' ); -} - -# and this makes sure that fix for the above bug didn't break -# _non-leapsecond_ second addition -{ - my $dt = DateTime->new( - year => 2005, month => 12, day => 30, - hour => 23, minute => 59, second => 58, - time_zone => 'UTC', - ); - - $dt->add( seconds => 1 ); - is( $dt->datetime, '2005-12-30T23:59:59', 'dt is 2005-12-30T23:59:59' ); - - $dt->add( seconds => 1 ); - is( $dt->datetime, '2005-12-31T00:00:00', 'dt is 2005-12-31T00:00:00' ); -} - -{ - for my $date ( - [ 1972, 6, 30 ], - [ 1972, 12, 31 ], - [ 1973, 12, 31 ], - [ 1974, 12, 31 ], - [ 1975, 12, 31 ], - [ 1976, 12, 31 ], - [ 1977, 12, 31 ], - [ 1978, 12, 31 ], - [ 1979, 12, 31 ], - [ 1981, 6, 30 ], - [ 1982, 6, 30 ], - [ 1983, 6, 30 ], - [ 1985, 6, 30 ], - [ 1987, 12, 31 ], - [ 1989, 12, 31 ], - [ 1990, 12, 31 ], - [ 1992, 6, 30 ], - [ 1993, 6, 30 ], - [ 1994, 6, 30 ], - [ 1995, 12, 31 ], - [ 1997, 6, 30 ], - [ 1998, 12, 31 ], - [ 2005, 12, 31 ], - [ 2008, 12, 31 ], - [ 2012, 6, 30 ], - [ 2015, 6, 30 ], - ) { - my $formatted = join '-', map { sprintf( '%02d', $_ ) } @{$date}; - - is( - exception { - DateTime->new( - year => $date->[0], - month => $date->[1], - day => $date->[2], - hour => 23, - minute => 59, - second => 60, - time_zone => 'UTC', - ); - }, - undef, - "We can make a DateTime object for the leap second on $formatted" - ); - } -} - -done_testing(); - diff -Nru libdatetime-perl-1.21/t/release-pp-20infinite.t libdatetime-perl-1.46/t/release-pp-20infinite.t --- libdatetime-perl-1.21/t/release-pp-20infinite.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-20infinite.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,205 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -use strict; -use warnings; - -use Test::More; - -use DateTime; -use DateTime::Locale; - -my $pos = DateTime::Infinite::Future->new; -my $neg = DateTime::Infinite::Past->new; -my $posinf = DateTime::INFINITY; -my $neginf = DateTime::NEG_INFINITY; -my $nan_string = DateTime::NAN; - -# infinite date math -{ - ok( $pos->is_infinite, 'positive infinity should be infinite' ); - ok( $neg->is_infinite, 'negative infinity should be infinite' ); - ok( !$pos->is_finite, 'positive infinity should not be finite' ); - ok( !$neg->is_finite, 'negative infinity should not be finite' ); - - # that's a long time ago! - my $long_ago = DateTime->new( year => -100_000 ); - - ok( - $neg < $long_ago, - 'negative infinity is really negative' - ); - - my $far_future = DateTime->new( year => 100_000 ); - ok( - $pos > $far_future, - 'positive infinity is really positive' - ); - - ok( - $pos > $neg, - 'positive infinity is bigger than negative infinity' - ); - - my $pos_dur = $pos - $far_future; - ok( - $pos_dur->is_positive, - 'infinity - normal = infinity' - ); - - my $pos2 = $long_ago + $pos_dur; - ok( - $pos2 == $pos, - 'normal + infinite duration = infinity' - ); - - my $neg_dur = $far_future - $pos; - ok( - $neg_dur->is_negative, - 'normal - infinity = neg infinity' - ); - - my $neg2 = $long_ago + $neg_dur; - ok( - $neg2 == $neg, - 'normal + neg infinite duration = neg infinity' - ); - - my $dur = $pos - $pos; - my %deltas = $dur->deltas; - my @compare = qw( days seconds nanoseconds ); - foreach (@compare) { - - # NaN != NaN (but should stringify the same) - is( - $deltas{$_} . '', $nan_string, - "infinity - infinity = nan ($_)" - ); - } - - my $new_pos = $pos->clone->add( days => 10 ); - ok( - $new_pos == $pos, - "infinity + normal duration = infinity" - ); - - my $new_pos2 = $pos->clone->subtract( days => 10 ); - ok( - $new_pos2 == $pos, - "infinity - normal duration = infinity" - ); - - ok( - $pos == $posinf, - "infinity (datetime) == infinity (number)" - ); - - ok( - $neg == $neginf, - "neg infinity (datetime) == neg infinity (number)" - ); -} - -# This could vary across platforms -my $pos_as_string = $posinf . ''; -my $neg_as_string = $neginf . ''; - -# formatting -{ - foreach my $m ( - qw( year month day hour minute second - microsecond millisecond nanosecond ) - ) { - is( - $pos->$m() . '', $pos_as_string, - "pos $m is $pos_as_string" - ); - - is( - $neg->$m() . '', $neg_as_string, - "neg $m is $pos_as_string" - ); - } -} - -{ - my $now = DateTime->now; - - is( - DateTime->compare( $pos, $now ), 1, - 'positive infinite is greater than now' - ); - is( - DateTime->compare( $neg, $now ), -1, - 'negative infinite is less than now' - ); -} - -{ - my $now = DateTime->now; - my $pos2 = $pos + DateTime::Duration->new( months => 1 ); - - ok( - $pos == $pos2, - "infinity (datetime) == infinity (datetime)" - ); -} - -{ - my $now = DateTime->now; - my $neg2 = $neg + DateTime::Duration->new( months => 1 ); - - ok( - $neg == $neg2, - "-infinity (datetime) == -infinity (datetime)" - ); -} - -{ - cmp_ok( - "$pos", 'eq', $posinf, - 'stringified infinity (datetime) eq infinity (number)' - ); - cmp_ok( - "$neg", 'eq', $neginf, - 'stringified neg infinity (datetime) eq neg infinity (number)' - ); -} - -{ - is( - $pos->day_name(), - undef, - 'day_name returns undef', - ); - - is( - $pos->am_or_pm(), - undef, - 'am_or_pm returns undef' - ); - - is( - $pos->locale()->name(), - 'Fake locale for Infinite DateTime objects', - 'locale name for fake locale' - ); - - is( - $pos->locale()->datetime_format_long(), - DateTime::Locale->load('en_US')->datetime_format_long(), - 'fake locale returns same format as en_US' - ); -} - -done_testing(); - diff -Nru libdatetime-perl-1.21/t/release-pp-21bad-params.t libdatetime-perl-1.46/t/release-pp-21bad-params.t --- libdatetime-perl-1.21/t/release-pp-21bad-params.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-21bad-params.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,77 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -use strict; -use warnings; - -use Test::More; - -use DateTime; - -foreach my $p ( - { year => 2000, month => 13 }, - { year => 2000, month => 0 }, - { year => 2000, month => 12, day => 32 }, - { year => 2000, month => 12, day => 0 }, - { year => 2000, month => 12, day => 10, hour => -1 }, - { year => 2000, month => 12, day => 10, hour => 24 }, - { year => 2000, month => 12, day => 10, hour => 12, minute => -1 }, - { year => 2000, month => 12, day => 10, hour => 12, minute => 60 }, - { year => 2000, month => 12, day => 10, hour => 12, second => -1 }, - { year => 2000, month => 12, day => 10, hour => 12, second => 62 }, - ) { - eval { DateTime->new(%$p) }; - like( - $@, qr/did not pass/, - "Parameters outside valid range should fail in call to new()" - ); - - eval { DateTime->new( year => 2000 )->set(%$p) }; - like( - $@, qr/did not pass/, - "Parameters outside valid range should fail in call to set()" - ); -} - -{ - eval { DateTime->last_day_of_month( year => 2000, month => 13 ) }; - like( - $@, qr/did not pass/, - "Parameters outside valid range should fail in call to last_day_of_month()" - ); - - eval { DateTime->last_day_of_month( year => 2000, month => 0 ) }; - like( - $@, qr/did not pass/, - "Parameters outside valid range should fail in call to last_day_of_month()" - ); -} - -{ - eval { DateTime->new( year => 2000, month => 4, day => 31 ) }; - like( - $@, qr/valid day of month/i, - "Day past last day of month should fail" - ); - - eval { DateTime->new( year => 2001, month => 2, day => 29 ) }; - like( - $@, qr/valid day of month/i, - "Day past last day of month should fail" - ); - - eval { DateTime->new( year => 2000, month => 2, day => 29 ) }; - ok( !$@, "February 29 should be valid in leap years" ); -} - -done_testing(); - diff -Nru libdatetime-perl-1.21/t/release-pp-22from-doy.t libdatetime-perl-1.46/t/release-pp-22from-doy.t --- libdatetime-perl-1.21/t/release-pp-22from-doy.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-22from-doy.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,72 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -use strict; -use warnings; - -use Test::More; - -use DateTime; - -my @last = ( 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ); -my @leap_last = @last; -$leap_last[1]++; - -{ - my $doy = 15; - foreach my $month ( 1 .. 12 ) { - $doy += $last[ $month - 2 ] if $month > 1; - - my $dt = DateTime->from_day_of_year( - year => 2001, - day_of_year => $doy, - time_zone => 'UTC', - ); - - is( $dt->year, 2001, 'check year' ); - is( $dt->month, $month, 'check month' ); - is( $dt->day, 15, 'check day' ); - is( $dt->day_of_year, $doy, 'check day of year' ); - } -} - -{ - my $doy = 15; - foreach my $month ( 1 .. 12 ) { - $doy += $leap_last[ $month - 2 ] if $month > 1; - - my $dt = DateTime->from_day_of_year( - year => 2004, - day_of_year => $doy, - time_zone => 'UTC', - ); - - is( $dt->year, 2004, 'check year' ); - is( $dt->month, $month, 'check month' ); - is( $dt->day, 15, 'check day' ); - is( $dt->day_of_year, $doy, 'check day of year' ); - } -} - -{ - eval { DateTime->from_day_of_year( year => 2001, day_of_year => 366 ) }; - like( - $@, qr/2001 is not a leap year/, - "Cannot give day of year 366 in non-leap years" - ); - - eval { DateTime->from_day_of_year( year => 2004, day_of_year => 366 ) }; - ok( !$@, "Day of year 366 should work in leap years" ); -} - -done_testing(); - diff -Nru libdatetime-perl-1.21/t/release-pp-23storable.t libdatetime-perl-1.46/t/release-pp-23storable.t --- libdatetime-perl-1.21/t/release-pp-23storable.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-23storable.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,118 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -use strict; -use warnings; - -use Test::More; - -use DateTime; - -unless ( eval { require Storable; 1 } ) { - plan skip_all => 'Cannot load Storable'; -} - -{ - my @dt = ( - DateTime->new( - year => 1950, - hour => 1, - nanosecond => 1, - time_zone => 'America/Chicago', - language => 'German' - ), - DateTime::Infinite::Past->new, - DateTime::Infinite::Future->new, - ); - - foreach my $dt (@dt) { - my $copy = Storable::thaw( Storable::nfreeze($dt) ); - - is( - $copy->time_zone->name, $dt->time_zone->name, - 'Storable freeze/thaw preserves tz' - ); - - is( - ref $copy->locale, ref $dt->locale, - 'Storable freeze/thaw preserves locale' - ); - - is( - $copy->year, $dt->year, - 'Storable freeze/thaw preserves rd values' - ); - - is( - $copy->hour, $dt->hour, - 'Storable freeze/thaw preserves rd values' - ); - - is( - $copy->nanosecond, $dt->nanosecond, - 'Storable freeze/thaw preserves rd values' - ); - } -} - -{ - my $dt1 = DateTime->now( locale => 'en-US' ); - my $dt2 = Storable::dclone($dt1); - my $dt3 = Storable::thaw( Storable::nfreeze($dt2) ); - - is( - $dt1->iso8601, $dt2->iso8601, - 'dclone produces date equal to original' - ); - is( - $dt2->iso8601, $dt3->iso8601, - 'explicit freeze and thaw produces date equal to original' - ); - - # Back-compat shim for new DateTime::Locale. Remove once DT::Locale based - # on CLDR 28+ is released. - my $meth = $dt1->locale->can('code') ? 'code' : 'id'; - my $orig_code = $dt1->locale->$meth; - is( - $dt2->locale->$meth, - $orig_code, - 'check locale id after dclone' - ); - is( - $dt3->locale->$meth, - $orig_code, - 'check locale id after explicit freeze/thaw' - ); -} - -{ - package Formatter; - - sub format_datetime { } -} - -{ - my $dt = DateTime->new( - year => 2004, - formatter => 'Formatter', - ); - - my $copy = Storable::thaw( Storable::nfreeze($dt) ); - - is( - $dt->formatter, $copy->formatter, - 'Storable freeze/thaw preserves formatter' - ); -} - -done_testing(); - diff -Nru libdatetime-perl-1.21/t/release-pp-24from-object.t libdatetime-perl-1.46/t/release-pp-24from-object.t --- libdatetime-perl-1.21/t/release-pp-24from-object.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-24from-object.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,104 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -use strict; -use warnings; - -use Test::More; - -use DateTime; - -my $dt1 = DateTime->new( year => 1970, hour => 1, nanosecond => 100 ); - -my $dt2 = DateTime->from_object( object => $dt1 ); - -is( $dt1->year, 1970, 'year is 1970' ); -is( $dt1->hour, 1, 'hour is 1' ); -is( $dt1->nanosecond, 100, 'nanosecond is 100' ); - -{ - my $t1 = DateTime::Calendar::_Test::WithoutTZ->new( - rd_days => 1, - rd_secs => 0 - ); - - # Tests creating objects from other calendars (without time zones) - my $t2 = DateTime->from_object( object => $t1 ); - - isa_ok( $t2, 'DateTime' ); - is( - $t2->datetime, '0001-01-01T00:00:00', - 'convert from object without tz' - ); - ok( $t2->time_zone->is_floating, 'time_zone is floating' ); -} - -{ - my $tz = DateTime::TimeZone->new( name => 'America/Chicago' ); - my $t1 = DateTime::Calendar::_Test::WithTZ->new( - rd_days => 1, rd_secs => 0, - time_zone => $tz - ); - - # Tests creating objects from other calendars (with time zones) - my $t2 = DateTime->from_object( object => $t1 ); - - isa_ok( $t2, 'DateTime' ); - is( $t2->time_zone->name, 'America/Chicago', 'time_zone is preserved' ); -} - -{ - my $tz = DateTime::TimeZone->new( name => 'UTC' ); - my $t1 = DateTime::Calendar::_Test::WithTZ->new( - rd_days => 720258, - rd_secs => 86400, time_zone => $tz - ); - - my $t2 = DateTime->from_object( object => $t1 ); - - isa_ok( $t2, 'DateTime' ); - is( - $t2->second, 60, - 'new DateTime from_object with TZ which is a leap second' - ); -} - -done_testing(); - -# Set up two simple test packages - -package DateTime::Calendar::_Test::WithoutTZ; - -sub new { - my $class = shift; - bless {@_}, $class; -} - -sub utc_rd_values { - return $_[0]{rd_days}, $_[0]{rd_secs}, 0; -} - -package DateTime::Calendar::_Test::WithTZ; - -sub new { - my $class = shift; - bless {@_}, $class; -} - -sub utc_rd_values { - return $_[0]{rd_days}, $_[0]{rd_secs}, 0; -} - -sub time_zone { - return $_[0]{time_zone}; -} - diff -Nru libdatetime-perl-1.21/t/release-pp-25add-subtract.t libdatetime-perl-1.46/t/release-pp-25add-subtract.t --- libdatetime-perl-1.21/t/release-pp-25add-subtract.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-25add-subtract.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -use strict; -use warnings; - -use Test::More; - -use DateTime; - -# exercises a bug found in Perl version of _normalize_tai_seconds - -# fixed in 0.15 -{ - my $dt = DateTime->new( year => 2000, month => 12 ); - - $dt->add( months => 1 )->truncate( to => 'month' ) - ->subtract( seconds => 1 ); - - is( $dt->year, 2000, 'year is 2001' ); - is( $dt->month, 12, 'month is 12' ); - is( $dt->hour, 23, 'hour is 23' ); - is( $dt->minute, 59, 'minute is 59' ); - is( $dt->second, 59, 'second is 59' ); -} - -{ - my $dt = DateTime->new( year => 2000, month => 12 ); - my $dt2 = $dt->clone->add( months => 1 )->subtract( seconds => 1 ); - - is( $dt2->year, 2000, 'year is 2001' ); - is( $dt2->month, 12, 'month is 12' ); - is( $dt2->hour, 23, 'hour is 23' ); - is( $dt2->minute, 59, 'minute is 59' ); - is( $dt2->second, 59, 'second is 59' ); -} - -done_testing(); - diff -Nru libdatetime-perl-1.21/t/release-pp-27delta.t libdatetime-perl-1.46/t/release-pp-27delta.t --- libdatetime-perl-1.21/t/release-pp-27delta.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-27delta.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,117 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -use strict; -use warnings; - -use Test::More; - -use DateTime; - -{ - my $date1 = DateTime->new( - year => 2001, month => 5, day => 10, - hour => 4, minute => 3, second => 2, - nanosecond => 12, - time_zone => 'UTC' - ); - - my $date2 = DateTime->new( - year => 2001, month => 6, day => 12, - hour => 5, minute => 7, second => 23, - nanosecond => 7, - time_zone => 'UTC' - ); - - { - my $dur_md = $date2->delta_md($date1); - - is( $dur_md->delta_months, 1, 'delta_md months is 1' ); - is( $dur_md->delta_days, 2, 'delta_md days is 2' ); - is( $dur_md->delta_minutes, 0, 'delta_md minutes is 0' ); - is( $dur_md->delta_seconds, 0, 'delta_md seconds is 0' ); - is( $dur_md->delta_nanoseconds, 0, 'delta_md nanoseconds is 0' ); - - my $dur_d = $date2->delta_days($date1); - - is( $dur_d->delta_months, 0, 'delta_d months is 0' ); - is( $dur_d->delta_days, 33, 'delta_d days is 33' ); - is( $dur_d->delta_minutes, 0, 'delta_d minutes is 0' ); - is( $dur_d->delta_seconds, 0, 'delta_d seconds is 0' ); - is( $dur_d->delta_nanoseconds, 0, 'delta_d nanoseconds is 0' ); - - my $dur_ms = $date2->delta_ms($date1); - - is( $dur_ms->delta_months, 0, 'delta_ms months is 0' ); - is( $dur_ms->delta_days, 0, 'delta_ms days is 0' ); - is( $dur_ms->delta_minutes, 47584, 'delta_ms minutes is 47584' ); - is( $dur_ms->delta_seconds, 20, 'delta_ms seconds is 20' ); - is( $dur_ms->delta_nanoseconds, 0, 'delta_ms nanoseconds is 0' ); - - is( $dur_ms->hours, 793, 'hours is 793' ); - } - - { - my $dur_md = $date1->delta_md($date2); - - is( $dur_md->delta_months, 1, 'delta_md months is 1' ); - is( $dur_md->delta_days, 2, 'delta_md days is 2' ); - is( $dur_md->delta_minutes, 0, 'delta_md minutes is 0' ); - is( $dur_md->delta_seconds, 0, 'delta_md seconds is 0' ); - is( $dur_md->delta_nanoseconds, 0, 'delta_md nanoseconds is 0' ); - - my $dur_d = $date1->delta_days($date2); - - is( $dur_d->delta_months, 0, 'delta_d months is 0' ); - is( $dur_d->delta_days, 33, 'delta_d days is 33' ); - is( $dur_d->delta_minutes, 0, 'delta_d minutes is 0' ); - is( $dur_d->delta_seconds, 0, 'delta_d seconds is 0' ); - is( $dur_d->delta_nanoseconds, 0, 'delta_d nanoseconds is 0' ); - - my $dur_ms = $date1->delta_ms($date2); - - is( $dur_ms->delta_months, 0, 'delta_ms months is 0' ); - is( $dur_ms->delta_days, 0, 'delta_ms days is 0' ); - is( $dur_ms->delta_minutes, 47584, 'delta_ms minutes is 47584' ); - is( $dur_ms->delta_seconds, 20, 'delta_ms seconds is 20' ); - is( $dur_ms->delta_nanoseconds, 0, 'delta_ms nanoseconds is 0' ); - - is( $dur_ms->hours, 793, 'hours is 793' ); - } -} - -{ - my $date1 = DateTime->new( - year => 2001, month => 5, day => 10, - hour => 15, minute => 0, second => 0, - time_zone => 'UTC' - ); - - my $date2 = DateTime->new( - year => 2001, month => 5, day => 11, - hour => 12, minute => 30, second => 10, - time_zone => 'UTC' - ); - - my $dur_ms = $date1->delta_ms($date2); - - is( $dur_ms->delta_months, 0, 'delta_ms months is 0' ); - is( $dur_ms->delta_days, 0, 'delta_ms days is 0' ); - is( $dur_ms->delta_minutes, 1290, 'delta_ms minutes is 1290' ); - is( $dur_ms->delta_seconds, 10, 'delta_ms seconds is 30' ); - is( $dur_ms->delta_nanoseconds, 0, 'delta_ms nanoseconds is 0' ); - - is( $dur_ms->hours, 21, 'hours is 21' ); -} - -done_testing(); - diff -Nru libdatetime-perl-1.21/t/release-pp-28dow.t libdatetime-perl-1.46/t/release-pp-28dow.t --- libdatetime-perl-1.21/t/release-pp-28dow.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-28dow.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,78 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -use strict; -use warnings; - -use Test::More; - -use DateTime; - -{ - my $dt = DateTime->new( year => 0 ); - - is( $dt->year, 0, 'year is 0' ); - is( $dt->month, 1, 'month is 1' ); - is( $dt->day, 1, 'day is 1' ); - is( $dt->day_of_week, 6, 'day of week is 6' ); -} - -{ - my $dt = DateTime->new( year => 0, month => 12, day => 31 ); - - is( $dt->year, 0, 'year is 0' ); - is( $dt->month, 12, 'month is 12' ); - is( $dt->day, 31, 'day is 31' ); - is( $dt->day_of_week, 7, 'day of week is 7' ); -} - -{ - my $dt = DateTime->new( year => -1 ); - - is( $dt->year, -1, 'year is -1' ); - is( $dt->month, 1, 'month is 1' ); - is( $dt->day, 1, 'day is 1' ); - is( $dt->day_of_week, 5, 'day of week is 5' ); -} - -{ - my $dt = DateTime->new( year => 1 ); - - is( $dt->year, 1, 'year is 1' ); - is( $dt->month, 1, 'month is 1' ); - is( $dt->day, 1, 'day is 1' ); - is( $dt->day_of_week, 1, 'day of week is 1' ); -} - -{ - my $dow = 1; - for my $year ( 1, 0, -1 ) { - my $days_in_year = $year ? 365 : 366; - - for my $doy ( reverse 1 .. $days_in_year ) { - is( - DateTime->from_day_of_year( - year => $year, - day_of_year => $doy, - )->day_of_week, - $dow, - "day of week for day $doy of year $year is $dow" - ); - - $dow--; - $dow = 7 if $dow == 0; - } - } -} - -done_testing(); - diff -Nru libdatetime-perl-1.21/t/release-pp-29overload.t libdatetime-perl-1.46/t/release-pp-29overload.t --- libdatetime-perl-1.21/t/release-pp-29overload.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-29overload.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,160 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -use strict; -use warnings; - -use Test::More; -use Test::Warnings 0.005 ':all'; - -use DateTime; - -{ - my $dt = DateTime->new( year => 1900, month => 12, day => 1 ); - - is( "$dt", '1900-12-01T00:00:00', 'stringification overloading' ); -} - -{ - my $dt = DateTime->new( - year => 2050, month => 1, day => 15, - hour => 20, minute => 10, second => 10 - ); - - my $before_string = '2050-01-15T20:10:09'; - my $same_string = '2050-01-15T20:10:10'; - my $after_string = '2050-01-15T20:10:11'; - - is( "$dt", $same_string, 'stringification overloading' ); - ok( $dt eq $same_string, 'eq overloading true' ); - ok( !( $dt eq $after_string ), 'eq overloading false' ); - ok( $dt ne $after_string, 'ne overloading true' ); - ok( !( $dt ne $same_string ), 'ne overloading false' ); - - is( $dt cmp $same_string, 0, 'cmp overloading' ); - is( $dt cmp $after_string, -1, ' less than' ); - ok( $dt lt $after_string, 'lt overloading' ); - ok( !( $dt lt $same_string ), ' not' ); - - { - - package Other::Date; - use overload - q[""] => sub { return ${ $_[0] }; }, - fallback => 1; - - sub new { - my ( $class, $date ) = @_; - return bless \$date, $class; - } - } - - my $same_od = Other::Date->new($same_string); - my $after_od = Other::Date->new($after_string); - my $before_od = Other::Date->new($before_string); - - ok( $dt eq $same_od, "DateTime eq non-DateTime overloaded object true" ); - ok( !( $dt eq $after_od ), " eq false" ); - ok( $dt ne $after_od, " ne true" ); - ok( !( $dt ne $same_od ), " ne false" ); - - is( $dt cmp $same_od, 0, 'cmp overloading' ); - is( $dt cmp $after_od, -1, ' lt overloading' ); - ok( $dt lt $after_od, 'lt overloading' ); - ok( !( $dt lt $same_od ), ' not' ); - - is_deeply( - [ - map { $_ . ' - ' . ( ref $_ || 'no ref' ) } - sort { $a cmp $b or ref $a cmp ref $b } $same_od, $after_od, - $before_od, $dt, $same_string, $after_string, $before_string - ], - [ - map { $_ . ' - ' . ( ref $_ || 'no ref' ) } $before_string, - $before_od, $same_string, $dt, $same_od, $after_string, $after_od - ], - "eq sort" - ); - - eval { my $x = $dt + 1 }; - like( - $@, qr/Cannot add 1 to a DateTime object/, - 'Cannot add plain scalar to a DateTime object' - ); - - eval { my $x = $dt + bless {}, 'FooBar' }; - like( - $@, qr/Cannot add FooBar=HASH\([^\)]+\) to a DateTime object/, - 'Cannot add plain FooBar object to a DateTime object' - ); - - eval { my $x = $dt - 1 }; - like( - $@, qr/Cannot subtract 1 from a DateTime object/, - 'Cannot subtract plain scalar from a DateTime object' - ); - - eval { my $x = $dt - bless {}, 'FooBar' }; - like( - $@, qr/Cannot subtract FooBar=HASH\([^\)]+\) from a DateTime object/, - 'Cannot subtract plain FooBar object from a DateTime object' - ); - - eval { my $x = $dt > 1 }; - like( - $@, - qr/A DateTime object can only be compared to another DateTime object/, - 'Cannot compare a DateTime object to a scalar' - ); - - eval { my $x = $dt > bless {}, 'FooBar' }; - like( - $@, - qr/A DateTime object can only be compared to another DateTime object/, - 'Cannot compare a DateTime object to a FooBar object' - ); - - like( - warning { my $x = undef; $dt > $x; }, - qr/uninitialized value in numeric gt .+ at .*t.(release-pp-)?29overload\.t/, - 'Comparing undef to a DateTime object generates a Perl warning at the right spot ($dt > undef)' - ); - - like( - warning { my $x = undef; $x > $dt; }, - qr/uninitialized value in numeric gt .+ at .*t.(release-pp-)?29overload\.t/, - 'Comparing undef to a DateTime object generates a Perl warning at the right spot (undef > $dt)' - ); - - ok( - !( $dt eq 'some string' ), - 'DateTime object always compares false to a string' - ); - - ok( - $dt ne 'some string', - 'DateTime object always compares false to a string' - ); - - ok( - $dt eq $dt->clone, - 'DateTime object is equal to a clone of itself' - ); - - ok( - !( $dt ne $dt->clone ), - 'DateTime object is equal to a clone of itself (! ne)' - ); -} - -done_testing(); - diff -Nru libdatetime-perl-1.21/t/release-pp-30future-tz.t libdatetime-perl-1.46/t/release-pp-30future-tz.t --- libdatetime-perl-1.21/t/release-pp-30future-tz.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-30future-tz.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,66 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -use strict; -use warnings; - -use Test::More; - -use DateTime; - -# -# This test exercises a bug that occurred when date math did not -# always make sure to update the utc_year attribute of the given -# DateTime. The sympton was that the time zone future span generation -# would fail because utc_year was less than the span's max_year, so -# span generation wouldn't actually do anything, and it would die with -# "Invalid local time". -# -{ - - # Each iteration needs to use a different zone, because if it - # works once, the generated spans are cached. - for my $add ( - [ years => 50, 1, 'America/New_York' ], - [ days => 50, 365, 'America/Chicago' ], - [ minutes => 50, 365 * 1440, 'America/Denver', ], - [ seconds => 50, 365 * 1440 * 60, 'America/Los_Angeles' ], - [ - nanoseconds => 50, 365 * 1440 * 60 * 1_000_000_000, - 'America/North_Dakota/Center' - ], - - [ years => 750, 1, 'Europe/Paris' ], - [ days => 750, 365, 'Europe/London' ], - [ minutes => 750, 365 * 1440, 'Europe/Brussels', ], - [ seconds => 750, 365 * 1440 * 60, 'Europe/Vienna' ], - [ - nanoseconds => 750, 365 * 1440 * 60 * 1_000_000_000, - 'Europe/Prague' - ], - ) { - - my $dt = DateTime->now->set( hour => 12 )->set_time_zone( $add->[3] ); - - my $new - = eval { $dt->clone->add( $add->[0], $add->[1] * $add->[2] ) }; - - is( - $@, - q{}, - "Make sure we can add $add->[1] years worth of $add->[0] in $add->[3] time zone" - ); - } -} - -done_testing(); - diff -Nru libdatetime-perl-1.21/t/release-pp-31formatter.t libdatetime-perl-1.46/t/release-pp-31formatter.t --- libdatetime-perl-1.21/t/release-pp-31formatter.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-31formatter.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,86 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -use strict; -use warnings; - -use Test::More; - -use DateTime; - -{ - package Formatter; - - sub new { - return bless {}, __PACKAGE__; - } - - sub format_datetime { - $_[1]->strftime('%Y%m%d %T'); - } -} - -my $formatter = Formatter->new(); - -my $dt = DateTime->from_epoch( epoch => time(), formatter => $formatter ); -ok( $dt, "Constructor (from_epoch) : $@" ); - -$dt = eval { - DateTime->new( - year => 2004, - month => 9, - day => 2, - hour => 13, - minute => 23, - second => 34, - formatter => $formatter - ); -}; -ok( $dt, "Constructor (new) : $@" ); - -$dt - = eval { DateTime->from_object( object => $dt, formatter => $formatter ) }; -ok( $dt, "Constructor (from_object) : $@" ); - -is( $dt->formatter, $formatter, "check from_object copies formatter" ); - -is( $dt->_stringify(), '20040902 13:23:34', 'Format datetime' ); - -# check stringification (with formatter) -is( $dt->_stringify, "$dt", "Stringification (with formatter)" ); - -# check that set() and truncate() don't lose formatter -$dt->set( hour => 3 ); -is( - $dt->_stringify, '20040902 03:23:34', - 'formatter is preserved after set()' -); - -$dt->truncate( to => 'minute' ); -is( - $dt->_stringify, '20040902 03:23:00', - 'formatter is preserved after truncate()' -); - -# check if the default behavior works -$dt->set_formatter(undef); -is( $dt->_stringify(), $dt->iso8601, 'Default iso8601 works' ); - -# check stringification (default) -is( - $dt->_stringify, "$dt", - "Stringification (no formatter -> format_datetime)" -); -is( $dt->iso8601, "$dt", "Stringification (no formatter -> iso8601)" ); - -done_testing(); - diff -Nru libdatetime-perl-1.21/t/release-pp-32leap-second2.t libdatetime-perl-1.46/t/release-pp-32leap-second2.t --- libdatetime-perl-1.21/t/release-pp-32leap-second2.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-32leap-second2.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,344 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -use strict; -use warnings; - -use Test::More; - -use DateTime; - -{ - my $t = DateTime->new( - year => 1972, month => 7, day => 1, - hour => 0, minute => 59, second => 58, - time_zone => '+0100', - ); - - is( $t->second, 58, 'second value for leap second T-2, +0100' ); - - is( - $t->{utc_rd_days}, 720074, - 'UTC RD days for leap second T-2' - ); - is( - $t->{utc_rd_secs}, 86398, - 'UTC RD seconds for leap second T-2' - ); - - is( - $t->{local_rd_days}, 720075, - 'local RD days for leap second T-2' - ); - is( - $t->{local_rd_secs}, 3598, - 'local RD seconds for leap second T-2' - ); -} - -{ - my $t = DateTime->new( - year => 1972, month => 7, day => 1, - hour => 0, minute => 59, second => 59, - time_zone => '+0100', - ); - - is( $t->second, 59, 'second value for leap second T-1, +0100' ); - is( - $t->{utc_rd_days}, 720074, - 'UTC RD days for leap second T-1' - ); - is( - $t->{utc_rd_secs}, 86399, - 'UTC RD seconds for leap second T-1' - ); - - is( - $t->{local_rd_days}, 720075, - 'local RD days for leap second T-1' - ); - is( - $t->{local_rd_secs}, 3599, - 'local RD seconds for leap second T-1' - ); -} - -{ - my $t = eval { - DateTime->new( - year => 1972, month => 7, day => 1, - hour => 0, minute => 59, second => 60, - time_zone => '+0100', - ); - }; - - ok( !$@, 'constructor for second = 60' ); - -SKIP: - { - skip 'constructor failed - no object to test', 5 - unless $t; - - is( $t->second, 60, 'second value for leap second T-0, +0100' ); - is( - $t->{utc_rd_days}, 720074, - 'UTC RD days for leap second T-0' - ); - is( - $t->{utc_rd_secs}, 86400, - 'UTC RD seconds for leap second T-0' - ); - - is( - $t->{local_rd_days}, 720075, - 'local RD days for leap second T-0' - ); - is( - $t->{local_rd_secs}, 3600, - 'local RD seconds for leap second T-0' - ); - } -} - -{ - my $t = DateTime->new( - year => 1972, month => 7, day => 1, - hour => 1, minute => 0, second => 0, - time_zone => '+0100', - ); - - is( $t->second, 0, 'second value for leap second T+1, +0100' ); - is( - $t->{utc_rd_days}, 720075, - 'UTC RD days for leap second T+1' - ); - is( - $t->{utc_rd_secs}, 0, - 'UTC RD seconds for leap second T+1' - ); - - is( - $t->{local_rd_days}, 720075, - 'local RD days for leap second T+1' - ); - is( - $t->{local_rd_secs}, 3601, - 'local RD seconds for leap second T+1' - ); -} - -{ - my $t = DateTime->new( - year => 1972, month => 7, day => 1, - hour => 1, minute => 0, second => 1, - time_zone => '+0100', - ); - - is( $t->second, 1, 'second value for leap second T+2, +0100' ); - is( - $t->{utc_rd_days}, 720075, - 'UTC RD days for leap second T+2' - ); - is( - $t->{utc_rd_secs}, 1, - 'UTC RD seconds for leap second T+2' - ); - - is( - $t->{local_rd_days}, 720075, - 'local RD days for leap second T+2' - ); - is( - $t->{local_rd_secs}, 3602, - 'local RD seconds for leap second T+2' - ); -} - -{ - my $t = DateTime->new( - year => 1972, month => 7, day => 1, - hour => 23, minute => 59, second => 59, - time_zone => '+0100', - ); - - is( $t->second, 59, 'second value for end of leap second day, +0100' ); - is( - $t->{utc_rd_days}, 720075, - 'UTC RD days for end of leap second day' - ); - is( - $t->{utc_rd_secs}, 82799, - 'UTC RD seconds for end of leap second day' - ); - - is( - $t->{local_rd_days}, 720075, - 'local RD days for leap second day' - ); - is( - $t->{local_rd_secs}, 86400, - 'local RD seconds for end of leap second day' - ); -} - -{ - my $t = DateTime->new( - year => 1972, month => 6, day => 30, - hour => 22, minute => 59, second => 58, - time_zone => '-0100', - ); - - is( $t->second, 58, 'second value for leap second T-2, -0100' ); - - is( - $t->{utc_rd_days}, 720074, - 'UTC RD days for leap second T-2' - ); - is( - $t->{utc_rd_secs}, 86398, - 'UTC RD seconds for leap second T-2' - ); - - is( - $t->{local_rd_days}, 720074, - 'local RD days for leap second T-2' - ); - is( - $t->{local_rd_secs}, 82798, - 'local RD seconds for leap second T-2' - ); -} - -{ - my $t = DateTime->new( - year => 1972, month => 6, day => 30, - hour => 22, minute => 59, second => 59, - time_zone => '-0100', - ); - - is( $t->second, 59, 'second value for leap second T-1, -0100' ); - - is( - $t->{utc_rd_days}, 720074, - 'UTC RD days for leap second T-1' - ); - is( - $t->{utc_rd_secs}, 86399, - 'UTC RD seconds for leap second T-1' - ); - - is( - $t->{local_rd_days}, 720074, - 'local RD days for leap second T-1' - ); - is( - $t->{local_rd_secs}, 82799, - 'local RD seconds for leap second T-1' - ); -} - -{ - my $t = eval { - DateTime->new( - year => 1972, month => 6, day => 30, - hour => 22, minute => 59, second => 60, - time_zone => '-0100', - ); - }; - - ok( !$@, 'constructor for second = 60' ); - -SKIP: - { - skip 'constructor failed - no object to test', 5 - unless $t; - - is( $t->second, 60, 'second value for leap second T-0, -0100' ); - - is( - $t->{utc_rd_days}, 720074, - 'UTC RD days for leap second T-0' - ); - is( - $t->{utc_rd_secs}, 86400, - 'UTC RD seconds for leap second T-0' - ); - - is( - $t->{local_rd_days}, 720074, - 'local RD days for leap second T-0' - ); - is( - $t->{local_rd_secs}, 82800, - 'local RD seconds for leap second T-0' - ); - } -} - -{ - my $t = DateTime->new( - year => 1972, month => 6, day => 30, - hour => 23, minute => 0, second => 0, - time_zone => '-0100', - ); - - is( $t->second, 0, 'second value for leap second T+1, -0100' ); - - is( - $t->{utc_rd_days}, 720075, - 'UTC RD days for leap second T+1' - ); - is( - $t->{utc_rd_secs}, 0, - 'UTC RD seconds for leap second T+1' - ); - - is( - $t->{local_rd_days}, 720074, - 'local RD days for leap second T+1' - ); - is( - $t->{local_rd_secs}, 82801, - 'local RD seconds for leap second T+1' - ); -} - -{ - my $t = DateTime->new( - year => 1972, month => 6, day => 30, - hour => 23, minute => 0, second => 1, - time_zone => '-0100', - ); - - is( $t->second, 1, 'second value for leap second T+2, -0100' ); - - is( - $t->{utc_rd_days}, 720075, - 'UTC RD days for leap second T+2' - ); - is( - $t->{utc_rd_secs}, 1, - 'UTC RD seconds for leap second T+2' - ); - - is( - $t->{local_rd_days}, 720074, - 'local RD days for leap second T+2' - ); - is( - $t->{local_rd_secs}, 82802, - 'local RD seconds for leap second T+2' - ); -} - -done_testing(); - diff -Nru libdatetime-perl-1.21/t/release-pp-33seconds-offset.t libdatetime-perl-1.46/t/release-pp-33seconds-offset.t --- libdatetime-perl-1.21/t/release-pp-33seconds-offset.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-33seconds-offset.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,99 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -use strict; -use warnings; - -use Test::More; - -use DateTime; - -{ - my $dt = DateTime->new( - year => 1997, month => 6, day => 30, - hour => 23, minute => 58, second => 59, - time_zone => 'UTC' - ); - - $dt->set_time_zone('+00:00:30'); - - is( $dt->datetime, '1997-06-30T23:59:29', '+00:00:30 leap second T-61' ); -} - -{ - my $dt = DateTime->new( - year => 1997, month => 6, day => 30, - hour => 23, minute => 59, second => 29, - time_zone => 'UTC' - ); - - $dt->set_time_zone('+00:00:30'); - - is( $dt->datetime, '1997-06-30T23:59:59', '+00:00:30 leap second T-31' ); -} - -{ - local $TODO = 'offsets with seconds are broken near leap seconds'; - - my $dt = DateTime->new( - year => 1997, month => 6, day => 30, - hour => 23, minute => 59, second => 30, - time_zone => 'UTC' - ); - - $dt->set_time_zone('+00:00:30'); - - is( $dt->datetime, '1997-06-30T23:59:60', '+00:00:30 leap second T-30' ); -} - -{ - local $TODO = 'offsets with seconds are broken near leap seconds'; - - my $dt = DateTime->new( - year => 1997, month => 6, day => 30, - hour => 23, minute => 59, second => 31, - time_zone => 'UTC' - ); - - $dt->set_time_zone('+00:00:30'); - - is( $dt->datetime, '1997-07-01T00:00:00', '+00:00:30 leap second T-29' ); -} - -{ - local $TODO = 'offsets with seconds are broken near leap seconds'; - - my $dt = DateTime->new( - year => 1997, month => 6, day => 30, - hour => 23, minute => 59, second => 60, - time_zone => 'UTC' - ); - - $dt->set_time_zone('+00:00:30'); - - is( $dt->datetime, '1997-07-01T00:00:30', '+00:00:30 leap second T-0' ); -} - -{ - my $dt = DateTime->new( - year => 1997, month => 7, day => 1, - hour => 0, minute => 0, second => 0, - time_zone => 'UTC' - ); - - $dt->set_time_zone('+00:00:30'); - - is( $dt->datetime, '1997-07-01T00:00:30', '+00:00:30 leap second T+1' ); -} - -done_testing(); - diff -Nru libdatetime-perl-1.21/t/release-pp-34set-tz.t libdatetime-perl-1.46/t/release-pp-34set-tz.t --- libdatetime-perl-1.21/t/release-pp-34set-tz.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-34set-tz.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,95 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -use strict; -use warnings; - -use Test::Fatal; -use Test::More 0.88; - -use DateTime; - -# These tests are for a bug related to a bad interaction between the -# horrid ->_handle_offset_modifier method and calling ->set_time_zone -# on a real Olson time zone. When _handle_offset_modifier was called -# from set_time_zone, it tried calling ->_offset_for_local_datetime, -# which was bogus, because at that point it doesn't know the local -# date time any more, only UTC. -# -# The fix is to have ->_handle_offset_modifier call ->offset when it -# knows that UTC is valid, which is determined by an arg to -# ->_handle_offset_modifier - -# These tests come from one of the zdump-generated test files in -# DT::TZ -{ - my $dt = DateTime->new( - year => 1922, month => 8, day => 31, - hour => 23, minute => 59, second => 59, - time_zone => 'UTC', - ); - $dt->set_time_zone('Africa/Accra'); - - is( $dt->year, 1922, 'local year should be 1922 (1922-08-31 23:59:59)' ); - is( $dt->month, 8, 'local month should be 8 (1922-08-31 23:59:59)' ); - is( $dt->day, 31, 'local day should be 31 (1922-08-31 23:59:59)' ); - is( $dt->hour, 23, 'local hour should be 23 (1922-08-31 23:59:59)' ); - is( $dt->minute, 59, 'local minute should be 59 (1922-08-31 23:59:59)' ); - is( $dt->second, 59, 'local second should be 59 (1922-08-31 23:59:59)' ); - - is( $dt->is_dst, 0, 'is_dst should be 0 (1922-08-31 23:59:59)' ); - is( $dt->offset, 0, 'offset should be 0 (1922-08-31 23:59:59)' ); - is( - $dt->time_zone_short_name, 'GMT', - 'short name should be GMT (1922-08-31 23:59:59)' - ); -} - -{ - my $dt = DateTime->new( - year => 2013, - month => 3, - day => 10, - hour => 2, - minute => 4, - time_zone => 'floating', - ); - - like( - exception { $dt->set_time_zone('America/Los_Angeles') }, - qr/\QInvalid local time for date in time zone/, - 'got an exception when trying to set time zone when it leads to invalid local time' - ); - - is( - $dt->time_zone()->name(), - 'floating', - 'time zone was not changed after set_time_zone() throws an exception' - ); -} - -{ - my $dt = DateTime->now( time_zone => 'America/Chicago' ); - - ok( - $dt->set_time_zone('America/Chicago'), - 'set_time_zone returns object when time zone name is same as current' - ); - - ok( - $dt->set_time_zone( $dt->time_zone() ), - 'set_time_zone returns object when time zone object is same as current' - ); -} - -done_testing(); - diff -Nru libdatetime-perl-1.21/t/release-pp-35rd-values.t libdatetime-perl-1.46/t/release-pp-35rd-values.t --- libdatetime-perl-1.21/t/release-pp-35rd-values.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-35rd-values.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,65 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -use strict; -use warnings; - -use Test::More; - -use DateTime; - -{ - my $dt = DateTime->new( - year => 2000, - hour => 1, - nanosecond => 500, - time_zone => 'UTC', - ); - - my ( $utc_rd_days, $utc_rd_secs, $utc_nanosecs ) = $dt->utc_rd_values; - - is( $utc_rd_days, 730120, 'utc rd days is 730120' ); - is( $utc_rd_secs, 3600, 'utc rd seconds is 3600' ); - is( $utc_nanosecs, 500, 'nanoseconds is 500' ); - - my ( $local_rd_days, $local_rd_secs, $local_nanosecs ) - = $dt->local_rd_values; - - is( $local_rd_days, $utc_rd_days, 'local & utc rd days are equal' ); - is( $local_rd_secs, $utc_rd_secs, 'local & utc rd seconds are equal' ); - is( $local_nanosecs, $utc_nanosecs, 'local & UTC nanoseconds are equal' ); -} - -{ - my $dt = DateTime->new( - year => 2000, - hour => 1, - nanosecond => 500, - time_zone => '+02:00', - ); - - my ( $utc_rd_days, $utc_rd_secs, $utc_nanosecs ) = $dt->utc_rd_values; - - is( $utc_rd_days, 730119, 'utc rd days is 730119' ); - is( $utc_rd_secs, 82800, 'utc rd seconds is 82800' ); - is( $utc_nanosecs, 500, 'nanoseconds is 500' ); - - my ( $local_rd_days, $local_rd_secs, $local_nanosecs ) - = $dt->local_rd_values; - - is( $local_rd_days, 730120, 'local rd days is 730120' ); - is( $local_rd_secs, 3600, 'local rd seconds is 3600' ); - is( $local_nanosecs, 500, 'local nanoseconds is 500' ); -} - -done_testing(); - diff -Nru libdatetime-perl-1.21/t/release-pp-36invalid-local.t libdatetime-perl-1.46/t/release-pp-36invalid-local.t --- libdatetime-perl-1.21/t/release-pp-36invalid-local.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-36invalid-local.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,63 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -use strict; -use warnings; - -use Test::More; - -use DateTime; - -my $badlt_rx = qr/Invalid local time|local time [0-9\-:T]+ does not exist/; - -{ - eval { - DateTime->new( - year => 2003, month => 4, day => 6, - hour => 2, time_zone => 'America/Chicago', - ); - }; - - like( $@, $badlt_rx, 'exception for invalid time' ); - - eval { - DateTime->new( - year => 2003, month => 4, day => 6, - hour => 2, minute => 59, second => 59, - time_zone => 'America/Chicago', - ); - }; - like( $@, $badlt_rx, 'exception for invalid time' ); -} - -{ - eval { - DateTime->new( - year => 2003, month => 4, day => 6, - hour => 1, minute => 59, second => 59, - time_zone => 'America/Chicago', - ); - }; - ok( !$@, 'no exception for valid time' ); - - my $dt = DateTime->new( - year => 2003, month => 4, day => 5, - hour => 2, - time_zone => 'America/Chicago', - ); - - eval { $dt->add( days => 1 ) }; - like( $@, $badlt_rx, 'exception for invalid time produced via add' ); -} - -done_testing(); - diff -Nru libdatetime-perl-1.21/t/release-pp-37local-add.t libdatetime-perl-1.46/t/release-pp-37local-add.t --- libdatetime-perl-1.21/t/release-pp-37local-add.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-37local-add.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,235 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -use strict; -use warnings; - -use Test::More; - -use DateTime; - -# These tests should be the final word on dt addition involving a -# DST-changing time zone - -# time addition is "wait X amount of time, then what does the clock -# say?" this means it acts on the UTC components. -{ - my $dt = DateTime->new( - year => 2003, month => 4, day => 6, - time_zone => 'America/Chicago', - ); - - $dt->add( hours => 1 ); - is( - $dt->datetime, '2003-04-06T01:00:00', - 'add one hour to midnight, get 1 am' - ); - - eval { $dt->add( hours => 1 ) }; - is( $@, '', 'no error adding 1 hour just before DST leap forward' ); - is( - $dt->datetime, '2003-04-06T03:00:00', - 'add one hour to 1 am, get 3 am' - ); - - $dt->subtract( hours => 1 ); - is( - $dt->datetime, '2003-04-06T01:00:00', - 'subtract one hour from 3 am, get 1 am' - ); - - $dt->subtract( hours => 1 ); - is( - $dt->datetime, '2003-04-06T00:00:00', - 'subtract one hour from 1 am, get midnight' - ); -} - -{ - my $dt = DateTime->new( - year => 2003, month => 10, day => 26, - time_zone => 'America/Chicago', - ); - - $dt->add( hours => 1 ); - is( - $dt->datetime, '2003-10-26T01:00:00', - 'add one hour to midnight, get 1 am' - ); - - $dt->add( hours => 1 ); - is( - $dt->datetime, '2003-10-26T01:00:00', - 'add one hour to 1 am, get 1 am (again)' - ); - - $dt->add( hours => 1 ); - is( - $dt->datetime, '2003-10-26T02:00:00', - 'add one hour to 1 am (2nd time), get 2 am' - ); - - $dt->subtract( hours => 1 ); - is( - $dt->datetime, '2003-10-26T01:00:00', - 'subtract 1 hour from 2 am, get 1 am' - ); - - $dt->subtract( hours => 1 ); - is( - $dt->datetime, '2003-10-26T01:00:00', - 'subtract 1 hour from 1 am, get 1 am (again)' - ); - - $dt->subtract( hours => 1 ); - is( - $dt->datetime, '2003-10-26T00:00:00', - 'subtract 1 hour from 1 am (2nd), get midnight' - ); -} - -# date addition is "leave the clock alone, just change the date -# portion". this means it acts on local components -{ - my $dt = DateTime->new( - year => 2003, month => 4, day => 6, - time_zone => 'America/Chicago', - ); - - $dt->add( days => 1 ); - is( - $dt->datetime, '2003-04-07T00:00:00', - 'add 1 day at midnight, same clock time' - ); - - $dt->add( months => 7 ); - is( - $dt->datetime, '2003-11-07T00:00:00', - 'add 7 months at midnight, same clock time' - ); - - $dt->subtract( months => 7 ); - is( - $dt->datetime, '2003-04-07T00:00:00', - 'subtract 7 months at midnight, same clock time' - ); - - $dt->subtract( days => 1 ); - is( - $dt->datetime, '2003-04-06T00:00:00', - 'subtract 1 day at midnight, same clock time' - ); -} - -{ - my $dt = DateTime->new( - year => 2003, month => 10, day => 26, - time_zone => 'America/Chicago', - ); - - $dt->add( days => 1 ); - is( - $dt->datetime, '2003-10-27T00:00:00', - 'add 1 day at midnight, get midnight' - ); - - $dt->add( months => 7 ); - is( - $dt->datetime, '2004-05-27T00:00:00', - 'add 7 months at midnight, get midnight' - ); - - $dt->subtract( months => 7 ); - is( - $dt->datetime, '2003-10-27T00:00:00', - 'subtract 7 months at midnight, get midnight' - ); - - $dt->subtract( days => 1 ); - is( - $dt->datetime, '2003-10-26T00:00:00', - 'subtract 1 day at midnight, get midnight' - ); -} - -# date and time addition in one call is still two separate operations. -# First we do date, then time. -{ - my $dt = DateTime->new( - year => 2003, month => 4, day => 5, - time_zone => 'America/Chicago', - ); - - $dt->add( days => 1, hours => 2 ); - is( - $dt->datetime, '2003-04-06T03:00:00', - 'add one day & 2 hours from midnight, get 3 am' - ); - - # !!! - not reversible this way - needs some good docs - my $dt1 = $dt->clone->subtract( days => 1, hours => 2 ); - is( - $dt1->datetime, '2003-04-05T01:00:00', - 'subtract one day & 2 hours from 3 am, get 1 am' - ); - - # is reversible this way - also needs docs - my $dt2 = $dt->clone->subtract( hours => 2 )->subtract( days => 1 ); - is( - $dt2->datetime, '2003-04-05T00:00:00', - 'subtract 2 hours and then one day from 3 am, get midnight' - ); -} - -{ - my $dt = DateTime->new( - year => 2003, month => 10, day => 25, - time_zone => 'America/Chicago', - ); - - $dt->add( days => 1, hours => 2 ); - is( - $dt->datetime, '2003-10-26T01:00:00', - 'add one day & 2 hours from midnight, get 1 am' - ); - - my $dt1 = $dt->clone->subtract( days => 1, hours => 2 ); - is( - $dt1->datetime, '2003-10-24T23:00:00', - 'add one day & 2 hours from midnight, get 11 pm' - ); - - my $dt2 = $dt->clone->subtract( hours => 2 )->subtract( days => 1 ); - is( - $dt2->datetime, '2003-10-25T00:00:00', - 'subtract 2 hours and then one day from 3 am, get midnight' - ); -} - -# an example from the docs -{ - my $dt = DateTime->new( - year => 2003, month => 4, day => 5, - hour => 2, - time_zone => 'America/Chicago', - ); - - $dt->add( hours => 24 ); - - is( - $dt->datetime, '2003-04-06T03:00:00', - 'datetime after adding 24 hours is 2003-04-06T03:00:00' - ); -} - -done_testing(); - diff -Nru libdatetime-perl-1.21/t/release-pp-38local-subtract.t libdatetime-perl-1.46/t/release-pp-38local-subtract.t --- libdatetime-perl-1.21/t/release-pp-38local-subtract.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-38local-subtract.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,671 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -use strict; -use warnings; - -use Test::More; - -use DateTime; - -# These tests should be the final word on dt subtraction involving a -# DST-changing time zone - -{ - my $dt1 = DateTime->new( - year => 2003, month => 5, day => 6, - time_zone => 'America/Chicago', - ); - - my $dt2 = DateTime->new( - year => 2003, month => 11, day => 6, - time_zone => 'America/Chicago', - ); - - my $dur1 = $dt2->subtract_datetime($dt1); - my %deltas1 = $dur1->deltas; - is( $deltas1{months}, 6, 'delta_months is 6' ); - is( $deltas1{days}, 0, 'delta_days is 0' ); - is( $deltas1{minutes}, 0, 'delta_minutes is 0' ); - is( $deltas1{seconds}, 0, 'delta_seconds is 0' ); - - is( - DateTime->compare( $dt1->clone->add_duration($dur1), $dt2 ), 0, - 'subtract_datetime is reversible from start point' - ); - is( - DateTime->compare( $dt2->clone->subtract_duration($dur1), $dt1 ), 0, - 'subtract_datetime is reversible from end point' - ); - is( $deltas1{nanoseconds}, 0, 'delta_nanoseconds is 0' ); - - my $dur2 = $dt1->subtract_datetime($dt2); - my %deltas2 = $dur2->deltas; - is( $deltas2{months}, -6, 'delta_months is -6' ); - is( $deltas2{days}, 0, 'delta_days is 0' ); - is( $deltas2{minutes}, 0, 'delta_minutes is 0' ); - is( $deltas2{seconds}, 0, 'delta_seconds is 0' ); - is( $deltas2{nanoseconds}, 0, 'delta_nanoseconds is 0' ); - - my $dur3 = $dt2->delta_md($dt1); - my %deltas3 = $dur3->deltas; - is( $deltas3{months}, 6, 'delta_months is 6' ); - is( $deltas3{days}, 0, 'delta_days is 0' ); - is( $deltas3{minutes}, 0, 'delta_minutes is 0' ); - is( $deltas3{seconds}, 0, 'delta_seconds is 0' ); - is( $deltas3{nanoseconds}, 0, 'delta_nanoseconds is 0' ); - - is( - DateTime->compare( $dt1->clone->add_duration($dur3), $dt2 ), 0, - 'delta_md is reversible from start point' - ); - is( - DateTime->compare( $dt2->clone->subtract_duration($dur3), $dt1 ), 0, - 'delta_md is reversible from end point' - ); - - my $dur4 = $dt2->delta_days($dt1); - my %deltas4 = $dur4->deltas; - is( $deltas4{months}, 0, 'delta_months is 0' ); - is( $deltas4{days}, 184, 'delta_days is 184' ); - is( $deltas4{minutes}, 0, 'delta_minutes is 0' ); - is( $deltas4{seconds}, 0, 'delta_seconds is 0' ); - is( $deltas4{nanoseconds}, 0, 'delta_nanoseconds is 0' ); - - is( - DateTime->compare( $dt1->clone->add_duration($dur3), $dt2 ), 0, - 'delta_days is reversible from start point' - ); - is( - DateTime->compare( $dt2->clone->subtract_duration($dur4), $dt1 ), 0, - 'delta_days is reversible from end point' - ); -} - -# same as above, but now the UTC hour of the earlier datetime is -# _greater_ than that of the later one. this checks that overflows -# are handled correctly. -{ - my $dt1 = DateTime->new( - year => 2003, month => 5, day => 6, hour => 18, - time_zone => 'America/Chicago', - ); - - my $dt2 = DateTime->new( - year => 2003, month => 11, day => 6, hour => 18, - time_zone => 'America/Chicago', - ); - - my $dur1 = $dt2->subtract_datetime($dt1); - my %deltas1 = $dur1->deltas; - is( $deltas1{months}, 6, 'delta_months is 6' ); - is( $deltas1{days}, 0, 'delta_days is 0' ); - is( $deltas1{minutes}, 0, 'delta_minutes is 0' ); - is( $deltas1{seconds}, 0, 'delta_seconds is 0' ); - is( $deltas1{nanoseconds}, 0, 'delta_nanoseconds is 0' ); -} - -# make sure delta_md and delta_days work in the face of DST change -# where we lose an hour -{ - my $dt1 = DateTime->new( - year => 2003, month => 11, day => 6, - time_zone => 'America/Chicago', - ); - - my $dt2 = DateTime->new( - year => 2004, month => 5, day => 6, - time_zone => 'America/Chicago', - ); - - my $dur1 = $dt2->delta_md($dt1); - my %deltas1 = $dur1->deltas; - is( $deltas1{months}, 6, 'delta_months is 6' ); - is( $deltas1{days}, 0, 'delta_days is 0' ); - is( $deltas1{minutes}, 0, 'delta_minutes is 0' ); - is( $deltas1{seconds}, 0, 'delta_seconds is 0' ); - is( $deltas1{nanoseconds}, 0, 'delta_nanoseconds is 0' ); - - my $dur2 = $dt2->delta_days($dt1); - my %deltas2 = $dur2->deltas; - is( $deltas2{months}, 0, 'delta_months is 0' ); - is( $deltas2{days}, 182, 'delta_days is 182' ); - is( $deltas2{minutes}, 0, 'delta_minutes is 0' ); - is( $deltas2{seconds}, 0, 'delta_seconds is 0' ); - is( $deltas2{nanoseconds}, 0, 'delta_nanoseconds is 0' ); - -} - -# the docs say use UTC to guarantee reversibility -{ - my $dt1 = DateTime->new( - year => 2003, month => 5, day => 6, - time_zone => 'America/Chicago', - ); - - my $dt2 = DateTime->new( - year => 2003, month => 11, day => 6, - time_zone => 'America/Chicago', - ); - - $dt1->set_time_zone('UTC'); - $dt2->set_time_zone('UTC'); - - my $dur = $dt2->subtract_datetime($dt1); - - is( - DateTime->compare( $dt1->add_duration($dur), $dt2 ), 0, - 'subtraction is reversible from start point with UTC' - ); - is( - DateTime->compare( $dt2->subtract_duration($dur), $dt2 ), 0, - 'subtraction is reversible from start point with UTC' - ); -} - -# The important thing here is that after a subtraction, we can use the -# duration to get from one date to the other, regardless of the type -# of subtraction done. -{ - my $dt1 = DateTime->new( - year => 2003, month => 5, day => 6, - time_zone => 'America/Chicago', - ); - - my $dt2 = DateTime->new( - year => 2003, month => 11, day => 6, - time_zone => 'America/Chicago', - ); - - my $dur1 = $dt2->subtract_datetime_absolute($dt1); - - my %deltas1 = $dur1->deltas; - is( $deltas1{months}, 0, 'delta_months is 0' ); - is( $deltas1{days}, 0, 'delta_days is 0' ); - is( $deltas1{minutes}, 0, 'delta_minutes is 0' ); - is( $deltas1{seconds}, 15901200, 'delta_seconds is 15901200' ); - is( $deltas1{nanoseconds}, 0, 'delta_nanoseconds is 0' ); - - is( - DateTime->compare( $dt1->clone->add_duration($dur1), $dt2 ), 0, - 'subtraction is reversible' - ); - is( - DateTime->compare( $dt2->clone->subtract_duration($dur1), $dt1 ), 0, - 'subtraction is doubly reversible' - ); - - my $dur2 = $dt1->subtract_datetime_absolute($dt2); - - my %deltas2 = $dur2->deltas; - is( $deltas2{months}, 0, 'delta_months is 0' ); - is( $deltas2{days}, 0, 'delta_days is 0' ); - is( $deltas2{minutes}, 0, 'delta_minutes is 0' ); - is( $deltas2{seconds}, -15901200, 'delta_seconds is -15901200' ); - is( $deltas2{nanoseconds}, 0, 'delta_nanoseconds is 0' ); - - is( - DateTime->compare( $dt2->clone->add_duration($dur2), $dt1 ), 0, - 'subtraction is reversible' - ); - is( - DateTime->compare( $dt1->clone->subtract_duration($dur2), $dt2 ), 0, - 'subtraction is doubly reversible' - ); -} - -{ - my $dt1 = DateTime->new( - year => 2003, month => 4, day => 6, - hour => 1, minute => 58, - time_zone => 'America/Chicago', - ); - - my $dt2 = DateTime->new( - year => 2003, month => 4, day => 6, - hour => 3, minute => 1, - time_zone => 'America/Chicago', - ); - - my $dur = $dt2->subtract_datetime($dt1); - - my %deltas = $dur->deltas; - is( $deltas{months}, 0, 'delta_months is 0' ); - is( $deltas{days}, 0, 'delta_days is 0' ); - is( $deltas{minutes}, 3, 'delta_minutes is 3' ); - is( $deltas{seconds}, 0, 'delta_seconds is 0' ); - is( $deltas{nanoseconds}, 0, 'delta_nanoseconds is 0' ); - - is( - DateTime->compare( $dt1->clone->add_duration($dur), $dt2 ), 0, - 'subtraction is reversible' - ); - is( - DateTime->compare( $dt2->clone->subtract_duration($dur), $dt1 ), 0, - 'subtraction is doubly reversible' - ); -} - -{ - my $dt1 = DateTime->new( - year => 2003, month => 4, day => 5, - hour => 1, minute => 58, - time_zone => 'America/Chicago', - ); - - my $dt2 = DateTime->new( - year => 2003, month => 4, day => 6, - hour => 3, minute => 1, - time_zone => 'America/Chicago', - ); - - my $dur = $dt2->subtract_datetime($dt1); - - my %deltas = $dur->deltas; - is( $deltas{months}, 0, 'delta_months is 0' ); - is( $deltas{days}, 1, 'delta_days is 1' ); - is( $deltas{minutes}, 3, 'delta_minutes is 3' ); - is( $deltas{seconds}, 0, 'delta_seconds is 0' ); - is( $deltas{nanoseconds}, 0, 'delta_nanoseconds is 0' ); - - is( - DateTime->compare( $dt1->clone->add_duration($dur), $dt2 ), 0, - 'dt1 + dur = dt2' - ); - - # this are two examples from the docs - is( - DateTime->compare( - $dt2->clone->subtract_duration($dur), - $dt1->clone->add( hours => 1 ) - ), - 0, - 'dt2 - dur != dt1 (not reversible)' - ); - is( - DateTime->compare( - $dt2->clone->subtract_duration( $dur->clock_duration ) - ->subtract_duration( $dur->calendar_duration ), - $dt1 - ), - 0, - 'dt2 - dur->clock - dur->cal = dt1 (reversible when componentized)' - ); - - my $dur2 = $dt1->subtract_datetime($dt2); - my %deltas2 = $dur2->deltas; - is( $deltas2{months}, 0, 'delta_months is 0' ); - is( $deltas2{days}, -1, 'delta_days is 1' ); - is( $deltas2{minutes}, -3, 'delta_minutes is 3' ); - is( $deltas2{seconds}, 0, 'delta_seconds is 0' ); - is( $deltas2{nanoseconds}, 0, 'delta_nanoseconds is 0' ); - is( - $dt2->clone->add_duration($dur2)->datetime, '2003-04-05T02:58:00', - 'dt2 + dur2 != dt1' - ); - is( - DateTime->compare( - $dt2->clone->add_duration( $dur2->clock_duration ) - ->add_duration( $dur2->calendar_duration ), - $dt1 - ), - 0, - 'dt2 + dur2->clock + dur2->cal = dt1' - ); - is( - DateTime->compare( $dt1->clone->subtract_duration($dur2), $dt2 ), 0, - 'dt1 - dur2 = dt2' - ); - -} - -# These tests makes sure that days with DST changes are "normal" when -# they're the smaller operand -{ - my $dt1 = DateTime->new( - year => 2003, month => 4, day => 6, - hour => 3, minute => 1, - time_zone => 'America/Chicago', - ); - - my $dt2 = DateTime->new( - year => 2003, month => 4, day => 7, - hour => 3, minute => 2, - time_zone => 'America/Chicago', - ); - - my $dur = $dt2->subtract_datetime($dt1); - - my %deltas = $dur->deltas; - is( $deltas{months}, 0, 'delta_months is 0' ); - is( $deltas{days}, 1, 'delta_days is 1' ); - is( $deltas{minutes}, 1, 'delta_minutes is 1' ); - is( $deltas{seconds}, 0, 'delta_seconds is 0' ); - is( $deltas{nanoseconds}, 0, 'delta_nanoseconds is 0' ); - - my $dur2 = $dt1->subtract_datetime($dt2); - - my %deltas2 = $dur2->deltas; - is( $deltas2{months}, 0, 'delta_months is 0' ); - is( $deltas2{days}, -1, 'delta_days is -1' ); - is( $deltas2{minutes}, -1, 'delta_minutes is -1' ); - is( $deltas2{seconds}, 0, 'delta_seconds is 0' ); - is( $deltas2{nanoseconds}, 0, 'delta_nanoseconds is 0' ); - -} - -{ - my $dt1 = DateTime->new( - year => 2003, month => 4, day => 5, - hour => 1, minute => 58, - time_zone => 'America/Chicago', - ); - - my $dt2 = DateTime->new( - year => 2003, month => 4, day => 7, - hour => 2, minute => 1, - time_zone => 'America/Chicago', - ); - - my $dur = $dt2->subtract_datetime($dt1); - - my %deltas = $dur->deltas; - is( $deltas{months}, 0, 'delta_months is 0' ); - is( $deltas{days}, 2, 'delta_days is 2' ); - is( $deltas{minutes}, 3, 'delta_minutes is 3' ); - is( $deltas{seconds}, 0, 'delta_seconds is 0' ); - is( $deltas{nanoseconds}, 0, 'delta_nanoseconds is 0' ); - - is( - DateTime->compare( $dt1->clone->add_duration($dur), $dt2 ), 0, - 'subtraction is reversible' - ); - is( - DateTime->compare( $dt2->clone->subtract_duration($dur), $dt1 ), 0, - 'subtraction is doubly reversible' - ); -} - -# from example in docs -{ - my $dt1 = DateTime->new( - year => 2003, month => 5, day => 6, - time_zone => 'America/Chicago', - ); - - my $dt2 = DateTime->new( - year => 2003, month => 11, day => 6, - time_zone => 'America/Chicago', - ); - - $dt1->set_time_zone('floating'); - $dt2->set_time_zone('floating'); - - my $dur = $dt2->subtract_datetime($dt1); - my %deltas = $dur->deltas; - is( $deltas{months}, 6, 'delta_months is 6' ); - is( $deltas{days}, 0, 'delta_days is 0' ); - is( $deltas{minutes}, 0, 'delta_minutes is 0' ); - is( $deltas{seconds}, 0, 'delta_seconds is 0' ); - is( $deltas{nanoseconds}, 0, 'delta_nanoseconds is 0' ); - - is( - DateTime->compare( $dt1->clone->add_duration($dur), $dt2 ), 0, - 'subtraction is reversible from start point' - ); - is( - DateTime->compare( $dt2->clone->subtract_duration($dur), $dt1 ), 0, - 'subtraction is reversible from end point' - ); -} - -{ - my $dt1 = DateTime->new( - year => 2005, month => 8, - time_zone => 'Europe/London', - ); - - my $dt2 = DateTime->new( - year => 2005, month => 11, - time_zone => 'Europe/London', - ); - - my $dur = $dt2->subtract_datetime($dt1); - my %deltas = $dur->deltas; - is( - $deltas{months}, 3, - '3 months between two local times over DST change' - ); - is( $deltas{days}, 0, '0 days between two local times over DST change' ); - is( - $deltas{minutes}, 0, - '0 minutes between two local times over DST change' - ); -} - -# same as previous but without hours overflow -{ - my $dt1 = DateTime->new( - year => 2005, month => 8, hour => 12, - time_zone => 'Europe/London', - ); - - my $dt2 = DateTime->new( - year => 2005, month => 11, hour => 12, - time_zone => 'Europe/London', - ); - - my $dur = $dt2->subtract_datetime($dt1); - my %deltas = $dur->deltas; - is( - $deltas{months}, 3, - '3 months between two local times over DST change' - ); - is( $deltas{days}, 0, '0 days between two local times over DST change' ); - is( - $deltas{minutes}, 0, - '0 minutes between two local times over DST change' - ); -} - -# another docs example -{ - my $dt2 = DateTime->new( - year => 2003, month => 10, day => 26, - hour => 1, - time_zone => 'America/Chicago', - ); - - my $dt1 = $dt2->clone->subtract( hours => 1 ); - - my $dur = $dt2->subtract_datetime($dt1); - - my %deltas = $dur->deltas; - is( - $deltas{months}, 0, - '0 months between two local times over DST change' - ); - is( $deltas{days}, 0, '0 days between two local times over DST change' ); - is( - $deltas{minutes}, 60, - '60 minutes between two local times over DST change' - ); - - is( - DateTime->compare( $dt1->clone->add_duration($dur), $dt2 ), 0, - 'subtraction is reversible' - ); - is( - DateTime->compare( $dt2->clone->subtract_duration($dur), $dt1 ), 0, - 'subtraction is doubly reversible' - ); -} - -{ - my $dt1 = DateTime->new( - year => 2003, month => 5, day => 6, - time_zone => 'America/New_York', - ); - - my $dt2 = DateTime->new( - year => 2003, month => 5, day => 6, - time_zone => 'America/Chicago', - ); - - my $dur = $dt2->subtract_datetime($dt1); - - my %deltas = $dur->deltas; - is( - $deltas{months}, 0, - '0 months between two local times over DST change' - ); - is( $deltas{days}, 0, '0 days between two local times over DST change' ); - is( - $deltas{minutes}, 60, - '60 minutes between two local times over DST change' - ); - - is( - DateTime->compare( $dt1->clone->add_duration($dur), $dt2 ), 0, - 'subtraction is reversible' - ); - is( - DateTime->compare( $dt2->clone->subtract_duration($dur), $dt1 ), 0, - 'subtraction is doubly reversible' - ); -} - -# Fix a bug that occurred when the local time zone had DST and the two -# datetime objects were on the same day -{ - my $dt1 = DateTime->new( - year => 2005, month => 4, day => 3, - hour => 7, minute => 0, - time_zone => 'America/New_York' - ); - - my $dt2 = DateTime->new( - year => 2005, month => 4, day => 3, - hour => 8, minute => 0, - time_zone => 'America/New_York' - ); - - my $dur = $dt2->subtract_datetime($dt1); - my ( $minutes, $seconds ) = $dur->in_units( 'minutes', 'seconds' ); - - is( - $minutes, 60, - 'subtraction of two dates on a DST change date, minutes == 60' - ); - is( - $seconds, 0, - 'subtraction of two dates on a DST change date, seconds == 0' - ); - - $dur = $dt1->subtract_datetime($dt1); - ok( - $dur->is_zero, - 'dst change date (no dst) - itself, duration is zero' - ); -} - -{ - my $dt1 = DateTime->new( - year => 2005, month => 4, day => 3, - hour => 1, minute => 0, - time_zone => 'America/New_York' - ); - - my $dur = $dt1->subtract_datetime($dt1); - ok( - $dur->is_zero, - 'dst change date (with dst) - itself, duration is zero' - ); -} - -# This tests a bug where one of the datetimes is changing DST, and the -# other is not. In this case, no "adjustments" (aka hacks) are made in -# subtract_datetime, and it just gives the "UTC difference". -{ - - # This is UTC-4 - my $dt1 = DateTime->new( - year => 2009, month => 3, day => 9, - time_zone => 'America/New_York' - ); - - # This is UTC+8 - my $dt2 = DateTime->new( - year => 2009, month => 3, day => 9, - time_zone => 'Asia/Hong_Kong' - ); - - my $dur = $dt1->subtract_datetime($dt2); - - is( - $dur->delta_minutes, 720, - 'subtraction the day after a DST change in one zone, where the other datetime is in a different zone' - ); -} - -{ - - # This is UTC-5 - my $dt1 = DateTime->new( - year => 2009, month => 3, day => 8, - hour => 1, - time_zone => 'America/New_York' - ); - - # This is UTC+8 - my $dt2 = DateTime->new( - year => 2009, month => 3, day => 8, - hour => 1, - time_zone => 'Asia/Hong_Kong' - ); - - my $dur = $dt1->subtract_datetime($dt2); - - is( - $dur->delta_minutes, 780, - 'subtraction the day of a DST change in one zone (before the change),' - . ' where the other datetime is in a different zone' - ); -} - -{ - - # This is UTC-4 - my $dt1 = DateTime->new( - year => 2009, month => 3, day => 8, - hour => 4, - time_zone => 'America/New_York' - ); - - # This is UTC+8 - my $dt2 = DateTime->new( - year => 2009, month => 3, day => 8, - hour => 4, - time_zone => 'Asia/Hong_Kong' - ); - - my $dur = $dt1->subtract_datetime($dt2); - - is( - $dur->delta_minutes, 720, - 'subtraction the day of a DST change in one zone (after the change),' - . ' where the other datetime is in a different zone' - ); -} - -done_testing(); - diff -Nru libdatetime-perl-1.21/t/release-pp-40leap-years.t libdatetime-perl-1.46/t/release-pp-40leap-years.t --- libdatetime-perl-1.21/t/release-pp-40leap-years.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-40leap-years.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -use strict; -use warnings; - -use Test::More; - -use DateTime; - -for my $y ( 0, 400, 2000, 2004 ) { - ok( DateTime->_is_leap_year($y), "$y is a leap year" ); -} - -for my $y ( 1, 100, 1900, 2133 ) { - ok( !DateTime->_is_leap_year($y), "$y is not a leap year" ); -} - -done_testing(); - diff -Nru libdatetime-perl-1.21/t/release-pp-41cldr-format.t libdatetime-perl-1.46/t/release-pp-41cldr-format.t --- libdatetime-perl-1.21/t/release-pp-41cldr-format.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-41cldr-format.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,314 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -use strict; -use warnings; -use utf8; - -use Test::More; - -use DateTime; - -binmode $_, ':encoding(UTF-8)' for Test::Builder->new()->output(), - Test::Builder->new()->failure_output(), - Test::Builder->new()->todo_output(); - -{ - my $dt = DateTime->new( - year => 1976, - month => 10, - day => 20, - hour => 18, - minute => 34, - second => 55, - nanosecond => 1_000_000, - locale => 'en', - time_zone => 'America/Chicago', - ); - - my %tests = ( - 'GGGGG' => 'A', - 'GGGG' => 'Anno Domini', - 'GGG' => 'AD', - 'GG' => 'AD', - 'G' => 'AD', - - 'yyyyy' => '01976', - 'yyyy' => '1976', - 'yyy' => '1976', - 'yy' => '76', - 'y' => '1976', - - 'uuuuuu' => '001976', - 'uuuuu' => '01976', - 'uuuu' => '1976', - 'uuu' => '1976', - 'uu' => '1976', - 'u' => '1976', - - 'YYYYY' => '01976', - 'YYYY' => '1976', - 'YYY' => '1976', - 'YY' => '1976', - 'Y' => '1976', - - 'QQQQ' => '4th quarter', - 'QQQ' => 'Q4', - 'QQ' => '04', - 'Q' => '4', - - 'qqqq' => '4th quarter', - 'qqq' => 'Q4', - 'qq' => '04', - 'q' => '4', - - 'MMMMM' => 'O', - 'MMMM' => 'October', - 'MMM' => 'Oct', - 'MM' => '10', - 'M' => '10', - - 'LLLLL' => 'O', - 'LLLL' => 'October', - 'LLL' => 'Oct', - 'LL' => '10', - 'L' => '10', - - 'ww' => '43', - 'w' => '43', - 'W' => '3', - - 'dd' => '20', - 'd' => '20', - - 'DDD' => '294', - 'DD' => '294', - 'D' => '294', - - 'F' => '3', - 'gggggg' => '043071', - 'g' => '43071', - - 'EEEEE' => 'W', - 'EEEE' => 'Wednesday', - 'EEE' => 'Wed', - 'EE' => 'Wed', - 'E' => 'Wed', - - 'eeeee' => 'W', - 'eeee' => 'Wednesday', - 'eee' => 'Wed', - 'ee' => '03', - 'e' => '3', - - 'ccccc' => 'W', - 'cccc' => 'Wednesday', - 'ccc' => 'Wed', - 'cc' => '03', - 'c' => '3', - - 'a' => 'PM', - - 'hh' => '06', - 'h' => '6', - 'HH' => '18', - 'H' => '18', - 'KK' => '06', - 'K' => '6', - 'kk' => '18', - 'kk' => '18', - 'j' => '6', - 'jj' => '06', - - 'mm' => '34', - 'm' => '34', - - 'ss' => '55', - 's' => '55', - 'SS' => '00', - 'SSSSSS' => '001000', - 'A' => '66895001', - - 'zzzz' => 'America/Chicago', - 'zzz' => 'CDT', - 'ZZZZ' => 'CDT-0500', - 'ZZZ' => '-0500', - 'vvvv' => 'America/Chicago', - 'vvv' => 'CDT', - 'VVVV' => 'America/Chicago', - 'VVV' => 'CDT', - 'ZZZZZ' => '-05:00', - - q{'one fine day'} => 'one fine day', - q{'yy''yy' yyyy} => q{yy'yy 1976}, - - q{'yy''yy' 'hello' yyyy} => q{yy'yy hello 1976}, - - # Non-pattern text should pass through unchanged - 'd日' => '20日', - ); - - for my $k ( sort keys %tests ) { - is( - $dt->format_cldr($k), $tests{$k}, - "format_cldr for $k" - ); - } -} - -{ - my $dt = DateTime->new( - year => 2008, - month => 10, - day => 20, - hour => 18, - minute => 34, - second => 55, - nanosecond => 1_000_000, - locale => 'en', - time_zone => 'America/Chicago', - ); - - is( - $dt->format_cldr('yy'), '08', - 'format_cldr for yy in 2008 should be 08' - ); -} - -{ - my $dt = DateTime->new( - year => 2008, - month => 10, - day => 20, - hour => 18, - minute => 34, - second => 55, - nanosecond => 1_000_000, - locale => 'en_US', - time_zone => 'America/Chicago', - ); - - is( - $dt->format_cldr('j'), '6', - 'format_cldr for j in en_US should be 6 (at 18:34)' - ); -} - -{ - my $dt = DateTime->new( - year => 2008, - month => 10, - day => 20, - hour => 18, - minute => 34, - second => 55, - nanosecond => 1_000_000, - locale => 'fr', - time_zone => 'America/Chicago', - ); - - is( - $dt->format_cldr('j'), '18', - 'format_cldr for j in fr should be 18 (at 18:34)' - ); -} - -{ - my $dt = DateTime->new( - year => 2009, - month => 4, - day => 13, - locale => 'en_US', - ); - - is( - $dt->format_cldr('e'), '2', - 'format_cldr for e in en_US should be 2 (for Monday, 2009-04-13)' - ); - - is( - $dt->format_cldr('c'), '1', - 'format_cldr for c in en_US should be 1 (for Monday, 2009-04-13)' - ); -} - -{ - my $dt = DateTime->new( - year => 2009, - month => 4, - day => 13, - locale => 'fr_FR', - ); - - is( - $dt->format_cldr('e'), '1', - 'format_cldr for e in fr_FR should be 1 (for Monday, 2009-04-13)' - ); - - is( - $dt->format_cldr('c'), '1', - 'format_cldr for c in fr_FR should be 1 (for Monday, 2009-04-13)' - ); -} - -{ - my $dt = DateTime->new( year => -10 ); - - my %tests = ( - 'y' => '-10', - 'yy' => '-10', - 'yyy' => '-10', - 'yyyy' => '-010', - 'yyyyy' => '-0010', - - 'u' => '-10', - 'uu' => '-10', - 'uuu' => '-10', - 'uuuu' => '-010', - 'uuuuu' => '-0010', - ); - - for my $k ( sort keys %tests ) { - is( - $dt->format_cldr($k), $tests{$k}, - "format_cldr for $k" - ); - } -} - -{ - my $dt = DateTime->new( year => -1976 ); - - my %tests = ( - 'y' => '-1976', - 'yy' => '-76', - 'yyy' => '-1976', - 'yyyy' => '-1976', - 'yyyyy' => '-1976', - - 'u' => '-1976', - 'uu' => '-1976', - 'uuu' => '-1976', - 'uuuu' => '-1976', - 'uuuuu' => '-1976', - ); - - for my $k ( sort keys %tests ) { - is( - $dt->format_cldr($k), $tests{$k}, - "format_cldr for $k" - ); - } -} - -done_testing(); - diff -Nru libdatetime-perl-1.21/t/release-pp-42duration-class.t libdatetime-perl-1.46/t/release-pp-42duration-class.t --- libdatetime-perl-1.21/t/release-pp-42duration-class.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-42duration-class.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -use strict; -use warnings; - -use Test::More; -use DateTime; - -{ - - package DateTime::MySubclass; - use base 'DateTime'; - - sub duration_class {'DateTime::Duration::MySubclass'} - - package DateTime::Duration::MySubclass; - use base 'DateTime::Duration'; - - sub is_my_subclass {1} -} - -my $dt = DateTime::MySubclass->now; -my $delta = $dt - $dt; - -isa_ok( $delta, 'DateTime::Duration::MySubclass' ); -isa_ok( $dt + $delta, 'DateTime::MySubclass' ); - -my $delta_days = $dt->delta_days($dt); -isa_ok( $delta_days, 'DateTime::Duration::MySubclass' ); - -done_testing(); - diff -Nru libdatetime-perl-1.21/t/release-pp-43new-params.t libdatetime-perl-1.46/t/release-pp-43new-params.t --- libdatetime-perl-1.21/t/release-pp-43new-params.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-43new-params.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,114 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -use strict; -use warnings; - -use Test::Fatal; -use Test::More; - -use DateTime; - -like( - exception { DateTime->new( year => 10.5 ) }, - qr/is an integer/, - 'year must be an integer' -); -like( - exception { DateTime->new( year => -10.5 ) }, - qr/is an integer/, - 'year must be an integer' -); - -like( - exception { DateTime->new( year => 10, month => 2.5 ) }, - qr/an integer/, - 'month must be an integer' -); - -like( - exception { DateTime->new( year => 10, month => 2, day => 12.4 ) }, - qr/an integer/, - 'day must be an integer' -); - -like( - exception { - DateTime->new( year => 10, month => 2, day => 12, hour => 4.1 ); - }, - qr/an integer/, - 'hour must be an integer' -); - -like( - exception { - DateTime->new( - year => 10, - month => 2, - day => 12, - hour => 4, - minute => 12.2 - ); - }, - qr/an integer/, - 'minute must be an integer' -); - -like( - exception { - DateTime->new( - year => 10, - month => 2, - day => 12, - hour => 4, - minute => 12, - second => 51.8 - ); - }, - qr/an integer/, - 'second must be an integer' -); - -like( - exception { - DateTime->new( - year => 10, - month => 2, - day => 12, - hour => 4, - minute => 12, - second => 51, - nanosecond => 124512.12412 - ); - }, - qr/positive integer/, - 'nanosecond must be an integer' -); - -like( - exception { - DateTime->new( year => 10, month => 2, day => 12 )->today; - }, - qr/called with reference/, - 'today must be called as a class method, not an object method' -); - -like( - exception { - DateTime->new( year => 10, month => 2, day => 12 )->now; - }, - qr/called with reference/, - 'now must be called as a class method, not an object method' -); - -done_testing(); - diff -Nru libdatetime-perl-1.21/t/release-pp-44set-formatter.t libdatetime-perl-1.46/t/release-pp-44set-formatter.t --- libdatetime-perl-1.21/t/release-pp-44set-formatter.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-44set-formatter.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -use strict; -use warnings; - -use Test::Fatal; -use Test::More; - -use DateTime; -use overload; - -my $dt = DateTime->now; - -like( - exception { $dt->set_formatter('Invalid::Formatter') }, - qr/can format_datetime/, - 'set_format is validated' -); - -SKIP: -{ - skip 'This test requires DateTime::Format::Strptime 1.2000+', 1 - unless eval "use DateTime::Format::Strptime 1.2000"; - - my $formatter = DateTime::Format::Strptime->new( - pattern => '%Y%m%d %T', - ); - - is( - $dt->set_formatter($formatter), - $dt, - 'set_formatter returns the datetime object' - ); -} - -done_testing(); - diff -Nru libdatetime-perl-1.21/t/release-pp-45core-time.t libdatetime-perl-1.46/t/release-pp-45core-time.t --- libdatetime-perl-1.21/t/release-pp-45core-time.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-45core-time.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,32 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -use strict; -use warnings; - -use Test::More; - -use DateTime; - -no warnings 'redefine'; -local *DateTime::_core_time = sub {0}; - -my $dt = DateTime->now; - -is( - "$dt", - '1970-01-01T00:00:00', - 'overriding DateTime::_core_time() works' -); - -done_testing(); - diff -Nru libdatetime-perl-1.21/t/release-pp-46warnings.t libdatetime-perl-1.46/t/release-pp-46warnings.t --- libdatetime-perl-1.21/t/release-pp-46warnings.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-pp-46warnings.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,98 +0,0 @@ - - -use Test::More; - -BEGIN { - unless ( $ENV{RELEASE_TESTING} ) { - plan skip_all => 'these tests are for release testing'; - } - - $ENV{PERL_DATETIME_PP} = 1; -} - -use strict; -use warnings; - -use Test::More; -use Test::Warnings 0.005 ':all'; - -use DateTime; - -my $year_5001_epoch = 95649120000; - -SKIP: -{ - skip 'These tests require a 64-bit Perl', 2 - unless ( gmtime($year_5001_epoch) )[5] == 3101; - - { - like( - warning { - DateTime->from_epoch( - epoch => $year_5001_epoch, - time_zone => 'Asia/Taipei', - ); - }, - qr{\QYou are creating a DateTime object with a far future year (5001) and a time zone (Asia/Taipei).}, - 'got a warning when calling ->from_epoch with a far future epoch and a time_zone' - ); - } - - { - no warnings 'DateTime'; - is_deeply( - warning { - DateTime->from_epoch( - epoch => $year_5001_epoch, - time_zone => 'Asia/Taipei', - ); - }, - [], - 'no warning when calling ->from_epoch with a far future epoch and a time_zone with DateTime warnings category suppressed' - ); - } -} - -{ - like( - warning { - DateTime->new( - year => 5001, - time_zone => 'Asia/Taipei', - ); - }, - qr{\QYou are creating a DateTime object with a far future year (5001) and a time zone (Asia/Taipei).}, - 'got a warning when calling ->new with a far future year and a time_zone' - ); -} - -{ - no warnings 'DateTime'; - is_deeply( - warning { - DateTime->new( - year => 5001, - time_zone => 'Asia/Taipei', - ); - }, - [], - 'no warning when calling ->new with a far future epoch and a time_zone with DateTime warnings category suppressed' - ); -} - -{ - no warnings; - is_deeply( - warning { - DateTime->new( - year => 5001, - time_zone => 'Asia/Taipei', - ); - }, - [], - 'no warning when calling ->new with a far future epoch and a time_zone with all warnings suppressed' - ); -} - -done_testing(); - diff -Nru libdatetime-perl-1.21/t/release-tidyall.t libdatetime-perl-1.46/t/release-tidyall.t --- libdatetime-perl-1.21/t/release-tidyall.t 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/t/release-tidyall.t 1970-01-01 00:00:00.000000000 +0000 @@ -1,17 +0,0 @@ -#!perl - -BEGIN { - unless ($ENV{RELEASE_TESTING}) { - require Test::More; - Test::More::plan(skip_all => 'these tests are for release candidate testing'); - } -} - -# This file was automatically generated by Dist::Zilla::Plugin::Test::TidyAll - -use Test::Code::TidyAll 0.24; -use Test::More 0.88; - -tidyall_ok(); - -done_testing(); diff -Nru libdatetime-perl-1.21/t/zzz-check-breaks.t libdatetime-perl-1.46/t/zzz-check-breaks.t --- libdatetime-perl-1.21/t/zzz-check-breaks.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/t/zzz-check-breaks.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,36 @@ +use strict; +use warnings; + +# this test was generated with Dist::Zilla::Plugin::Test::CheckBreaks 0.019 + +use Test::More tests => 2; + +SKIP: { + eval { +require DateTime::Conflicts; DateTime::Conflicts->check_conflicts }; + skip('no DateTime::Conflicts module found', 1) if not $INC{'DateTime/Conflicts.pm'}; + + diag $@ if $@; + pass 'conflicts checked via DateTime::Conflicts'; +} + +# this data duplicates x_breaks in META.json +my $breaks = { + "DateTime::Format::Mail" => "<= 0.402" +}; + +use CPAN::Meta::Requirements; +use CPAN::Meta::Check 0.011; + +my $reqs = CPAN::Meta::Requirements->new; +$reqs->add_string_requirement($_, $breaks->{$_}) foreach keys %$breaks; + +our $result = CPAN::Meta::Check::check_requirements($reqs, 'conflicts'); + +if (my @breaks = grep { defined $result->{$_} } keys %$result) +{ + diag 'Breakages found with DateTime:'; + diag "$result->{$_}" for sort @breaks; + diag "\n", 'You should now update these modules!'; +} + +pass 'checked x_breaks data'; diff -Nru libdatetime-perl-1.21/tidyall.ini libdatetime-perl-1.46/tidyall.ini --- libdatetime-perl-1.21/tidyall.ini 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/tidyall.ini 2018-02-11 23:36:51.000000000 +0000 @@ -1,19 +1,36 @@ -[PerlTidy] -select = **/*.{pl,pm,t,psgi} +ignore = .build/**/* +ignore = DateTime-*/**/* +ignore = blib/**/* +ignore = inc/LeapSecondsHeader.pm +ignore = lib/DateTime/Conflicts.pm ignore = t/00-* ignore = t/author-* ignore = t/release-* -ignore = blib/**/* -ignore = .build/**/* -ignore = DateTime-*/**/* +ignore = t/zzz-* +ignore = xt/**/* + +[PerlCritic] +select = **/*.{pl,pm,t,psgi} +argv = --profile=$ROOT/perlcriticrc + +[PerlCritic non-auto-generated xt] +select = xt/author/pp-is-loaded.t +select = xt/author/test-all-my-deps.t +select = xt/author/xs-is-loaded.t +argv = --profile=$ROOT/perlcriticrc + +[PerlTidy] +select = **/*.{pl,pm,t,psgi} +argv = --profile=$ROOT/perltidyrc + +[PerlTidy non-auto-generated xt] +select = xt/author/pp-is-loaded.t +select = xt/author/test-all-my-deps.t +select = xt/author/xs-is-loaded.t argv = --profile=$ROOT/perltidyrc -; [PerlCritic] -; select = **/*.{pl,pm,t,psgi} -; ignore = t/00-* -; ignore = t/author-* -; ignore = t/release-* -; ignore = blib/**/* -; ignore = .build/**/* -; ignore = DateTime-*/**/* -; argv = --profile $ROOT/perlcriticrc --program-extensions .pl --program-extensions .t --program-extensions .psgi +[SortLines::Naturally] +select = .stopwords + +[Test::Vars] +select = **/*.pm diff -Nru libdatetime-perl-1.21/tools/leap_seconds_header.pl libdatetime-perl-1.46/tools/leap_seconds_header.pl --- libdatetime-perl-1.21/tools/leap_seconds_header.pl 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/tools/leap_seconds_header.pl 1970-01-01 00:00:00.000000000 +0000 @@ -1,178 +0,0 @@ -#!/usr/bin/env perl - -use strict; -use warnings; -use autodie; - -use lib './lib'; - -my $VERSION = 0.03; - -my $leap = shift || './leaptab.txt'; - -my $x = 1; -my %months = map { $_ => $x++ } - qw( Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec ); - -my @LeapSeconds; -my @RD; -my %RDLength; - -build_data_structures(); -write_header(); - -sub build_data_structures { - open my $fh, '<', $leap; - - my $value = -1; - while (<$fh>) { - my ( $year, $mon, $day, $leap_seconds ) = split /\s+/; - - $mon =~ s/\W//; - - $leap_seconds =~ s/^([+-])//; - my $mult = $1 eq '+' ? 1 : -1; - - my $utc_epoch = _ymd2rd( $year, $months{$mon}, $day ); - - $value += $leap_seconds * $mult; - - push @LeapSeconds, $value; - push @RD, $utc_epoch; - - $RDLength{ $utc_epoch - 1 } = $leap_seconds; - } - - close $fh; - - push @LeapSeconds, ++$value; -} - -sub write_header { - my $set_leap_seconds = <<"EOF"; - -#define SET_LEAP_SECONDS(utc_rd, ls) \\ -{ \\ - { \\ - if (utc_rd < $RD[0]) { \\ - ls = $LeapSeconds[0]; \\ -EOF - - for ( my $x = 1; $x < @RD; $x++ ) { - my $else = $x == 1 ? '' : 'else '; - - my $condition - = $x == @RD - ? "utc_rd < $RD[$x]" - : "utc_rd >= $RD[$x - 1] && utc_rd < $RD[$x]"; - - $set_leap_seconds .= <<"EOF" - } else if ($condition) { \\ - ls = $LeapSeconds[$x]; \\ -EOF - } - - $set_leap_seconds .= <<"EOF"; - } else { \\ - ls = $LeapSeconds[-1]; \\ - } \\ - } \\ -} -EOF - - my $set_extra_seconds = <<"EOF"; - -#define SET_EXTRA_SECONDS(utc_rd, es) \\ -{ \\ - { \\ - es = 0; \\ - switch (utc_rd) { \\ -EOF - - my $set_day_length = <<"EOF"; - -#define SET_DAY_LENGTH(utc_rd, dl) \\ -{ \\ - { \\ - dl = 86400; \\ - switch (utc_rd) { \\ -EOF - - foreach my $utc_rd ( sort keys %RDLength ) { - $set_extra_seconds .= <<"EOF"; - case $utc_rd: es = $RDLength{$utc_rd}; break; \\ -EOF - - $set_day_length .= <<"EOF"; - case $utc_rd: dl = 86400 + $RDLength{$utc_rd}; break; \\ -EOF - } - - $set_extra_seconds .= <<"EOF"; - } \\ - } \\ -} -EOF - - $set_day_length .= <<"EOF"; - } \\ - } \\ -} -EOF - - my $header = <<"EOF"; -/* This file is auto-generated by the leap second code generator - ($VERSION). This code generator comes with the DateTime.pm module - distribution in the tools/ directory - - Generated by $0. - - Do not edit this file directly. -*/ -EOF - - open my $fh, '>', 'c/leap_seconds.h'; - - print $fh ( - $header, - $set_leap_seconds, - $set_extra_seconds, - $set_day_length, - ); -} - -# from lib/DateTimePP.pm -sub _ymd2rd { - use integer; - my ( $y, $m, $d ) = @_; - my $adj; - - # make month in range 3..14 (treat Jan & Feb as months 13..14 of - # prev year) - if ( $m <= 2 ) { - $y -= ( $adj = ( 14 - $m ) / 12 ); - $m += 12 * $adj; - } - elsif ( $m > 14 ) { - $y += ( $adj = ( $m - 3 ) / 12 ); - $m -= 12 * $adj; - } - - # make year positive (oh, for a use integer 'sane_div'!) - if ( $y < 0 ) { - $d -= 146097 * ( $adj = ( 399 - $y ) / 400 ); - $y += 400 * $adj; - } - - # add: day of month, days of previous 0-11 month period that began - # w/March, days of previous 0-399 year period that began w/March - # of a 400-multiple year), days of any 400-year periods before - # that, and 306 days to adjust from Mar 1, year 0-relative to Jan - # 1, year 1-relative (whew) - - $d - += ( $m * 367 - 1094 ) / 12 - + $y % 100 * 1461 / 4 - + ( $y / 100 * 36524 + $y / 400 ) - - 306; -} diff -Nru libdatetime-perl-1.21/weaver.ini libdatetime-perl-1.46/weaver.ini --- libdatetime-perl-1.21/weaver.ini 2015-09-30 19:46:57.000000000 +0000 +++ libdatetime-perl-1.46/weaver.ini 1970-01-01 00:00:00.000000000 +0000 @@ -1,17 +0,0 @@ -[@CorePrep] - -[Name] -[Version] - -[Region / prelude] - -[Generic / SYNOPSIS] -[Generic / DESCRIPTION] - -[Leftovers] - -[Region / postlude] - -[Authors] -[Contributors] -[Legal] diff -Nru libdatetime-perl-1.21/xt/author/clean-namespaces.t libdatetime-perl-1.46/xt/author/clean-namespaces.t --- libdatetime-perl-1.21/xt/author/clean-namespaces.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/clean-namespaces.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,16 @@ +use strict; +use warnings; + +# this test was generated with Dist::Zilla::Plugin::Test::CleanNamespaces 0.006 + +use Test::More 0.94; +use Test::CleanNamespaces 0.15; + +subtest all_namespaces_clean => sub { + namespaces_clean( + grep { my $mod = $_; not grep { $mod =~ $_ } qr/DateTime::Conflicts/ } + Test::CleanNamespaces->find_modules + ); +}; + +done_testing; diff -Nru libdatetime-perl-1.21/xt/author/eol.t libdatetime-perl-1.46/xt/author/eol.t --- libdatetime-perl-1.21/xt/author/eol.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/eol.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,73 @@ +use strict; +use warnings; + +# this test was generated with Dist::Zilla::Plugin::Test::EOL 0.19 + +use Test::More 0.88; +use Test::EOL; + +my @files = ( + 'lib/DateTime.pm', + 'lib/DateTime/Conflicts.pm', + 'lib/DateTime/Duration.pm', + 'lib/DateTime/Helpers.pm', + 'lib/DateTime/Infinite.pm', + 'lib/DateTime/LeapSecond.pm', + 'lib/DateTime/PP.pm', + 'lib/DateTime/PPExtra.pm', + 'lib/DateTime/Types.pm', + 't/00-report-prereqs.dd', + 't/00-report-prereqs.t', + 't/00load.t', + 't/01sanity.t', + 't/02last-day.t', + 't/03components.t', + 't/04epoch.t', + 't/05set.t', + 't/06add.t', + 't/07compare.t', + 't/09greg.t', + 't/10subtract.t', + 't/11duration.t', + 't/12week.t', + 't/13strftime.t', + 't/14locale.t', + 't/15jd.t', + 't/16truncate.t', + 't/17set-return.t', + 't/18today.t', + 't/19leap-second.t', + 't/20infinite.t', + 't/21bad-params.t', + 't/22from-doy.t', + 't/23storable.t', + 't/24from-object.t', + 't/25add-subtract.t', + 't/26dt-leapsecond-pm.t', + 't/27delta.t', + 't/28dow.t', + 't/29overload.t', + 't/30future-tz.t', + 't/31formatter.t', + 't/32leap-second2.t', + 't/33seconds-offset.t', + 't/34set-tz.t', + 't/35rd-values.t', + 't/36invalid-local.t', + 't/37local-add.t', + 't/38local-subtract.t', + 't/39no-so.t', + 't/40leap-years.t', + 't/41cldr-format.t', + 't/42duration-class.t', + 't/43new-params.t', + 't/44set-formatter.t', + 't/45core-time.t', + 't/46warnings.t', + 't/47default-time-zone.t', + 't/48rt-115983.t', + 't/zzz-check-breaks.t' +); + +eol_unix_ok($_, { trailing_whitespace => 1 }) foreach @files; +done_testing; diff -Nru libdatetime-perl-1.21/xt/author/mojibake.t libdatetime-perl-1.46/xt/author/mojibake.t --- libdatetime-perl-1.21/xt/author/mojibake.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/mojibake.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,9 @@ +#!perl + +use strict; +use warnings qw(all); + +use Test::More; +use Test::Mojibake; + +all_files_encoding_ok(); diff -Nru libdatetime-perl-1.21/xt/author/no-tabs.t libdatetime-perl-1.46/xt/author/no-tabs.t --- libdatetime-perl-1.21/xt/author/no-tabs.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/no-tabs.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,73 @@ +use strict; +use warnings; + +# this test was generated with Dist::Zilla::Plugin::Test::NoTabs 0.15 + +use Test::More 0.88; +use Test::NoTabs; + +my @files = ( + 'lib/DateTime.pm', + 'lib/DateTime/Conflicts.pm', + 'lib/DateTime/Duration.pm', + 'lib/DateTime/Helpers.pm', + 'lib/DateTime/Infinite.pm', + 'lib/DateTime/LeapSecond.pm', + 'lib/DateTime/PP.pm', + 'lib/DateTime/PPExtra.pm', + 'lib/DateTime/Types.pm', + 't/00-report-prereqs.dd', + 't/00-report-prereqs.t', + 't/00load.t', + 't/01sanity.t', + 't/02last-day.t', + 't/03components.t', + 't/04epoch.t', + 't/05set.t', + 't/06add.t', + 't/07compare.t', + 't/09greg.t', + 't/10subtract.t', + 't/11duration.t', + 't/12week.t', + 't/13strftime.t', + 't/14locale.t', + 't/15jd.t', + 't/16truncate.t', + 't/17set-return.t', + 't/18today.t', + 't/19leap-second.t', + 't/20infinite.t', + 't/21bad-params.t', + 't/22from-doy.t', + 't/23storable.t', + 't/24from-object.t', + 't/25add-subtract.t', + 't/26dt-leapsecond-pm.t', + 't/27delta.t', + 't/28dow.t', + 't/29overload.t', + 't/30future-tz.t', + 't/31formatter.t', + 't/32leap-second2.t', + 't/33seconds-offset.t', + 't/34set-tz.t', + 't/35rd-values.t', + 't/36invalid-local.t', + 't/37local-add.t', + 't/38local-subtract.t', + 't/39no-so.t', + 't/40leap-years.t', + 't/41cldr-format.t', + 't/42duration-class.t', + 't/43new-params.t', + 't/44set-formatter.t', + 't/45core-time.t', + 't/46warnings.t', + 't/47default-time-zone.t', + 't/48rt-115983.t', + 't/zzz-check-breaks.t' +); + +notabs_ok($_) foreach @files; +done_testing; diff -Nru libdatetime-perl-1.21/xt/author/pod-coverage.t libdatetime-perl-1.46/xt/author/pod-coverage.t --- libdatetime-perl-1.21/xt/author/pod-coverage.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pod-coverage.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,72 @@ +#!perl +# This file was automatically generated by Dist::Zilla::Plugin::Test::Pod::Coverage::Configurable 0.07. + +use Test::Pod::Coverage 1.08; +use Test::More 0.88; + +BEGIN { + if ( $] <= 5.008008 ) { + plan skip_all => 'These tests require Pod::Coverage::TrustPod, which only works with Perl 5.8.9+'; + } +} +use Pod::Coverage::TrustPod; + +my %skip = map { $_ => 1 } qw( DateTime::Conflicts DateTime::Helpers DateTime::PP DateTime::PPExtra ); + +my @modules; +for my $module ( all_modules() ) { + next if $skip{$module}; + + push @modules, $module; +} + +plan skip_all => 'All the modules we found were excluded from POD coverage test.' + unless @modules; + +plan tests => scalar @modules; + +my %trustme = ( + 'DateTime' => [ + qr/^[A-Z_]+$/, + qr/0$/, + qr/^STORABLE/, + qr/^utc_year$/, + qr/^timegm$/, + qr/^day_of_month$/, + qr/^doq$/, + qr/^dow$/, + qr/^doy$/, + qr/^iso8601$/, + qr/^local_rd_as_seconds$/, + qr/^mday$/, + qr/^min$/, + qr/^mon$/, + qr/^sec$/, + qr/^wday$/, + qr/^DefaultLanguage$/, + qr/^era$/, + qr/^language$/ + ], + 'DateTime::Duration' => [ + qr/^[A-Z_]+$/ + ], + 'DateTime::Infinite' => [ + qr/^.+$/ + ] + ); + +my @also_private; + +for my $module ( sort @modules ) { + pod_coverage_ok( + $module, + { + coverage_class => 'Pod::Coverage::TrustPod', + also_private => \@also_private, + trustme => $trustme{$module} || [], + }, + "pod coverage for $module" + ); +} + +done_testing(); diff -Nru libdatetime-perl-1.21/xt/author/pod-spell.t libdatetime-perl-1.46/xt/author/pod-spell.t --- libdatetime-perl-1.21/xt/author/pod-spell.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pod-spell.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,187 @@ +use strict; +use warnings; +use Test::More; + +# generated by Dist::Zilla::Plugin::Test::PodSpelling 2.007005 +use Test::Spelling 0.12; +use Pod::Wordlist; + + +add_stopwords(); +all_pod_files_spelling_ok( qw( bin lib ) ); +__DATA__ +1nickt +Alders +Anno +BCE +Bell +Ben +Bennett +BooK +Book +Bowen +Bruhat +CLDR +CPAN +Ceccarelli +Christian +Conflicts +Conrad +DATETIME +DROLSKY +DROLSKY's +Daisuke +Dan +DateTime +DateTimes +Datetime +Datetimes +Dave +David +Davis +Domini +Doug +Duration +EEEE +EEEEE +Etheridge +Flávio +Formatters +GGGG +GGGGG +Gianni +Glock +Gregory +Hansen +Hant +Hauke +Helpers +Hill +Hoblitt +IEEE +Iain +Infinite +Jason +Joshua +Karen +Kington +LLL +LLLL +LLLLL +LeapSecond +Liang +Liang's +MMM +MMMM +MMMMM +Maki +McIntosh +Measham +Measham's +Michael +Nick +Olaf +Oschwald +Ovid +POSIX +PP +PPExtra +PayPal +Philippe +Precious +QQQ +QQQQ +Rata +Ricardo +Richard +Rolsky +Rolsky's +Ron +SU +Sam +Signes +Soibelmann +Somerville +Stewart +Storable +TW +TZ +Tonkin +Truskett +Tsai +Types +UTC +VVVV +Wheeler +YAPCs +ZZZZ +ZZZZZ +afterwards +autarch +bian +book +bowen +ccc +cccc +ccccc +chansen +conformant +curtis_ovid_poe +danielandrewstewart +datetime +datetime's +datetimes +david +davidp +deceased +decrement +dian +dmaki +dracos +drolsky +durations +eee +eeee +eeeee +ether +fallback +fglock +fiji +formatter +gianni +github +grinnz +haukex +hh +iCal +jhoblitt +ji +jmac +lib +madcityzen +mike +mrdvt92 +mutiplication +na +namespace +ni +nitty +olaf +oschwald +other's +proleptic +qqq +qqqq +rjbs +rkhill +sexagesimal +subclasses +uu +viviparous +vvvv +wiki +yy +yyyy +yyyyy +zh +zzzz diff -Nru libdatetime-perl-1.21/xt/author/pod-syntax.t libdatetime-perl-1.46/xt/author/pod-syntax.t --- libdatetime-perl-1.21/xt/author/pod-syntax.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pod-syntax.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,7 @@ +#!perl +# This file was automatically generated by Dist::Zilla::Plugin::PodSyntaxTests. +use strict; use warnings; +use Test::More; +use Test::Pod 1.41; + +all_pod_files_ok(); diff -Nru libdatetime-perl-1.21/xt/author/portability.t libdatetime-perl-1.46/xt/author/portability.t --- libdatetime-perl-1.21/xt/author/portability.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/portability.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,10 @@ +use strict; +use warnings; + +use Test::More; + +eval 'use Test::Portability::Files'; +plan skip_all => 'Test::Portability::Files required for testing portability' + if $@; + +run_tests(); diff -Nru libdatetime-perl-1.21/xt/author/pp-00load.t libdatetime-perl-1.46/xt/author/pp-00load.t --- libdatetime-perl-1.21/xt/author/pp-00load.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-00load.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,13 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +use strict; +use warnings; + +use Test::More 0.88; + +use_ok('DateTime'); + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-01sanity.t libdatetime-perl-1.46/xt/author/pp-01sanity.t --- libdatetime-perl-1.21/xt/author/pp-01sanity.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-01sanity.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,49 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +use strict; +use warnings; + +use Test::More; + +use DateTime; + +{ + my $dt = DateTime->new( + year => 1870, month => 10, day => 21, + hour => 12, minute => 10, second => 45, + nanosecond => 123456, + time_zone => 'UTC' + ); + + is( $dt->year, '1870', 'Year accessor, outside of the epoch' ); + is( $dt->month, '10', 'Month accessor, outside the epoch' ); + is( $dt->day, '21', 'Day accessor, outside the epoch' ); + is( $dt->hour, '12', 'Hour accessor, outside the epoch' ); + is( $dt->minute, '10', 'Minute accessor, outside the epoch' ); + is( $dt->second, '45', 'Second accessor, outside the epoch' ); + is( $dt->nanosecond, '123456', 'nanosecond accessor, outside the epoch' ); + + $dt = DateTime->from_object( object => $dt ); + is( $dt->year, '1870', 'Year should be identical' ); + is( $dt->month, '10', 'Month should be identical' ); + is( $dt->day, '21', 'Day should be identical' ); + is( $dt->hour, '12', 'Hour should be identical' ); + is( $dt->minute, '10', 'Minute should be identical' ); + is( $dt->second, '45', 'Second should be identical' ); + is( $dt->nanosecond, '123456', 'nanosecond should be identical' ); +} + +{ + my $dt = DateTime->new( + year => 1870, month => 10, day => 21, + hour => 12, minute => 10, second => 45, + time_zone => 'UTC' + ); + is( $dt->minute, '10', 'Minute accessor, outside the epoch' ); + is( $dt->second, '45', 'Second accessor, outside the epoch' ); +} + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-02last-day.t libdatetime-perl-1.46/xt/author/pp-02last-day.t --- libdatetime-perl-1.21/xt/author/pp-02last-day.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-02last-day.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,55 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +use strict; +use warnings; + +use Test::Fatal; +use Test::More; + +use DateTime; + +my @last_day = ( 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ); +my @leap_last_day = @last_day; +$leap_last_day[1]++; + +foreach my $month ( 1 .. 12 ) { + my $dt = DateTime->last_day_of_month( + year => 2001, + month => $month, + time_zone => 'UTC', + ); + + is( $dt->year, 2001, 'check year' ); + is( $dt->month, $month, 'check month' ); + is( $dt->day, $last_day[ $month - 1 ], 'check day' ); +} + +foreach my $month ( 1 .. 12 ) { + my $dt = DateTime->last_day_of_month( + year => 2004, + month => $month, + time_zone => 'UTC', + ); + + is( $dt->year, 2004, 'check year' ); + is( $dt->month, $month, 'check month' ); + is( $dt->day, $leap_last_day[ $month - 1 ], 'check day' ); +} + +{ + is( + exception { + DateTime->last_day_of_month( + year => 2000, month => 1, + nanosecond => 2000 + ); + }, + undef, + 'last_day_of_month should accept nanosecond' + ); +} + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-03components.t libdatetime-perl-1.46/xt/author/pp-03components.t --- libdatetime-perl-1.21/xt/author/pp-03components.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-03components.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,460 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +use strict; +use warnings; + +use Test::More; + +use DateTime; +{ + my $d = DateTime->new( + year => 2001, + month => 7, + day => 5, + hour => 2, + minute => 12, + second => 50, + time_zone => 'UTC', + ); + + is( $d->year, 2001, '->year' ); + is( $d->ce_year, 2001, '->ce_year' ); + is( $d->month, 7, '->month' ); + is( $d->quarter, 3, '->quarter' ); + is( $d->month_0, 6, '->month_0' ); + is( $d->month_name, 'July', '->month_name' ); + is( $d->month_abbr, 'Jul', '->month_abbr' ); + is( $d->day_of_month, 5, '->day_of_month' ); + is( $d->day_of_month_0, 4, '->day_of_month_0' ); + is( $d->day, 5, '->day' ); + is( $d->day_0, 4, '->day_0' ); + is( $d->mday, 5, '->mday' ); + is( $d->mday_0, 4, '->mday_0' ); + is( $d->mday, 5, '->mday' ); + is( $d->mday_0, 4, '->mday_0' ); + is( $d->hour, 2, '->hour' ); + is( $d->hour_1, 2, '->hour_1' ); + is( $d->hour_12, 2, '->hour_12' ); + is( $d->hour_12_0, 2, '->hour_12_0' ); + is( $d->minute, 12, '->minute' ); + is( $d->min, 12, '->min' ); + is( $d->second, 50, '->second' ); + is( $d->sec, 50, '->sec' ); + + is( $d->day_of_year, 186, '->day_of_year' ); + is( $d->day_of_year_0, 185, '->day_of_year' ); + is( $d->day_of_quarter, 5, '->day_of_quarter' ); + is( $d->doq, 5, '->doq' ); + is( $d->day_of_quarter_0, 4, '->day_of_quarter_0' ); + is( $d->doq_0, 4, '->doq_0' ); + is( $d->day_of_week, 4, '->day_of_week' ); + is( $d->day_of_week_0, 3, '->day_of_week_0' ); + is( $d->week_of_month, 1, '->week_of_month' ); + is( $d->weekday_of_month, 1, '->weekday_of_month' ); + is( $d->wday, 4, '->wday' ); + is( $d->wday_0, 3, '->wday_0' ); + is( $d->dow, 4, '->dow' ); + is( $d->dow_0, 3, '->dow_0' ); + is( $d->day_name, 'Thursday', '->day_name' ); + is( $d->day_abbr, 'Thu', '->day_abrr' ); + + is( $d->ymd, '2001-07-05', '->ymd' ); + is( $d->ymd('!'), '2001!07!05', q{->ymd('!')} ); + is( $d->date, '2001-07-05', '->date' ); + is( $d->date('!'), '2001!07!05', q{->date('!')} ); + + is( $d->mdy, '07-05-2001', '->mdy' ); + is( $d->mdy('!'), '07!05!2001', q{->mdy('!')} ); + + is( $d->dmy, '05-07-2001', '->dmy' ); + is( $d->dmy('!'), '05!07!2001', q{->dmy('!')} ); + + is( $d->hms, '02:12:50', '->hms' ); + is( $d->hms('!'), '02!12!50', q{->hms('!')} ); + is( $d->time, '02:12:50', '->hms' ); + is( $d->time('!'), '02!12!50', q{->time('!')} ); + + is( $d->datetime, '2001-07-05T02:12:50', '->datetime' ); + is( $d->datetime(q{ }), '2001-07-05 02:12:50', q{->datetime(q{ }} ); + is( $d->iso8601, '2001-07-05T02:12:50', '->iso8601' ); + is( + $d->iso8601(q{ }), '2001-07-05T02:12:50', + '->iso8601 ignores arguments' + ); + + ok( !$d->is_leap_year, '->is_leap_year' ); + ok( !$d->is_last_day_of_month, '->is_last_day_of_month' ); + + is( $d->month_length, 31, '->month_length' ); + is( $d->quarter_length, 92, '->quarter_length' ); + is( $d->year_length, 365, '->year_length' ); + + is( $d->era_abbr, 'AD', '->era_abbr' ); + is( $d->era, $d->era_abbr, '->era (deprecated)' ); + is( $d->era_name, 'Anno Domini', '->era_abbr' ); + + is( $d->quarter_abbr, 'Q3', '->quarter_abbr' ); + is( $d->quarter_name, '3rd quarter', '->quarter_name' ); +} + +{ + my $leap_d = DateTime->new( + year => 2004, + month => 7, + day => 5, + hour => 2, + minute => 12, + second => 50, + time_zone => 'UTC', + ); + + ok( $leap_d->is_leap_year, '->is_leap_year' ); + is( $leap_d->year_length, 366, '->year_length' ); +} + +{ + my @tests = ( + { year => 2017, month => 8, day => 19, expect => 0 }, + { year => 2017, month => 8, day => 31, expect => 1 }, + { year => 2017, month => 2, day => 28, expect => 1 }, + { year => 2016, month => 2, day => 28, expect => 0 }, + ); + + for my $t (@tests) { + my $expect = delete $t->{expect}; + + my $dt = DateTime->new($t); + + my $is = $dt->is_last_day_of_month; + ok( ( $expect ? $is : !$is ), '->is_last_day_of_month' ); + } +} + +{ + my @tests = ( + { year => 2016, month => 2, day => 1, expect => 29 }, + { year => 2017, month => 2, day => 1, expect => 28 }, + ); + + for my $t (@tests) { + my $expect = delete $t->{expect}; + + my $dt = DateTime->new($t); + is( $dt->month_length, $expect, '->month_length' ); + } +} + +{ + my $sunday = DateTime->new( + year => 2003, + month => 1, + day => 26, + time_zone => 'UTC', + ); + + is( $sunday->day_of_week, 7, 'Sunday is day 7' ); +} + +{ + my $monday = DateTime->new( + year => 2003, + month => 1, + day => 27, + time_zone => 'UTC', + ); + + is( $monday->day_of_week, 1, 'Monday is day 1' ); +} + +{ + # time zone offset should not affect the values returned + my $d = DateTime->new( + year => 2001, + month => 7, + day => 5, + hour => 2, + minute => 12, + second => 50, + time_zone => '-0124', + ); + + is( $d->year, 2001, '->year' ); + is( $d->ce_year, 2001, '->ce_year' ); + is( $d->month, 7, '->month' ); + is( $d->day_of_month, 5, '->day_of_month' ); + is( $d->hour, 2, '->hour' ); + is( $d->hour_1, 2, '->hour_1' ); + is( $d->minute, 12, '->minute' ); + is( $d->second, 50, '->second' ); +} + +{ + my $dt0 = DateTime->new( year => 1, time_zone => 'UTC' ); + + is( $dt0->year, 1, 'year 1 is year 1' ); + is( $dt0->ce_year, 1, 'ce_year 1 is year 1' ); + is( $dt0->era_abbr, 'AD', 'era is AD' ); + is( $dt0->year_with_era, '1AD', 'year_with_era is 1AD' ); + is( $dt0->christian_era, 'AD', 'christian_era is AD' ); + is( + $dt0->year_with_christian_era, '1AD', + 'year_with_christian_era is 1AD' + ); + is( $dt0->secular_era, 'CE', 'secular_era is CE' ); + is( $dt0->year_with_secular_era, '1CE', 'year_with_secular_era is 1CE' ); + + $dt0->subtract( years => 1 ); + + is( $dt0->year, 0, 'year 1 minus 1 is year 0' ); + is( $dt0->ce_year, -1, 'ce_year 1 minus 1 is year -1' ); + is( $dt0->era_abbr, 'BC', 'era is BC' ); + is( $dt0->year_with_era, '1BC', 'year_with_era is 1BC' ); + is( $dt0->christian_era, 'BC', 'christian_era is BC' ); + is( + $dt0->year_with_christian_era, '1BC', + 'year_with_christian_era is 1BC' + ); + is( $dt0->secular_era, 'BCE', 'secular_era is BCE' ); + is( + $dt0->year_with_secular_era, '1BCE', + 'year_with_secular_era is 1BCE' + ); +} + +{ + my $dt_neg = DateTime->new( year => -10, time_zone => 'UTC', ); + is( $dt_neg->year, -10, 'Year -10 is -10' ); + is( $dt_neg->ce_year, -11, 'year -10 is ce_year -11' ); + + my $dt1 = $dt_neg + DateTime::Duration->new( years => 10 ); + is( $dt1->year, 0, 'year is 0 after adding ten years to year -10' ); + is( + $dt1->ce_year, -1, + 'ce_year is -1 after adding ten years to year -10' + ); +} + +{ + my $dt = DateTime->new( + year => 50, month => 2, + hour => 3, minute => 20, second => 5, + time_zone => 'UTC', + ); + + is( $dt->ymd('%s'), '0050%s02%s01', 'use %s as separator in ymd' ); + is( $dt->mdy('%s'), '02%s01%s0050', 'use %s as separator in mdy' ); + is( $dt->dmy('%s'), '01%s02%s0050', 'use %s as separator in dmy' ); + + is( $dt->hms('%s'), '03%s20%s05', 'use %s as separator in hms' ); +} + +# test doy in leap year +{ + my $dt = DateTime->new( + year => 2000, month => 1, day => 5, + time_zone => 'UTC', + ); + + is( $dt->day_of_year, 5, 'doy for 2000-01-05 should be 5' ); + is( $dt->day_of_year_0, 4, 'doy_0 for 2000-01-05 should be 4' ); +} + +{ + my $dt = DateTime->new( + year => 2000, month => 2, day => 29, + time_zone => 'UTC', + ); + + is( $dt->day_of_year, 60, 'doy for 2000-02-29 should be 60' ); + is( $dt->day_of_year_0, 59, 'doy_0 for 2000-02-29 should be 59' ); +} + +{ + my $dt = DateTime->new( + year => -6, month => 2, day => 25, + time_zone => 'UTC', + ); + + is( $dt->ymd, '-0006-02-25', 'ymd is -0006-02-25' ); + is( + $dt->iso8601, '-0006-02-25T00:00:00', + 'iso8601 is -0005-02-25T00:00:00' + ); + is( $dt->year, -6, 'year is -6' ); + is( $dt->ce_year, -7, 'ce_year is -7' ); +} + +{ + my $dt = DateTime->new( year => 1995, month => 2, day => 1 ); + + is( $dt->quarter, 1, '->quarter is 1' ); + is( $dt->day_of_quarter, 32, '->day_of_quarter' ); + is( $dt->quarter_length, 90, '->quarter_length' ); +} + +{ + my $dt = DateTime->new( year => 1995, month => 5, day => 1 ); + + is( $dt->quarter, 2, '->quarter is 2' ); + is( $dt->day_of_quarter, 31, '->day_of_quarter' ); + is( $dt->quarter_length, 91, '->quarter_length' ); +} + +{ + my $dt = DateTime->new( year => 1995, month => 8, day => 1 ); + + is( $dt->quarter, 3, '->quarter is 3' ); + is( $dt->day_of_quarter, 32, '->day_of_quarter' ); + is( $dt->quarter_length, 92, '->quarter_length' ); +} + +{ + my $dt = DateTime->new( year => 1995, month => 11, day => 1 ); + + is( $dt->quarter, 4, '->quarter is 4' ); + is( $dt->day_of_quarter, 32, '->day_of_quarter' ); + is( $dt->quarter_length, 92, '->quarter_length' ); +} + +{ + my $dt = DateTime->new( year => 1996, month => 2, day => 1 ); + + is( $dt->quarter, 1, '->quarter is 1' ); + is( $dt->day_of_quarter, 32, '->day_of_quarter' ); + is( $dt->quarter_length, 91, '->quarter_length' ); +} + +{ + my $dt = DateTime->new( year => 1996, month => 5, day => 1 ); + + is( $dt->quarter, 2, '->quarter is 2' ); + is( $dt->day_of_quarter, 31, '->day_of_quarter' ); + is( $dt->quarter_length, 91, '->quarter_length' ); +} + +{ + my $dt = DateTime->new( year => 1996, month => 8, day => 1 ); + + is( $dt->quarter, 3, '->quarter is 3' ); + is( $dt->day_of_quarter, 32, '->day_of_quarter' ); + is( $dt->quarter_length, 92, '->quarter_length' ); +} + +{ + my $dt = DateTime->new( year => 1996, month => 11, day => 1 ); + + is( $dt->quarter, 4, '->quarter is 4' ); + is( $dt->day_of_quarter, 32, '->day_of_quarter' ); + is( $dt->quarter_length, 92, '->quarter_length' ); +} + +# nano, micro, and milli seconds +{ + my $dt = DateTime->new( year => 1996, nanosecond => 500_000_000 ); + + is( $dt->nanosecond, 500_000_000, 'nanosecond is 500,000,000' ); + is( $dt->microsecond, 500_000, 'microsecond is 500,000' ); + is( $dt->millisecond, 500, 'millisecond is 500' ); + + $dt->set( nanosecond => 500_000_500 ); + + is( $dt->nanosecond, 500_000_500, 'nanosecond is 500,000,500' ); + is( $dt->microsecond, 500_000, 'microsecond is 500,000' ); + is( $dt->millisecond, 500, 'millisecond is 500' ); + + $dt->set( nanosecond => 499_999_999 ); + + is( $dt->nanosecond, 499_999_999, 'nanosecond is 499,999,999' ); + is( $dt->microsecond, 499_999, 'microsecond is 499,999' ); + is( $dt->millisecond, 499, 'millisecond is 499' ); + + $dt->set( nanosecond => 450_000_001 ); + + is( $dt->nanosecond, 450_000_001, 'nanosecond is 450,000,001' ); + is( $dt->microsecond, 450_000, 'microsecond is 450,000' ); + is( $dt->millisecond, 450, 'millisecond is 450' ); + + $dt->set( nanosecond => 450_500_000 ); + + is( $dt->nanosecond, 450_500_000, 'nanosecond is 450,500,000' ); + is( $dt->microsecond, 450_500, 'microsecond is 450,500' ); + is( $dt->millisecond, 450, 'millisecond is 450' ); +} + +{ + my $dt = DateTime->new( year => 2003, month => 5, day => 7 ); + is( $dt->weekday_of_month, 1, '->weekday_of_month' ); + is( $dt->week_of_month, 2, '->week_of_month' ); +} + +{ + my $dt = DateTime->new( year => 2003, month => 5, day => 8 ); + is( $dt->weekday_of_month, 2, '->weekday_of_month' ); + is( $dt->week_of_month, 2, '->week_of_month' ); +} + +{ + my $dt = DateTime->new( year => 1000, hour => 23 ); + is( $dt->hour, 23, '->hour' ); + is( $dt->hour_1, 23, '->hour_1' ); + is( $dt->hour_12, 11, '->hour_12' ); + is( $dt->hour_12_0, 11, '->hour_12_0' ); +} + +{ + my $dt = DateTime->new( year => 1000, hour => 0 ); + is( $dt->hour, 0, '->hour' ); + is( $dt->hour_1, 24, '->hour_1' ); + is( $dt->hour_12, 12, '->hour_12' ); + is( $dt->hour_12_0, 0, '->hour_12_0' ); +} + +SKIP: +{ + ## no critic (BuiltinFunctions::ProhibitStringyEval) + skip 'These tests require Test::Warn', 9 + unless eval 'use Test::Warn; 1'; + + my $dt = DateTime->new( year => 2000 ); + warnings_like( + sub { $dt->year(2001) }, qr/is a read-only/, + 'year() is read-only' + ); + warnings_like( + sub { $dt->month(5) }, qr/is a read-only/, + 'month() is read-only' + ); + warnings_like( + sub { $dt->day(5) }, qr/is a read-only/, + 'day() is read-only' + ); + warnings_like( + sub { $dt->hour(5) }, qr/is a read-only/, + 'hour() is read-only' + ); + warnings_like( + sub { $dt->minute(5) }, qr/is a read-only/, + 'minute() is read-only' + ); + warnings_like( + sub { $dt->second(5) }, qr/is a read-only/, + 'second() is read-only' + ); + warnings_like( + sub { $dt->nanosecond(5) }, qr/is a read-only/, + 'nanosecond() is read-only' + ); + warnings_like( + sub { $dt->time_zone('America/Chicago') }, qr/is a read-only/, + 'time_zone() is read-only' + ); + warnings_like( + sub { $dt->locale('en_US') }, qr/is a read-only/, + 'locale() is read-only' + ); +} + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-04epoch.t libdatetime-perl-1.46/xt/author/pp-04epoch.t --- libdatetime-perl-1.21/xt/author/pp-04epoch.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-04epoch.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,234 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +use strict; +use warnings; + +use Test::More; +use Test::Fatal; + +use DateTime; + +{ + + # Tests creating objects from epoch time + my $t1 = DateTime->from_epoch( epoch => 0 ); + is( $t1->epoch, 0, 'epoch should be 0' ); + + is( $t1->second, 0, 'seconds are correct on epoch 0' ); + is( $t1->minute, 0, 'minutes are correct on epoch 0' ); + is( $t1->hour, 0, 'hours are correct on epoch 0' ); + is( $t1->day, 1, 'days are correct on epoch 0' ); + is( $t1->month, 1, 'months are correct on epoch 0' ); + is( $t1->year, 1970, 'year is correct on epoch 0' ); +} + +{ + my $dt = DateTime->from_epoch( epoch => '3600' ); + is( + $dt->epoch, 3600, + 'creation test from epoch = 3600 (compare to epoch)' + ); +} + +{ + + # these tests could break if the time changed during the next three lines + my $now = time; + my $nowtest = DateTime->now(); + my $nowtest2 = DateTime->from_epoch( epoch => $now ); + is( $nowtest->hour, $nowtest2->hour, 'Hour: Create without args' ); + is( $nowtest->month, $nowtest2->month, 'Month : Create without args' ); + is( $nowtest->minute, $nowtest2->minute, 'Minute: Create without args' ); +} + +{ + my $epochtest = DateTime->from_epoch( epoch => '997121000' ); + + is( + $epochtest->epoch, 997121000, + 'epoch method returns correct value' + ); + is( $epochtest->hour, 18, 'hour' ); + is( $epochtest->min, 3, 'minute' ); +} + +{ + my $dt = DateTime->from_epoch( epoch => 3600 ); + $dt->set_time_zone('+0100'); + + is( $dt->epoch, 3600, 'epoch is 3600' ); + is( $dt->hour, 2, 'hour is 2' ); +} + +{ + + my $dt = DateTime->new( + year => 1970, + month => 1, + day => 1, + hour => 0, + time_zone => '-0100', + ); + + is( $dt->epoch, 3600, 'epoch is 3600' ); +} + +{ + + my $dt = DateTime->from_epoch( + epoch => 0, + time_zone => '-0100', + ); + + is( $dt->offset, -3600, 'offset should be -3600' ); + is( $dt->epoch, 0, 'epoch is 0' ); +} + +# Adding/subtracting should affect epoch +{ + my $expected = 1049160602; + my $epochtest = DateTime->from_epoch( epoch => $expected ); + + is( + $epochtest->epoch, $expected, + "epoch method returns correct value ($expected)" + ); + is( $epochtest->hour, 1, 'hour' ); + is( $epochtest->min, 30, 'minute' ); + + $epochtest->add( hours => 2 ); + $expected += 2 * 60 * 60; + + is( $epochtest->hour, 3, 'adjusted hour' ); + is( + $epochtest->epoch, $expected, + "epoch method returns correct adjusted value ($expected)" + ); + +} + +{ + my $dt = DateTime->from_epoch( epoch => 0.5 ); + is( + $dt->nanosecond, 500_000_000, + 'nanosecond should be 500,000,000 with 0.5 as epoch' + ); + + is( $dt->epoch, 0, 'epoch should be 0' ); + is( $dt->hires_epoch, 0.5, 'hires_epoch should be 0.5' ); +} + +{ + my $dt = DateTime->from_epoch( epoch => -0.5 ); + is( + $dt->nanosecond, 500_000_000, + 'nanosecond should be 500,000,000 with -0.5 as epoch' + ); + + is( $dt->epoch, -1, 'epoch should be -1' ); + is( $dt->hires_epoch, -0.5, 'hires_epoch should be -0.5' ); +} + +{ + my $dt = DateTime->from_epoch( epoch => 1609459199.999999 ); + is( + $dt->nanosecond, 999999000, + 'nanosecond should be 999,999,000 with 1609459199.999999 as epoch' + ); + + is( $dt->epoch, 1609459199, 'epoch should be 1609459199' ); +} + +{ + my $dt = DateTime->from_epoch( epoch => 0.1234567891 ); + is( + $dt->nanosecond, 123_457_000, + 'nanosecond should be rounded to 123,457,000 when given 0.1234567891' + ); +} + +{ + my $dt = DateTime->from_epoch( epoch => -0.1234567891 ); + is( + $dt->nanosecond, 876_543_000, + 'nanosecond should be rounded to 876,543,000 when given -0.1234567891' + ); +} + +{ + is( + DateTime->new( year => 1904 )->epoch, -2082844800, + 'epoch should work back to at least 1904' + ); + + my $dt = DateTime->from_epoch( epoch => -2082844800 ); + is( $dt->year, 1904, 'year should be 1904' ); + is( $dt->month, 1, 'month should be 1904' ); + is( $dt->day, 1, 'day should be 1904' ); +} + +{ + for my $pair ( + [ 1 => -62135596800 ], + [ 99 => -59042995200 ], + [ 100 => -59011459200 ], + [ 999 => -30641760000 ], + ) { + + my ( $year, $epoch ) = @{$pair}; + + is( + DateTime->new( year => $year )->epoch, $epoch, + "epoch for $year is $epoch" + ); + } +} + +{ + + package Number::Overloaded; + use overload + '0+' => sub { $_[0]->{num} }, + fallback => 1; + + sub new { bless { num => $_[1] }, $_[0] } +} + +{ + my $time = Number::Overloaded->new(12345); + + my $dt = DateTime->from_epoch( epoch => $time ); + is( $dt->epoch, 12345, 'can pass overloaded object to from_epoch' ); + + $time = Number::Overloaded->new(12345.1234); + $dt = DateTime->from_epoch( epoch => $time ); + is( $dt->epoch, 12345, 'decimal epoch in overloaded object' ); +} + +{ + my $time = Number::Overloaded->new(-12345); + my $dt = DateTime->from_epoch( epoch => $time ); + + is( $dt->epoch, -12345, 'negative epoch in overloaded object' ); +} + +{ + my @tests = ( + 'asldkjlkjd', + '1234 foo', + 'adlkj 1234', + ); + + for my $test (@tests) { + like( + exception { DateTime->from_epoch( epoch => $test ) }, + qr/Validation failed for type named Num/, + qq{'$test' is not a valid epoch value} + ); + } +} + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-05set.t libdatetime-perl-1.46/xt/author/pp-05set.t --- libdatetime-perl-1.21/xt/author/pp-05set.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-05set.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,95 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +use strict; +use warnings; + +use Test::More; + +use DateTime; + +{ + my $dt = DateTime->new( + year => 1996, month => 11, day => 22, + hour => 18, minute => 30, second => 20, + time_zone => 'UTC', + ); + + is( $dt->month, 11, 'check month' ); + + $dt->set( month => 5 ); + is( $dt->year, 1996, 'check year after setting month' ); + is( $dt->month, 5, 'check month after setting it' ); + is( $dt->day, 22, 'check day after setting month' ); + is( $dt->hour, 18, 'check hour after setting month' ); + is( $dt->minute, 30, 'check minute after setting month' ); + is( $dt->second, 20, 'check second after setting month' ); + + $dt->set_time_zone('-060001'); + is( $dt->year, 1996, 'check year after setting time zone' ); + is( $dt->month, 5, 'check month after setting time zone' ); + is( $dt->day, 22, 'check day after setting time zone' ); + is( $dt->hour, 12, 'check hour after setting time zone' ); + is( $dt->minute, 30, 'check minute after setting time zone' ); + is( $dt->second, 19, 'check second after setting time zone' ); + is( + $dt->offset, -21601, + 'check time zone offset after setting new time zone' + ); + + $dt->set_time_zone('+0100'); + is( $dt->year, 1996, 'check year after setting time zone' ); + is( $dt->month, 5, 'check month after setting time zone' ); + is( $dt->day, 22, 'check day after setting time zone' ); + is( $dt->hour, 19, 'check hour after setting time zone' ); + is( $dt->minute, 30, 'check minute after setting time zone' ); + is( $dt->second, 20, 'check second after setting time zone' ); + is( + $dt->offset, 3600, + 'check time zone offset after setting new time zone' + ); + + $dt->set( hour => 17 ); + is( $dt->year, 1996, 'check year after setting hour' ); + is( $dt->month, 5, 'check month after setting hour' ); + is( $dt->day, 22, 'check day after setting hour' ); + is( $dt->hour, 17, 'check hour after setting hour' ); + is( $dt->minute, 30, 'check minute after setting hour' ); + is( $dt->second, 20, 'check second after setting hour' ); +} + +{ + my $dt = DateTime->new( + year => 1996, month => 11, day => 22, + hour => 18, minute => 30, second => 20, + time_zone => 'UTC', + ); + + $dt->set_year(2000); + is( $dt->year, 2000, 'check year after set_year' ); + + $dt->set_month(5); + is( $dt->month, 5, 'check month after set_month' ); + + $dt->set_day(6); + is( $dt->day, 6, 'check day after set_day' ); + + $dt->set_hour(7); + is( $dt->hour, 7, 'check hour after set_hour' ); + + $dt->set_minute(8); + is( $dt->minute, 8, 'check minute after set_minute' ); + + $dt->set_second(9); + is( $dt->second, 9, 'check second after set_second' ); + + $dt->set_nanosecond(9999); + is( $dt->nanosecond, 9999, 'check nanosecond after set_nanosecond' ); + + $dt->set_locale('fr_FR'); + is( $dt->month_name, 'mai', 'check month name after set_locale' ); +} + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-06add.t libdatetime-perl-1.46/xt/author/pp-06add.t --- libdatetime-perl-1.21/xt/author/pp-06add.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-06add.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,500 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +use strict; +use warnings; + +use Test::More; +use Test::Fatal; + +use DateTime; + +{ + my $dt = DateTime->new( + year => 1996, month => 11, day => 22, + hour => 18, minute => 30, second => 20, + time_zone => 'UTC', + ); + $dt->add( weeks => 8 ); + + is( $dt->year, 1997, 'year rollover' ); + is( $dt->month, 1, 'month set on year rollover' ); + is( $dt->datetime, '1997-01-17T18:30:20', 'okay on year rollover' ); + + $dt->add( weeks => 2 ); + is( $dt->datetime, '1997-01-31T18:30:20', 'Adding weeks' ); + + $dt->add( seconds => 15 ); + is( $dt->datetime, '1997-01-31T18:30:35', 'Adding seconds' ); + + $dt->add( minutes => 12 ); + is( $dt->datetime, '1997-01-31T18:42:35', 'Adding minutes' ); + + $dt->add( minutes => 25, hours => 3, seconds => 7 ); + is( $dt->datetime, '1997-01-31T22:07:42', 'Adding h,m,s' ); +} + +{ + # Now, test the adding of durations + my $dt = DateTime->new( + year => 1986, month => 1, day => 28, + hour => 16, minute => 38, + time_zone => 'UTC' + ); + + $dt->add( minutes => 1, seconds => 12 ); + is( + $dt->datetime, '1986-01-28T16:39:12', + 'Adding durations with minutes and seconds works' + ); +} + +{ + my $dt = DateTime->new( + year => 1986, month => 1, day => 28, + hour => 16, minute => 38, + time_zone => 'UTC' + ); + + $dt->add( seconds => 30 ); + is( + $dt->datetime, '1986-01-28T16:38:30', + 'Adding durations with seconds only works' + ); +} + +{ + my $dt = DateTime->new( + year => 1986, month => 1, day => 28, + hour => 16, minute => 38, + time_zone => 'UTC' + ); + + $dt->add( hours => 1, minutes => 10 ); + is( + $dt->datetime, '1986-01-28T17:48:00', + 'Adding durations with hours and minutes works' + ); +} + +{ + my $dt = DateTime->new( + year => 1986, month => 1, day => 28, + hour => 16, minute => 38, + time_zone => 'UTC' + ); + + $dt->add( days => 3 ); + is( + $dt->datetime, '1986-01-31T16:38:00', + 'Adding durations with days only works' + ); +} + +{ + my $dt = DateTime->new( + year => 1986, month => 1, day => 28, + hour => 16, minute => 38, + time_zone => 'UTC' + ); + + $dt->add( days => 3, hours => 2 ); + is( + $dt->datetime, '1986-01-31T18:38:00', + 'Adding durations with days and hours works' + ); +} + +{ + my $dt = DateTime->new( + year => 1986, month => 1, day => 28, + hour => 16, minute => 38, + time_zone => 'UTC' + ); + + $dt->add( days => 3, hours => 2, minutes => 20, seconds => 15 ); + is( + $dt->datetime, '1986-01-31T18:58:15', + 'Adding durations with days, hours, minutes, and seconds works' + ); +} + +{ + # Add 15M - this test failed at one point in N::I::Time + my $dt = DateTime->new( + year => 2001, month => 4, day => 5, + hour => 16, + time_zone => 'UTC' + ); + + $dt->add( minutes => 15 ); + is( + $dt->datetime, '2001-04-05T16:15:00', + 'Adding minutes to an ical string' + ); + + # Subtract a duration + $dt->add( minutes => -15 ); + is( $dt->datetime, '2001-04-05T16:00:00', 'Back where we started' ); +} + +{ + # Syntactic sugar works as well + my $dt = DateTime->new( + year => 2016, month => 11, day => 11, + hour => 17, + time_zone => 'UTC' + ); + my $duration = DateTime::Duration->new( years => 1 ); + $dt->add($duration); + is( + $dt->datetime, '2017-11-11T17:00:00', + 'Adding a Duration object via ->add works', + ); + $duration = DateTime::Duration->new( months => 5, days => 1 ); + $dt->subtract($duration); + is( + $dt->datetime, '2017-06-10T17:00:00', + 'Subtracting a Duration object via ->subtract works', + ); +} + +{ + my $dt = DateTime->new( + year => 1986, month => 1, day => 28, + hour => 16, minute => 38, + time_zone => 'UTC' + ); + + $dt->add( seconds => 60 ); + is( + $dt->datetime, '1986-01-28T16:39:00', + 'adding positive seconds with seconds works' + ); + $dt->add( seconds => -120 ); + is( + $dt->datetime, '1986-01-28T16:37:00', + 'adding negative seconds with seconds works' + ); +} + +{ + # test sub months + my $dt = DateTime->new( + year => 2001, month => 1, day => 31, + time_zone => 'UTC', + ); + $dt->add( days => 1 ); + is( $dt->date, '2001-02-01', 'february 1st' ); +} + +{ + my $dt = DateTime->new( + year => 2001, month => 2, day => 28, + time_zone => 'UTC', + ); + $dt->add( days => 1 ); + is( $dt->date, '2001-03-01', 'march 1st' ); +} + +{ + my $dt = DateTime->new( + year => 2001, month => 3, day => 31, + time_zone => 'UTC', + ); + $dt->add( days => 1 ); + is( $dt->date, '2001-04-01', 'april 1st' ); +} + +{ + my $dt = DateTime->new( + year => 2001, month => 4, day => 30, + time_zone => 'UTC', + ); + $dt->add( days => 1 ); + is( $dt->date, '2001-05-01', 'may 1st' ); +} + +{ + my $dt = DateTime->new( + year => 2001, month => 5, day => 31, + time_zone => 'UTC', + ); + $dt->add( days => 1 ); + is( $dt->date, '2001-06-01', 'june 1st' ); +} + +{ + my $dt = DateTime->new( + year => 2001, month => 6, day => 30, + time_zone => 'UTC', + ); + $dt->add( days => 1 ); + is( $dt->date, '2001-07-01', 'july 1st' ); +} + +{ + my $dt = DateTime->new( + year => 2001, month => 7, day => 31, + time_zone => 'UTC', + ); + $dt->add( days => 1 ); + is( $dt->date, '2001-08-01', 'august 1st' ); +} + +{ + my $dt = DateTime->new( + year => 2001, month => 8, day => 31, + time_zone => 'UTC', + ); + $dt->add( days => 1 ); + is( $dt->date, '2001-09-01', 'september 1st' ); +} + +{ + my $dt = DateTime->new( + year => 2001, month => 9, day => 30, + time_zone => 'UTC', + ); + $dt->add( days => 1 ); + is( $dt->date, '2001-10-01', 'october 1st' ); +} + +{ + my $dt = DateTime->new( + year => 2001, month => 10, day => 31, + time_zone => 'UTC', + ); + $dt->add( days => 1 ); + is( $dt->date, '2001-11-01', 'november 1st' ); +} + +{ + my $dt = DateTime->new( + year => 2001, month => 11, day => 30, + time_zone => 'UTC', + ); + $dt->add( days => 1 ); + is( $dt->date, '2001-12-01', 'december 1st' ); +} + +{ + my $dt = DateTime->new( + year => 2001, month => 12, day => 31, + time_zone => 'UTC', + ); + $dt->add( days => 1 ); + is( $dt->date, '2002-01-01', 'january 1st' ); +} + +{ + # Before leap day, not a leap year ... + my $dt = DateTime->new( + year => 2001, month => 2, day => 28, + time_zone => 'UTC', + ); + $dt->add( years => 1 ); + is( $dt->date, '2002-02-28', 'Adding a year' ); + $dt->add( years => 17 ); + is( $dt->date, '2019-02-28', 'Adding 17 years' ); +} + +{ + # After leap day, not a leap year ... + my $dt = DateTime->new( + year => 2001, month => 3, day => 28, + time_zone => 'UTC', + ); + $dt->add( years => 1 ); + is( $dt->date, '2002-03-28', 'Adding a year' ); + $dt->add( years => 17 ); + is( $dt->date, '2019-03-28', 'Adding 17 years' ); +} + +{ + # On leap day, in a leap year ... + my $dt = DateTime->new( + year => 2000, month => 2, day => 29, + time_zone => 'UTC', + ); + $dt->add( years => 1 ); + is( $dt->date, '2001-03-01', 'Adding a year' ); + $dt->add( years => 17 ); + is( $dt->date, '2018-03-01', 'Adding 17 years' ); +} + +{ + # Before leap day, in a leap year ... + my $dt = DateTime->new( + year => 2000, month => 2, day => 28, + time_zone => 'UTC', + ); + $dt->add( years => 1 ); + is( $dt->date, '2001-02-28', 'Adding a year' ); + $dt->add( years => 17 ); + is( $dt->date, '2018-02-28', 'Adding 17 years' ); +} + +{ + # After leap day, in a leap year ... + my $dt = DateTime->new( + year => 2000, month => 3, day => 28, + time_zone => 'UTC', + ); + $dt->add( years => 1 ); + is( $dt->date, '2001-03-28', 'Adding a year' ); + $dt->add( years => 17 ); + is( $dt->date, '2018-03-28', 'Adding 17 years' ); +} + +{ + # Test a bunch of years, before leap day + for ( 1 .. 99 ) { + my $dt = DateTime->new( + year => 2000, month => 2, day => 28, + time_zone => 'UTC', + ); + $dt->add( years => $_ ); + my $x = sprintf '%02d', $_; + is( $dt->date, "20${x}-02-28", "Adding $_ years" ); + } + + # Test a bunch of years, after leap day + for ( 1 .. 99 ) { + my $dt = DateTime->new( + year => 2000, month => 3, day => 28, + time_zone => 'UTC', + ); + $dt->add( years => $_ ); + my $x = sprintf '%02d', $_; + is( $dt->date, "20${x}-03-28", "Adding $_ years" ); + } +} + +# And more of the same, starting on a non-leap year + +{ + # Test a bunch of years, before leap day + for ( 1 .. 97 ) { + my $dt = DateTime->new( + year => 2002, month => 2, day => 28, + time_zone => 'UTC', + ); + $dt->add( years => $_ ); + my $x = sprintf '%02d', $_ + 2; + is( $dt->date, "20${x}-02-28", "Adding $_ years" ); + } + + # Test a bunch of years, after leap day + for ( 1 .. 97 ) { + my $dt = DateTime->new( + year => 2002, month => 3, day => 28, + time_zone => 'UTC', + ); + $dt->add( years => $_ ); + my $x = sprintf '%02d', $_ + 2; + is( $dt->date, "20${x}-03-28", "Adding $_ years" ); + } +} + +{ + # subtract years + for ( 1 .. 97 ) { + my $dt = DateTime->new( + year => 1999, month => 3, day => 1, + time_zone => 'UTC', + ); + $dt->add( years => -$_ ); + my $x = sprintf '%02d', 99 - $_; + is( $dt->date, "19${x}-03-01", "Subtracting $_ years" ); + } +} + +# test some old bugs + +{ + # bug adding months where current month + months added were > 25 + my $dt = DateTime->new( + year => 1997, month => 12, day => 1, + time_zone => 'UTC', + ); + $dt->add( months => 14 ); + is( $dt->date, '1999-02-01', 'Adding months--rollover year' ); +} + +{ + # bug subtracting months with year rollover + my $dt = DateTime->new( + year => 1997, month => 1, day => 1, + time_zone => 'UTC', + ); + $dt->add( months => -1 ); + is( $dt->date, '1996-12-01', 'Subtracting months--rollover year' ); + + my $new = $dt + DateTime::Duration->new( years => 2 ); + is( $new->date, '1998-12-01', 'test + overloading' ); +} + +{ + my $dt = DateTime->new( + year => 1997, month => 1, day => 1, + hour => 1, minute => 1, second => 59, + nanosecond => 500000000, + time_zone => 'UTC', + ); + + $dt->add( nanoseconds => 500000000 ); + is( $dt->second, 0, 'fractional second rollover' ); + $dt->add( nanoseconds => 123000000 ); + is( $dt->fractional_second, 0.123, 'as fractional_second' ); +} + +{ + my $dt = DateTime->new( year => 2003, month => 2, day => 28 ); + $dt->add( months => 1, days => 1 ); + + is( $dt->ymd, '2003-04-01', 'order of units in date math' ); +} + +{ + my $dt = DateTime->new( year => 2003, hour => 12, minute => 1 ); + $dt->add( minutes => 30, seconds => -1 ); + + is( $dt->hour, 12, 'hour is 12' ); + is( $dt->minute, 30, 'minute is 30' ); + is( $dt->second, 59, 'second is 59' ); +} + +{ + my $dt = DateTime->new( + year => 2014, + month => 7, + day => 1, + time_zone => 'floating', + ); + + $dt->add( days => 2 ); + is( $dt->date, '2014-07-03', 'adding 2 days to a floating datetime' ); +} + +{ + my $dt = DateTime->new( year => 0, month => 1, day => 1 ); + my $dt2; + is( + exception { $dt2 = $dt->clone->add( days => 268_526_345 ) }, + undef, + 'no exception adding 268,526,345 days to 0000-01-01' + ); + + if ($dt2) { + is( + $dt2->ymd(), + '735200-02-29', + 'adding 268,526,345 days produces 735200-02-29' + ); + } +} + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-07compare.t libdatetime-perl-1.46/xt/author/pp-07compare.t --- libdatetime-perl-1.21/xt/author/pp-07compare.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-07compare.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,227 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +use strict; +use warnings; + +use Test::More; + +use DateTime; + +my $date1 = DateTime->new( + year => 1997, month => 10, day => 24, + hour => 12, minute => 0, second => 0, + time_zone => 'UTC' +); +my $date2 = DateTime->new( + year => 1997, month => 10, day => 24, + hour => 12, minute => 0, second => 0, + time_zone => 'UTC' +); + +# make sure that comparing to itself eq 0 +my $identity = $date1->compare($date2); +ok( $identity == 0, 'Identity comparison' ); + +$date2 = DateTime->new( + year => 1997, month => 10, day => 24, + hour => 12, minute => 0, second => 1, + time_zone => 'UTC' +); +ok( $date1->compare($date2) == -1, 'Comparison $a < $b, 1 second diff' ); + +$date2 = DateTime->new( + year => 1997, month => 10, day => 24, + hour => 12, minute => 1, second => 0, + time_zone => 'UTC' +); +ok( $date1->compare($date2) == -1, 'Comparison $a < $b, 1 minute diff' ); + +$date2 = DateTime->new( + year => 1997, month => 10, day => 24, + hour => 13, minute => 0, second => 0, + time_zone => 'UTC' +); +ok( $date1->compare($date2) == -1, 'Comparison $a < $b, 1 hour diff' ); + +$date2 = DateTime->new( + year => 1997, month => 10, day => 25, + hour => 12, minute => 0, second => 0, + time_zone => 'UTC' +); +ok( $date1->compare($date2) == -1, 'Comparison $a < $b, 1 day diff' ); + +$date2 = DateTime->new( + year => 1997, month => 11, day => 24, + hour => 12, minute => 0, second => 0, + time_zone => 'UTC' +); +ok( $date1->compare($date2) == -1, 'Comparison $a < $b, 1 month diff' ); + +$date2 = DateTime->new( + year => 1998, month => 10, day => 24, + hour => 12, minute => 0, second => 0, + time_zone => 'UTC' +); +ok( $date1->compare($date2) == -1, 'Comparison $a < $b, 1 year diff' ); + +# $a > $b tests + +$date2 = DateTime->new( + year => 1997, month => 10, day => 24, + hour => 11, minute => 59, second => 59, + time_zone => 'UTC' +); +ok( $date1->compare($date2) == 1, 'Comparison $a > $b, 1 second diff' ); + +$date2 = DateTime->new( + year => 1997, month => 10, day => 24, + hour => 11, minute => 59, second => 0, + time_zone => 'UTC' +); +ok( $date1->compare($date2) == 1, 'Comparison $a > $b, 1 minute diff' ); + +$date2 = DateTime->new( + year => 1997, month => 10, day => 24, + hour => 11, minute => 0, second => 0, + time_zone => 'UTC' +); +ok( $date1->compare($date2) == 1, 'Comparison $a > $b, 1 hour diff' ); + +$date2 = DateTime->new( + year => 1997, month => 10, day => 23, + hour => 12, minute => 0, second => 0, + time_zone => 'UTC' +); +ok( $date1->compare($date2) == 1, 'Comparison $a > $b, 1 day diff' ); + +$date2 = DateTime->new( + year => 1997, month => 9, day => 24, + hour => 12, minute => 0, second => 0, + time_zone => 'UTC' +); +ok( $date1->compare($date2) == 1, 'Comparison $a > $b, 1 month diff' ); + +$date2 = DateTime->new( + year => 1996, month => 10, day => 24, + hour => 12, minute => 0, second => 0, + time_zone => 'UTC' +); +ok( $date1->compare($date2) == 1, 'Comparison $a > $b, 1 year diff' ); + +my $infinity = DateTime::INFINITY; + +ok( $date1->compare($infinity) == -1, 'Comparison $a < inf' ); + +ok( $date1->compare( -$infinity ) == 1, 'Comparison $a > -inf' ); + +# comparison overloading, and infinity + +ok( ( $date1 <=> $infinity ) == -1, 'Comparison overload $a <=> inf' ); + +ok( ( $infinity <=> $date1 ) == 1, 'Comparison overload $inf <=> $a' ); + +# comparison with floating time +{ + my $dt1 = DateTime->new( + year => 1997, month => 10, day => 24, + hour => 12, minute => 0, second => 0, + time_zone => 'America/Chicago' + ); + my $dt2 = DateTime->new( + year => 1997, month => 10, day => 24, + hour => 12, minute => 0, second => 0, + time_zone => 'floating' + ); + + is( + DateTime->compare( $dt1, $dt2 ), 0, + 'Comparison with floating time (cmp)' + ); + is( ( $dt1 <=> $dt2 ), 0, 'Comparison with floating time (<=>)' ); + is( ( $dt1 cmp $dt2 ), 0, 'Comparison with floating time (cmp)' ); + is( + DateTime->compare_ignore_floating( $dt1, $dt2 ), 1, + 'Comparison with floating time (cmp)' + ); +} + +# sub-second +{ + my $dt1 = DateTime->new( + year => 1997, month => 10, day => 24, + hour => 12, minute => 0, second => 0, + nanosecond => 100, + ); + + my $dt2 = DateTime->new( + year => 1997, month => 10, day => 24, + hour => 12, minute => 0, second => 0, + nanosecond => 200, + ); + + is( + DateTime->compare( $dt1, $dt2 ), -1, + 'Comparison with floating time (cmp)' + ); + is( ( $dt1 <=> $dt2 ), -1, 'Comparison with floating time (<=>)' ); + is( ( $dt1 cmp $dt2 ), -1, 'Comparison with floating time (cmp)' ); +} + +{ + my $dt1 = DateTime->new( + year => 2000, month => 10, day => 24, + hour => 12, minute => 0, second => 0, + nanosecond => 10000, + ); + + my $dt2 = DateTime->new( + year => 2000, month => 10, day => 24, + hour => 12, minute => 0, second => 0, + nanosecond => 10000, + ); + + is( + DateTime->compare( $dt1, $dt2 ), 0, + 'Comparison with floating time (cmp)' + ); + is( ( $dt1 <=> $dt2 ), 0, 'Comparison with floating time (<=>)' ); + is( ( $dt1 cmp $dt2 ), 0, 'Comparison with floating time (cmp)' ); + is( + DateTime->compare_ignore_floating( $dt1, $dt2 ), 0, + 'Comparison with compare_ignore_floating (cmp)' + ); +} + +{ + + package DT::Test; + + sub new { + my $class = shift; + return bless [@_], $class; + } + + sub utc_rd_values { @{ $_[0] } } +} + +{ + my $dt = DateTime->new( year => 1950 ); + my @values = $dt->utc_rd_values; + + $values[2] += 50; + + my $dt_test1 = DT::Test->new(@values); + + ok( $dt < $dt_test1, 'comparison works across different classes' ); + + $values[0] -= 1; + + my $dt_test2 = DT::Test->new(@values); + + ok( $dt > $dt_test2, 'comparison works across different classes' ); +} + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-09greg.t libdatetime-perl-1.46/xt/author/pp-09greg.t --- libdatetime-perl-1.21/xt/author/pp-09greg.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-09greg.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,125 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +use strict; +use warnings; + +use Test::More; + +use DateTime; + +## no critic (Subroutines::ProtectPrivateSubs) + +# test _ymd2rd and _rd2ymd for various dates +# 2 tests are performed for each date (on _ymd2rd and _rd2ymd) +# dates are specified as [rd,year,month,day] +for ( # min and max supported days (for 32-bit system) + [ -( 2**28 ), -734951, 9, 7 ], + [ 2**28, 734952, 4, 25 ], + + # some miscellaneous dates (these are actually epoch dates for + # various calendars from Calendrical Calculations (1st ed) Table + # 1.1) + [ -1721425, -4713, 11, 24 ], + [ -1373427, -3760, 9, 7 ], + [ -1137142, -3113, 8, 11 ], + [ -1132959, -3101, 1, 23 ], + [ -963099, -2636, 2, 15 ], + [ -1, 0, 12, 30 ], [ 1, 1, 1, 1 ], + [ 2796, 8, 8, 27 ], + [ 103605, 284, 8, 29 ], + [ 226896, 622, 3, 22 ], + [ 227015, 622, 7, 19 ], + [ 654415, 1792, 9, 22 ], + [ 673222, 1844, 3, 21 ] +) { + is( + join( '/', DateTime->_rd2ymd( $_->[0] ) ), + join( '/', @{$_}[ 1 .. 3 ] ), + $_->[0] . " \t=> " . join '/', @{$_}[ 1 .. 3 ] + ); + + is( + DateTime->_ymd2rd( @{$_}[ 1 .. 3 ] ), $_->[0], + join( '/', @{$_}[ 1 .. 3 ] ) . " \t=> " . $_->[0] + ); +} + +# normalization tests +for ( + [ -1753469, -4797, -33, 1 ], + [ -1753469, -4803, 39, 1 ], + [ -1753105, -4796, -34, 28 ], + [ -1753105, -4802, 38, 28 ] +) { + is( + DateTime->_ymd2rd( @{$_}[ 1 .. 3 ] ), $_->[0], + join( '/', @{$_}[ 1 .. 3 ] ) + . " \t=> " + . $_->[0] + . ' (normalization)' + ); +} + +# test first and last day of each month from Jan -4800..Dec 4800 +# this test bails after the first failure with a not ok. +# if it completes successfully, only one ok is issued. + +my @mlen = ( 0, 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ); +my ( $dno, $y, $m, $dno2, $y2, $m2, $d2, $mlen ) = ( -1753530, -4800, 1 ); + +while ( $y <= 4800 ) { + + # test $y,$m,1 + ++$dno; + $dno2 = DateTime->_ymd2rd( $y, $m, 1 ); + if ( $dno != $dno2 ) { + is( + $dno2, $dno, + "greg torture test: _ymd2rd($y,$m,1) should be $dno" + ); + last; + } + ( $y2, $m2, $d2 ) = DateTime->_rd2ymd($dno); + + if ( $y2 != $y || $m2 != $m || $d2 != 1 ) { + is( + "$y2/$m2/$d2", "$y/$m/1", + "greg torture test: _rd2ymd($dno) should be $y/$m/1" + ); + last; + } + + # test $y,$m,$mlen + $mlen = $mlen[$m] || ( $y % 4 ? 28 : $y % 100 ? 29 : $y % 400 ? 28 : 29 ); + $dno += $mlen - 1; + $dno2 = DateTime->_ymd2rd( $y, $m, $mlen ); + if ( $dno != $dno2 ) { + is( + $dno2, $dno, + "greg torture test: _ymd2rd($y,$m,$mlen) should be $dno" + ); + last; + } + ( $y2, $m2, $d2 ) = DateTime->_rd2ymd($dno); + + if ( $y2 != $y || $m2 != $m || $d2 != $mlen ) { + is( + "$y2/$m2/$d2", "$y/$m/$mlen", + "greg torture test: _rd2ymd($dno) should be $y/$m/$mlen" + ); + last; + } + + # and on to the next month... + if ( ++$m > 12 ) { + $m = 1; + ++$y; + } +} + +pass('greg torture test') if $y == 4801; + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-10subtract.t libdatetime-perl-1.46/xt/author/pp-10subtract.t --- libdatetime-perl-1.21/xt/author/pp-10subtract.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-10subtract.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,489 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +use strict; +use warnings; + +use Test::More; + +use DateTime; + +{ + my $date1 = DateTime->new( + year => 2001, month => 5, day => 10, + hour => 4, minute => 3, second => 2, + nanosecond => 12, + time_zone => 'UTC' + ); + + my $date2 = DateTime->new( + year => 2001, month => 6, day => 12, + hour => 5, minute => 7, second => 23, + nanosecond => 7, + time_zone => 'UTC' + ); + + my $dur = $date2 - $date1; + + is( $dur->delta_months, 1, 'delta_months should be 1' ); + is( $dur->delta_days, 2, 'delta_days should be 2' ); + is( $dur->delta_minutes, 64, 'delta_minutes should be 64' ); + is( $dur->delta_seconds, 20, 'delta_seconds should be 20' ); + is( + $dur->delta_nanoseconds, 999_999_995, + 'delta_nanoseconds should be 999,999,995' + ); + + is( $dur->years, 0, 'Years' ); + is( $dur->months, 1, 'Months' ); + is( $dur->weeks, 0, 'Weeks' ); + is( $dur->days, 2, 'Days' ); + is( $dur->hours, 1, 'Hours' ); + is( $dur->minutes, 4, 'Minutes' ); + is( $dur->seconds, 20, 'Seconds' ); + is( $dur->nanoseconds, 999_999_995, 'Nanoseconds' ); +} + +{ + my $date1 = DateTime->new( + year => 2001, month => 5, day => 10, + hour => 4, minute => 3, second => 2, + time_zone => 'UTC' + ); + + my $date2 = DateTime->new( + year => 2001, month => 6, day => 12, + hour => 5, minute => 7, second => 23, + time_zone => 'UTC' + ); + + my $dur = $date1 - $date2; + + is( $dur->delta_months, -1, 'delta_months should be -1' ); + is( $dur->delta_days, -2, 'delta_days should be -2' ); + is( $dur->delta_minutes, -64, 'delta_minutes should be 64' ); + is( $dur->delta_seconds, -21, 'delta_seconds should be 20' ); + is( $dur->delta_nanoseconds, 0, 'delta_nanoseconds should be 0' ); + + is( $dur->years, 0, 'Years' ); + is( $dur->months, 1, 'Months' ); + is( $dur->weeks, 0, 'Weeks' ); + is( $dur->days, 2, 'Days' ); + is( $dur->hours, 1, 'Hours' ); + is( $dur->minutes, 4, 'Minutes' ); + is( $dur->seconds, 21, 'Seconds' ); + is( $dur->nanoseconds, 0, 'Nanoseconds' ); + + $dur = $date1 - $date1; + is( $dur->delta_days, 0, 'date minus itself should have no delta days' ); + is( + $dur->delta_seconds, 0, + 'date minus itself should have no delta seconds' + ); + + my $new = $date1 - DateTime::Duration->new( years => 2 ); + is( $new->datetime, '1999-05-10T04:03:02', 'test - overloading' ); +} + +{ + my $d = DateTime->new( + year => 2001, month => 10, day => 19, + hour => 5, minute => 1, second => 1, + time_zone => 'UTC' + ); + + my $d2 = $d->clone; + $d2->subtract( + weeks => 1, + days => 1, + hours => 1, + minutes => 1, + seconds => 1, + ); + + ok( defined $d2, 'Defined' ); + is( + $d2->datetime, '2001-10-11T04:00:00', + 'Subtract and get the right thing' + ); +} + +# based on bug report from Eric Cholet +{ + my $dt1 = DateTime->new( + year => 2003, month => 2, day => 9, + hour => 0, minute => 0, second => 1, + time_zone => 'UTC', + ); + + my $dt2 = DateTime->new( + year => 2003, month => 2, day => 7, + hour => 23, minute => 59, second => 59, + time_zone => 'UTC', + ); + + my $dur1 = $dt1->subtract_datetime($dt2); + + is( $dur1->delta_days, 1, 'delta_days should be 1' ); + is( $dur1->delta_seconds, 2, 'delta_seconds should be 2' ); + + my $dt3 = $dt2 + $dur1; + + is( + DateTime->compare( $dt1, $dt3 ), 0, + 'adding difference back to dt1 should give same datetime' + ); + + my $dur2 = $dt2->subtract_datetime($dt1); + + is( $dur2->delta_days, -1, 'delta_days should be -1' ); + is( $dur2->delta_seconds, -2, 'delta_seconds should be -2' ); + + my $dt4 = $dt1 + $dur2; + + is( + DateTime->compare( $dt2, $dt4 ), 0, + 'adding difference back to dt2 should give same datetime' + ); +} + +# test if the day changes because of a nanosecond subtract +{ + my $dt = DateTime->new( + year => 2001, month => 6, day => 12, + hour => 0, minute => 0, second => 0, + time_zone => 'UTC' + ); + $dt->subtract( nanoseconds => 1 ); + is( $dt->nanosecond, 999999999, 'negative nanoseconds normalize ok' ); + is( $dt->second, 59, 'seconds normalize ok' ); + is( $dt->minute, 59, 'minutes normalize ok' ); + is( $dt->hour, 23, 'hours normalize ok' ); + is( $dt->day, 11, 'days normalize ok' ); +} + +# test for a bug when nanoseconds were greater in earlier datetime +{ + my $dt1 = DateTime->new( + year => 2000, month => 1, day => 5, + hour => 0, minute => 10, second => 0, + nanosecond => 1, + time_zone => 'UTC', + ); + + my $dt2 = DateTime->new( + year => 2000, month => 1, day => 6, + hour => 0, minute => 10, second => 0, + nanosecond => 0, + time_zone => 'UTC', + ); + my $dur = $dt2 - $dt1; + + is( $dur->delta_days, 0, 'delta_days is 0' ); + is( $dur->delta_minutes, 1439, 'delta_minutes is 1439' ); + is( $dur->delta_seconds, 59, 'delta_seconds is 59' ); + is( + $dur->delta_nanoseconds, 999_999_999, + 'delta_nanoseconds is 999,999,999' + ); + ok( $dur->is_positive, 'duration is positive' ); +} + +{ + my $dt1 = DateTime->new( + year => 2000, month => 1, day => 5, + hour => 0, minute => 10, second => 0, + nanosecond => 20, + time_zone => 'UTC', + ); + + my $dt2 = DateTime->new( + year => 2000, month => 1, day => 5, + hour => 0, minute => 10, second => 0, + nanosecond => 10, + time_zone => 'UTC', + ); + + my $dur = $dt2 - $dt1; + + is( $dur->delta_days, 0, 'days is 0' ); + is( $dur->delta_seconds, 0, 'seconds is 0' ); + is( $dur->delta_nanoseconds, -10, 'nanoseconds is -10' ); + ok( $dur->is_negative, 'duration is negative' ); +} + +{ + my $dt1 = DateTime->new( + year => 2000, month => 1, day => 5, + hour => 0, minute => 11, second => 0, + nanosecond => 20, + time_zone => 'UTC', + ); + + my $dt2 = DateTime->new( + year => 2000, month => 1, day => 5, + hour => 0, minute => 10, second => 0, + nanosecond => 10, + time_zone => 'UTC', + ); + + my $dur = $dt2 - $dt1; + + is( $dur->delta_days, 0, 'delta_days is 0' ); + is( $dur->delta_minutes, -1, 'delta_minutes is -1' ); + is( $dur->delta_seconds, 0, 'delta_seconds is 0' ); + is( $dur->delta_nanoseconds, -10, 'nanoseconds is -10' ); + ok( $dur->is_negative, 'duration is negative' ); +} + +{ + my $dt1 = DateTime->new( + year => 2000, month => 1, day => 5, + hour => 0, minute => 10, second => 0, + nanosecond => 20, + time_zone => 'UTC', + ); + + my $dt2 = DateTime->new( + year => 2000, month => 1, day => 5, + hour => 0, minute => 11, second => 0, + nanosecond => 10, + time_zone => 'UTC', + ); + + my $dur = $dt2 - $dt1; + + is( $dur->delta_days, 0, 'days is 0' ); + is( $dur->delta_seconds, 59, 'seconds is 59' ); + is( $dur->delta_nanoseconds, 999_999_990, 'nanoseconds is 999,999,990' ); + ok( $dur->is_positive, 'duration is positive' ); +} + +{ + my $dt1 = DateTime->new( + year => 2000, month => 1, day => 5, + hour => 0, minute => 11, second => 0, + nanosecond => 10, + time_zone => 'UTC', + ); + + my $dt2 = DateTime->new( + year => 2000, month => 1, day => 5, + hour => 0, minute => 10, second => 0, + nanosecond => 20, + time_zone => 'UTC', + ); + + my $dur = $dt2 - $dt1; + + is( $dur->delta_days, 0, 'days is 0' ); + is( $dur->delta_seconds, -59, 'seconds is -59' ); + is( + $dur->delta_nanoseconds, -999_999_990, + 'nanoseconds is -999,999,990' + ); + ok( $dur->is_negative, 'duration is negative' ); +} + +{ + my $dt1 = DateTime->new( + year => 2000, month => 1, day => 5, + hour => 0, minute => 11, second => 0, + nanosecond => 20, + time_zone => 'UTC', + ); + + my $dur = $dt1 - $dt1; + + is( $dur->delta_days, 0, 'days is 0' ); + is( $dur->delta_seconds, 0, 'seconds is 0' ); + is( $dur->delta_nanoseconds, 0, 'nanoseconds is 0' ); + ok( !$dur->is_positive, 'not positive' ); + ok( !$dur->is_negative, 'not negative' ); +} + +{ + my $dt1 = DateTime->new( year => 2003, month => 12, day => 31 ); + my $dt2 = $dt1->clone->subtract( months => 1 ); + + is( $dt2->year, 2003, '2003-12-31 - 1 month = 2003-11-30' ); + is( $dt2->month, 11, '2003-12-31 - 1 month = 2003-11-30' ); + is( $dt2->day, 30, '2003-12-31 - 1 month = 2003-11-30' ); +} + +{ + my $date1 = DateTime->new( + year => 2001, month => 5, day => 10, + hour => 4, minute => 3, second => 2, + nanosecond => 12, + time_zone => 'UTC' + ); + + my $date2 = DateTime->new( + year => 2001, month => 6, day => 12, + hour => 5, minute => 7, second => 23, + nanosecond => 7, + time_zone => 'UTC' + ); + + my $dur = $date2->subtract_datetime_absolute($date1); + + is( $dur->delta_months, 0, 'delta_months is 0' ); + is( $dur->delta_minutes, 0, 'delta_minutes is 0' ); + is( $dur->delta_seconds, 2_855_060, 'delta_seconds is 2,855,060' ); + is( + $dur->delta_nanoseconds, 999_999_995, + 'delta_seconds is 999,999,995' + ); +} + +{ + my $date1 = DateTime->new( + year => 2001, month => 5, day => 10, + hour => 4, minute => 3, second => 2, + time_zone => 'UTC' + ); + + my $date2 = DateTime->new( + year => 2001, month => 6, day => 12, + hour => 5, minute => 7, second => 23, + time_zone => 'UTC' + ); + + my $dur = $date1->subtract_datetime_absolute($date2); + + is( $dur->delta_months, 0, 'delta_months is 0' ); + is( $dur->delta_minutes, 0, 'delta_minutes is 0' ); + is( $dur->delta_seconds, -2_855_061, 'delta_seconds is -2,855,061' ); + is( $dur->delta_nanoseconds, 0, 'delta_nanoseconds is 0' ); +} + +{ + my $date1 = DateTime->new( year => 2003, month => 9, day => 30 ); + my $date2 = DateTime->new( year => 2003, month => 10, day => 1 ); + + my $date3 = DateTime->new( year => 2003, month => 10, day => 31 ); + my $date4 = DateTime->new( year => 2003, month => 11, day => 1 ); + + my $date5 = DateTime->new( year => 2003, month => 2, day => 28 ); + my $date6 = DateTime->new( year => 2003, month => 3, day => 1 ); + + my $date7 = DateTime->new( year => 2003, month => 1, day => 31 ); + my $date8 = DateTime->new( year => 2003, month => 2, day => 1 ); + + foreach my $p ( + [ $date1, $date2 ], + [ $date3, $date4 ], + [ $date5, $date6 ], + [ $date7, $date8 ], + ) { + my $pos_diff = $p->[1]->subtract_datetime( $p->[0] ); + + is( $pos_diff->delta_days, 1, '1 day diff at end of month' ); + is( $pos_diff->delta_months, 0, '0 month diff at end of month' ); + + my $neg_diff = $p->[0]->subtract_datetime( $p->[1] ); + + is( $neg_diff->delta_days, -1, '-1 day diff at end of month' ); + is( $neg_diff->delta_months, 0, '0 month diff at end of month' ); + } +} + +{ + my $dt1 = DateTime->new( + year => 2005, month => 6, day => 11, + time_zone => 'UTC', + ); + + my $dt2 = DateTime->new( + year => 2005, month => 11, day => 10, + time_zone => 'UTC', + ); + + my $dur = $dt2->subtract_datetime($dt1); + my %deltas = $dur->deltas; + is( $deltas{months}, 4, '4 months - smaller day > bigger day' ); + is( $deltas{days}, 29, '29 days - smaller day > bigger day' ); + is( $deltas{minutes}, 0, '0 minutes - smaller day > bigger day' ); + + is( + DateTime->compare( $dt1->clone->add_duration($dur), $dt2 ), 0, + '$dt1 + $dur == $dt2' + ); + + # XXX - this does not work, nor will it ever work + # is( $dt2->clone->subtract_duration($dur), $dt1, '$dt2 - $dur == $dt1' ); +} + +{ + my $dt1 = DateTime->new( + year => 2005, month => 6, day => 11, + time_zone => 'UTC', + ); + + my $dt2 = DateTime->new( + year => 2005, month => 11, day => 10, + time_zone => 'UTC', + ); + + my $dur = $dt2->delta_days($dt1); + my %deltas = $dur->deltas; + is( $deltas{months}, 0, '30 months - smaller day > bigger day' ); + is( $deltas{days}, 152, '152 days - smaller day > bigger day' ); + is( $deltas{minutes}, 0, '0 minutes - smaller day > bigger day' ); + + is( + DateTime->compare( $dt1->clone->add_duration($dur), $dt2 ), 0, + '$dt1 + $dur == $dt2' + ); + is( + DateTime->compare( $dt2->clone->subtract_duration($dur), $dt1 ), 0, + '$dt2 - $dur == $dt1' + ); +} + +{ + my $dt = DateTime->new( + year => 2012, + month => 6, + day => 30, + time_zone => 'floating', + ); + + my $default = $dt->clone()->subtract( months => 1 ); + is( + $default->format_cldr('yyyy-MM-dd'), + '2012-05-31', + 'default subtract uses preserve end_of_month mode' + ); + + my $with_mode = $dt->clone()->subtract( + months => 1, + end_of_month => 'limit', + ); + is( + $with_mode->format_cldr('yyyy-MM-dd'), + '2012-05-30', + 'set end_of_month mode to limit in call to subtract()' + ); + +} + +{ + my $dt = DateTime->new( + year => 2014, + month => 7, + day => 3, + time_zone => 'floating', + ); + + $dt->subtract( days => 2 ); + is( + $dt->date, '2014-07-01', + 'subtracting 2 days from a floating datetime' + ); +} + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-11duration.t libdatetime-perl-1.46/xt/author/pp-11duration.t --- libdatetime-perl-1.21/xt/author/pp-11duration.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-11duration.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,463 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +use strict; +use warnings; + +use Test::Fatal; +use Test::More; + +use DateTime; +use DateTime::Duration; + +{ + my %pairs = ( + years => 1, + months => 2, + weeks => 3, + days => 4, + hours => 6, + minutes => 7, + seconds => 8, + nanoseconds => 9, + ); + + my $dur = DateTime::Duration->new(%pairs); + + while ( my ( $unit, $val ) = each %pairs ) { + is( $dur->$unit(), $val, "$unit should be $val" ); + } + + is( $dur->delta_months, 14, 'delta_months' ); + is( $dur->delta_days, 25, 'delta_days' ); + is( $dur->delta_minutes, 367, 'delta_minutes' ); + is( $dur->delta_seconds, 8, 'delta_seconds' ); + is( $dur->delta_nanoseconds, 9, 'delta_nanoseconds' ); + + is( $dur->in_units('months'), 14, 'in_units months' ); + is( $dur->in_units('days'), 25, 'in_units days' ); + is( $dur->in_units('minutes'), 367, 'in_units minutes' ); + is( $dur->in_units('seconds'), 8, 'in_units seconds' ); + is( + $dur->in_units( 'nanoseconds', 'seconds' ), 9, + 'in_units nanoseconds, seconds' + ); + + is( $dur->in_units('years'), 1, 'in_units years' ); + is( $dur->in_units( 'months', 'years' ), 2, 'in_units months, years' ); + is( $dur->in_units('weeks'), 3, 'in_units weeks' ); + is( $dur->in_units( 'days', 'weeks' ), 4, 'in_units days, weeks' ); + is( $dur->in_units('hours'), 6, 'in_units hours' ); + is( $dur->in_units( 'minutes', 'hours' ), 7, 'in_units minutes, hours' ); + is( + $dur->in_units('nanoseconds'), 8_000_000_009, + 'in_units nanoseconds' + ); + + my ( + $years, $months, $weeks, $days, $hours, + $minutes, $seconds, $nanoseconds + ) + = $dur->in_units( + qw( years months weeks days hours + minutes seconds nanoseconds ) + ); + + is( $years, 1, 'in_units years, list context' ); + is( $months, 2, 'in_units months, list context' ); + is( $weeks, 3, 'in_units weeks, list context' ); + is( $days, 4, 'in_units days, list context' ); + is( $hours, 6, 'in_units hours, list context' ); + is( $minutes, 7, 'in_units minutes, list context' ); + is( $seconds, 8, 'in_units seconds, list context' ); + is( $nanoseconds, 9, 'in_units nanoseconds, list context' ); + + ok( $dur->is_positive, 'should be positive' ); + ok( !$dur->is_zero, 'should not be zero' ); + ok( !$dur->is_negative, 'should not be negative' ); + + ok( $dur->is_wrap_mode, 'wrap mode' ); +} +{ + my %pairs = ( + years => 1, + months => 2, + weeks => 3, + days => 4, + hours => 6, + minutes => 7, + seconds => 8, + nanoseconds => 9, + ); + + my $dur = DateTime::Duration->new( %pairs, end_of_month => 'limit' ); + + my $calendar_dur = $dur->calendar_duration; + is( $calendar_dur->delta_months, 14, 'date - delta_months is 14' ); + is( $calendar_dur->delta_minutes, 0, 'date - delta_minutes is 0' ); + is( $calendar_dur->delta_seconds, 0, 'date - delta_seconds is 0' ); + is( + $calendar_dur->delta_nanoseconds, 0, + 'date - delta_nanoseconds is 0' + ); + ok( $calendar_dur->is_limit_mode, 'limit mode' ); + + my $clock_dur = $dur->clock_duration; + is( $clock_dur->delta_months, 0, 'time - delta_months is 0' ); + is( $clock_dur->delta_minutes, 367, 'time - delta_minutes is 367' ); + is( $clock_dur->delta_seconds, 8, 'time - delta_seconds is 8' ); + is( $clock_dur->delta_nanoseconds, 9, 'time - delta_nanoseconds is 9' ); + ok( $clock_dur->is_limit_mode, 'limit mode' ); +} + +{ + my $dur = DateTime::Duration->new( days => 1, end_of_month => 'limit' ); + ok( $dur->is_limit_mode, 'limit mode' ); +} + +{ + my $dur + = DateTime::Duration->new( days => 1, end_of_month => 'preserve' ); + ok( $dur->is_preserve_mode, 'preserve mode' ); +} + +my $leap_day = DateTime->new( + year => 2004, month => 2, day => 29, + time_zone => 'UTC', +); + +{ + my $new = $leap_day + DateTime::Duration->new( + years => 1, + end_of_month => 'wrap' + ); + + is( $new->date, '2005-03-01', 'new date should be 2005-03-01' ); +} + +{ + my $new = $leap_day + DateTime::Duration->new( + years => 1, + end_of_month => 'limit' + ); + + is( $new->date, '2005-02-28', 'new date should be 2005-02-28' ); +} + +{ + my $new = $leap_day + DateTime::Duration->new( + years => 1, + end_of_month => 'preserve' + ); + + is( $new->date, '2005-02-28', 'new date should be 2005-02-28' ); + + my $new2 = $leap_day + DateTime::Duration->new( + months => 1, + end_of_month => 'preserve' + ); + is( $new2->date, '2004-03-31', 'new date should be 2004-03-31' ); +} + +{ + my $inverse = DateTime::Duration->new( + years => 1, months => 1, + weeks => 1, days => 1, + hours => 1, minutes => 2, seconds => 3, + )->inverse; + + is( $inverse->years, 1, 'inverse years should be positive' ); + is( $inverse->months, 1, 'inverse months should be positive' ); + is( $inverse->weeks, 1, 'inverse weeks should be positive' ); + is( $inverse->days, 1, 'inverse days should be positive' ); + is( $inverse->hours, 1, 'inverse hours should be positive' ); + is( $inverse->minutes, 2, 'inverse minutes should be positive' ); + is( $inverse->seconds, 3, 'inverse minutes should be positive' ); + + is( + $inverse->delta_months, -13, + 'inverse delta months should be negative' + ); + is( $inverse->delta_days, -8, 'inverse delta months should be negative' ); + is( + $inverse->delta_minutes, -62, + 'inverse delta minutes should be negative' + ); + is( + $inverse->delta_seconds, -3, + 'inverse delta seconds should be negative' + ); + + ok( $inverse->is_negative, 'should be negative' ); + ok( !$inverse->is_zero, 'should not be zero' ); + ok( !$inverse->is_positive, 'should not be positivea' ); + + is( + $inverse->end_of_month_mode(), 'preserve', + 'inverse method uses default end_of_month_mode without explicit parameter' + ); + + my $inverse2 = DateTime::Duration->new( years => 1 ) + ->inverse( end_of_month => 'limit' ); + + is( + $inverse2->end_of_month_mode(), 'limit', + 'inverse method allows setting end_of_month_mode' + ); +} + +{ + my $dur1 = DateTime::Duration->new( months => 6, days => 10 ); + + my $dur2 = DateTime::Duration->new( months => 3, days => 7 ); + + my $new1 = $dur1 + $dur2; + is( $new1->delta_months, 9, 'test + overloading' ); + is( $new1->delta_days, 17, 'test + overloading' ); + + my $new2 = $dur1 - $dur2; + is( $new2->delta_months, 3, 'test - overloading' ); + is( $new2->delta_days, 3, 'test - overloading' ); + + my $new3 = $dur2 - $dur1; + is( $new3->delta_months, -3, 'test - overloading' ); + is( $new3->delta_days, -3, 'test - overloading' ); +} + +{ + my $dur1 = DateTime::Duration->new( months => 6, days => 10 ); + + my $new1 = $dur1 * 4; + is( $new1->delta_months, 24, 'test * overloading' ); + is( $new1->delta_days, 40, 'test * overloading' ); + + $dur1->multiply(4); + is( $dur1->delta_months, 24, 'test multiply' ); + is( $dur1->delta_days, 40, 'test multiply' ); +} + +{ + my $dur1 = DateTime::Duration->new( + months => 6, days => 10, seconds => 3, + nanoseconds => 1_200_300_400 + ); + + my $dur2 + = DateTime::Duration->new( seconds => 1, nanoseconds => 500_000_000 ); + + is( $dur1->delta_seconds, 4, 'test nanoseconds overflow' ); + is( $dur1->delta_nanoseconds, 200_300_400, 'test nanoseconds remainder' ); + + my $new1 = $dur1 - $dur2; + + is( $new1->delta_seconds, 2, 'seconds is positive' ); + is( + $new1->delta_nanoseconds, 700_300_400, + 'nanoseconds remainder is negative' + ); + + $new1->add( nanoseconds => 500_000_000 ); + is( $new1->delta_seconds, 3, 'seconds are unaffected' ); + is( $new1->delta_nanoseconds, 200_300_400, 'nanoseconds are back' ); + + my $new2 = $dur1 - $dur2; + $new2->add( nanoseconds => 1_500_000_000 ); + is( $new2->delta_seconds, 4, 'seconds go up' ); + is( $new2->delta_nanoseconds, 200_300_400, 'nanoseconds are normalized' ); + + $new2->subtract( nanoseconds => 100_000_000 ); + is( $new2->delta_nanoseconds, 100_300_400, 'sub nanoseconds works' ); + + my $new3 = $dur2 * 3; + + is( $new3->delta_seconds, 4, 'seconds normalized after multiplication' ); + is( + $new3->delta_nanoseconds, 500_000_000, + 'nanoseconds normalized after multiplication' + ); +} + +{ + my $dur1 = DateTime::Duration->new( seconds => 1 ); + my $dur2 = DateTime::Duration->new( seconds => 1 ); + + $dur1->add($dur2); + is( + $dur1->delta_seconds, 2, + 'add method works with a duration object' + ); + + $dur1->subtract($dur2); + is( + $dur1->delta_seconds, 1, + 'subtract method works with a duration object' + ); +} + +{ + my $dur = DateTime::Duration->new( nanoseconds => -10 ); + is( $dur->nanoseconds, 10, 'nanoseconds is 10' ); + is( $dur->delta_nanoseconds, -10, 'delta_nanoseconds is -10' ); + ok( $dur->is_negative, 'duration is negative' ); +} + +{ + my $dur = DateTime::Duration->new( days => 0 ); + is( $dur->delta_days, 0, 'delta_days is 0' ); + ok( !$dur->is_positive, 'not positive' ); + ok( $dur->is_zero, 'is zero' ); + ok( !$dur->is_negative, 'not negative' ); +} + +{ + is( + exception { + DateTime::Duration->new( months => 3 )->add( hours => -3 ) + ->add( minutes => 1 ); + }, + undef, + 'method chaining should work' + ); +} + +{ + my $min_1 = DateTime::Duration->new( minutes => 1 ); + my $hour_1 = DateTime::Duration->new( hours => 1 ); + + my $min_59 = $hour_1 - $min_1; + + is( $min_59->delta_months, 0, 'delta_months is 0' ); + is( $min_59->delta_days, 0, 'delta_days is 0' ); + is( $min_59->delta_minutes, 59, 'delta_minutes is 59' ); + is( $min_59->delta_seconds, 0, 'delta_seconds is 0' ); + is( $min_59->delta_nanoseconds, 0, 'delta_nanoseconds is 0' ); + + my $min_neg_59 = $min_1 - $hour_1; + + is( $min_neg_59->delta_months, 0, 'delta_months is 0' ); + is( $min_neg_59->delta_days, 0, 'delta_days is 0' ); + is( $min_neg_59->delta_minutes, -59, 'delta_minutes is -59' ); + is( $min_neg_59->delta_seconds, 0, 'delta_seconds is 0' ); + is( $min_neg_59->delta_nanoseconds, 0, 'delta_nanoseconds is 0' ); +} + +{ + my $dur1 = DateTime::Duration->new( minutes => 10 ); + my $dur2 = DateTime::Duration->new( minutes => 20 ); + + like( + exception { 1 if $dur1 <=> $dur2 }, + qr/does not overload comparison/, + 'check error for duration comparison overload' + ); + + is( + DateTime::Duration->compare( $dur1, $dur2 ), -1, + '20 minutes is greater than 10 minutes' + ); + + is( + DateTime::Duration->compare( + $dur1, $dur2, DateTime->new( year => 1 ) + ), + -1, + '20 minutes is greater than 10 minutes' + ); +} + +{ + my $dur1 = DateTime::Duration->new( days => 29 ); + my $dur2 = DateTime::Duration->new( months => 1 ); + + my $base = DateTime->new( year => 2004 ); + is( + DateTime::Duration->compare( $dur1, $dur2, $base ), -1, + '29 days is less than 1 month with base of 2004-01-01' + ); + + $base = DateTime->new( year => 2004, month => 2 ); + is( + DateTime::Duration->compare( $dur1, $dur2, $base ), 0, + '29 days is equal to 1 month with base of 2004-02-01' + ); + + $base = DateTime->new( year => 2005, month => 2 ); + is( + DateTime::Duration->compare( $dur1, $dur2, $base ), 1, + '29 days is greater than 1 month with base of 2005-02-01' + ); +} + +{ + my $dur1 = DateTime::Duration->new( + nanoseconds => 1_000, + seconds => 1, + ); + + my $dur2 = $dur1->clone->subtract( nanoseconds => 5_000 ); + + is( $dur2->delta_seconds, 0, 'normalize nanoseconds to positive' ); + is( + $dur2->delta_nanoseconds, 999_996_000, + 'normalize nanoseconds to positive' + ); + + my $dur3 = $dur1->clone->subtract( nanoseconds => 6_000 ) + ->subtract( nanoseconds => 999_999_000 ); + + is( $dur3->delta_seconds, 0, 'normalize nanoseconds to negative' ); + is( + $dur3->delta_nanoseconds, -4_000, + 'normalize nanoseconds to negative' + ); + + my $dur4 = DateTime::Duration->new( + seconds => -1, + nanoseconds => -2_500_000_000 + ); + + is( $dur4->delta_seconds, -3, 'normalize many negative nanoseconds' ); + is( + $dur4->delta_nanoseconds, -500_000_000, + 'normalize many negative nanoseconds' + ); +} + +{ + my $dur = DateTime::Duration->new( + minutes => 30, + seconds => -1, + ); + + ok( !$dur->is_positive, 'is not positive' ); + ok( !$dur->is_zero, 'is not zero' ); + ok( !$dur->is_negative, 'is not negative' ); +} + +{ + my $dur = DateTime::Duration->new( minutes => 50 ); + + is( $dur->in_units('years'), 0, 'in_units returns 0 for years' ); + is( $dur->in_units('months'), 0, 'in_units returns 0 for months' ); + is( $dur->in_units('days'), 0, 'in_units returns 0 for days' ); + is( $dur->in_units('hours'), 0, 'in_units returns 0 for hours' ); + is( $dur->in_units('seconds'), 0, 'in_units returns 0 for seconds' ); + is( + $dur->in_units('nanoseconds'), 0, + 'in_units returns 0 for nanoseconds' + ); +} + +{ + local $TODO = 'reject fractional units in DateTime::Duration->new'; + + like( + exception { DateTime::Duration->new( minutes => 50.2 ) }, + qr/is an integer/, + 'cannot create a duration with fractional units' + ); +} + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-12week.t libdatetime-perl-1.46/xt/author/pp-12week.t --- libdatetime-perl-1.21/xt/author/pp-12week.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-12week.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,58 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +use strict; +use warnings; + +use Test::More; + +use DateTime; + +my @tests = ( + [ [ 1964, 12, 31 ], [ 1964, 53 ] ], + [ [ 1965, 1, 1 ], [ 1964, 53 ] ], + [ [ 1971, 9, 7 ], [ 1971, 36 ] ], + [ [ 1971, 10, 25 ], [ 1971, 43 ] ], + [ [ 1995, 1, 1 ], [ 1994, 52 ] ], + [ [ 1995, 11, 18 ], [ 1995, 46 ] ], + [ [ 1995, 12, 31 ], [ 1995, 52 ] ], + [ [ 1996, 12, 31 ], [ 1997, 1 ] ], + [ [ 2001, 4, 28 ], [ 2001, 17 ] ], + [ [ 2001, 8, 2 ], [ 2001, 31 ] ], + [ [ 2001, 9, 11 ], [ 2001, 37 ] ], + [ [ 2002, 12, 25 ], [ 2002, 52 ] ], + [ [ 2002, 12, 31 ], [ 2003, 1 ] ], + [ [ 2003, 1, 1 ], [ 2003, 1 ] ], + [ [ 2003, 12, 31 ], [ 2004, 1 ] ], + [ [ 2004, 1, 1 ], [ 2004, 1 ] ], + [ [ 2004, 12, 31 ], [ 2004, 53 ] ], + [ [ 2005, 1, 1 ], [ 2004, 53 ] ], + [ [ 2005, 12, 31 ], [ 2005, 52 ] ], + [ [ 2006, 1, 1 ], [ 2005, 52 ] ], + [ [ 2006, 12, 31 ], [ 2006, 52 ] ], + [ [ 2007, 1, 1 ], [ 2007, 1 ] ], + [ [ 2007, 12, 31 ], [ 2008, 1 ] ], + [ [ 2008, 1, 1 ], [ 2008, 1 ] ], + [ [ 2008, 12, 31 ], [ 2009, 1 ] ], + [ [ 2009, 1, 1 ], [ 2009, 1 ] ], +); + +foreach my $test (@tests) { + my @args = @{ $test->[0] }; + my @results = @{ $test->[1] }; + + my $dt = DateTime->new( + year => $args[0], + month => $args[1], + day => $args[2], + time_zone => 'UTC', + ); + + my ( $year, $week ) = $dt->week(); + + is( "$year-W$week", "$results[0]-W$results[1]", 'week for ' . $dt->ymd ); +} + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-13strftime.t libdatetime-perl-1.46/xt/author/pp-13strftime.t --- libdatetime-perl-1.21/xt/author/pp-13strftime.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-13strftime.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,433 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +# test suite stolen shamelessly from TimeDate distro +use strict; +use warnings; +use utf8; + +use Test::More 0.96; + +use DateTime; +use DateTime::Locale; + +test_strftime_for_locale( 'en-US', en_tests() ); +test_strftime_for_locale( 'de', de_tests() ); +test_strftime_for_locale( 'it', it_tests() ); + +subtest( + 'strftime with multiple params', + sub { + my $dt = DateTime->new( + year => 1800, + month => 1, + day => 10, + time_zone => 'UTC', + ); + + my ( $y, $d ) = $dt->strftime( '%Y', '%d' ); + is( $y, 1800, 'first value is year' ); + is( $d, 10, 'second value is day' ); + + $y = $dt->strftime( '%Y', '%d' ); + is( $y, 1800, 'scalar context returns year' ); + } +); + +subtest( + 'hour formatting', + sub { + my $dt = DateTime->new( + year => 2003, + hour => 0, + minute => 0 + ); + + is( + $dt->strftime('%I %M %p'), '12 00 AM', + 'formatting of hours as 1-12' + ); + is( + $dt->strftime('%l %M %p'), '12 00 AM', + 'formatting of hours as 1-12' + ); + + $dt->set( hour => 1 ); + is( + $dt->strftime('%I %M %p'), '01 00 AM', + 'formatting of hours as 1-12' + ); + is( + $dt->strftime('%l %M %p'), ' 1 00 AM', + 'formatting of hours as 1-12' + ); + + $dt->set( hour => 11 ); + is( + $dt->strftime('%I %M %p'), '11 00 AM', + 'formatting of hours as 1-12' + ); + is( + $dt->strftime('%l %M %p'), '11 00 AM', + 'formatting of hours as 1-12' + ); + + $dt->set( hour => 12 ); + is( + $dt->strftime('%I %M %p'), '12 00 PM', + 'formatting of hours as 1-12' + ); + is( + $dt->strftime('%l %M %p'), '12 00 PM', + 'formatting of hours as 1-12' + ); + + $dt->set( hour => 13 ); + is( + $dt->strftime('%I %M %p'), '01 00 PM', + 'formatting of hours as 1-12' + ); + is( + $dt->strftime('%l %M %p'), ' 1 00 PM', + 'formatting of hours as 1-12' + ); + + $dt->set( hour => 23 ); + is( + $dt->strftime('%I %M %p'), '11 00 PM', + 'formatting of hours as 1-12' + ); + is( + $dt->strftime('%l %M %p'), '11 00 PM', + 'formatting of hours as 1-12' + ); + + $dt->set( hour => 0 ); + is( + $dt->strftime('%I %M %p'), '12 00 AM', + 'formatting of hours as 1-12' + ); + is( + $dt->strftime('%l %M %p'), '12 00 AM', + 'formatting of hours as 1-12' + ); + } +); + +subtest( + '%V', + sub { + is( + DateTime->new( year => 2003, month => 1, day => 1 ) + ->strftime('%V'), + '01', '%V is 01' + ); + } +); + +subtest( + '%% and %{method}', + sub { + my $dt = DateTime->new( + year => 2004, month => 8, day => 16, + hour => 15, minute => 30, nanosecond => 123456789, + locale => 'en', + ); + + # Should print '%{day_name}', prints '30onday'! + is( + $dt->strftime('%%{day_name}%n'), "%{day_name}\n", + '%%{day_name}%n bug' + ); + + # Should print '%6N', prints '123456' + is( $dt->strftime('%%6N%n'), "%6N\n", '%%6N%n bug' ); + } +); + +subtest( + 'nanosecond formatting', + sub { + subtest( + 'nanosecond floating point rounding', + sub { + # Internally this becomes 119999885 nanoseconds (floating point math is awesome) + my $epoch = 1297777805.12; + my $dt = DateTime->from_epoch( epoch => $epoch ); + + my @vals = ( + 1, + 12, + 120, + 1200, + 12000, + 120000, + 1200000, + 12000000, + 120000000, + 1200000000, + ); + + my $x = 1; + for my $val (@vals) { + my $spec = '%' . $x++ . 'N'; + is( + $dt->strftime($spec), $val, + "strftime($spec) for $epoch == $val" + ); + } + } + ); + subtest( + 'nanosecond rounding in strftime', + sub { + my $dt = DateTime->new( + 'year' => 1999, + month => 9, + day => 7, + hour => 13, + minute => 2, + second => 42, + nanosecond => 12345678, + ); + + my %tests = ( + '%N' => '012345678', + '%3N' => '012', + '%6N' => '012345', + '%10N' => '0123456780', + ); + for my $fmt ( sort keys %tests ) { + is( + $dt->strftime($fmt), $tests{$fmt}, + "$fmt is $tests{$fmt}" + ); + } + } + ); + } +); + +subtest( + '0 nanoseconds', + sub { + my $dt = DateTime->new( year => 2011 ); + + for my $i ( 1 .. 9 ) { + my $spec = '%' . $i . 'N'; + my $expect = '0' x $i; + + is( + $dt->strftime($spec), $expect, + "strftime $spec with 0 nanoseconds" + ); + } + } +); + +subtest( + 'week-year formatting', + sub { + my $dt = DateTime->new( 'year' => 2012, month => 1, day => 1 ); + subtest( + $dt->ymd, + sub { + my %tests = ( + '%U' => '01', + '%W' => '00', + '%j' => '001', + ); + for my $fmt ( sort keys %tests ) { + is( + $dt->strftime($fmt), $tests{$fmt}, + "$fmt is $tests{$fmt}" + ); + } + } + ); + + $dt = DateTime->new( 'year' => 2012, month => 1, day => 10 ); + subtest( + $dt->ymd, + sub { + my %tests = ( + '%U' => '02', + '%W' => '02', + '%j' => '010', + ); + for my $fmt ( sort keys %tests ) { + is( + $dt->strftime($fmt), $tests{$fmt}, + "$fmt is $tests{$fmt}" + ); + } + } + ); + } +); + +done_testing(); + +sub test_strftime_for_locale { + my $locale = shift; + my $tests = shift; + + my $dt = DateTime->new( + year => 1999, + month => 9, + day => 7, + hour => 13, + minute => 2, + second => 42, + nanosecond => 123456789, + time_zone => 'UTC', + locale => $locale, + ); + + subtest( + $locale, + sub { + for my $fmt ( sort keys %{$tests} ) { + is( + $dt->strftime($fmt), + $tests->{$fmt}, + "$fmt is $tests->{$fmt}" + ); + } + } + ); +} + +sub en_tests { + my $en_locale = DateTime::Locale->load('en-US'); + + my $c_format = $en_locale->datetime_format; + $c_format + =~ s/\{1\}/$en_locale->month_format_abbreviated->[8] . ' 7, 1999'/e; + $c_format =~ s/\{0\}/'1:02:42 ' . $en_locale->am_pm_abbreviated->[1]/e; + + return { + '%%' => '%', + '%a' => $en_locale->day_format_abbreviated->[1], + '%A' => $en_locale->day_format_wide->[1], + '%b' => $en_locale->month_format_abbreviated->[8], + '%B' => $en_locale->month_format_wide->[8], + '%C' => '19', + '%d' => '07', + '%e' => ' 7', + '%D' => '09/07/99', + '%h' => $en_locale->month_format_abbreviated->[8], + '%H' => '13', + '%I' => '01', + '%j' => '250', + '%k' => '13', + '%l' => ' 1', + '%m' => '09', + '%M' => '02', + '%N' => '123456789', + '%3N' => '123', + '%6N' => '123456', + '%10N' => '1234567890', + '%p' => $en_locale->am_pm_abbreviated->[1], + '%r' => '01:02:42 ' . $en_locale->am_pm_abbreviated->[1], + '%R' => '13:02', + '%s' => '936709362', + '%S' => '42', + '%T' => '13:02:42', + '%U' => '36', + '%V' => '36', + '%w' => '2', + '%W' => '36', + '%y' => '99', + '%Y' => '1999', + '%Z' => 'UTC', + '%z' => '+0000', + '%E' => '%E', + '%{foobar}' => '%{foobar}', + '%{month}' => '9', + '%{year}' => '1999', + '%x' => $en_locale->month_format_abbreviated->[8] . ' 7, 1999', + '%X' => '1:02:42 ' . $en_locale->am_pm_abbreviated->[1], + '%c' => $c_format, + }; +} + +sub de_tests { + my $de_locale = DateTime::Locale->load('de'); + return { + '%%' => '%', + '%a' => $de_locale->day_format_abbreviated->[1], + '%A' => $de_locale->day_format_wide->[1], + '%b' => $de_locale->month_format_abbreviated->[8], + '%B' => $de_locale->month_format_wide->[8], + '%C' => '19', + '%d' => '07', + '%e' => ' 7', + '%D' => '09/07/99', + '%b' => $de_locale->month_format_abbreviated->[8], + '%H' => '13', + '%I' => '01', + '%j' => '250', + '%k' => '13', + '%l' => ' 1', + '%m' => '09', + '%M' => '02', + '%p' => $de_locale->am_pm_abbreviated->[1], + '%r' => '01:02:42 ' . $de_locale->am_pm_abbreviated->[1], + '%R' => '13:02', + '%s' => '936709362', + '%S' => '42', + '%T' => '13:02:42', + '%U' => '36', + '%V' => '36', + '%w' => '2', + '%W' => '36', + '%y' => '99', + '%Y' => '1999', + '%Z' => 'UTC', + '%z' => '+0000', + '%{month}' => '9', + '%{year}' => '1999', + }; +} + +sub it_tests { + my $it_locale = DateTime::Locale->load('it'); + return { + '%%' => '%', + '%a' => $it_locale->day_format_abbreviated->[1], + '%A' => $it_locale->day_format_wide->[1], + '%b' => $it_locale->month_format_abbreviated->[8], + '%B' => $it_locale->month_format_wide->[8], + '%C' => '19', + '%d' => '07', + '%e' => ' 7', + '%D' => '09/07/99', + '%b' => $it_locale->month_format_abbreviated->[8], + '%H' => '13', + '%I' => '01', + '%j' => '250', + '%k' => '13', + '%l' => ' 1', + '%m' => '09', + '%M' => '02', + '%p' => $it_locale->am_pm_abbreviated->[1], + '%r' => '01:02:42 ' . $it_locale->am_pm_abbreviated->[1], + '%R' => '13:02', + '%s' => '936709362', + '%S' => '42', + '%T' => '13:02:42', + '%U' => '36', + '%V' => '36', + '%w' => '2', + '%W' => '36', + '%y' => '99', + '%Y' => '1999', + '%Z' => 'UTC', + '%z' => '+0000', + '%{month}' => '9', + '%{year}' => '1999', + }; +} + diff -Nru libdatetime-perl-1.21/xt/author/pp-14locale.t libdatetime-perl-1.46/xt/author/pp-14locale.t --- libdatetime-perl-1.21/xt/author/pp-14locale.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-14locale.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,106 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +use strict; +use warnings; + +use Test::Fatal; +use Test::More; + +use DateTime; +use DateTime::Locale; + +is( + exception { DateTime->new( year => 100, locale => 'en_US' ) }, + undef, + 'make sure new accepts locale parameter' +); + +is( + exception { DateTime->now( locale => 'en_US' ) }, + undef, + 'make sure now accepts locale parameter' +); + +is( + exception { DateTime->today( locale => 'en_US' ) }, + undef, + 'make sure today accepts locale parameter' +); + +is( + exception { DateTime->from_epoch( epoch => 1, locale => 'en_US' ) }, + undef, + 'make sure from_epoch accepts locale parameter' +); + +is( + exception { + DateTime->last_day_of_month( + year => 100, month => 2, + locale => 'en_US' + ); + }, + undef, + 'make sure last_day_of_month accepts locale parameter' +); + +{ + + package DT::Object; + sub utc_rd_values { ( 0, 0 ) } +} + +is( + exception { + DateTime->from_object( + object => ( bless {}, 'DT::Object' ), + locale => 'en_US' + ); + }, + undef, + , + 'make sure constructor accepts locale parameter' +); + +is( + exception { + DateTime->new( + year => 100, + locale => DateTime::Locale->load('en_US') + ); + }, + undef, + 'make sure constructor accepts locale parameter as object' +); + +DateTime->DefaultLocale('it'); +is( DateTime->now->locale->id, 'it', 'default locale should now be "it"' ); + +{ + my $dt = DateTime->new( + year => 2013, month => 10, day => 27, hour => 0, + time_zone => 'UTC' + ); + + my $after_zone = $dt->clone()->set_time_zone('Europe/Rome'); + + is( + $after_zone->offset(), + '7200', + 'offset is 7200 after set_time_zone()' + ); + + my $after_locale + = $dt->clone()->set_time_zone('Europe/Rome')->set_locale('en_GB'); + + is( + $after_locale->offset(), + '7200', + 'offset is 7200 after set_time_zone() and set_locale()' + ); +} + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-15jd.t libdatetime-perl-1.46/xt/author/pp-15jd.t --- libdatetime-perl-1.21/xt/author/pp-15jd.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-15jd.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,104 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +use strict; +use warnings; + +use Test::More; + +use DateTime; + +# Borrowed from Matt Sergeant's Time::Piece + +# A table of MJD and components +my @mjd = ( + '51603.524' => { + year => 2000, + month => 2, + day => 29, + hour => 12, + minute => 34, + second => 56, + }, + + '40598.574' => { + year => 1970, + month => 1, + day => 12, + hour => 13, + minute => 46, + second => 51, + }, + + '52411.140' => { + year => 2002, + month => 5, + day => 17, + hour => 3, + minute => 21, + second => 43, + }, + + '53568.547' => { + year => 2005, + month => 7, + day => 17, + hour => 13, + minute => 8, + second => 23, + }, + + '52295.218' => { + year => 2002, + month => 1, + day => 21, + hour => 5, + minute => 13, + second => 20, + }, + + '52295.399' => { + year => 2002, + month => 1, + day => 21, + hour => 9, + minute => 35, + second => 3, + }, + + # beginning of MJD + '0.000' => { + year => 1858, + month => 11, + day => 17, + hour => 0, + minute => 0, + second => 0, + }, + + # beginning of JD + '-2400000.500' => { + year => -4713, + month => 11, + day => 24, + hour => 12, + minute => 0, + second => 0, + }, +); + +while ( my ( $mjd, $comps ) = splice @mjd, 0, 2 ) { + my $dt = DateTime->new( + %$comps, + time_zone => 'UTC', + ); + + is( sprintf( '%.3f', $dt->mjd ), $mjd, "MJD should be $mjd" ); + + my $jd = sprintf( '%.3f', $mjd + 2_400_000.5 ); + is( sprintf( '%.3f', $dt->jd ), $jd, "JD should be $jd" ); +} + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-16truncate.t libdatetime-perl-1.46/xt/author/pp-16truncate.t --- libdatetime-perl-1.21/xt/author/pp-16truncate.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-16truncate.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,350 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +## no critic (Modules::ProhibitExcessMainComplexity) +use strict; +use warnings; + +use Test::Fatal; +use Test::More 0.88; + +use DateTime; +use Try::Tiny; + +my %vals = ( + year => 50, + month => 3, + day => 15, + hour => 10, + minute => 55, + second => 17, + nanosecond => 1234, +); + +{ + my $dt = DateTime->new(%vals); + $dt->truncate( to => 'second' ); + foreach my $f (qw( year month day hour minute second )) { + is( $dt->$f(), $vals{$f}, "$f should be $vals{$f}" ); + } + + foreach my $f (qw( nanosecond )) { + is( $dt->$f(), 0, "$f should be 0" ); + } +} + +{ + my $dt = DateTime->new(%vals); + $dt->truncate( to => 'minute' ); + foreach my $f (qw( year month day hour minute )) { + is( $dt->$f(), $vals{$f}, "$f should be $vals{$f}" ); + } + + foreach my $f (qw( second nanosecond )) { + is( $dt->$f(), 0, "$f should be 0" ); + } +} + +{ + my $dt = DateTime->new(%vals); + $dt->truncate( to => 'hour' ); + foreach my $f (qw( year month day hour )) { + is( $dt->$f(), $vals{$f}, "$f should be $vals{$f}" ); + } + + foreach my $f (qw( minute second nanosecond )) { + is( $dt->$f(), 0, "$f should be 0" ); + } +} + +{ + my $dt = DateTime->new(%vals); + $dt->truncate( to => 'day' ); + foreach my $f (qw( year month day )) { + is( $dt->$f(), $vals{$f}, "$f should be $vals{$f}" ); + } + + foreach my $f (qw( hour minute second nanosecond )) { + is( $dt->$f(), 0, "$f should be 0" ); + } +} + +{ + my $dt = DateTime->new(%vals); + $dt->truncate( to => 'month' ); + foreach my $f (qw( year month )) { + is( $dt->$f(), $vals{$f}, "$f should be $vals{$f}" ); + } + + foreach my $f (qw( day )) { + is( $dt->$f(), 1, "$f should be 1" ); + } + + foreach my $f (qw( hour minute second nanosecond )) { + is( $dt->$f(), 0, "$f should be 0" ); + } +} + +{ + my $dt = DateTime->new(%vals); + $dt->truncate( to => 'year' ); + foreach my $f (qw( year )) { + is( $dt->$f(), $vals{$f}, "$f should be $vals{$f}" ); + } + + foreach my $f (qw( month day )) { + is( $dt->$f(), 1, "$f should be 1" ); + } + + foreach my $f (qw( hour minute second nanosecond )) { + is( $dt->$f(), 0, "$f should be 0" ); + } +} + +{ + my $dt = DateTime->new( year => 2003, month => 11, day => 17 ); + + for ( 1 .. 6 ) { + my $trunc = $dt->clone->add( days => $_ )->truncate( to => 'week' ); + + is( + $trunc->day, 17, + 'truncate to week should always truncate to monday of week' + ); + } + + { + my $trunc = $dt->clone->add( days => 7 )->truncate( to => 'week' ); + + is( + $trunc->day, 24, + 'truncate to week should always truncate to monday of week' + ); + } +} + +{ + my $dt = DateTime->new( year => 2003, month => 10, day => 2 ) + ->truncate( to => 'week' ); + + is( $dt->year, 2003, 'truncation to week across month boundary' ); + is( $dt->month, 9, 'truncation to week across month boundary' ); + is( $dt->day, 29, 'truncation to week across month boundary' ); +} + +{ + my $dt = DateTime->new( + year => 2013, month => 12, day => 16, + locale => 'fr_FR' + ); + + for ( 1 .. 6 ) { + my $trunc + = $dt->clone->add( days => $_ )->truncate( to => 'local_week' ); + + is( + $trunc->day, 16, + 'truncate to local_week returns correct date - locale start is Monday' + ); + } + + { + my $trunc + = $dt->clone->add( days => 7 )->truncate( to => 'local_week' ); + + is( + $trunc->day, 23, + 'truncate to local_week returns correct date - locale start is Monday' + ); + } +} + +{ + my $dt = DateTime->new( + year => 2013, month => 11, day => 2, + locale => 'fr_FR' + )->truncate( to => 'local_week' ); + + is( + $dt->year, 2013, + 'truncation to local_week across month boundary - locale start is Monday' + ); + is( + $dt->month, 10, + 'truncation to local_week across month boundary - locale start is Monday' + ); + is( + $dt->day, 28, + 'truncation to local_week across month boundary - locale start is Monday' + ); +} + +{ + my $dt = DateTime->new( + year => 2013, month => 12, day => 15, + locale => 'en_US' + ); + + for ( 1 .. 6 ) { + my $trunc + = $dt->clone->add( days => $_ )->truncate( to => 'local_week' ); + + is( + $trunc->day, 15, + 'truncate to local_week returns correct date - locale start is Sunday' + ); + } + + { + my $trunc + = $dt->clone->add( days => 7 )->truncate( to => 'local_week' ); + + is( + $trunc->day, 22, + 'truncate to local_week returns correct date - locale start is Sunday' + ); + } +} + +{ + my $dt = DateTime->new( + year => 2013, month => 11, day => 2, + locale => 'en_US' + )->truncate( to => 'local_week' ); + + is( + $dt->year, 2013, + 'truncation to local_week across month boundary - locale start is Sunday' + ); + is( + $dt->month, 10, + 'truncation to local_week across month boundary - locale start is Sunday' + ); + is( + $dt->day, 27, + 'truncation to local_week across month boundary - locale start is Sunday' + ); +} + +{ + my %months_to_quarter = ( + 1 => 1, + 2 => 1, + 3 => 1, + 4 => 4, + 5 => 4, + 6 => 4, + 7 => 7, + 8 => 7, + 9 => 7, + 10 => 10, + 11 => 10, + 12 => 10, + ); + + for my $year ( -1, 100, 2016 ) { + for my $month ( sort keys %months_to_quarter ) { + for my $day ( 1, 15, 27 ) { + my $dt = DateTime->new( + year => $year, + month => $month, + day => $day, + ); + subtest( + 'truncate to quarter - ' . $dt->ymd, + sub { + $dt->truncate( to => 'quarter' ); + is( + $dt->year, + $year, + 'year is unchanged' + ); + is( + $dt->month, + $months_to_quarter{$month}, + "month $month becomes month $months_to_quarter{$month}" + ); + is( + $dt->day, + 1, + 'day is always 1' + ); + is( + $dt->hour, + 0, + 'hour is always 0' + ); + is( + $dt->minute, + 0, + 'minute is always 0' + ); + is( + $dt->second, + 0, + 'second is always 0' + ); + is( + $dt->nanosecond, + 0, + 'nanosecond is always 0' + ); + } + ); + } + } + } +} + +{ + my $dt = DateTime->new(%vals); + + for my $bad (qw( seconds minutes year_foo month_bar )) { + like( + exception { $dt->truncate( to => $bad ) }, + qr/Validation failed for type named TruncationLevel/, + "bad truncate parameter ($bad) throws an error" + ); + } +} + +{ + my $dt = DateTime->new( + year => 2010, + month => 3, + day => 25, + hour => 1, + minute => 5, + time_zone => 'Asia/Tehran', + ); + + is( + $dt->day_of_week(), + 4, + 'day of week is Thursday' + ); + + my $error; + try { + $dt->truncate( to => 'week' ); + } + catch { + $error = $_; + }; + + like( + $error, + qr/Invalid local time for date/, + 'truncate operation threw an error because of an invalid local datetime' + ); + + is( + $dt->day_of_week(), + 4, + 'day of week does not change after failed truncate() call' + ); +} + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-17set-return.t libdatetime-perl-1.46/xt/author/pp-17set-return.t --- libdatetime-perl-1.21/xt/author/pp-17set-return.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-17set-return.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,43 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +use strict; +use warnings; + +use Test::More; + +use DateTime; +use DateTime::Duration; + +{ + my $dt = DateTime->new( year => 2008, month => 2, day => 28 ); + my $du = DateTime::Duration->new( years => 1 ); + + my $p; + + $p = $dt->set( year => 1882 ); + is( DateTime->compare( $p, $dt ), 0, 'set returns self' ); + + $p = $dt->set_time_zone('Australia/Sydney'); + is( DateTime->compare( $p, $dt ), 0, 'set_time_zone returns self' ); + + $p = $dt->add_duration($du); + is( DateTime->compare( $p, $dt ), 0, 'add_duration returns self' ); + + $p = $dt->add( years => 2 ); + is( DateTime->compare( $p, $dt ), 0, 'add returns self' ); + + $p = $dt->subtract_duration($du); + is( DateTime->compare( $p, $dt ), 0, 'subtract_duration returns self' ); + + $p = $dt->subtract( years => 3 ); + is( DateTime->compare( $p, $dt ), 0, 'subtract returns self' ); + + $p = $dt->truncate( to => 'day' ); + is( DateTime->compare( $p, $dt ), 0, 'truncate returns self' ); + +} + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-18today.t libdatetime-perl-1.46/xt/author/pp-18today.t --- libdatetime-perl-1.21/xt/author/pp-18today.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-18today.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,26 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +use strict; +use warnings; + +use Test::More; + +use DateTime; + +{ + my $now = DateTime->now; + my $today = DateTime->today; + + is( $today->year, $now->year, 'today->year' ); + is( $today->month, $now->month, 'today->month' ); + is( $today->day, $now->day, 'today->day' ); + + is( $today->hour, 0, 'today->hour' ); + is( $today->minute, 0, 'today->hour' ); + is( $today->second, 0, 'today->hour' ); +} + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-19leap-second.t libdatetime-perl-1.46/xt/author/pp-19leap-second.t --- libdatetime-perl-1.21/xt/author/pp-19leap-second.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-19leap-second.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,1198 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +use strict; +use warnings; + +use Test::Fatal; +use Test::More; +use DateTime; +use DateTime::LeapSecond; + +# tests using UTC times +{ + + # 1972-06-30T23:58:20 UTC + my $t = DateTime->new( + year => 1972, month => 6, day => 30, + hour => 23, minute => 58, second => 20, + time_zone => 'UTC', + ); + my $t1 = $t->clone; + + is( $t->year, 1972, 'year is 1972' ); + is( $t->minute, 58, 'minute is 58' ); + is( $t->second, 20, 'second is 20' ); + + # 1972-06-30T23:59:20 UTC + $t->add( seconds => 60 ); + is( $t->year, 1972, 'year is 1972' ); + is( $t->minute, 59, 'minute is 59' ); + is( $t->second, 20, 'second is 20' ); + + # 1972-07-01T00:00:19 UTC + $t->add( seconds => 60 ); + is( $t->year, 1972, 'year is 1972' ); + is( $t->minute, 0, 'minute is 0' ); + is( $t->second, 19, 'second is 19' ); + + # 1972-06-30T23:59:60 UTC + $t->subtract( seconds => 20 ); + is( $t->year, 1972, 'year is 1972' ); + is( $t->minute, 59, 'minute is 59' ); + is( $t->second, 60, 'second is 60' ); + is( $t->{utc_rd_secs}, 86400, 'utc_rd_secs is 86400' ); + + # subtract_datetime + my $t2 = DateTime->new( + year => 1972, month => 7, day => 1, + hour => 0, minute => 0, second => 20, + time_zone => 'UTC', + ); + my $dur = $t2->subtract_datetime_absolute($t1); + is( $dur->delta_seconds, 121, 'delta_seconds is 121' ); + + $dur = $t1->subtract_datetime_absolute($t2); + is( $dur->delta_seconds, -121, 'delta_seconds is -121' ); +} + +{ + + # tests using floating times + # a floating time has no leap seconds + + my $t = DateTime->new( + year => 1971, month => 12, day => 31, + hour => 23, minute => 58, second => 20, + time_zone => 'floating', + ); + my $t1 = $t->clone; + + $t->add( seconds => 60 ); + is( $t->minute, 59, 'min' ); + is( $t->second, 20, 'sec' ); + + $t->add( seconds => 60 ); + is( $t->minute, 0, 'min' ); + is( $t->second, 20, 'sec' ); + + # subtract_datetime, using floating times + + my $t2 = DateTime->new( + year => 1972, month => 1, day => 1, + hour => 0, minute => 0, second => 20, + time_zone => 'floating', + ); + my $dur = $t2->subtract_datetime_absolute($t1); + is( $dur->delta_seconds, 120, 'delta_seconds is 120' ); + + $dur = $t1->subtract_datetime_absolute($t2); + is( $dur->delta_seconds, -120, 'delta_seconds is -120' ); +} + +{ + + # tests using time zones + # leap seconds occur during _UTC_ midnight + + # 1972-06-30 20:58:20 -03:00 = 1972-06-30 23:58:20 UTC + my $t = DateTime->new( + year => 1972, month => 6, day => 30, + hour => 20, minute => 58, second => 20, + time_zone => 'America/Sao_Paulo', + ); + + $t->add( seconds => 60 ); + is( $t->datetime, '1972-06-30T20:59:20', 'normal add' ); + is( $t->minute, 59, 'min' ); + is( $t->second, 20, 'sec' ); + + $t->add( seconds => 60 ); + is( $t->datetime, '1972-06-30T21:00:19', 'add over a leap second' ); + is( $t->minute, 0, 'min' ); + is( $t->second, 19, 'sec' ); + + $t->subtract( seconds => 20 ); + is( $t->datetime, '1972-06-30T20:59:60', 'subtract over a leap second' ); + is( $t->minute, 59, 'min' ); + is( $t->second, 60, 'sec' ); + is( $t->{utc_rd_secs}, 86400, 'rd_sec' ); +} + +# test that we can set second to 60 (negative offset) +{ + my $t = DateTime->new( + year => 1972, month => 6, day => 30, + hour => 20, minute => 59, second => 60, + time_zone => 'America/Sao_Paulo', + ); + + is( $t->second, 60, 'second set to 60 in constructor' ); +} + +{ + my $t = DateTime->new( + year => 1972, month => 6, day => 30, + hour => 21, minute => 0, second => 0, + time_zone => 'America/Sao_Paulo', + ); + + is( $t->second, 0, 'datetime just after leap second' ); +} + +{ + my $t = DateTime->new( + year => 1972, month => 6, day => 30, + hour => 21, minute => 0, second => 1, + time_zone => 'America/Sao_Paulo', + ); + + is( $t->second, 1, 'datetime two seconds after leap second' ); +} + +# test that we can set second to 60 (negative offset) +{ + is( + exception { + my $t = DateTime->new( + year => 1972, month => 6, day => 30, + hour => 22, minute => 59, second => 60, + time_zone => '-0100', + ); + + is( + $t->second, 60, + 'second set to 60 in constructor, negative TZ offset' + ); + }, + undef, + 'can set second to 60 in constructor' + ); +} + +# test that we can set second to 60 (positive offset) +{ + is( + exception { + my $t = DateTime->new( + year => 1972, month => 7, day => 1, + hour => 0, minute => 59, second => 60, + time_zone => '+0100', + ); + + is( + $t->second, 60, + 'second set to 60 in constructor, positive TZ offset' + ); + }, + undef, + 'can set second to 60 with positive TZ offset' + ); +} + +{ + my $t = DateTime->new( + year => 1972, month => 7, day => 1, + hour => 0, minute => 59, second => 59, + time_zone => '+0100', + ); + + is( $t->second, 59, 'datetime just before leap second' ); +} + +{ + my $t = DateTime->new( + year => 1972, month => 7, day => 1, + hour => 1, minute => 0, second => 0, + time_zone => '+0100', + ); + + is( $t->second, 0, 'datetime just after leap second' ); +} + +{ + my $t = DateTime->new( + year => 1972, month => 7, day => 1, + hour => 1, minute => 0, second => 1, + time_zone => '+0100', + ); + + is( $t->second, 1, 'datetime two seconds after leap second' ); +} + +{ + my $t = DateTime->new( + year => 1972, month => 7, day => 1, + hour => 0, minute => 0, second => 29, + time_zone => '+00:00:30', + ); + + is( + $t->second, 29, + 'time zone +00:00:30 and leap seconds, second value' + ); + is( $t->minute, 0, 'time zone +00:00:30 and leap seconds, minute value' ); +} + +{ + my $t = DateTime->new( + year => 1972, month => 6, day => 30, + hour => 20, minute => 59, second => 60, + time_zone => 'America/Sao_Paulo', + ); + + $t->set_time_zone('UTC'); + is( $t->second, 60, 'second after setting time zone' ); + is( $t->hour, 23, 'hour after setting time zone' ); + + $t->add( days => 1 ); + is( + $t->datetime, '1972-07-02T00:00:00', + 'add 1 day starting on leap second' + ); + + $t->subtract( days => 1 ); + + is( + $t->datetime, '1972-07-01T00:00:00', + 'add and subtract 1 day starting on leap second' + ); + + is( $t->leap_seconds, 1, 'datetime has 1 leap second' ); +} + +{ + my $t = DateTime->new( + year => 1972, month => 6, day => 30, + hour => 23, minute => 59, second => 59, + time_zone => 'UTC', + ); + + is( + $t->epoch, 78796799, + 'epoch just before first leap second is 78796799' + ); + + $t->add( seconds => 1 ); + + is( $t->epoch, 78796800, 'epoch of first leap second is 78796800' ); + + $t->add( seconds => 1 ); + + is( + $t->epoch, 78796800, + 'epoch of first second after first leap second is 78796700' + ); +} + +{ + my $dt = DateTime->new( year => 2003, time_zone => 'UTC' ); + + is( $dt->leap_seconds, 22, 'datetime has 22 leap seconds' ); +} + +{ + my $dt = DateTime->new( year => 2003, time_zone => 'floating' ); + + is( $dt->leap_seconds, 0, 'floating datetime has 0 leap seconds' ); +} + +# date math across leap seconds distinguishes between minutes and second +{ + my $t = DateTime->new( + year => 1972, month => 12, day => 31, + hour => 23, minute => 59, second => 30, + time_zone => 'UTC' + ); + + $t->add( minutes => 1 ); + + is( $t->year, 1973, '+1 minute, year == 1973' ); + is( $t->month, 1, '+1 minute, month == 1' ); + is( $t->day, 1, '+1 minute, day == 1' ); + is( $t->hour, 0, '+1 minute, hour == 0' ); + is( $t->minute, 0, '+1 minute, minute == 0' ); + is( $t->second, 30, '+1 minute, second == 30' ); +} + +{ + my $t = DateTime->new( + year => 1972, month => 12, day => 31, + hour => 23, minute => 59, second => 30, + time_zone => 'UTC' + ); + + $t->add( seconds => 60 ); + + is( $t->year, 1973, '+60 seconds, year == 1973' ); + is( $t->month, 1, '+60 seconds, month == 1' ); + is( $t->day, 1, '+60 seconds, day == 1' ); + is( $t->hour, 0, '+60 seconds, hour == 0' ); + is( $t->minute, 0, '+60 seconds, minute == 0' ); + is( $t->second, 29, '+60 seconds, second == 29' ); +} + +{ + my $t = DateTime->new( + year => 1972, month => 12, day => 31, + hour => 23, minute => 59, second => 30, + time_zone => 'UTC' + ); + + $t->add( minutes => 1, seconds => 1 ); + + is( $t->year, 1973, '+1 minute & 1 second, year == 1973' ); + is( $t->month, 1, '+1 minute & 1 second, month == 1' ); + is( $t->day, 1, '+1 minute & 1 second, day == 1' ); + is( $t->hour, 0, '+1 minute & 1 second, hour == 0' ); + is( $t->minute, 0, '+1 minute & 1 second, minute == 0' ); + is( $t->second, 31, '+1 minute & 1 second, second == 31' ); +} + +{ + ok( + exception { + DateTime->new( + year => 1972, month => 12, day => 31, + hour => 23, minute => 59, second => 61, + time_zone => 'UTC', + ); + }, + 'Cannot give second of 61 except when it matches a leap second' + ); + + ok( + exception { + DateTime->new( + year => 1972, month => 12, day => 31, + hour => 23, minute => 58, second => 60, + time_zone => 'UTC', + ); + }, + 'Cannot give second of 60 except when it matches a leap second' + ); + + ok( + exception { + DateTime->new( + year => 1972, month => 12, day => 31, + hour => 23, minute => 59, second => 60, + time_zone => 'floating', + ); + }, + 'Cannot give second of 60 with floating time zone' + ); +} + +{ + my $dt1 = DateTime->new( + year => 1998, month => 12, day => 31, + hour => 23, minute => 59, second => 60, + time_zone => 'UTC', + ); + + my $dt2 = DateTime->new( + year => 1998, month => 12, day => 31, + hour => 23, minute => 58, second => 50, + time_zone => 'UTC', + ); + + my $pos_dur = $dt1 - $dt2; + + is( $pos_dur->delta_minutes, 1, 'delta_minutes is 1' ); + is( $pos_dur->delta_seconds, 10, 'delta_seconds is 10' ); + + my $neg_dur = $dt2 - $dt1; + + is( $neg_dur->delta_minutes, -1, 'delta_minutes is -1' ); + is( $neg_dur->delta_seconds, -10, 'delta_seconds is -10' ); +} + +{ + my $dt1 = DateTime->new( + year => 1998, month => 12, day => 31, + hour => 23, minute => 59, second => 55, + time_zone => 'UTC', + ); + + my $dt2 = DateTime->new( + year => 1998, month => 12, day => 31, + hour => 23, minute => 58, second => 50, + time_zone => 'UTC', + ); + + my $pos_dur = $dt1 - $dt2; + + is( $pos_dur->delta_minutes, 1, 'delta_minutes is 1' ); + is( $pos_dur->delta_seconds, 5, 'delta_seconds is 5' ); + + my $neg_dur = $dt2 - $dt1; + + is( $neg_dur->delta_minutes, -1, 'delta_minutes is -1' ); + is( $neg_dur->delta_seconds, -5, 'delta_seconds is -5' ); +} + +{ + my $dt1 = DateTime->new( + year => 1998, month => 12, day => 31, + hour => 23, minute => 59, second => 55, + time_zone => 'UTC', + ); + + my $dt2 = DateTime->new( + year => 1999, month => 1, day => 1, + hour => 0, minute => 0, second => 30, + time_zone => 'UTC', + ); + + my $pos_dur = $dt2 - $dt1; + + is( $pos_dur->delta_minutes, 0, 'delta_minutes is 0' ); + is( $pos_dur->delta_seconds, 36, 'delta_seconds is 36' ); + + my $neg_dur = $dt1 - $dt2; + + is( $neg_dur->delta_minutes, 0, 'delta_minutes is 0' ); + is( $neg_dur->delta_seconds, -36, 'delta_seconds is -36' ); +} + +# catch off-by-one when carrying a leap second +{ + my $dt1 = DateTime->new( + year => 1998, month => 12, day => 31, + hour => 23, minute => 59, second => 0, + nanosecond => 1, + time_zone => 'UTC', + ); + + my $dt2 = DateTime->new( + year => 1999, month => 1, day => 1, + hour => 0, minute => 0, second => 0, + time_zone => 'UTC', + ); + + my $pos_dur = $dt2 - $dt1; + + is( $pos_dur->delta_minutes, 0, 'delta_minutes is 0' ); + is( $pos_dur->delta_seconds, 60, 'delta_seconds is 60' ); + is( + $pos_dur->delta_nanoseconds, 999999999, + 'delta_nanoseconds is 999...' + ); +} + +{ + my $dt = DateTime->new( + year => 1972, month => 6, day => 30, + hour => 23, minute => 58, second => 20, + time_zone => 'UTC', + ); + + $dt->add( days => 2 ); + + is( + $dt->datetime, '1972-07-02T23:58:20', + 'add two days crossing a leap second (UTC)' + ); +} + +# a bunch of tests that math works across a leap second for various time zones +{ + my $dt = DateTime->new( + year => 1972, month => 6, day => 30, + hour => 20, minute => 58, second => 20, + time_zone => '-0300', + ); + + $dt->add( days => 2 ); + + is( + $dt->datetime, '1972-07-02T20:58:20', + 'add two days crossing a leap second (-0300)' + ); +} + +{ + my $dt = DateTime->new( + year => 1972, month => 7, day => 1, + hour => 2, minute => 58, second => 20, + time_zone => '+0300', + ); + + $dt->add( days => 2 ); + + is( + $dt->datetime, '1972-07-03T02:58:20', + 'add two days crossing a leap second (+0300)' + ); +} + +{ + my $dt = DateTime->new( + year => 1972, month => 6, day => 30, + hour => 23, minute => 58, second => 20, + time_zone => 'UTC', + ); + + $dt->add( hours => 48 ); + + is( + $dt->datetime, '1972-07-02T23:58:20', + 'add 48 hours crossing a leap second (UTC)' + ); +} + +{ + my $dt = DateTime->new( + year => 1972, month => 6, day => 30, + hour => 20, minute => 58, second => 20, + time_zone => '-0300', + ); + + $dt->add( hours => 48 ); + + is( + $dt->datetime, '1972-07-02T20:58:20', + 'add 48 hours crossing a leap second (-0300)' + ); +} + +{ + my $dt = DateTime->new( + year => 1972, month => 7, day => 1, + hour => 2, minute => 58, second => 20, + time_zone => '+0300', + ); + + $dt->add( hours => 48 ); + + is( + $dt->datetime, '1972-07-03T02:58:20', + 'add 48 hours crossing a leap second (+0300)' + ); +} + +{ + my $dt = DateTime->new( + year => 1972, month => 6, day => 30, + hour => 23, minute => 58, second => 20, + time_zone => 'UTC', + ); + + $dt->add( minutes => 2880 ); + + is( + $dt->datetime, '1972-07-02T23:58:20', + 'add 2880 minutes crossing a leap second (UTC)' + ); +} + +{ + my $dt = DateTime->new( + year => 1972, month => 6, day => 30, + hour => 20, minute => 58, second => 20, + time_zone => '-0300', + ); + + $dt->add( minutes => 2880 ); + + is( + $dt->datetime, '1972-07-02T20:58:20', + 'add 2880 minutes crossing a leap second (-0300)' + ); +} + +{ + my $dt = DateTime->new( + year => 1972, month => 7, day => 1, + hour => 2, minute => 58, second => 20, + time_zone => '+0300', + ); + + $dt->add( minutes => 2880 ); + + is( + $dt->datetime, '1972-07-03T02:58:20', + 'add 2880 minutes crossing a leap second (+0300)' + ); +} + +{ + my $dt = DateTime->new( + year => 1972, month => 6, day => 30, + hour => 23, minute => 58, second => 20, + time_zone => 'UTC', + ); + + $dt->add( seconds => 172801 ); + + is( + $dt->datetime, '1972-07-02T23:58:20', + 'add 172801 seconds crossing a leap second (UTC)' + ); +} + +{ + my $dt = DateTime->new( + year => 1972, month => 6, day => 30, + hour => 20, minute => 58, second => 20, + time_zone => '-0300', + ); + + $dt->add( seconds => 172801 ); + + is( + $dt->datetime, '1972-07-02T20:58:20', + 'add 172801 seconds crossing a leap second (-0300)' + ); +} + +{ + my $dt = DateTime->new( + year => 1972, month => 7, day => 1, + hour => 2, minute => 58, second => 20, + time_zone => '+0300', + ); + + $dt->add( seconds => 172801 ); + + is( + $dt->datetime, '1972-07-03T02:58:20', + 'add 172801 seconds crossing a leap second (+0300)' + ); +} + +{ + my $dt = DateTime->new( + year => 1972, month => 7, day => 2, + hour => 23, minute => 58, second => 20, + time_zone => 'UTC', + ); + + $dt->subtract( days => 2 ); + + is( + $dt->datetime, '1972-06-30T23:58:20', + 'subtract two days crossing a leap second (UTC)' + ); +} + +{ + my $dt = DateTime->new( + year => 1972, month => 7, day => 2, + hour => 20, minute => 58, second => 20, + time_zone => '-0300', + ); + + $dt->subtract( days => 2 ); + + is( + $dt->datetime, '1972-06-30T20:58:20', + 'subtract two days crossing a leap second (-0300)' + ); +} + +{ + my $dt = DateTime->new( + year => 1972, month => 7, day => 3, + hour => 2, minute => 58, second => 20, + time_zone => '+0300', + ); + + $dt->subtract( days => 2 ); + + is( + $dt->datetime, '1972-07-01T02:58:20', + 'subtract two days crossing a leap second (+0300)' + ); +} + +{ + my $dt = DateTime->new( + year => 1972, month => 7, day => 2, + hour => 23, minute => 58, second => 20, + time_zone => 'UTC', + ); + + $dt->subtract( hours => 48 ); + + is( + $dt->datetime, '1972-06-30T23:58:20', + 'subtract 48 hours crossing a leap second (UTC)' + ); +} + +{ + my $dt = DateTime->new( + year => 1972, month => 7, day => 2, + hour => 20, minute => 58, second => 20, + time_zone => '-0300', + ); + + $dt->subtract( hours => 48 ); + + is( + $dt->datetime, '1972-06-30T20:58:20', + 'subtract 48 hours crossing a leap second (-0300)' + ); +} + +{ + my $dt = DateTime->new( + year => 1972, month => 7, day => 3, + hour => 2, minute => 58, second => 20, + time_zone => '+0300', + ); + + $dt->subtract( hours => 48 ); + + is( + $dt->datetime, '1972-07-01T02:58:20', + 'subtract 48 hours crossing a leap second (+0300)' + ); +} + +{ + my $dt = DateTime->new( + year => 1972, month => 7, day => 2, + hour => 23, minute => 58, second => 20, + time_zone => 'UTC', + ); + + $dt->subtract( minutes => 2880 ); + + is( + $dt->datetime, '1972-06-30T23:58:20', + 'subtract 2880 minutes crossing a leap second (UTC)' + ); +} + +{ + my $dt = DateTime->new( + year => 1972, month => 7, day => 2, + hour => 20, minute => 58, second => 20, + time_zone => '-0300', + ); + + $dt->subtract( minutes => 2880 ); + + is( + $dt->datetime, '1972-06-30T20:58:20', + 'subtract 2880 minutes crossing a leap second (-0300)' + ); +} + +{ + my $dt = DateTime->new( + year => 1972, month => 7, day => 3, + hour => 2, minute => 58, second => 20, + time_zone => '+0300', + ); + + $dt->subtract( minutes => 2880 ); + + is( + $dt->datetime, '1972-07-01T02:58:20', + 'subtract 2880 minutes crossing a leap second (+0300)' + ); +} + +{ + my $dt = DateTime->new( + year => 1972, month => 7, day => 2, + hour => 23, minute => 58, second => 20, + time_zone => 'UTC', + ); + + $dt->subtract( seconds => 172801 ); + + is( + $dt->datetime, '1972-06-30T23:58:20', + 'subtract 172801 seconds crossing a leap second (UTC)' + ); +} + +{ + my $dt = DateTime->new( + year => 1972, month => 7, day => 2, + hour => 20, minute => 58, second => 20, + time_zone => '-0300', + ); + + $dt->subtract( seconds => 172801 ); + + is( + $dt->datetime, '1972-06-30T20:58:20', + 'subtract 172801 seconds crossing a leap second (-0300)' + ); +} + +{ + my $dt = DateTime->new( + year => 1972, month => 7, day => 3, + hour => 2, minute => 58, second => 20, + time_zone => '+0300', + ); + + $dt->subtract( seconds => 172801 ); + + is( + $dt->datetime, '1972-07-01T02:58:20', + 'subtract 172801 seconds crossing a leap second (+0300)' + ); +} + +{ + my $dt = DateTime->new( + year => 1972, month => 7, day => 1, + hour => 12, minute => 58, second => 20, + time_zone => '+1200', + ); + + $dt->set_time_zone('-1200'); + + is( + $dt->datetime, '1972-06-30T12:58:20', + '24 hour time zone change near leap second' + ); +} + +{ + my $dt = DateTime->new( + year => 1972, month => 6, day => 30, + hour => 12, minute => 58, second => 20, + time_zone => '-1200', + ); + + $dt->set_time_zone('+1200'); + + is( + $dt->datetime, '1972-07-01T12:58:20', + '24 hour time zone change near leap second' + ); +} + +{ + my $dt = DateTime->new( + year => 1997, month => 7, day => 1, + hour => 0, minute => 59, second => 59, + time_zone => '+0100' + ); + + is( $dt->datetime, '1997-07-01T00:59:59', '+0100 time leap second T-1' ); + + $dt->set_time_zone('UTC'); + + is( $dt->datetime, '1997-06-30T23:59:59', 'UTC time leap second T-1' ); +} + +{ + my $dt = DateTime->new( + year => 1997, month => 7, day => 1, + hour => 0, minute => 59, second => 60, + time_zone => '+0100' + ); + + is( $dt->datetime, '1997-07-01T00:59:60', 'local time leap second T-0' ); + + $dt->set_time_zone('UTC'); + + is( $dt->datetime, '1997-06-30T23:59:60', 'UTC time leap second T-0' ); +} + +{ + my $dt = DateTime->new( + year => 1997, month => 7, day => 1, + hour => 1, minute => 0, second => 0, + time_zone => '+0100' + ); + + is( $dt->datetime, '1997-07-01T01:00:00', 'local time leap second T+1' ); + + $dt->set_time_zone('UTC'); + + is( $dt->datetime, '1997-07-01T00:00:00', 'UTC time leap second T+1' ); +} + +{ + my $dt = DateTime->new( + year => 1997, month => 7, day => 1, + hour => 23, minute => 59, second => 59, + time_zone => '+0100' + ); + + is( + $dt->datetime, '1997-07-01T23:59:59', + 'local time end of leap second day' + ); + + $dt->set_time_zone('UTC'); + + is( + $dt->datetime, '1997-07-01T22:59:59', + 'UTC time end of leap second day' + ); +} + +{ + my $dt = DateTime->new( + year => 1997, month => 6, day => 30, + hour => 22, minute => 59, second => 59, + time_zone => '-0100' + ); + + is( $dt->datetime, '1997-06-30T22:59:59', '-0100 time leap second T-1' ); + + $dt->set_time_zone('UTC'); + + is( $dt->datetime, '1997-06-30T23:59:59', 'UTC time leap second T-1' ); +} + +{ + my $dt = DateTime->new( + year => 1997, month => 6, day => 30, + hour => 22, minute => 59, second => 60, + time_zone => '-0100' + ); + + is( $dt->datetime, '1997-06-30T22:59:60', '-0100 time leap second T-0' ); + + $dt->set_time_zone('UTC'); + + is( $dt->datetime, '1997-06-30T23:59:60', 'UTC time leap second T-0' ); +} + +{ + my $dt = DateTime->new( + year => 1997, month => 6, day => 30, + hour => 23, minute => 0, second => 0, + time_zone => '-0100' + ); + + is( $dt->datetime, '1997-06-30T23:00:00', '-0100 time leap second T+1' ); + + $dt->set_time_zone('UTC'); + + is( $dt->datetime, '1997-07-01T00:00:00', 'UTC time leap second T+1' ); +} + +{ + my $dt = DateTime->new( + year => 1997, month => 6, day => 30, + hour => 23, minute => 59, second => 59, + time_zone => 'UTC' + ); + + is( $dt->datetime, '1997-06-30T23:59:59', 'UTC time leap second T-1' ); + + $dt->set_time_zone('+0100'); + + is( $dt->datetime, '1997-07-01T00:59:59', '+0100 time leap second T-1' ); +} + +{ + my $dt = DateTime->new( + year => 1997, month => 6, day => 30, + hour => 23, minute => 59, second => 60, + time_zone => 'UTC' + ); + + is( $dt->datetime, '1997-06-30T23:59:60', 'UTC time leap second T-0' ); + + $dt->set_time_zone('+0100'); + + is( $dt->datetime, '1997-07-01T00:59:60', '+0100 time leap second T-0' ); +} + +{ + my $dt = DateTime->new( + year => 1997, month => 7, day => 1, + hour => 0, minute => 0, second => 0, + time_zone => 'UTC' + ); + + is( $dt->datetime, '1997-07-01T00:00:00', 'UTC time leap second T+1' ); + + $dt->set_time_zone('+0100'); + + is( $dt->datetime, '1997-07-01T01:00:00', '+0100 time leap second T+1' ); +} + +{ + my $dt = DateTime->new( + year => 1997, month => 6, day => 30, + hour => 23, minute => 59, second => 59, + time_zone => 'UTC' + ); + + is( + $dt->datetime, '1997-06-30T23:59:59', + 'UTC time end of leap second day' + ); + + $dt->set_time_zone('+0100'); + + is( + $dt->datetime, '1997-07-01T00:59:59', + '+0100 time end of leap second day' + ); +} + +{ + my $dt = DateTime->new( + year => 1997, month => 6, day => 30, + hour => 23, minute => 59, second => 59, + time_zone => 'UTC' + ); + + is( $dt->datetime, '1997-06-30T23:59:59', 'UTC time leap second T-1' ); + + $dt->set_time_zone('-0100'); + + is( $dt->datetime, '1997-06-30T22:59:59', '-0100 time leap second T-1' ); +} + +{ + my $dt = DateTime->new( + year => 1997, month => 6, day => 30, + hour => 23, minute => 59, second => 60, + time_zone => 'UTC' + ); + + is( $dt->datetime, '1997-06-30T23:59:60', 'UTC time leap second T-0' ); + + $dt->set_time_zone('-0100'); + + is( $dt->datetime, '1997-06-30T22:59:60', '-0100 time leap second T-0' ); +} + +{ + my $dt = DateTime->new( + year => 1997, month => 7, day => 1, + hour => 0, minute => 0, second => 0, + time_zone => 'UTC' + ); + + is( $dt->datetime, '1997-07-01T00:00:00', 'UTC time leap second T+1' ); + + $dt->set_time_zone('-0100'); + + is( $dt->datetime, '1997-06-30T23:00:00', '-0100 time leap second T+1' ); +} + +{ + my $dt = DateTime->new( + year => 2005, month => 12, day => 31, + hour => 23, minute => 59, second => 60, + time_zone => 'UTC' + ); + + is( $dt->second, 60, 'leap second at end of 2005 is allowed' ); +} + +{ + my $dt = DateTime->new( + year => 2005, month => 12, day => 31, + hour => 23, minute => 59, second => 59, + time_zone => 'UTC', + ); + + $dt->add( seconds => 1 ); + is( $dt->datetime, '2005-12-31T23:59:60', 'dt is 2005-12-31T23:59:60' ); + + $dt->add( seconds => 1 ); + is( $dt->datetime, '2006-01-01T00:00:00', 'dt is 2006-01-01T00:00:00' ); +} + +# bug reported by Mike Schilli - addition got "stuck" at 60 seconds +# and never rolled over to the following day +{ + my $dt = DateTime->new( + year => 2005, month => 12, day => 31, + hour => 23, minute => 59, second => 59, + time_zone => 'UTC', + ); + + $dt->add( seconds => 1 ); + is( $dt->datetime, '2005-12-31T23:59:60', 'dt is 2005-12-31T23:59:60' ); + + $dt->add( seconds => 1 ); + is( $dt->datetime, '2006-01-01T00:00:00', 'dt is 2006-01-01T00:00:00' ); +} + +# and this makes sure that fix for the above bug didn't break +# _non-leapsecond_ second addition +{ + my $dt = DateTime->new( + year => 2005, month => 12, day => 30, + hour => 23, minute => 59, second => 58, + time_zone => 'UTC', + ); + + $dt->add( seconds => 1 ); + is( $dt->datetime, '2005-12-30T23:59:59', 'dt is 2005-12-30T23:59:59' ); + + $dt->add( seconds => 1 ); + is( $dt->datetime, '2005-12-31T00:00:00', 'dt is 2005-12-31T00:00:00' ); +} + +{ + for my $date ( + [ 1972, 6, 30 ], + [ 1972, 12, 31 ], + [ 1973, 12, 31 ], + [ 1974, 12, 31 ], + [ 1975, 12, 31 ], + [ 1976, 12, 31 ], + [ 1977, 12, 31 ], + [ 1978, 12, 31 ], + [ 1979, 12, 31 ], + [ 1981, 6, 30 ], + [ 1982, 6, 30 ], + [ 1983, 6, 30 ], + [ 1985, 6, 30 ], + [ 1987, 12, 31 ], + [ 1989, 12, 31 ], + [ 1990, 12, 31 ], + [ 1992, 6, 30 ], + [ 1993, 6, 30 ], + [ 1994, 6, 30 ], + [ 1995, 12, 31 ], + [ 1997, 6, 30 ], + [ 1998, 12, 31 ], + [ 2005, 12, 31 ], + [ 2008, 12, 31 ], + [ 2012, 6, 30 ], + [ 2015, 6, 30 ], + [ 2016, 12, 31 ], + ) { + my $formatted = join '-', map { sprintf( '%02d', $_ ) } @{$date}; + + my $dt; + is( + exception { + $dt = DateTime->new( + year => $date->[0], + month => $date->[1], + day => $date->[2], + hour => 23, + minute => 59, + second => 60, + time_zone => 'UTC', + ); + }, + undef, + "We can make a DateTime object for the leap second on $formatted" + ); + + is( + DateTime::LeapSecond::day_length( ( $dt->utc_rd_values )[0] ), + 86401, + "DateTime::LeapSecond::day_length returns 86401 for $formatted" + ); + } +} + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-20infinite.t libdatetime-perl-1.46/xt/author/pp-20infinite.t --- libdatetime-perl-1.21/xt/author/pp-20infinite.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-20infinite.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,216 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +use strict; +use warnings; + +use Test::More; + +use DateTime; +use DateTime::Locale; + +my $pos = DateTime::Infinite::Future->new; +my $neg = DateTime::Infinite::Past->new; +my $posinf = DateTime::INFINITY; +my $neginf = DateTime::NEG_INFINITY; +my $nan_string = DateTime::NAN; + +# infinite date math +{ + ok( $pos->is_infinite, 'positive infinity should be infinite' ); + ok( $neg->is_infinite, 'negative infinity should be infinite' ); + ok( !$pos->is_finite, 'positive infinity should not be finite' ); + ok( !$neg->is_finite, 'negative infinity should not be finite' ); + + # These methods produce numbers or strings - we want to make sure they all + # return Inf or -Inf as expected. + my @ification_methods = qw( + ymd mdy dmy hms time iso8601 datetime + year ce_year month day day_of_week + quarter + hour hour_1 hour_12 hour_12_0 minute second + fractional_second + week week_year week_number + mjd jd + nanosecond millisecond microsecond + epoch + ); + + for my $meth (@ification_methods) { + is( $pos->$meth, $posinf, "+Infinity $meth returns $posinf" ); + is( $neg->$meth, $neginf, "-Infinity $meth returns $neginf" ); + } + + # that's a long time ago! + my $long_ago = DateTime->new( year => -100_000 ); + + ok( + $neg < $long_ago, + 'negative infinity is really negative' + ); + + my $far_future = DateTime->new( year => 100_000 ); + ok( + $pos > $far_future, + 'positive infinity is really positive' + ); + + ok( + $pos > $neg, + 'positive infinity is bigger than negative infinity' + ); + + my $pos_dur = $pos - $far_future; + ok( + $pos_dur->is_positive, + 'infinity - normal = infinity' + ); + + my $pos2 = $long_ago + $pos_dur; + ok( + $pos2 == $pos, + 'normal + infinite duration = infinity' + ); + + my $neg_dur = $far_future - $pos; + ok( + $neg_dur->is_negative, + 'normal - infinity = neg infinity' + ); + + my $neg2 = $long_ago + $neg_dur; + ok( + $neg2 == $neg, + 'normal + neg infinite duration = neg infinity' + ); + + my $dur = $pos - $pos; + my %deltas = $dur->deltas; + my @compare = qw( days seconds nanoseconds ); + foreach (@compare) { + + # NaN != NaN (but should stringify the same) + is( + $deltas{$_} . q{}, $nan_string, + "infinity - infinity = nan ($_)" + ); + } + + my $new_pos = $pos->clone->add( days => 10 ); + ok( + $new_pos == $pos, + 'infinity + normal duration = infinity' + ); + + my $new_pos2 = $pos->clone->subtract( days => 10 ); + ok( + $new_pos2 == $pos, + 'infinity - normal duration = infinity' + ); + + ok( + $pos == $posinf, + 'infinity (datetime) == infinity (number)' + ); + + ok( + $neg == $neginf, + 'neg infinity (datetime) == neg infinity (number)' + ); +} + +# This could vary across platforms +my $pos_as_string = $posinf . q{}; +my $neg_as_string = $neginf . q{}; + +# formatting +{ + foreach my $m ( + qw( year month day hour minute second + microsecond millisecond nanosecond ) + ) { + is( + $pos->$m() . q{}, $pos_as_string, + "pos $m is $pos_as_string" + ); + + is( + $neg->$m() . q{}, $neg_as_string, + "neg $m is $pos_as_string" + ); + } +} + +{ + my $now = DateTime->now; + + is( + DateTime->compare( $pos, $now ), 1, + 'positive infinite is greater than now' + ); + is( + DateTime->compare( $neg, $now ), -1, + 'negative infinite is less than now' + ); +} + +{ + my $now = DateTime->now; + my $pos2 = $pos + DateTime::Duration->new( months => 1 ); + + ok( + $pos == $pos2, + 'infinity (datetime) == infinity (datetime)' + ); +} + +{ + my $now = DateTime->now; + my $neg2 = $neg + DateTime::Duration->new( months => 1 ); + + ok( + $neg == $neg2, + '-infinity (datetime) == -infinity (datetime)' + ); +} + +{ + cmp_ok( + "$pos", 'eq', $posinf, + 'stringified infinity (datetime) eq infinity (number)' + ); + cmp_ok( + "$neg", 'eq', $neginf, + 'stringified neg infinity (datetime) eq neg infinity (number)' + ); +} + +{ + is( + $pos->day_name(), + undef, + 'day_name returns undef', + ); + + is( + $pos->am_or_pm(), + undef, + 'am_or_pm returns undef' + ); + + is( + $pos->locale()->name(), + 'Fake locale for Infinite DateTime objects', + 'locale name for fake locale' + ); + + is( + $pos->locale()->datetime_format_long(), + DateTime::Locale->load('en_US')->datetime_format_long(), + 'fake locale returns same format as en_US' + ); +} + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-21bad-params.t libdatetime-perl-1.46/xt/author/pp-21bad-params.t --- libdatetime-perl-1.21/xt/author/pp-21bad-params.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-21bad-params.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,78 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +use strict; +use warnings; + +use Test::Fatal; +use Test::More; + +use DateTime; + +foreach my $p ( + { year => 2000, month => 13 }, + { year => 2000, month => 0 }, + { year => 2000, month => 12, day => 32 }, + { year => 2000, month => 12, day => 0 }, + { year => 2000, month => 12, day => 10, hour => -1 }, + { year => 2000, month => 12, day => 10, hour => 24 }, + { year => 2000, month => 12, day => 10, hour => 12, minute => -1 }, + { year => 2000, month => 12, day => 10, hour => 12, minute => 60 }, + { year => 2000, month => 12, day => 10, hour => 12, second => -1 }, + { year => 2000, month => 12, day => 10, hour => 12, second => 62 }, +) { + like( + exception { DateTime->new(%$p) }, + qr/Validation failed/, + 'Parameters outside valid range should fail in call to new()' + ); + + like( + exception { DateTime->new( year => 2000 )->set(%$p) }, + qr/Validation failed/, + 'Parameters outside valid range should fail in call to set()' + ); +} + +{ + like( + exception { + DateTime->last_day_of_month( + year => 2000, + month => 13, + ); + }, + qr/Validation failed/, + 'Parameters outside valid range should fail in call to last_day_of_month()' + ); + + like( + exception { DateTime->last_day_of_month( year => 2000, month => 0 ) }, + qr/Validation failed/, + 'Parameters outside valid range should fail in call to last_day_of_month()' + ); +} + +{ + like( + exception { DateTime->new( year => 2000, month => 4, day => 31 ) }, + qr/valid day of month/i, + 'Day past last day of month should fail' + ); + + like( + exception { DateTime->new( year => 2001, month => 2, day => 29 ) }, + qr/valid day of month/i, + 'Day past last day of month should fail' + ); + + is( + exception { DateTime->new( year => 2000, month => 2, day => 29 ) }, + undef, + 'February 29 should be valid in leap years' + ); +} + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-22from-doy.t libdatetime-perl-1.46/xt/author/pp-22from-doy.t --- libdatetime-perl-1.21/xt/author/pp-22from-doy.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-22from-doy.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,72 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +use strict; +use warnings; + +use Test::Fatal; +use Test::More; + +use DateTime; + +my @last_day = ( 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ); +my @leap_last_day = @last_day; +$leap_last_day[1]++; + +{ + my $doy = 15; + foreach my $month ( 1 .. 12 ) { + $doy += $last_day[ $month - 2 ] if $month > 1; + + my $dt = DateTime->from_day_of_year( + year => 2001, + day_of_year => $doy, + time_zone => 'UTC', + ); + + is( $dt->year, 2001, 'check year' ); + is( $dt->month, $month, 'check month' ); + is( $dt->day, 15, 'check day' ); + is( $dt->day_of_year, $doy, 'check day of year' ); + } +} + +{ + my $doy = 15; + foreach my $month ( 1 .. 12 ) { + $doy += $leap_last_day[ $month - 2 ] if $month > 1; + + my $dt = DateTime->from_day_of_year( + year => 2004, + day_of_year => $doy, + time_zone => 'UTC', + ); + + is( $dt->year, 2004, 'check year' ); + is( $dt->month, $month, 'check month' ); + is( $dt->day, 15, 'check day' ); + is( $dt->day_of_year, $doy, 'check day of year' ); + } +} + +{ + like( + exception { + DateTime->from_day_of_year( year => 2001, day_of_year => 366 ) + }, + qr/2001 is not a leap year/, + 'Cannot give day of year 366 in non-leap years' + ); + + is( + exception { + DateTime->from_day_of_year( year => 2004, day_of_year => 366 ) + }, + undef, + 'Day of year 366 should work in leap years' + ); +} + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-23storable.t libdatetime-perl-1.46/xt/author/pp-23storable.t --- libdatetime-perl-1.21/xt/author/pp-23storable.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-23storable.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,110 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +use strict; +use warnings; + +use Test::More; + +use DateTime; + +unless ( eval { require Storable; 1 } ) { + plan skip_all => 'Cannot load Storable'; +} + +{ + my @dt = ( + DateTime->new( + year => 1950, + hour => 1, + nanosecond => 1, + time_zone => 'America/Chicago', + locale => 'de' + ), + DateTime::Infinite::Past->new, + DateTime::Infinite::Future->new, + ); + + foreach my $dt (@dt) { + my $copy = Storable::thaw( Storable::nfreeze($dt) ); + + is( + $copy->time_zone->name, $dt->time_zone->name, + 'Storable freeze/thaw preserves tz' + ); + + is( + ref $copy->locale, ref $dt->locale, + 'Storable freeze/thaw preserves locale' + ); + + is( + $copy->year, $dt->year, + 'Storable freeze/thaw preserves rd values' + ); + + is( + $copy->hour, $dt->hour, + 'Storable freeze/thaw preserves rd values' + ); + + is( + $copy->nanosecond, $dt->nanosecond, + 'Storable freeze/thaw preserves rd values' + ); + } +} + +{ + my $dt1 = DateTime->now( locale => 'en-US' ); + my $dt2 = Storable::dclone($dt1); + my $dt3 = Storable::thaw( Storable::nfreeze($dt2) ); + + is( + $dt1->iso8601, $dt2->iso8601, + 'dclone produces date equal to original' + ); + is( + $dt2->iso8601, $dt3->iso8601, + 'explicit freeze and thaw produces date equal to original' + ); + + # Back-compat shim for new DateTime::Locale. Remove once DT::Locale based + # on CLDR 28+ is released. + my $meth = $dt1->locale->can('code') ? 'code' : 'id'; + my $orig_code = $dt1->locale->$meth; + is( + $dt2->locale->$meth, + $orig_code, + 'check locale id after dclone' + ); + is( + $dt3->locale->$meth, + $orig_code, + 'check locale id after explicit freeze/thaw' + ); +} + +{ + package Formatter; + + sub format_datetime { } +} + +{ + my $dt = DateTime->new( + year => 2004, + formatter => 'Formatter', + ); + + my $copy = Storable::thaw( Storable::nfreeze($dt) ); + + is( + $dt->formatter, $copy->formatter, + 'Storable freeze/thaw preserves formatter' + ); +} + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-24from-object.t libdatetime-perl-1.46/xt/author/pp-24from-object.t --- libdatetime-perl-1.21/xt/author/pp-24from-object.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-24from-object.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,108 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +## no critic (Modules::ProhibitMultiplePackages) +use strict; +use warnings; + +use Test::More; + +use DateTime; + +my $dt1 = DateTime->new( year => 1970, hour => 1, nanosecond => 100 ); + +my $dt2 = DateTime->from_object( object => $dt1 ); + +is( $dt1->year, 1970, 'year is 1970' ); +is( $dt1->hour, 1, 'hour is 1' ); +is( $dt1->nanosecond, 100, 'nanosecond is 100' ); + +{ + my $t1 = DateTime::Calendar::_Test::WithoutTZ->new( + rd_days => 1, + rd_secs => 0 + ); + + # Tests creating objects from other calendars (without time zones) + my $t2 = DateTime->from_object( object => $t1 ); + + isa_ok( $t2, 'DateTime' ); + is( + $t2->datetime, '0001-01-01T00:00:00', + 'convert from object without tz' + ); + ok( $t2->time_zone->is_floating, 'time_zone is floating' ); +} + +{ + my $tz = DateTime::TimeZone->new( name => 'America/Chicago' ); + my $t1 = DateTime::Calendar::_Test::WithTZ->new( + rd_days => 1, rd_secs => 0, + time_zone => $tz + ); + + # Tests creating objects from other calendars (with time zones) + my $t2 = DateTime->from_object( object => $t1 ); + + isa_ok( $t2, 'DateTime' ); + is( $t2->time_zone->name, 'America/Chicago', 'time_zone is preserved' ); +} + +{ + my $tz = DateTime::TimeZone->new( name => 'UTC' ); + my $t1 = DateTime::Calendar::_Test::WithTZ->new( + rd_days => 720258, + rd_secs => 86400, time_zone => $tz + ); + + my $t2 = DateTime->from_object( object => $t1 ); + + isa_ok( $t2, 'DateTime' ); + is( + $t2->second, 60, + 'new DateTime from_object with TZ which is a leap second' + ); +} + +{ + for my $class (qw( DateTime::Infinite::Past DateTime::Infinite::Future )) + { + isa_ok( + DateTime->from_object( object => $class->new ), + $class, + "from_object($class)" + ); + } +} + +done_testing(); + +# Set up two simple test packages + +package DateTime::Calendar::_Test::WithoutTZ; + +sub new { + my $class = shift; + bless {@_}, $class; +} + +sub utc_rd_values { + return $_[0]{rd_days}, $_[0]{rd_secs}, 0; +} + +package DateTime::Calendar::_Test::WithTZ; + +sub new { + my $class = shift; + bless {@_}, $class; +} + +sub utc_rd_values { + return $_[0]{rd_days}, $_[0]{rd_secs}, 0; +} + +sub time_zone { + return $_[0]{time_zone}; +} + diff -Nru libdatetime-perl-1.21/xt/author/pp-25add-subtract.t libdatetime-perl-1.46/xt/author/pp-25add-subtract.t --- libdatetime-perl-1.21/xt/author/pp-25add-subtract.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-25add-subtract.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,39 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +use strict; +use warnings; + +use Test::More; + +use DateTime; + +# exercises a bug found in Perl version of _normalize_tai_seconds - +# fixed in 0.15 +{ + my $dt = DateTime->new( year => 2000, month => 12 ); + + $dt->add( months => 1 )->truncate( to => 'month' ) + ->subtract( seconds => 1 ); + + is( $dt->year, 2000, 'year is 2001' ); + is( $dt->month, 12, 'month is 12' ); + is( $dt->hour, 23, 'hour is 23' ); + is( $dt->minute, 59, 'minute is 59' ); + is( $dt->second, 59, 'second is 59' ); +} + +{ + my $dt = DateTime->new( year => 2000, month => 12 ); + my $dt2 = $dt->clone->add( months => 1 )->subtract( seconds => 1 ); + + is( $dt2->year, 2000, 'year is 2001' ); + is( $dt2->month, 12, 'month is 12' ); + is( $dt2->hour, 23, 'hour is 23' ); + is( $dt2->minute, 59, 'minute is 59' ); + is( $dt2->second, 59, 'second is 59' ); +} + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-27delta.t libdatetime-perl-1.46/xt/author/pp-27delta.t --- libdatetime-perl-1.21/xt/author/pp-27delta.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-27delta.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,109 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +use strict; +use warnings; + +use Test::More; + +use DateTime; + +{ + my $date1 = DateTime->new( + year => 2001, month => 5, day => 10, + hour => 4, minute => 3, second => 2, + nanosecond => 12, + time_zone => 'UTC' + ); + + my $date2 = DateTime->new( + year => 2001, month => 6, day => 12, + hour => 5, minute => 7, second => 23, + nanosecond => 7, + time_zone => 'UTC' + ); + + { + my $dur_md = $date2->delta_md($date1); + + is( $dur_md->delta_months, 1, 'delta_md months is 1' ); + is( $dur_md->delta_days, 2, 'delta_md days is 2' ); + is( $dur_md->delta_minutes, 0, 'delta_md minutes is 0' ); + is( $dur_md->delta_seconds, 0, 'delta_md seconds is 0' ); + is( $dur_md->delta_nanoseconds, 0, 'delta_md nanoseconds is 0' ); + + my $dur_d = $date2->delta_days($date1); + + is( $dur_d->delta_months, 0, 'delta_d months is 0' ); + is( $dur_d->delta_days, 33, 'delta_d days is 33' ); + is( $dur_d->delta_minutes, 0, 'delta_d minutes is 0' ); + is( $dur_d->delta_seconds, 0, 'delta_d seconds is 0' ); + is( $dur_d->delta_nanoseconds, 0, 'delta_d nanoseconds is 0' ); + + my $dur_ms = $date2->delta_ms($date1); + + is( $dur_ms->delta_months, 0, 'delta_ms months is 0' ); + is( $dur_ms->delta_days, 0, 'delta_ms days is 0' ); + is( $dur_ms->delta_minutes, 47584, 'delta_ms minutes is 47584' ); + is( $dur_ms->delta_seconds, 20, 'delta_ms seconds is 20' ); + is( $dur_ms->delta_nanoseconds, 0, 'delta_ms nanoseconds is 0' ); + + is( $dur_ms->hours, 793, 'hours is 793' ); + } + + { + my $dur_md = $date1->delta_md($date2); + + is( $dur_md->delta_months, 1, 'delta_md months is 1' ); + is( $dur_md->delta_days, 2, 'delta_md days is 2' ); + is( $dur_md->delta_minutes, 0, 'delta_md minutes is 0' ); + is( $dur_md->delta_seconds, 0, 'delta_md seconds is 0' ); + is( $dur_md->delta_nanoseconds, 0, 'delta_md nanoseconds is 0' ); + + my $dur_d = $date1->delta_days($date2); + + is( $dur_d->delta_months, 0, 'delta_d months is 0' ); + is( $dur_d->delta_days, 33, 'delta_d days is 33' ); + is( $dur_d->delta_minutes, 0, 'delta_d minutes is 0' ); + is( $dur_d->delta_seconds, 0, 'delta_d seconds is 0' ); + is( $dur_d->delta_nanoseconds, 0, 'delta_d nanoseconds is 0' ); + + my $dur_ms = $date1->delta_ms($date2); + + is( $dur_ms->delta_months, 0, 'delta_ms months is 0' ); + is( $dur_ms->delta_days, 0, 'delta_ms days is 0' ); + is( $dur_ms->delta_minutes, 47584, 'delta_ms minutes is 47584' ); + is( $dur_ms->delta_seconds, 20, 'delta_ms seconds is 20' ); + is( $dur_ms->delta_nanoseconds, 0, 'delta_ms nanoseconds is 0' ); + + is( $dur_ms->hours, 793, 'hours is 793' ); + } +} + +{ + my $date1 = DateTime->new( + year => 2001, month => 5, day => 10, + hour => 15, minute => 0, second => 0, + time_zone => 'UTC' + ); + + my $date2 = DateTime->new( + year => 2001, month => 5, day => 11, + hour => 12, minute => 30, second => 10, + time_zone => 'UTC' + ); + + my $dur_ms = $date1->delta_ms($date2); + + is( $dur_ms->delta_months, 0, 'delta_ms months is 0' ); + is( $dur_ms->delta_days, 0, 'delta_ms days is 0' ); + is( $dur_ms->delta_minutes, 1290, 'delta_ms minutes is 1290' ); + is( $dur_ms->delta_seconds, 10, 'delta_ms seconds is 30' ); + is( $dur_ms->delta_nanoseconds, 0, 'delta_ms nanoseconds is 0' ); + + is( $dur_ms->hours, 21, 'hours is 21' ); +} + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-28dow.t libdatetime-perl-1.46/xt/author/pp-28dow.t --- libdatetime-perl-1.21/xt/author/pp-28dow.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-28dow.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,70 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +use strict; +use warnings; + +use Test::More; + +use DateTime; + +{ + my $dt = DateTime->new( year => 0 ); + + is( $dt->year, 0, 'year is 0' ); + is( $dt->month, 1, 'month is 1' ); + is( $dt->day, 1, 'day is 1' ); + is( $dt->day_of_week, 6, 'day of week is 6' ); +} + +{ + my $dt = DateTime->new( year => 0, month => 12, day => 31 ); + + is( $dt->year, 0, 'year is 0' ); + is( $dt->month, 12, 'month is 12' ); + is( $dt->day, 31, 'day is 31' ); + is( $dt->day_of_week, 7, 'day of week is 7' ); +} + +{ + my $dt = DateTime->new( year => -1 ); + + is( $dt->year, -1, 'year is -1' ); + is( $dt->month, 1, 'month is 1' ); + is( $dt->day, 1, 'day is 1' ); + is( $dt->day_of_week, 5, 'day of week is 5' ); +} + +{ + my $dt = DateTime->new( year => 1 ); + + is( $dt->year, 1, 'year is 1' ); + is( $dt->month, 1, 'month is 1' ); + is( $dt->day, 1, 'day is 1' ); + is( $dt->day_of_week, 1, 'day of week is 1' ); +} + +{ + my $dow = 1; + for my $year ( 1, 0, -1 ) { + my $days_in_year = $year ? 365 : 366; + + for my $doy ( reverse 1 .. $days_in_year ) { + is( + DateTime->from_day_of_year( + year => $year, + day_of_year => $doy, + )->day_of_week, + $dow, + "day of week for day $doy of year $year is $dow" + ); + + $dow--; + $dow = 7 if $dow == 0; + } + } +} + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-29overload.t libdatetime-perl-1.46/xt/author/pp-29overload.t --- libdatetime-perl-1.21/xt/author/pp-29overload.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-29overload.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,151 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +use strict; +use warnings; + +use Test::Fatal; +use Test::More; +use Test::Warnings 0.005 ':all'; + +use DateTime; + +{ + my $dt = DateTime->new( year => 1900, month => 12, day => 1 ); + + is( "$dt", '1900-12-01T00:00:00', 'stringification overloading' ); +} + +{ + my $dt = DateTime->new( + year => 2050, month => 1, day => 15, + hour => 20, minute => 10, second => 10 + ); + + my $before_string = '2050-01-15T20:10:09'; + my $same_string = '2050-01-15T20:10:10'; + my $after_string = '2050-01-15T20:10:11'; + + is( "$dt", $same_string, 'stringification overloading' ); + ok( $dt eq $same_string, 'eq overloading true' ); + ok( !( $dt eq $after_string ), 'eq overloading false' ); + ok( $dt ne $after_string, 'ne overloading true' ); + ok( !( $dt ne $same_string ), 'ne overloading false' ); + + is( $dt cmp $same_string, 0, 'cmp overloading' ); + is( $dt cmp $after_string, -1, ' less than' ); + ok( $dt lt $after_string, 'lt overloading' ); + ok( !( $dt lt $same_string ), ' not' ); + + { + + package Other::Date; + use overload + q[""] => sub { return ${ $_[0] }; }, + fallback => 1; + + sub new { + my ( $class, $date ) = @_; + return bless \$date, $class; + } + } + + my $same_od = Other::Date->new($same_string); + my $after_od = Other::Date->new($after_string); + my $before_od = Other::Date->new($before_string); + + ok( $dt eq $same_od, 'DateTime eq non-DateTime overloaded object true' ); + ok( !( $dt eq $after_od ), ' eq false' ); + ok( $dt ne $after_od, ' ne true' ); + ok( !( $dt ne $same_od ), ' ne false' ); + + is( $dt cmp $same_od, 0, 'cmp overloading' ); + is( $dt cmp $after_od, -1, ' lt overloading' ); + ok( $dt lt $after_od, 'lt overloading' ); + ok( !( $dt lt $same_od ), ' not' ); + + is_deeply( + [ + map { $_ . ' - ' . ( ref $_ || 'no ref' ) } + sort { $a cmp $b or ref $a cmp ref $b } $same_od, $after_od, + $before_od, $dt, $same_string, $after_string, $before_string + ], + [ + map { $_ . ' - ' . ( ref $_ || 'no ref' ) } $before_string, + $before_od, $same_string, $dt, $same_od, $after_string, $after_od + ], + 'eq sort' + ); + + like( + exception { my $x = $dt + 1 }, + qr/Cannot add 1 to a DateTime object/, + 'Cannot add plain scalar to a DateTime object' + ); + + like( + exception { my $x = $dt + bless {}, 'FooBar' }, + qr/Cannot add FooBar=HASH\([^\)]+\) to a DateTime object/, + 'Cannot add plain FooBar object to a DateTime object' + ); + + like( + exception { my $x = $dt - 1 }, + qr/Cannot subtract 1 from a DateTime object/, + 'Cannot subtract plain scalar from a DateTime object' + ); + + like( + exception { my $x = $dt - bless {}, 'FooBar' }, + qr/Cannot subtract FooBar=HASH\([^\)]+\) from a DateTime object/, + 'Cannot subtract plain FooBar object from a DateTime object' + ); + + like( + exception { my $x = $dt > 1 }, + qr/A DateTime object can only be compared to another DateTime object/, + 'Cannot compare a DateTime object to a scalar' + ); + + like( + exception { my $x = $dt > bless {}, 'FooBar' }, + qr/A DateTime object can only be compared to another DateTime object/, + 'Cannot compare a DateTime object to a FooBar object' + ); + + like( + warning { my $x = undef; $dt > $x; }, + qr/uninitialized value in numeric gt .+ at .*x?t.(author.pp.)?29overload\.t/, + 'Comparing undef to a DateTime object generates a Perl warning at the right spot ($dt > undef)' + ); + + like( + warning { my $x = undef; $x > $dt; }, + qr/uninitialized value in numeric gt .+ at .*x?t.(author.pp.)?29overload\.t/, + 'Comparing undef to a DateTime object generates a Perl warning at the right spot (undef > $dt)' + ); + + ok( + !( $dt eq 'some string' ), + 'DateTime object always compares false to a string' + ); + + ok( + $dt ne 'some string', + 'DateTime object always compares false to a string' + ); + + ok( + $dt eq $dt->clone, + 'DateTime object is equal to a clone of itself' + ); + + ok( + !( $dt ne $dt->clone ), + 'DateTime object is equal to a clone of itself (! ne)' + ); +} + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-30future-tz.t libdatetime-perl-1.46/xt/author/pp-30future-tz.t --- libdatetime-perl-1.21/xt/author/pp-30future-tz.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-30future-tz.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,58 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +use strict; +use warnings; + +use Test::More; + +use DateTime; + +# +# This test exercises a bug that occurred when date math did not +# always make sure to update the utc_year attribute of the given +# DateTime. The sympton was that the time zone future span generation +# would fail because utc_year was less than the span's max_year, so +# span generation wouldn't actually do anything, and it would die with +# "Invalid local time". +# +{ + + # Each iteration needs to use a different zone, because if it + # works once, the generated spans are cached. + for my $add ( + [ years => 50, 1, 'America/New_York' ], + [ days => 50, 365, 'America/Chicago' ], + [ minutes => 50, 365 * 1440, 'America/Denver', ], + [ seconds => 50, 365 * 1440 * 60, 'America/Los_Angeles' ], + [ + nanoseconds => 50, 365 * 1440 * 60 * 1_000_000_000, + 'America/North_Dakota/Center' + ], + + [ years => 750, 1, 'Europe/Paris' ], + [ days => 750, 365, 'Europe/London' ], + [ minutes => 750, 365 * 1440, 'Europe/Brussels', ], + [ seconds => 750, 365 * 1440 * 60, 'Europe/Vienna' ], + [ + nanoseconds => 750, 365 * 1440 * 60 * 1_000_000_000, + 'Europe/Prague' + ], + ) { + + my $dt = DateTime->now->set( hour => 12 )->set_time_zone( $add->[3] ); + + my $new + = eval { $dt->clone->add( $add->[0], $add->[1] * $add->[2] ) }; + + is( + $@, + q{}, + "Make sure we can add $add->[1] years worth of $add->[0] in $add->[3] time zone" + ); + } +} + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-31formatter.t libdatetime-perl-1.46/xt/author/pp-31formatter.t --- libdatetime-perl-1.21/xt/author/pp-31formatter.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-31formatter.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,116 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +use strict; +use warnings; + +use Test::Fatal; +use Test::More; + +use DateTime; + +{ + package Formatter; + + sub new { + return bless {}, __PACKAGE__; + } + + sub format_datetime { + $_[1]->strftime('%Y%m%d %T'); + } +} + +my $formatter = Formatter->new(); + +{ + is( + exception { + DateTime->from_epoch( epoch => time(), formatter => $formatter ) + }, + undef, + 'passed formatter to from_epoch' + ); +} + +{ + is( + exception { + DateTime->new( + year => 2004, + month => 9, + day => 2, + hour => 13, + minute => 23, + second => 34, + formatter => $formatter + ); + }, + undef, + 'passed formatter to new' + ); +} + +{ + my $from = DateTime->new( + year => 2004, + month => 9, + day => 2, + hour => 13, + minute => 23, + second => 34, + formatter => $formatter + ); + my $dt; + is( + exception { + $dt = DateTime->from_object( + object => $from, + formatter => $formatter + ); + }, + undef, + 'passed formatter to from_object' + ); + + is( + $dt->formatter, $formatter, + 'check from_object copies formatter' + ); + + is( $dt->stringify(), '20040902 13:23:34', 'Format datetime' ); + + # check stringification (with formatter) + is( $dt->stringify, "$dt", 'Stringification (with formatter)' ); + + # check that set() and truncate() don't lose formatter + $dt->set( hour => 3 ); + is( + $dt->stringify, '20040902 03:23:34', + 'formatter is preserved after set()' + ); + + $dt->truncate( to => 'minute' ); + is( + $dt->stringify, '20040902 03:23:00', + 'formatter is preserved after truncate()' + ); + + # check if the default behavior works + $dt->set_formatter(undef); + is( $dt->stringify(), $dt->iso8601, 'Default iso8601 works' ); + + # check stringification (default) + is( + $dt->stringify, "$dt", + 'Stringification (no formatter -> format_datetime)' + ); + is( + $dt->iso8601, "$dt", + 'Stringification (no formatter -> iso8601)' + ); +} + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-32leap-second2.t libdatetime-perl-1.46/xt/author/pp-32leap-second2.t --- libdatetime-perl-1.21/xt/author/pp-32leap-second2.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-32leap-second2.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,336 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +use strict; +use warnings; + +use Test::More; + +use DateTime; + +{ + my $t = DateTime->new( + year => 1972, month => 7, day => 1, + hour => 0, minute => 59, second => 58, + time_zone => '+0100', + ); + + is( $t->second, 58, 'second value for leap second T-2, +0100' ); + + is( + $t->{utc_rd_days}, 720074, + 'UTC RD days for leap second T-2' + ); + is( + $t->{utc_rd_secs}, 86398, + 'UTC RD seconds for leap second T-2' + ); + + is( + $t->{local_rd_days}, 720075, + 'local RD days for leap second T-2' + ); + is( + $t->{local_rd_secs}, 3598, + 'local RD seconds for leap second T-2' + ); +} + +{ + my $t = DateTime->new( + year => 1972, month => 7, day => 1, + hour => 0, minute => 59, second => 59, + time_zone => '+0100', + ); + + is( $t->second, 59, 'second value for leap second T-1, +0100' ); + is( + $t->{utc_rd_days}, 720074, + 'UTC RD days for leap second T-1' + ); + is( + $t->{utc_rd_secs}, 86399, + 'UTC RD seconds for leap second T-1' + ); + + is( + $t->{local_rd_days}, 720075, + 'local RD days for leap second T-1' + ); + is( + $t->{local_rd_secs}, 3599, + 'local RD seconds for leap second T-1' + ); +} + +{ + my $t = eval { + DateTime->new( + year => 1972, month => 7, day => 1, + hour => 0, minute => 59, second => 60, + time_zone => '+0100', + ); + }; + + ok( !$@, 'constructor for second = 60' ); + +SKIP: + { + skip 'constructor failed - no object to test', 5 + unless $t; + + is( $t->second, 60, 'second value for leap second T-0, +0100' ); + is( + $t->{utc_rd_days}, 720074, + 'UTC RD days for leap second T-0' + ); + is( + $t->{utc_rd_secs}, 86400, + 'UTC RD seconds for leap second T-0' + ); + + is( + $t->{local_rd_days}, 720075, + 'local RD days for leap second T-0' + ); + is( + $t->{local_rd_secs}, 3600, + 'local RD seconds for leap second T-0' + ); + } +} + +{ + my $t = DateTime->new( + year => 1972, month => 7, day => 1, + hour => 1, minute => 0, second => 0, + time_zone => '+0100', + ); + + is( $t->second, 0, 'second value for leap second T+1, +0100' ); + is( + $t->{utc_rd_days}, 720075, + 'UTC RD days for leap second T+1' + ); + is( + $t->{utc_rd_secs}, 0, + 'UTC RD seconds for leap second T+1' + ); + + is( + $t->{local_rd_days}, 720075, + 'local RD days for leap second T+1' + ); + is( + $t->{local_rd_secs}, 3601, + 'local RD seconds for leap second T+1' + ); +} + +{ + my $t = DateTime->new( + year => 1972, month => 7, day => 1, + hour => 1, minute => 0, second => 1, + time_zone => '+0100', + ); + + is( $t->second, 1, 'second value for leap second T+2, +0100' ); + is( + $t->{utc_rd_days}, 720075, + 'UTC RD days for leap second T+2' + ); + is( + $t->{utc_rd_secs}, 1, + 'UTC RD seconds for leap second T+2' + ); + + is( + $t->{local_rd_days}, 720075, + 'local RD days for leap second T+2' + ); + is( + $t->{local_rd_secs}, 3602, + 'local RD seconds for leap second T+2' + ); +} + +{ + my $t = DateTime->new( + year => 1972, month => 7, day => 1, + hour => 23, minute => 59, second => 59, + time_zone => '+0100', + ); + + is( $t->second, 59, 'second value for end of leap second day, +0100' ); + is( + $t->{utc_rd_days}, 720075, + 'UTC RD days for end of leap second day' + ); + is( + $t->{utc_rd_secs}, 82799, + 'UTC RD seconds for end of leap second day' + ); + + is( + $t->{local_rd_days}, 720075, + 'local RD days for leap second day' + ); + is( + $t->{local_rd_secs}, 86400, + 'local RD seconds for end of leap second day' + ); +} + +{ + my $t = DateTime->new( + year => 1972, month => 6, day => 30, + hour => 22, minute => 59, second => 58, + time_zone => '-0100', + ); + + is( $t->second, 58, 'second value for leap second T-2, -0100' ); + + is( + $t->{utc_rd_days}, 720074, + 'UTC RD days for leap second T-2' + ); + is( + $t->{utc_rd_secs}, 86398, + 'UTC RD seconds for leap second T-2' + ); + + is( + $t->{local_rd_days}, 720074, + 'local RD days for leap second T-2' + ); + is( + $t->{local_rd_secs}, 82798, + 'local RD seconds for leap second T-2' + ); +} + +{ + my $t = DateTime->new( + year => 1972, month => 6, day => 30, + hour => 22, minute => 59, second => 59, + time_zone => '-0100', + ); + + is( $t->second, 59, 'second value for leap second T-1, -0100' ); + + is( + $t->{utc_rd_days}, 720074, + 'UTC RD days for leap second T-1' + ); + is( + $t->{utc_rd_secs}, 86399, + 'UTC RD seconds for leap second T-1' + ); + + is( + $t->{local_rd_days}, 720074, + 'local RD days for leap second T-1' + ); + is( + $t->{local_rd_secs}, 82799, + 'local RD seconds for leap second T-1' + ); +} + +{ + my $t = eval { + DateTime->new( + year => 1972, month => 6, day => 30, + hour => 22, minute => 59, second => 60, + time_zone => '-0100', + ); + }; + + ok( !$@, 'constructor for second = 60' ); + +SKIP: + { + skip 'constructor failed - no object to test', 5 + unless $t; + + is( $t->second, 60, 'second value for leap second T-0, -0100' ); + + is( + $t->{utc_rd_days}, 720074, + 'UTC RD days for leap second T-0' + ); + is( + $t->{utc_rd_secs}, 86400, + 'UTC RD seconds for leap second T-0' + ); + + is( + $t->{local_rd_days}, 720074, + 'local RD days for leap second T-0' + ); + is( + $t->{local_rd_secs}, 82800, + 'local RD seconds for leap second T-0' + ); + } +} + +{ + my $t = DateTime->new( + year => 1972, month => 6, day => 30, + hour => 23, minute => 0, second => 0, + time_zone => '-0100', + ); + + is( $t->second, 0, 'second value for leap second T+1, -0100' ); + + is( + $t->{utc_rd_days}, 720075, + 'UTC RD days for leap second T+1' + ); + is( + $t->{utc_rd_secs}, 0, + 'UTC RD seconds for leap second T+1' + ); + + is( + $t->{local_rd_days}, 720074, + 'local RD days for leap second T+1' + ); + is( + $t->{local_rd_secs}, 82801, + 'local RD seconds for leap second T+1' + ); +} + +{ + my $t = DateTime->new( + year => 1972, month => 6, day => 30, + hour => 23, minute => 0, second => 1, + time_zone => '-0100', + ); + + is( $t->second, 1, 'second value for leap second T+2, -0100' ); + + is( + $t->{utc_rd_days}, 720075, + 'UTC RD days for leap second T+2' + ); + is( + $t->{utc_rd_secs}, 1, + 'UTC RD seconds for leap second T+2' + ); + + is( + $t->{local_rd_days}, 720074, + 'local RD days for leap second T+2' + ); + is( + $t->{local_rd_secs}, 82802, + 'local RD seconds for leap second T+2' + ); +} + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-33seconds-offset.t libdatetime-perl-1.46/xt/author/pp-33seconds-offset.t --- libdatetime-perl-1.21/xt/author/pp-33seconds-offset.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-33seconds-offset.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,91 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +use strict; +use warnings; + +use Test::More; + +use DateTime; + +{ + my $dt = DateTime->new( + year => 1997, month => 6, day => 30, + hour => 23, minute => 58, second => 59, + time_zone => 'UTC' + ); + + $dt->set_time_zone('+00:00:30'); + + is( $dt->datetime, '1997-06-30T23:59:29', '+00:00:30 leap second T-61' ); +} + +{ + my $dt = DateTime->new( + year => 1997, month => 6, day => 30, + hour => 23, minute => 59, second => 29, + time_zone => 'UTC' + ); + + $dt->set_time_zone('+00:00:30'); + + is( $dt->datetime, '1997-06-30T23:59:59', '+00:00:30 leap second T-31' ); +} + +{ + local $TODO = 'offsets with seconds are broken near leap seconds'; + + my $dt = DateTime->new( + year => 1997, month => 6, day => 30, + hour => 23, minute => 59, second => 30, + time_zone => 'UTC' + ); + + $dt->set_time_zone('+00:00:30'); + + is( $dt->datetime, '1997-06-30T23:59:60', '+00:00:30 leap second T-30' ); +} + +{ + local $TODO = 'offsets with seconds are broken near leap seconds'; + + my $dt = DateTime->new( + year => 1997, month => 6, day => 30, + hour => 23, minute => 59, second => 31, + time_zone => 'UTC' + ); + + $dt->set_time_zone('+00:00:30'); + + is( $dt->datetime, '1997-07-01T00:00:00', '+00:00:30 leap second T-29' ); +} + +{ + local $TODO = 'offsets with seconds are broken near leap seconds'; + + my $dt = DateTime->new( + year => 1997, month => 6, day => 30, + hour => 23, minute => 59, second => 60, + time_zone => 'UTC' + ); + + $dt->set_time_zone('+00:00:30'); + + is( $dt->datetime, '1997-07-01T00:00:30', '+00:00:30 leap second T-0' ); +} + +{ + my $dt = DateTime->new( + year => 1997, month => 7, day => 1, + hour => 0, minute => 0, second => 0, + time_zone => 'UTC' + ); + + $dt->set_time_zone('+00:00:30'); + + is( $dt->datetime, '1997-07-01T00:00:30', '+00:00:30 leap second T+1' ); +} + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-34set-tz.t libdatetime-perl-1.46/xt/author/pp-34set-tz.t --- libdatetime-perl-1.21/xt/author/pp-34set-tz.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-34set-tz.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,87 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +use strict; +use warnings; + +use Test::Fatal; +use Test::More 0.88; + +use DateTime; + +# These tests are for a bug related to a bad interaction between the +# horrid ->_handle_offset_modifier method and calling ->set_time_zone +# on a real Olson time zone. When _handle_offset_modifier was called +# from set_time_zone, it tried calling ->_offset_for_local_datetime, +# which was bogus, because at that point it doesn't know the local +# date time any more, only UTC. +# +# The fix is to have ->_handle_offset_modifier call ->offset when it +# knows that UTC is valid, which is determined by an arg to +# ->_handle_offset_modifier + +# These tests come from one of the zdump-generated test files in +# DT::TZ +{ + my $dt = DateTime->new( + year => 1922, month => 8, day => 31, + hour => 23, minute => 59, second => 59, + time_zone => 'UTC', + ); + $dt->set_time_zone('Africa/Accra'); + + is( $dt->year, 1922, 'local year should be 1922 (1922-08-31 23:59:59)' ); + is( $dt->month, 8, 'local month should be 8 (1922-08-31 23:59:59)' ); + is( $dt->day, 31, 'local day should be 31 (1922-08-31 23:59:59)' ); + is( $dt->hour, 23, 'local hour should be 23 (1922-08-31 23:59:59)' ); + is( $dt->minute, 59, 'local minute should be 59 (1922-08-31 23:59:59)' ); + is( $dt->second, 59, 'local second should be 59 (1922-08-31 23:59:59)' ); + + is( $dt->is_dst, 0, 'is_dst should be 0 (1922-08-31 23:59:59)' ); + is( $dt->offset, 0, 'offset should be 0 (1922-08-31 23:59:59)' ); + is( + $dt->time_zone_short_name, 'GMT', + 'short name should be GMT (1922-08-31 23:59:59)' + ); +} + +{ + my $dt = DateTime->new( + year => 2013, + month => 3, + day => 10, + hour => 2, + minute => 4, + time_zone => 'floating', + ); + + like( + exception { $dt->set_time_zone('America/Los_Angeles') }, + qr/\QInvalid local time for date in time zone/, + 'got an exception when trying to set time zone when it leads to invalid local time' + ); + + is( + $dt->time_zone()->name(), + 'floating', + 'time zone was not changed after set_time_zone() throws an exception' + ); +} + +{ + my $dt = DateTime->now( time_zone => 'America/Chicago' ); + + ok( + $dt->set_time_zone('America/Chicago'), + 'set_time_zone returns object when time zone name is same as current' + ); + + ok( + $dt->set_time_zone( $dt->time_zone() ), + 'set_time_zone returns object when time zone object is same as current' + ); +} + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-35rd-values.t libdatetime-perl-1.46/xt/author/pp-35rd-values.t --- libdatetime-perl-1.21/xt/author/pp-35rd-values.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-35rd-values.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,57 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +use strict; +use warnings; + +use Test::More; + +use DateTime; + +{ + my $dt = DateTime->new( + year => 2000, + hour => 1, + nanosecond => 500, + time_zone => 'UTC', + ); + + my ( $utc_rd_days, $utc_rd_secs, $utc_nanosecs ) = $dt->utc_rd_values; + + is( $utc_rd_days, 730120, 'utc rd days is 730120' ); + is( $utc_rd_secs, 3600, 'utc rd seconds is 3600' ); + is( $utc_nanosecs, 500, 'nanoseconds is 500' ); + + my ( $local_rd_days, $local_rd_secs, $local_nanosecs ) + = $dt->local_rd_values; + + is( $local_rd_days, $utc_rd_days, 'local & utc rd days are equal' ); + is( $local_rd_secs, $utc_rd_secs, 'local & utc rd seconds are equal' ); + is( $local_nanosecs, $utc_nanosecs, 'local & UTC nanoseconds are equal' ); +} + +{ + my $dt = DateTime->new( + year => 2000, + hour => 1, + nanosecond => 500, + time_zone => '+02:00', + ); + + my ( $utc_rd_days, $utc_rd_secs, $utc_nanosecs ) = $dt->utc_rd_values; + + is( $utc_rd_days, 730119, 'utc rd days is 730119' ); + is( $utc_rd_secs, 82800, 'utc rd seconds is 82800' ); + is( $utc_nanosecs, 500, 'nanoseconds is 500' ); + + my ( $local_rd_days, $local_rd_secs, $local_nanosecs ) + = $dt->local_rd_values; + + is( $local_rd_days, 730120, 'local rd days is 730120' ); + is( $local_rd_secs, 3600, 'local rd seconds is 3600' ); + is( $local_nanosecs, 500, 'local nanoseconds is 500' ); +} + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-36invalid-local.t libdatetime-perl-1.46/xt/author/pp-36invalid-local.t --- libdatetime-perl-1.21/xt/author/pp-36invalid-local.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-36invalid-local.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,67 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +use strict; +use warnings; + +use Test::Fatal; +use Test::More; + +use DateTime; + +my $badlt_rx = qr/Invalid local time|local time [0-9\-:T]+ does not exist/; + +{ + like( + exception { + DateTime->new( + year => 2003, month => 4, day => 6, + hour => 2, time_zone => 'America/Chicago', + ); + }, + $badlt_rx, + 'exception for invalid time' + ); + + like( + exception { + DateTime->new( + year => 2003, month => 4, day => 6, + hour => 2, minute => 59, second => 59, + time_zone => 'America/Chicago', + ); + }, + $badlt_rx, + 'exception for invalid time' + ); +} + +{ + is( + exception { + DateTime->new( + year => 2003, month => 4, day => 6, + hour => 1, minute => 59, second => 59, + time_zone => 'America/Chicago', + ); + }, + undef, + 'no exception for valid time' + ); + + my $dt = DateTime->new( + year => 2003, month => 4, day => 5, + hour => 2, + time_zone => 'America/Chicago', + ); + + like( + exception { $dt->add( days => 1 ) }, + $badlt_rx, + 'exception for invalid time produced via add' + ); +} + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-37local-add.t libdatetime-perl-1.46/xt/author/pp-37local-add.t --- libdatetime-perl-1.21/xt/author/pp-37local-add.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-37local-add.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,231 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +use strict; +use warnings; + +use Test::Fatal; +use Test::More; + +use DateTime; + +# These tests should be the final word on dt addition involving a +# DST-changing time zone + +# time addition is "wait X amount of time, then what does the clock +# say?" this means it acts on the UTC components. +{ + my $dt = DateTime->new( + year => 2003, month => 4, day => 6, + time_zone => 'America/Chicago', + ); + + $dt->add( hours => 1 ); + is( + $dt->datetime, '2003-04-06T01:00:00', + 'add one hour to midnight, get 1 am' + ); + + is( + exception { $dt->add( hours => 1 ) }, + undef, + 'no error adding 1 hour just before DST leap forward' + ); + is( + $dt->datetime, '2003-04-06T03:00:00', + 'add one hour to 1 am, get 3 am' + ); + + $dt->subtract( hours => 1 ); + is( + $dt->datetime, '2003-04-06T01:00:00', + 'subtract one hour from 3 am, get 1 am' + ); + + $dt->subtract( hours => 1 ); + is( + $dt->datetime, '2003-04-06T00:00:00', + 'subtract one hour from 1 am, get midnight' + ); +} + +{ + my $dt = DateTime->new( + year => 2003, month => 10, day => 26, + time_zone => 'America/Chicago', + ); + + $dt->add( hours => 1 ); + is( + $dt->datetime, '2003-10-26T01:00:00', + 'add one hour to midnight, get 1 am' + ); + + $dt->add( hours => 1 ); + is( + $dt->datetime, '2003-10-26T01:00:00', + 'add one hour to 1 am, get 1 am (again)' + ); + + $dt->add( hours => 1 ); + is( + $dt->datetime, '2003-10-26T02:00:00', + 'add one hour to 1 am (2nd time), get 2 am' + ); + + $dt->subtract( hours => 1 ); + is( + $dt->datetime, '2003-10-26T01:00:00', + 'subtract 1 hour from 2 am, get 1 am' + ); + + $dt->subtract( hours => 1 ); + is( + $dt->datetime, '2003-10-26T01:00:00', + 'subtract 1 hour from 1 am, get 1 am (again)' + ); + + $dt->subtract( hours => 1 ); + is( + $dt->datetime, '2003-10-26T00:00:00', + 'subtract 1 hour from 1 am (2nd), get midnight' + ); +} + +# date addition is "leave the clock alone, just change the date +# portion". this means it acts on local components +{ + my $dt = DateTime->new( + year => 2003, month => 4, day => 6, + time_zone => 'America/Chicago', + ); + + $dt->add( days => 1 ); + is( + $dt->datetime, '2003-04-07T00:00:00', + 'add 1 day at midnight, same clock time' + ); + + $dt->add( months => 7 ); + is( + $dt->datetime, '2003-11-07T00:00:00', + 'add 7 months at midnight, same clock time' + ); + + $dt->subtract( months => 7 ); + is( + $dt->datetime, '2003-04-07T00:00:00', + 'subtract 7 months at midnight, same clock time' + ); + + $dt->subtract( days => 1 ); + is( + $dt->datetime, '2003-04-06T00:00:00', + 'subtract 1 day at midnight, same clock time' + ); +} + +{ + my $dt = DateTime->new( + year => 2003, month => 10, day => 26, + time_zone => 'America/Chicago', + ); + + $dt->add( days => 1 ); + is( + $dt->datetime, '2003-10-27T00:00:00', + 'add 1 day at midnight, get midnight' + ); + + $dt->add( months => 7 ); + is( + $dt->datetime, '2004-05-27T00:00:00', + 'add 7 months at midnight, get midnight' + ); + + $dt->subtract( months => 7 ); + is( + $dt->datetime, '2003-10-27T00:00:00', + 'subtract 7 months at midnight, get midnight' + ); + + $dt->subtract( days => 1 ); + is( + $dt->datetime, '2003-10-26T00:00:00', + 'subtract 1 day at midnight, get midnight' + ); +} + +# date and time addition in one call is still two separate operations. +# First we do date, then time. +{ + my $dt = DateTime->new( + year => 2003, month => 4, day => 5, + time_zone => 'America/Chicago', + ); + + $dt->add( days => 1, hours => 2 ); + is( + $dt->datetime, '2003-04-06T03:00:00', + 'add one day & 2 hours from midnight, get 3 am' + ); + + # !!! - not reversible this way - needs some good docs + my $dt1 = $dt->clone->subtract( days => 1, hours => 2 ); + is( + $dt1->datetime, '2003-04-05T01:00:00', + 'subtract one day & 2 hours from 3 am, get 1 am' + ); + + # is reversible this way - also needs docs + my $dt2 = $dt->clone->subtract( hours => 2 )->subtract( days => 1 ); + is( + $dt2->datetime, '2003-04-05T00:00:00', + 'subtract 2 hours and then one day from 3 am, get midnight' + ); +} + +{ + my $dt = DateTime->new( + year => 2003, month => 10, day => 25, + time_zone => 'America/Chicago', + ); + + $dt->add( days => 1, hours => 2 ); + is( + $dt->datetime, '2003-10-26T01:00:00', + 'add one day & 2 hours from midnight, get 1 am' + ); + + my $dt1 = $dt->clone->subtract( days => 1, hours => 2 ); + is( + $dt1->datetime, '2003-10-24T23:00:00', + 'add one day & 2 hours from midnight, get 11 pm' + ); + + my $dt2 = $dt->clone->subtract( hours => 2 )->subtract( days => 1 ); + is( + $dt2->datetime, '2003-10-25T00:00:00', + 'subtract 2 hours and then one day from 3 am, get midnight' + ); +} + +# an example from the docs +{ + my $dt = DateTime->new( + year => 2003, month => 4, day => 5, + hour => 2, + time_zone => 'America/Chicago', + ); + + $dt->add( hours => 24 ); + + is( + $dt->datetime, '2003-04-06T03:00:00', + 'datetime after adding 24 hours is 2003-04-06T03:00:00' + ); +} + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-38local-subtract.t libdatetime-perl-1.46/xt/author/pp-38local-subtract.t --- libdatetime-perl-1.21/xt/author/pp-38local-subtract.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-38local-subtract.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,663 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +use strict; +use warnings; + +use Test::More; + +use DateTime; + +# These tests should be the final word on dt subtraction involving a +# DST-changing time zone + +{ + my $dt1 = DateTime->new( + year => 2003, month => 5, day => 6, + time_zone => 'America/Chicago', + ); + + my $dt2 = DateTime->new( + year => 2003, month => 11, day => 6, + time_zone => 'America/Chicago', + ); + + my $dur1 = $dt2->subtract_datetime($dt1); + my %deltas1 = $dur1->deltas; + is( $deltas1{months}, 6, 'delta_months is 6' ); + is( $deltas1{days}, 0, 'delta_days is 0' ); + is( $deltas1{minutes}, 0, 'delta_minutes is 0' ); + is( $deltas1{seconds}, 0, 'delta_seconds is 0' ); + + is( + DateTime->compare( $dt1->clone->add_duration($dur1), $dt2 ), 0, + 'subtract_datetime is reversible from start point' + ); + is( + DateTime->compare( $dt2->clone->subtract_duration($dur1), $dt1 ), 0, + 'subtract_datetime is reversible from end point' + ); + is( $deltas1{nanoseconds}, 0, 'delta_nanoseconds is 0' ); + + my $dur2 = $dt1->subtract_datetime($dt2); + my %deltas2 = $dur2->deltas; + is( $deltas2{months}, -6, 'delta_months is -6' ); + is( $deltas2{days}, 0, 'delta_days is 0' ); + is( $deltas2{minutes}, 0, 'delta_minutes is 0' ); + is( $deltas2{seconds}, 0, 'delta_seconds is 0' ); + is( $deltas2{nanoseconds}, 0, 'delta_nanoseconds is 0' ); + + my $dur3 = $dt2->delta_md($dt1); + my %deltas3 = $dur3->deltas; + is( $deltas3{months}, 6, 'delta_months is 6' ); + is( $deltas3{days}, 0, 'delta_days is 0' ); + is( $deltas3{minutes}, 0, 'delta_minutes is 0' ); + is( $deltas3{seconds}, 0, 'delta_seconds is 0' ); + is( $deltas3{nanoseconds}, 0, 'delta_nanoseconds is 0' ); + + is( + DateTime->compare( $dt1->clone->add_duration($dur3), $dt2 ), 0, + 'delta_md is reversible from start point' + ); + is( + DateTime->compare( $dt2->clone->subtract_duration($dur3), $dt1 ), 0, + 'delta_md is reversible from end point' + ); + + my $dur4 = $dt2->delta_days($dt1); + my %deltas4 = $dur4->deltas; + is( $deltas4{months}, 0, 'delta_months is 0' ); + is( $deltas4{days}, 184, 'delta_days is 184' ); + is( $deltas4{minutes}, 0, 'delta_minutes is 0' ); + is( $deltas4{seconds}, 0, 'delta_seconds is 0' ); + is( $deltas4{nanoseconds}, 0, 'delta_nanoseconds is 0' ); + + is( + DateTime->compare( $dt1->clone->add_duration($dur3), $dt2 ), 0, + 'delta_days is reversible from start point' + ); + is( + DateTime->compare( $dt2->clone->subtract_duration($dur4), $dt1 ), 0, + 'delta_days is reversible from end point' + ); +} + +# same as above, but now the UTC hour of the earlier datetime is +# _greater_ than that of the later one. this checks that overflows +# are handled correctly. +{ + my $dt1 = DateTime->new( + year => 2003, month => 5, day => 6, hour => 18, + time_zone => 'America/Chicago', + ); + + my $dt2 = DateTime->new( + year => 2003, month => 11, day => 6, hour => 18, + time_zone => 'America/Chicago', + ); + + my $dur1 = $dt2->subtract_datetime($dt1); + my %deltas1 = $dur1->deltas; + is( $deltas1{months}, 6, 'delta_months is 6' ); + is( $deltas1{days}, 0, 'delta_days is 0' ); + is( $deltas1{minutes}, 0, 'delta_minutes is 0' ); + is( $deltas1{seconds}, 0, 'delta_seconds is 0' ); + is( $deltas1{nanoseconds}, 0, 'delta_nanoseconds is 0' ); +} + +# make sure delta_md and delta_days work in the face of DST change +# where we lose an hour +{ + my $dt1 = DateTime->new( + year => 2003, month => 11, day => 6, + time_zone => 'America/Chicago', + ); + + my $dt2 = DateTime->new( + year => 2004, month => 5, day => 6, + time_zone => 'America/Chicago', + ); + + my $dur1 = $dt2->delta_md($dt1); + my %deltas1 = $dur1->deltas; + is( $deltas1{months}, 6, 'delta_months is 6' ); + is( $deltas1{days}, 0, 'delta_days is 0' ); + is( $deltas1{minutes}, 0, 'delta_minutes is 0' ); + is( $deltas1{seconds}, 0, 'delta_seconds is 0' ); + is( $deltas1{nanoseconds}, 0, 'delta_nanoseconds is 0' ); + + my $dur2 = $dt2->delta_days($dt1); + my %deltas2 = $dur2->deltas; + is( $deltas2{months}, 0, 'delta_months is 0' ); + is( $deltas2{days}, 182, 'delta_days is 182' ); + is( $deltas2{minutes}, 0, 'delta_minutes is 0' ); + is( $deltas2{seconds}, 0, 'delta_seconds is 0' ); + is( $deltas2{nanoseconds}, 0, 'delta_nanoseconds is 0' ); + +} + +# the docs say use UTC to guarantee reversibility +{ + my $dt1 = DateTime->new( + year => 2003, month => 5, day => 6, + time_zone => 'America/Chicago', + ); + + my $dt2 = DateTime->new( + year => 2003, month => 11, day => 6, + time_zone => 'America/Chicago', + ); + + $dt1->set_time_zone('UTC'); + $dt2->set_time_zone('UTC'); + + my $dur = $dt2->subtract_datetime($dt1); + + is( + DateTime->compare( $dt1->add_duration($dur), $dt2 ), 0, + 'subtraction is reversible from start point with UTC' + ); + is( + DateTime->compare( $dt2->subtract_duration($dur), $dt2 ), 0, + 'subtraction is reversible from start point with UTC' + ); +} + +# The important thing here is that after a subtraction, we can use the +# duration to get from one date to the other, regardless of the type +# of subtraction done. +{ + my $dt1 = DateTime->new( + year => 2003, month => 5, day => 6, + time_zone => 'America/Chicago', + ); + + my $dt2 = DateTime->new( + year => 2003, month => 11, day => 6, + time_zone => 'America/Chicago', + ); + + my $dur1 = $dt2->subtract_datetime_absolute($dt1); + + my %deltas1 = $dur1->deltas; + is( $deltas1{months}, 0, 'delta_months is 0' ); + is( $deltas1{days}, 0, 'delta_days is 0' ); + is( $deltas1{minutes}, 0, 'delta_minutes is 0' ); + is( $deltas1{seconds}, 15901200, 'delta_seconds is 15901200' ); + is( $deltas1{nanoseconds}, 0, 'delta_nanoseconds is 0' ); + + is( + DateTime->compare( $dt1->clone->add_duration($dur1), $dt2 ), 0, + 'subtraction is reversible' + ); + is( + DateTime->compare( $dt2->clone->subtract_duration($dur1), $dt1 ), 0, + 'subtraction is doubly reversible' + ); + + my $dur2 = $dt1->subtract_datetime_absolute($dt2); + + my %deltas2 = $dur2->deltas; + is( $deltas2{months}, 0, 'delta_months is 0' ); + is( $deltas2{days}, 0, 'delta_days is 0' ); + is( $deltas2{minutes}, 0, 'delta_minutes is 0' ); + is( $deltas2{seconds}, -15901200, 'delta_seconds is -15901200' ); + is( $deltas2{nanoseconds}, 0, 'delta_nanoseconds is 0' ); + + is( + DateTime->compare( $dt2->clone->add_duration($dur2), $dt1 ), 0, + 'subtraction is reversible' + ); + is( + DateTime->compare( $dt1->clone->subtract_duration($dur2), $dt2 ), 0, + 'subtraction is doubly reversible' + ); +} + +{ + my $dt1 = DateTime->new( + year => 2003, month => 4, day => 6, + hour => 1, minute => 58, + time_zone => 'America/Chicago', + ); + + my $dt2 = DateTime->new( + year => 2003, month => 4, day => 6, + hour => 3, minute => 1, + time_zone => 'America/Chicago', + ); + + my $dur = $dt2->subtract_datetime($dt1); + + my %deltas = $dur->deltas; + is( $deltas{months}, 0, 'delta_months is 0' ); + is( $deltas{days}, 0, 'delta_days is 0' ); + is( $deltas{minutes}, 3, 'delta_minutes is 3' ); + is( $deltas{seconds}, 0, 'delta_seconds is 0' ); + is( $deltas{nanoseconds}, 0, 'delta_nanoseconds is 0' ); + + is( + DateTime->compare( $dt1->clone->add_duration($dur), $dt2 ), 0, + 'subtraction is reversible' + ); + is( + DateTime->compare( $dt2->clone->subtract_duration($dur), $dt1 ), 0, + 'subtraction is doubly reversible' + ); +} + +{ + my $dt1 = DateTime->new( + year => 2003, month => 4, day => 5, + hour => 1, minute => 58, + time_zone => 'America/Chicago', + ); + + my $dt2 = DateTime->new( + year => 2003, month => 4, day => 6, + hour => 3, minute => 1, + time_zone => 'America/Chicago', + ); + + my $dur = $dt2->subtract_datetime($dt1); + + my %deltas = $dur->deltas; + is( $deltas{months}, 0, 'delta_months is 0' ); + is( $deltas{days}, 1, 'delta_days is 1' ); + is( $deltas{minutes}, 3, 'delta_minutes is 3' ); + is( $deltas{seconds}, 0, 'delta_seconds is 0' ); + is( $deltas{nanoseconds}, 0, 'delta_nanoseconds is 0' ); + + is( + DateTime->compare( $dt1->clone->add_duration($dur), $dt2 ), 0, + 'dt1 + dur = dt2' + ); + + # this are two examples from the docs + is( + DateTime->compare( + $dt2->clone->subtract_duration($dur), + $dt1->clone->add( hours => 1 ) + ), + 0, + 'dt2 - dur != dt1 (not reversible)' + ); + is( + DateTime->compare( + $dt2->clone->subtract_duration( $dur->clock_duration ) + ->subtract_duration( $dur->calendar_duration ), + $dt1 + ), + 0, + 'dt2 - dur->clock - dur->cal = dt1 (reversible when componentized)' + ); + + my $dur2 = $dt1->subtract_datetime($dt2); + my %deltas2 = $dur2->deltas; + is( $deltas2{months}, 0, 'delta_months is 0' ); + is( $deltas2{days}, -1, 'delta_days is 1' ); + is( $deltas2{minutes}, -3, 'delta_minutes is 3' ); + is( $deltas2{seconds}, 0, 'delta_seconds is 0' ); + is( $deltas2{nanoseconds}, 0, 'delta_nanoseconds is 0' ); + is( + $dt2->clone->add_duration($dur2)->datetime, '2003-04-05T02:58:00', + 'dt2 + dur2 != dt1' + ); + is( + DateTime->compare( + $dt2->clone->add_duration( $dur2->clock_duration ) + ->add_duration( $dur2->calendar_duration ), + $dt1 + ), + 0, + 'dt2 + dur2->clock + dur2->cal = dt1' + ); + is( + DateTime->compare( $dt1->clone->subtract_duration($dur2), $dt2 ), 0, + 'dt1 - dur2 = dt2' + ); + +} + +# These tests makes sure that days with DST changes are "normal" when +# they're the smaller operand +{ + my $dt1 = DateTime->new( + year => 2003, month => 4, day => 6, + hour => 3, minute => 1, + time_zone => 'America/Chicago', + ); + + my $dt2 = DateTime->new( + year => 2003, month => 4, day => 7, + hour => 3, minute => 2, + time_zone => 'America/Chicago', + ); + + my $dur = $dt2->subtract_datetime($dt1); + + my %deltas = $dur->deltas; + is( $deltas{months}, 0, 'delta_months is 0' ); + is( $deltas{days}, 1, 'delta_days is 1' ); + is( $deltas{minutes}, 1, 'delta_minutes is 1' ); + is( $deltas{seconds}, 0, 'delta_seconds is 0' ); + is( $deltas{nanoseconds}, 0, 'delta_nanoseconds is 0' ); + + my $dur2 = $dt1->subtract_datetime($dt2); + + my %deltas2 = $dur2->deltas; + is( $deltas2{months}, 0, 'delta_months is 0' ); + is( $deltas2{days}, -1, 'delta_days is -1' ); + is( $deltas2{minutes}, -1, 'delta_minutes is -1' ); + is( $deltas2{seconds}, 0, 'delta_seconds is 0' ); + is( $deltas2{nanoseconds}, 0, 'delta_nanoseconds is 0' ); + +} + +{ + my $dt1 = DateTime->new( + year => 2003, month => 4, day => 5, + hour => 1, minute => 58, + time_zone => 'America/Chicago', + ); + + my $dt2 = DateTime->new( + year => 2003, month => 4, day => 7, + hour => 2, minute => 1, + time_zone => 'America/Chicago', + ); + + my $dur = $dt2->subtract_datetime($dt1); + + my %deltas = $dur->deltas; + is( $deltas{months}, 0, 'delta_months is 0' ); + is( $deltas{days}, 2, 'delta_days is 2' ); + is( $deltas{minutes}, 3, 'delta_minutes is 3' ); + is( $deltas{seconds}, 0, 'delta_seconds is 0' ); + is( $deltas{nanoseconds}, 0, 'delta_nanoseconds is 0' ); + + is( + DateTime->compare( $dt1->clone->add_duration($dur), $dt2 ), 0, + 'subtraction is reversible' + ); + is( + DateTime->compare( $dt2->clone->subtract_duration($dur), $dt1 ), 0, + 'subtraction is doubly reversible' + ); +} + +# from example in docs +{ + my $dt1 = DateTime->new( + year => 2003, month => 5, day => 6, + time_zone => 'America/Chicago', + ); + + my $dt2 = DateTime->new( + year => 2003, month => 11, day => 6, + time_zone => 'America/Chicago', + ); + + $dt1->set_time_zone('floating'); + $dt2->set_time_zone('floating'); + + my $dur = $dt2->subtract_datetime($dt1); + my %deltas = $dur->deltas; + is( $deltas{months}, 6, 'delta_months is 6' ); + is( $deltas{days}, 0, 'delta_days is 0' ); + is( $deltas{minutes}, 0, 'delta_minutes is 0' ); + is( $deltas{seconds}, 0, 'delta_seconds is 0' ); + is( $deltas{nanoseconds}, 0, 'delta_nanoseconds is 0' ); + + is( + DateTime->compare( $dt1->clone->add_duration($dur), $dt2 ), 0, + 'subtraction is reversible from start point' + ); + is( + DateTime->compare( $dt2->clone->subtract_duration($dur), $dt1 ), 0, + 'subtraction is reversible from end point' + ); +} + +{ + my $dt1 = DateTime->new( + year => 2005, month => 8, + time_zone => 'Europe/London', + ); + + my $dt2 = DateTime->new( + year => 2005, month => 11, + time_zone => 'Europe/London', + ); + + my $dur = $dt2->subtract_datetime($dt1); + my %deltas = $dur->deltas; + is( + $deltas{months}, 3, + '3 months between two local times over DST change' + ); + is( $deltas{days}, 0, '0 days between two local times over DST change' ); + is( + $deltas{minutes}, 0, + '0 minutes between two local times over DST change' + ); +} + +# same as previous but without hours overflow +{ + my $dt1 = DateTime->new( + year => 2005, month => 8, hour => 12, + time_zone => 'Europe/London', + ); + + my $dt2 = DateTime->new( + year => 2005, month => 11, hour => 12, + time_zone => 'Europe/London', + ); + + my $dur = $dt2->subtract_datetime($dt1); + my %deltas = $dur->deltas; + is( + $deltas{months}, 3, + '3 months between two local times over DST change' + ); + is( $deltas{days}, 0, '0 days between two local times over DST change' ); + is( + $deltas{minutes}, 0, + '0 minutes between two local times over DST change' + ); +} + +# another docs example +{ + my $dt2 = DateTime->new( + year => 2003, month => 10, day => 26, + hour => 1, + time_zone => 'America/Chicago', + ); + + my $dt1 = $dt2->clone->subtract( hours => 1 ); + + my $dur = $dt2->subtract_datetime($dt1); + + my %deltas = $dur->deltas; + is( + $deltas{months}, 0, + '0 months between two local times over DST change' + ); + is( $deltas{days}, 0, '0 days between two local times over DST change' ); + is( + $deltas{minutes}, 60, + '60 minutes between two local times over DST change' + ); + + is( + DateTime->compare( $dt1->clone->add_duration($dur), $dt2 ), 0, + 'subtraction is reversible' + ); + is( + DateTime->compare( $dt2->clone->subtract_duration($dur), $dt1 ), 0, + 'subtraction is doubly reversible' + ); +} + +{ + my $dt1 = DateTime->new( + year => 2003, month => 5, day => 6, + time_zone => 'America/New_York', + ); + + my $dt2 = DateTime->new( + year => 2003, month => 5, day => 6, + time_zone => 'America/Chicago', + ); + + my $dur = $dt2->subtract_datetime($dt1); + + my %deltas = $dur->deltas; + is( + $deltas{months}, 0, + '0 months between two local times over DST change' + ); + is( $deltas{days}, 0, '0 days between two local times over DST change' ); + is( + $deltas{minutes}, 60, + '60 minutes between two local times over DST change' + ); + + is( + DateTime->compare( $dt1->clone->add_duration($dur), $dt2 ), 0, + 'subtraction is reversible' + ); + is( + DateTime->compare( $dt2->clone->subtract_duration($dur), $dt1 ), 0, + 'subtraction is doubly reversible' + ); +} + +# Fix a bug that occurred when the local time zone had DST and the two +# datetime objects were on the same day +{ + my $dt1 = DateTime->new( + year => 2005, month => 4, day => 3, + hour => 7, minute => 0, + time_zone => 'America/New_York' + ); + + my $dt2 = DateTime->new( + year => 2005, month => 4, day => 3, + hour => 8, minute => 0, + time_zone => 'America/New_York' + ); + + my $dur = $dt2->subtract_datetime($dt1); + my ( $minutes, $seconds ) = $dur->in_units( 'minutes', 'seconds' ); + + is( + $minutes, 60, + 'subtraction of two dates on a DST change date, minutes == 60' + ); + is( + $seconds, 0, + 'subtraction of two dates on a DST change date, seconds == 0' + ); + + $dur = $dt1->subtract_datetime($dt1); + ok( + $dur->is_zero, + 'dst change date (no dst) - itself, duration is zero' + ); +} + +{ + my $dt1 = DateTime->new( + year => 2005, month => 4, day => 3, + hour => 1, minute => 0, + time_zone => 'America/New_York' + ); + + my $dur = $dt1->subtract_datetime($dt1); + ok( + $dur->is_zero, + 'dst change date (with dst) - itself, duration is zero' + ); +} + +# This tests a bug where one of the datetimes is changing DST, and the +# other is not. In this case, no "adjustments" (aka hacks) are made in +# subtract_datetime, and it just gives the "UTC difference". +{ + + # This is UTC-4 + my $dt1 = DateTime->new( + year => 2009, month => 3, day => 9, + time_zone => 'America/New_York' + ); + + # This is UTC+8 + my $dt2 = DateTime->new( + year => 2009, month => 3, day => 9, + time_zone => 'Asia/Hong_Kong' + ); + + my $dur = $dt1->subtract_datetime($dt2); + + is( + $dur->delta_minutes, 720, + 'subtraction the day after a DST change in one zone, where the other datetime is in a different zone' + ); +} + +{ + + # This is UTC-5 + my $dt1 = DateTime->new( + year => 2009, month => 3, day => 8, + hour => 1, + time_zone => 'America/New_York' + ); + + # This is UTC+8 + my $dt2 = DateTime->new( + year => 2009, month => 3, day => 8, + hour => 1, + time_zone => 'Asia/Hong_Kong' + ); + + my $dur = $dt1->subtract_datetime($dt2); + + is( + $dur->delta_minutes, 780, + 'subtraction the day of a DST change in one zone (before the change),' + . ' where the other datetime is in a different zone' + ); +} + +{ + + # This is UTC-4 + my $dt1 = DateTime->new( + year => 2009, month => 3, day => 8, + hour => 4, + time_zone => 'America/New_York' + ); + + # This is UTC+8 + my $dt2 = DateTime->new( + year => 2009, month => 3, day => 8, + hour => 4, + time_zone => 'Asia/Hong_Kong' + ); + + my $dur = $dt1->subtract_datetime($dt2); + + is( + $dur->delta_minutes, 720, + 'subtraction the day of a DST change in one zone (after the change),' + . ' where the other datetime is in a different zone' + ); +} + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-40leap-years.t libdatetime-perl-1.46/xt/author/pp-40leap-years.t --- libdatetime-perl-1.21/xt/author/pp-40leap-years.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-40leap-years.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,22 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +use strict; +use warnings; + +use Test::More; + +use DateTime; + +## no critic (Subroutines::ProtectPrivateSubs) +for my $y ( 0, 400, 2000, 2004 ) { + ok( DateTime->_is_leap_year($y), "$y is a leap year" ); +} + +for my $y ( 1, 100, 1900, 2133 ) { + ok( !DateTime->_is_leap_year($y), "$y is not a leap year" ); +} + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-41cldr-format.t libdatetime-perl-1.46/xt/author/pp-41cldr-format.t --- libdatetime-perl-1.21/xt/author/pp-41cldr-format.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-41cldr-format.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,330 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +use strict; +use warnings; +use utf8; + +use Test::More; + +use DateTime; + +for my $o ( + Test::Builder->new->output, + Test::Builder->new->failure_output, + Test::Builder->new->todo_output +) { + + binmode $o, ':encoding(UTF-8)' or die $!; +} + +{ + my $dt = DateTime->new( + year => 1976, + month => 10, + day => 20, + hour => 18, + minute => 34, + second => 55, + nanosecond => 1_000_000, + locale => 'en', + time_zone => 'America/Chicago', + ); + + my %tests = ( + 'GGGGG' => 'A', + 'GGGG' => 'Anno Domini', + 'GGG' => 'AD', + 'GG' => 'AD', + 'G' => 'AD', + + 'yyyyy' => '01976', + 'yyyy' => '1976', + 'yyy' => '1976', + 'yy' => '76', + 'y' => '1976', + + 'uuuuuu' => '001976', + 'uuuuu' => '01976', + 'uuuu' => '1976', + 'uuu' => '1976', + 'uu' => '1976', + 'u' => '1976', + + 'YYYYY' => '01976', + 'YYYY' => '1976', + 'YYY' => '1976', + 'YY' => '1976', + 'Y' => '1976', + + 'QQQQ' => '4th quarter', + 'QQQ' => 'Q4', + 'QQ' => '04', + 'Q' => '4', + + 'qqqq' => '4th quarter', + 'qqq' => 'Q4', + 'qq' => '04', + 'q' => '4', + + 'MMMMM' => 'O', + 'MMMM' => 'October', + 'MMM' => 'Oct', + 'MM' => '10', + 'M' => '10', + + 'LLLLL' => 'O', + 'LLLL' => 'October', + 'LLL' => 'Oct', + 'LL' => '10', + 'L' => '10', + + 'ww' => '43', + 'w' => '43', + 'W' => '3', + + 'dd' => '20', + 'd' => '20', + + 'DDD' => '294', + 'DD' => '294', + 'D' => '294', + + 'F' => '3', + 'gggggg' => '043071', + 'g' => '43071', + + 'EEEEE' => 'W', + 'EEEE' => 'Wednesday', + 'EEE' => 'Wed', + 'EE' => 'Wed', + 'E' => 'Wed', + + 'eeeee' => 'W', + 'eeee' => 'Wednesday', + 'eee' => 'Wed', + 'ee' => '03', + 'e' => '3', + + 'ccccc' => 'W', + 'cccc' => 'Wednesday', + 'ccc' => 'Wed', + 'cc' => '03', + 'c' => '3', + + 'a' => 'PM', + + 'hh' => '06', + 'h' => '6', + 'HH' => '18', + 'H' => '18', + 'KK' => '06', + 'K' => '6', + 'kk' => '18', + 'j' => '6', + 'jj' => '06', + + 'mm' => '34', + 'm' => '34', + + 'ss' => '55', + 's' => '55', + 'SS' => '00', + 'SSSSSS' => '001000', + 'A' => '66895001', + + 'zzzz' => 'America/Chicago', + 'zzz' => 'CDT', + 'ZZZZ' => 'CDT-0500', + 'ZZZ' => '-0500', + 'vvvv' => 'America/Chicago', + 'vvv' => 'CDT', + 'VVVV' => 'America/Chicago', + 'VVV' => 'CDT', + 'ZZZZZ' => '-05:00', + + q{'one fine day'} => 'one fine day', + q{'yy''yy' yyyy} => q{yy'yy 1976}, + + q{'yy''yy' 'hello' yyyy} => q{yy'yy hello 1976}, + + # Non-pattern text should pass through unchanged + 'd日' => '20日', + ); + + for my $k ( sort keys %tests ) { + is( + $dt->format_cldr($k), $tests{$k}, + "format_cldr for $k" + ); + } +} + +{ + my $dt = DateTime->new( + year => 2008, + month => 10, + day => 20, + hour => 18, + minute => 34, + second => 55, + nanosecond => 1_000_000, + locale => 'en', + time_zone => 'America/Chicago', + ); + + is( + $dt->format_cldr('yy'), '08', + 'format_cldr for yy in 2008 should be 08' + ); +} + +{ + my $dt = DateTime->new( + year => 2008, + month => 10, + day => 20, + hour => 18, + minute => 34, + second => 55, + nanosecond => 1_000_000, + locale => 'en_US', + time_zone => 'America/Chicago', + ); + + is( + $dt->format_cldr('j'), '6', + 'format_cldr for j in en_US should be 6 (at 18:34)' + ); +} + +{ + my $dt = DateTime->new( + year => 2008, + month => 10, + day => 20, + hour => 18, + minute => 34, + second => 55, + nanosecond => 1_000_000, + locale => 'fr', + time_zone => 'America/Chicago', + ); + + is( + $dt->format_cldr('j'), '18', + 'format_cldr for j in fr should be 18 (at 18:34)' + ); +} + +{ + my $dt = DateTime->new( + year => 2009, + month => 4, + day => 13, + locale => 'en_US', + ); + + is( + $dt->format_cldr('e'), '2', + 'format_cldr for e in en_US should be 2 (for Monday, 2009-04-13)' + ); + + is( + $dt->format_cldr('c'), '1', + 'format_cldr for c in en_US should be 1 (for Monday, 2009-04-13)' + ); +} + +{ + my $dt = DateTime->new( + year => 2009, + month => 4, + day => 13, + locale => 'fr_FR', + ); + + is( + $dt->format_cldr('e'), '1', + 'format_cldr for e in fr_FR should be 1 (for Monday, 2009-04-13)' + ); + + is( + $dt->format_cldr('c'), '1', + 'format_cldr for c in fr_FR should be 1 (for Monday, 2009-04-13)' + ); +} + +{ + my $dt = DateTime->new( year => -10 ); + + my %tests = ( + 'y' => '-10', + 'yy' => '-10', + 'yyy' => '-10', + 'yyyy' => '-010', + 'yyyyy' => '-0010', + + 'u' => '-10', + 'uu' => '-10', + 'uuu' => '-10', + 'uuuu' => '-010', + 'uuuuu' => '-0010', + ); + + for my $k ( sort keys %tests ) { + is( + $dt->format_cldr($k), $tests{$k}, + "format_cldr for $k" + ); + } +} + +{ + my $dt = DateTime->new( year => -1976 ); + + my %tests = ( + 'y' => '-1976', + 'yy' => '-76', + 'yyy' => '-1976', + 'yyyy' => '-1976', + 'yyyyy' => '-1976', + + 'u' => '-1976', + 'uu' => '-1976', + 'uuu' => '-1976', + 'uuuu' => '-1976', + 'uuuuu' => '-1976', + ); + + for my $k ( sort keys %tests ) { + is( + $dt->format_cldr($k), $tests{$k}, + "format_cldr for $k" + ); + } +} + +{ + my $dt = DateTime->new( + year => 1976, + month => 10, + day => 20, + hour => 18, + minute => 34, + second => 55, + nanosecond => 999_999_999, + locale => 'en', + time_zone => 'UTC', + ); + + is( + $dt->format_cldr('ss,SSS'), + '55,999', + 'milliseconds are rounded down', + ); +} + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-42duration-class.t libdatetime-perl-1.46/xt/author/pp-42duration-class.t --- libdatetime-perl-1.21/xt/author/pp-42duration-class.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-42duration-class.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,34 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +## no critic (Modules::ProhibitMultiplePackages) +use strict; +use warnings; + +use Test::More; +use DateTime; + +{ + package DateTime::MySubclass; + use base 'DateTime'; + + sub duration_class {'DateTime::Duration::MySubclass'} + + package DateTime::Duration::MySubclass; + use base 'DateTime::Duration'; + + sub is_my_subclass {1} +} + +my $dt = DateTime::MySubclass->now; +my $delta = $dt - $dt; + +isa_ok( $delta, 'DateTime::Duration::MySubclass' ); +isa_ok( $dt + $delta, 'DateTime::MySubclass' ); + +my $delta_days = $dt->delta_days($dt); +isa_ok( $delta_days, 'DateTime::Duration::MySubclass' ); + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-43new-params.t libdatetime-perl-1.46/xt/author/pp-43new-params.t --- libdatetime-perl-1.21/xt/author/pp-43new-params.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-43new-params.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,106 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +use strict; +use warnings; + +use Test::Fatal; +use Test::More; + +use DateTime; + +like( + exception { DateTime->new( year => 10.5 ) }, + qr/Validation failed for type named Year/, + 'year must be an integer' +); +like( + exception { DateTime->new( year => -10.5 ) }, + qr/Validation failed for type named Year/, + 'year must be an integer' +); + +like( + exception { DateTime->new( year => 10, month => 2.5 ) }, + qr/Validation failed for type named Month/, + 'month must be an integer' +); + +like( + exception { DateTime->new( year => 10, month => 2, day => 12.4 ) }, + qr/Validation failed for type named DayOfMonth/, + 'day must be an integer' +); + +like( + exception { + DateTime->new( year => 10, month => 2, day => 12, hour => 4.1 ); + }, + qr/Validation failed for type named Hour/, + 'hour must be an integer' +); + +like( + exception { + DateTime->new( + year => 10, + month => 2, + day => 12, + hour => 4, + minute => 12.2 + ); + }, + qr/Validation failed for type named Minute/, + 'minute must be an integer' +); + +like( + exception { + DateTime->new( + year => 10, + month => 2, + day => 12, + hour => 4, + minute => 12, + second => 51.8 + ); + }, + qr/Validation failed for type named Second/, + 'second must be an integer' +); + +like( + exception { + DateTime->new( + year => 10, + month => 2, + day => 12, + hour => 4, + minute => 12, + second => 51, + nanosecond => 124512.12412 + ); + }, + qr/Validation failed for type named Nanosecond/, + 'nanosecond must be an integer' +); + +like( + exception { + DateTime->new( year => 10, month => 2, day => 12 )->today; + }, + qr/called with reference/, + 'today must be called as a class method, not an object method' +); + +like( + exception { + DateTime->new( year => 10, month => 2, day => 12 )->now; + }, + qr/called with reference/, + 'now must be called as a class method, not an object method' +); + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-44set-formatter.t libdatetime-perl-1.46/xt/author/pp-44set-formatter.t --- libdatetime-perl-1.21/xt/author/pp-44set-formatter.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-44set-formatter.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,40 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +use strict; +use warnings; + +use Test::Fatal; +use Test::More; + +use DateTime; +use overload; + +my $dt = DateTime->now; + +like( + exception { $dt->set_formatter('Invalid::Formatter') }, + qr/\QValidation failed for type named Maybe[Formatter]/, + 'set_format is validated' +); + +SKIP: +{ + ## no critic (BuiltinFunctions::ProhibitStringyEval) + skip 'This test requires DateTime::Format::Strptime 1.2000+', 1 + unless eval 'use DateTime::Format::Strptime 1.2000; 1;'; + + my $formatter = DateTime::Format::Strptime->new( + pattern => '%Y%m%d %T', + ); + + is( + $dt->set_formatter($formatter), + $dt, + 'set_formatter returns the datetime object' + ); +} + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-45core-time.t libdatetime-perl-1.46/xt/author/pp-45core-time.t --- libdatetime-perl-1.21/xt/author/pp-45core-time.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-45core-time.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,25 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +use strict; +use warnings; + +use Test::More; + +use DateTime; + +no warnings 'redefine'; +## no critic (Variables::ProtectPrivateVars) +local *DateTime::_core_time = sub {0}; + +my $dt = DateTime->now; + +is( + "$dt", + '1970-01-01T00:00:00', + 'overriding DateTime::_core_time() works' +); + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-46warnings.t libdatetime-perl-1.46/xt/author/pp-46warnings.t --- libdatetime-perl-1.21/xt/author/pp-46warnings.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-46warnings.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,92 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +use strict; +use warnings; + +use Test::More; +use Test::Warnings 0.005 ':all'; + +use DateTime; + +my $year_5001_epoch = 95649120000; + +## no critic (TestingAndDebugging::ProhibitNoWarnings) +SKIP: +{ + my $year = ( gmtime($year_5001_epoch) )[5]; + skip 'These tests require a 64-bit Perl', 2 + unless defined $year && $year == 3101; + + { + like( + warning { + DateTime->from_epoch( + epoch => $year_5001_epoch, + time_zone => 'Asia/Taipei', + ); + }, + qr{\QYou are creating a DateTime object with a far future year (5001) and a time zone (Asia/Taipei).}, + 'got a warning when calling ->from_epoch with a far future epoch and a time_zone' + ); + } + + { + no warnings 'DateTime'; + is_deeply( + warning { + DateTime->from_epoch( + epoch => $year_5001_epoch, + time_zone => 'Asia/Taipei', + ); + }, + [], + 'no warning when calling ->from_epoch with a far future epoch and a time_zone with DateTime warnings category suppressed' + ); + } +} + +{ + like( + warning { + DateTime->new( + year => 5001, + time_zone => 'Asia/Taipei', + ); + }, + qr{\QYou are creating a DateTime object with a far future year (5001) and a time zone (Asia/Taipei).}, + 'got a warning when calling ->new with a far future year and a time_zone' + ); +} + +{ + no warnings 'DateTime'; + is_deeply( + warning { + DateTime->new( + year => 5001, + time_zone => 'Asia/Taipei', + ); + }, + [], + 'no warning when calling ->new with a far future epoch and a time_zone with DateTime warnings category suppressed' + ); +} + +{ + no warnings; + is_deeply( + warning { + DateTime->new( + year => 5001, + time_zone => 'Asia/Taipei', + ); + }, + [], + 'no warning when calling ->new with a far future epoch and a time_zone with all warnings suppressed' + ); +} + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-47default-time-zone.t libdatetime-perl-1.46/xt/author/pp-47default-time-zone.t --- libdatetime-perl-1.21/xt/author/pp-47default-time-zone.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-47default-time-zone.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,95 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +use strict; +use warnings; + +use Test::More; + +use DateTime; + +{ + my $dt = DateTime->new( year => 2000, month => 2, day => 21 ); + is( + $dt->time_zone->name, 'floating', + 'Time zones for new DateTime objects should default to floating' + ); + is( + DateTime->last_day_of_month( year => 2000, month => 2 ) + ->time_zone->name, + 'floating', + 'last_day_of_month time zone also should default to floating' + ); + is( + DateTime->from_day_of_year( year => 2000, day_of_year => 212 ) + ->time_zone->name, + 'floating', + 'from_day_of_year time zone also should default to floating' + ); + is( + DateTime->now->time_zone->name, 'UTC', + '... except for constructors which assume UTC' + ); + is( + DateTime->from_epoch( epoch => time() )->time_zone->name, 'UTC', + '... except for constructors which assume UTC' + ); +} + +{ + my $dt1 = DateTime->new( year => 1970, hour => 1, nanosecond => 100 ); + my $dt2 = DateTime->from_object( object => $dt1 ); + is( + $dt2->time_zone->name, 'floating', + 'Copying DateTime objects from other DateTime objects should retain the timezone' + ); +} + +{ + my $dt = DateTime->new( year => 2000, month => 2, day => 21 ); + local $ENV{PERL_DATETIME_DEFAULT_TZ} = 'America/Los_Angeles'; + is( + $dt->time_zone->name, 'floating', + 'Setting PERL_DATETIME_DEFAULT_TZ env should not impact existing objects' + ); + $dt = DateTime->new( year => 2000, month => 2, day => 21 ); + is( + $dt->time_zone->name, $ENV{PERL_DATETIME_DEFAULT_TZ}, + '... but new objects should no longer default to the floating time zone' + ); + is( + DateTime->last_day_of_month( year => 2000, month => 2 ) + ->time_zone->name, + $ENV{PERL_DATETIME_DEFAULT_TZ}, + 'last_day_of_month time zone also should default to floating' + ); + is( + DateTime->from_day_of_year( year => 2000, day_of_year => 212 ) + ->time_zone->name, + $ENV{PERL_DATETIME_DEFAULT_TZ}, + 'from_day_of_year time zone also should default to floating' + ); + is( + DateTime->now->time_zone->name, 'UTC', + '... and constructors which assume UTC should remain unchanged' + ); + + my $dt1 = DateTime->new( year => 1970, hour => 1, nanosecond => 100 ); + my $dt2 = DateTime->from_object( object => $dt1 ); + is( + $dt2->time_zone->name, $ENV{PERL_DATETIME_DEFAULT_TZ}, + 'Copying DateTime objects from other DateTime objects should retain the timezone' + ); +} + +{ + my $dt = DateTime->new( year => 2000, month => 2, day => 21 ); + is( + $dt->time_zone->name, 'floating', + 'Default time zone should revert to "floating" when PERL_DATETIME_DEFAULT_TZ no longer set' + ); +} + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-48rt-115983.t libdatetime-perl-1.46/xt/author/pp-48rt-115983.t --- libdatetime-perl-1.21/xt/author/pp-48rt-115983.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-48rt-115983.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,30 @@ +BEGIN { + $ENV{PERL_DATETIME_PP} = 1; +} + +use strict; +use warnings; + +use Test::Fatal; +use Test::More; + +use DateTime; + +# The bug here is that if DateTime doesn't clean it's namespace, it ends up +# having a catch method that is getting called here and being passed a hashref +# containing the return value of $dt->truncate. See +# https://rt.cpan.org/Ticket/Display.html?id=115983 + +my $dt = DateTime->now; +like( + exception { + try { } catch { + $dt->truncate( to => 'hour' ); + }; + }, + qr/Can\'t locate object method "catch"/, + 'DateTime does not have a catch method' +); + +done_testing(); + diff -Nru libdatetime-perl-1.21/xt/author/pp-is-loaded.t libdatetime-perl-1.46/xt/author/pp-is-loaded.t --- libdatetime-perl-1.21/xt/author/pp-is-loaded.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/pp-is-loaded.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,19 @@ +use strict; +use warnings; + +use Test::More; + +BEGIN { + ## no critic (Variables::RequireLocalizedPunctuationVars) + $ENV{PERL_DATETIME_PP} = 1; +} + +use DateTime; + +## no critic (Variables::ProhibitPackageVars) +ok( + $DateTime::IsPurePerl, + 'PurePerl implementation is loaded when env var is set' +); + +done_testing(); diff -Nru libdatetime-perl-1.21/xt/author/test-all-my-deps.t libdatetime-perl-1.46/xt/author/test-all-my-deps.t --- libdatetime-perl-1.21/xt/author/test-all-my-deps.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/test-all-my-deps.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,28 @@ +use strict; +use warnings; + +use Cwd qw( abs_path ); +use Test::More; + +BEGIN { + plan skip_all => + 'Must set DATETIME_TEST_DEPS to true in order to run these tests' + unless $ENV{DATETIME_TEST_DEPS}; +} + +use Test::DependentModules qw( test_all_dependents ); + +local $ENV{PERL_TEST_DM_LOG_DIR} = abs_path('.'); + +my $exclude = $ENV{DATETIME_TEST_DEPS} eq 'all' + ? qr/(?:^App-) + | + ^(?: + Archive-RPM + | + Video-Xine + )$ + /x + : qr/^(?!DateTime-)/; + +test_all_dependents( 'DateTime', { exclude => $exclude } ); diff -Nru libdatetime-perl-1.21/xt/author/test-version.t libdatetime-perl-1.46/xt/author/test-version.t --- libdatetime-perl-1.21/xt/author/test-version.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/test-version.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,23 @@ +use strict; +use warnings; +use Test::More; + +# generated by Dist::Zilla::Plugin::Test::Version 1.09 +use Test::Version; + +my @imports = qw( version_all_ok ); + +my $params = { + is_strict => 1, + has_version => 1, + multiple => 0, + +}; + +push @imports, $params + if version->parse( $Test::Version::VERSION ) >= version->parse('1.002'); + +Test::Version->import(@imports); + +version_all_ok; +done_testing; diff -Nru libdatetime-perl-1.21/xt/author/tidyall.t libdatetime-perl-1.46/xt/author/tidyall.t --- libdatetime-perl-1.21/xt/author/tidyall.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/tidyall.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,16 @@ +# This file was automatically generated by Dist::Zilla::Plugin::Test::TidyAll v$VERSION + +use Test::More 0.88; +BEGIN { + if ( $] < 5.010 ) { + plan skip_all => 'This test requires Perl version 5.010'; + } +} +use Test::Code::TidyAll 0.24; + +tidyall_ok( + verbose => ( exists $ENV{TEST_TIDYALL_VERBOSE} ? $ENV{TEST_TIDYALL_VERBOSE} : 1 ), + jobs => ( exists $ENV{TEST_TIDYALL_JOBS} ? $ENV{TEST_TIDYALL_JOBS} : 4 ), +); + +done_testing; diff -Nru libdatetime-perl-1.21/xt/author/xs-is-loaded.t libdatetime-perl-1.46/xt/author/xs-is-loaded.t --- libdatetime-perl-1.21/xt/author/xs-is-loaded.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/author/xs-is-loaded.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,14 @@ +use strict; +use warnings; + +use Test::More; + +use DateTime; + +## no critic (Variables::ProhibitPackageVars) +ok( + !$DateTime::IsPurePerl, + 'XS implementation is loaded by default' +); + +done_testing(); diff -Nru libdatetime-perl-1.21/xt/release/cpan-changes.t libdatetime-perl-1.46/xt/release/cpan-changes.t --- libdatetime-perl-1.21/xt/release/cpan-changes.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/release/cpan-changes.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,10 @@ +use strict; +use warnings; + +# this test was generated with Dist::Zilla::Plugin::Test::CPAN::Changes 0.012 + +use Test::More 0.96 tests => 1; +use Test::CPAN::Changes; +subtest 'changes_ok' => sub { + changes_file_ok('Changes'); +}; diff -Nru libdatetime-perl-1.21/xt/release/meta-json.t libdatetime-perl-1.46/xt/release/meta-json.t --- libdatetime-perl-1.21/xt/release/meta-json.t 1970-01-01 00:00:00.000000000 +0000 +++ libdatetime-perl-1.46/xt/release/meta-json.t 2018-02-11 23:36:51.000000000 +0000 @@ -0,0 +1,4 @@ +#!perl + +use Test::CPAN::Meta::JSON; +meta_json_ok();