App-dateseq

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN


0.098.1 2019-11-29  Released-By: PERLANCAR; Urgency: medium

	- Update coerce rule names in Sah schemas (Data::Sah::Coerce 0.034+).
	  UPDATE: Rename release from 0.098 -> 0.098.1, cancel release
	  (duplicate version).


0.098   2019-11-19  Released-By: PERLANCAR; Urgency: medium

	- Now use DateTime::Format::Strftimeq instead of
	  DateTime::Format::Strptime, for ease of custom formatting.


0.097   2019-07-22  Released-By: PERLANCAR; Urgency: medium

	- Allow using other DateTime::Format::* classes: rename
	  --date-format to --strftime, add --format-class &
	  --format-class-attrs.


0.096   2019-07-16  Released-By: PERLANCAR; Urgency: medium

	- [bugfix] When --to is specified, the date specified in --to was
	  not included.

	- Replace broken str_alami_en coercion with str_natural.

META.json  view on Meta::CPAN

            "Data::Sah::Coerce::perl::To_int::From_str::convert_en_dow_name_to_num" : "0",
            "Data::Sah::Coerce::perl::To_int::From_str::convert_en_month_name_to_num" : "0",
            "Data::Sah::Compiler::perl::TH::array" : "0.911",
            "Data::Sah::Compiler::perl::TH::bool" : "0.911",
            "Data::Sah::Compiler::perl::TH::date" : "0.911",
            "Data::Sah::Compiler::perl::TH::duration" : "0.911",
            "Data::Sah::Compiler::perl::TH::hash" : "0.911",
            "Data::Sah::Compiler::perl::TH::int" : "0.911",
            "Data::Sah::Compiler::perl::TH::str" : "0.911",
            "Data::Sah::Filter::perl::Perl::normalize_perl_modname" : "0",
            "DateTime::Duration" : "0",
            "DateTime::Format::Strftimeq" : "0",
            "Perinci::CmdLine::Any" : "0.152",
            "Perinci::CmdLine::Lite" : "1.915",
            "Sah::Schema::date::dow_num" : "0",
            "Sah::Schema::date::dow_nums" : "0",
            "Sah::Schema::date::month_num" : "0",
            "Sah::Schema::date::month_nums" : "0",
            "Sah::Schema::perl::modname" : "0.035",
            "Sah::Schema::posint" : "0",
            "Sah::Schema::true" : "0",
            "Scalar::Util" : "0",

META.yml  view on Meta::CPAN

  Data::Sah::Coerce::perl::To_int::From_str::convert_en_dow_name_to_num: '0'
  Data::Sah::Coerce::perl::To_int::From_str::convert_en_month_name_to_num: '0'
  Data::Sah::Compiler::perl::TH::array: '0.911'
  Data::Sah::Compiler::perl::TH::bool: '0.911'
  Data::Sah::Compiler::perl::TH::date: '0.911'
  Data::Sah::Compiler::perl::TH::duration: '0.911'
  Data::Sah::Compiler::perl::TH::hash: '0.911'
  Data::Sah::Compiler::perl::TH::int: '0.911'
  Data::Sah::Compiler::perl::TH::str: '0.911'
  Data::Sah::Filter::perl::Perl::normalize_perl_modname: '0'
  DateTime::Duration: '0'
  DateTime::Format::Strftimeq: '0'
  Perinci::CmdLine::Any: '0.152'
  Perinci::CmdLine::Lite: '1.915'
  Sah::Schema::date::dow_num: '0'
  Sah::Schema::date::dow_nums: '0'
  Sah::Schema::date::month_num: '0'
  Sah::Schema::date::month_nums: '0'
  Sah::Schema::perl::modname: '0.035'
  Sah::Schema::posint: '0'
  Sah::Schema::true: '0'
  Scalar::Util: '0'

Makefile.PL  view on Meta::CPAN

    "Data::Sah::Coerce::perl::To_int::From_str::convert_en_dow_name_to_num" => 0,
    "Data::Sah::Coerce::perl::To_int::From_str::convert_en_month_name_to_num" => 0,
    "Data::Sah::Compiler::perl::TH::array" => "0.911",
    "Data::Sah::Compiler::perl::TH::bool" => "0.911",
    "Data::Sah::Compiler::perl::TH::date" => "0.911",
    "Data::Sah::Compiler::perl::TH::duration" => "0.911",
    "Data::Sah::Compiler::perl::TH::hash" => "0.911",
    "Data::Sah::Compiler::perl::TH::int" => "0.911",
    "Data::Sah::Compiler::perl::TH::str" => "0.911",
    "Data::Sah::Filter::perl::Perl::normalize_perl_modname" => 0,
    "DateTime::Duration" => 0,
    "DateTime::Format::Strftimeq" => 0,
    "Perinci::CmdLine::Any" => "0.152",
    "Perinci::CmdLine::Lite" => "1.915",
    "Sah::Schema::date::dow_num" => 0,
    "Sah::Schema::date::dow_nums" => 0,
    "Sah::Schema::date::month_num" => 0,
    "Sah::Schema::date::month_nums" => 0,
    "Sah::Schema::perl::modname" => "0.035",
    "Sah::Schema::posint" => 0,
    "Sah::Schema::true" => 0,
    "Scalar::Util" => 0,

Makefile.PL  view on Meta::CPAN

  "Data::Sah::Coerce::perl::To_int::From_str::convert_en_dow_name_to_num" => 0,
  "Data::Sah::Coerce::perl::To_int::From_str::convert_en_month_name_to_num" => 0,
  "Data::Sah::Compiler::perl::TH::array" => "0.911",
  "Data::Sah::Compiler::perl::TH::bool" => "0.911",
  "Data::Sah::Compiler::perl::TH::date" => "0.911",
  "Data::Sah::Compiler::perl::TH::duration" => "0.911",
  "Data::Sah::Compiler::perl::TH::hash" => "0.911",
  "Data::Sah::Compiler::perl::TH::int" => "0.911",
  "Data::Sah::Compiler::perl::TH::str" => "0.911",
  "Data::Sah::Filter::perl::Perl::normalize_perl_modname" => 0,
  "DateTime::Duration" => 0,
  "DateTime::Format::Strftimeq" => 0,
  "File::Spec" => 0,
  "IO::Handle" => 0,
  "IPC::Open3" => 0,
  "Perinci::CmdLine::Any" => "0.152",
  "Perinci::CmdLine::Lite" => "1.915",
  "Sah::Schema::date::dow_num" => 0,
  "Sah::Schema::date::dow_nums" => 0,
  "Sah::Schema::date::month_num" => 0,
  "Sah::Schema::date::month_nums" => 0,
  "Sah::Schema::perl::modname" => "0.035",

README  view on Meta::CPAN

        Only list business days (Mon-Fri), or non-business days.

    *   business6 => *bool*

        Only list business days (Mon-Sat), or non-business days.

    *   eval => *str*

        Run perl code for each date.

        Specified perl code will receive the date as DateTime object in
        $_and expected to return result to print.

    *   exclude_dow => *date::dow_nums*

        Do not show dates with these day-of-weeks.

    *   exclude_month => *date::month_nums*

        Do not show dates with these month numbers.

    *   format_class => *perl::modname*

        Use a DateTime::Format::* class for formatting.

        By default, DateTime::Format::Strptime is used with pattern set from
        the <strftime> option.

    *   format_class_attrs => *hash*

        Arguments to pass to constructor of DateTime::Format::* class.

    *   from => *date*

        Starting date.

    *   header => *str*

        Add a header row.

    *   include_dow => *date::dow_nums*

README  view on Meta::CPAN


        Decrement instead of increment.

    *   strftime => *str*

        strftime() format for each date.

        Default is "%Y-%m-%d", unless when hour/minute/second is specified,
        then it is "%Y-%m-%dT%H:%M:%S".

        "dateseq" actually uses DateTimeX::strftimeq, so you can embed Perl
        code for flexibility. For example:

         % dateseq 2019-11-19 2019-11-25 -f '%Y-%m-%d%( $_->day_of_week == 7 ? "su" : "" )q'

        will print something like:

         2019-11-19
         2019-11-20
         2019-11-21
         2019-11-22

dist.ini  view on Meta::CPAN

read_config=0

[@Author::PERLANCAR]
:version=0.606

[Prereqs]
perl=5.010001
strict=0
warnings=0
Complete::Module=0.262
;DateTime=0
DateTime::Duration=0
DateTime::Format::Strftimeq=0
Scalar::Util=0

[Prereqs / DevelopX_spec]
-phase=develop
-relationship=x_spec
Rinci=1.1.102

lib/App/dateseq.pm  view on Meta::CPAN

_
    args_rels => {
        'choose_one&' => [
            [qw/business business6/],
        ],
    },
    args => {
        from => {
            summary => 'Starting date',
            schema => ['date*', {
                'x.perl.coerce_to' => 'DateTime',
                'x.perl.coerce_rules' => ['From_str::natural'],
            }],
            pos => 0,
        },
        to => {
            summary => 'End date, if not specified will generate an infinite* stream of dates',
            schema => ['date*', {
                'x.perl.coerce_to' => 'DateTime',
                'x.perl.coerce_rules' => ['From_str::natural'],
            }],
            pos => 1,
        },
        increment => {
            schema => ['duration*', {
                'x.perl.coerce_to' => 'DateTime::Duration',
            }],
            cmdline_aliases => {i=>{}},
            pos => 2,
        },
        reverse => {
            summary => 'Decrement instead of increment',
            schema => 'true*',
            cmdline_aliases => {r=>{}},
        },
        business => {

lib/App/dateseq.pm  view on Meta::CPAN

            schema => ['posint*'],
        },
        # XXX limit_weekly, limit_daily, limit_hourly, limit_minutely, limit_secondly
        strftime => {
            summary => 'strftime() format for each date',
            description => <<'_',

Default is `%Y-%m-%d`, unless when hour/minute/second is specified, then it is
`%Y-%m-%dT%H:%M:%S`.

`dateseq` actually uses <pm:DateTimeX::strftimeq>, so you can embed Perl code
for flexibility. For example:

    % dateseq 2019-11-19 2019-11-25 -f '%Y-%m-%d%( $_->day_of_week == 7 ? "su" : "" )q'

will print something like:

    2019-11-19
    2019-11-20
    2019-11-21
    2019-11-22
    2019-11-23
    2019-11-24su
    2019-11-25

_
            schema => ['str*'],
            cmdline_aliases => {f=>{}},
            tags => ['category:formatting'],
        },
        format_class => {
            summary => 'Use a DateTime::Format::* class for formatting',
            schema => ['perl::modname'],
            tags => ['category:formatting'],
            completion => sub {
                require Complete::Module;
                my %args = @_;
                Complete::Module::complete_module(
                    word => $args{word}, ns_prefix => 'DateTime::Format');
            },
            description => <<'_',

By default, <pm:DateTime::Format::Strptime> is used with pattern set from the
<strftime> option.

_
        },
        format_class_attrs => {
            summary => 'Arguments to pass to constructor of DateTime::Format::* class',
            schema => ['hash'],
            tags => ['category:formatting'],
        },
        eval => {
            summary => 'Run perl code for each date',
            schema => 'str*',
            tags => ['category:output'],
            cmdline_aliases => {e=>{}},
            description => <<'_',

Specified perl code will receive the date as DateTime object in `$_`and expected
to return result to print.

_
        },
    },
    examples => [
        {
            summary => 'Generate "infinite" dates from today',
            src => '[[prog]]',
            src_plang => 'bash',

lib/App/dateseq.pm  view on Meta::CPAN

            src_plang => 'bash',
            'x.doc.max_result_lines' => 10,
        },
        {
            summary => 'Use with fsql',
            src => q{[[prog]] 2010-01-01 2015-12-01 -f "%Y,%m" -i P1M --header "year,month" | fsql --add-csv - --add-csv data.csv -F YEAR -F MONTH 'SELECT year, month, data1 FROM stdin WHERE YEAR(data.date)=year AND MONTH(data.date)=month'},
            src_plang => 'bash',
            'x.doc.show_result' => 0,
        },
        {
            summary => 'Use %q (see DateTimeX::strftimeq)',
            src => q{[[prog]] 2020-12-24 2021-01-15 -f '%Y-%m-%d%( $_->day_of_week == 7 ? "su" : "" )q'},
            src_plang => 'bash',
            'x.doc.max_result_lines' => 10,
        },
        {
            summary => 'Print first and last days of each month of 2021',
            src => q{[[prog]] 2021-01-01 2021-12-01 --increment '1 month' -e 'my $dt2 = $_->clone; $dt2->add(months=>1); $dt2->add(days => -1); $_->ymd . " " . $dt2->ymd'},
            src_plang => 'bash',
            'x.doc.max_result_lines' => 10,
        },

lib/App/dateseq.pm  view on Meta::CPAN

        },
    ],
    links => [
        {url=>'prog:durseq', summary=>'Produce sequence of date durations'},
        {url=>'prog:dateseq-idn', summary=>'A wrapper for dateseq, with built-in support for Indonesian holidays'},
        {url=>'prog:seq'},
        {url=>'prog:seq-pl', summary=>'Perl variant of seq'},
    ],
};
sub dateseq {
    require DateTime::Duration;
    require DateTime::Format::Strftimeq;

    my %args = @_;

    $args{from} //= DateTime->today;
    $args{increment} //= DateTime::Duration->new(days=>1);
    my $reverse = $args{reverse};

    my $random = $args{random};
    return [412, "If you specify --random, you must also specify --from *and* --to"]
        if $random && !$args{to};

    my $formatter;
    if (my $cl = $args{format_class}) {
        $cl = "DateTime::Format::$cl";
        (my $cl_pm = "$cl.pm") =~ s!::!/!g;
        require $cl_pm;
        my $attrs = $args{format_class_attrs} // {};
        $formatter = $cl->new(%$attrs);
    } else {
        my $strftime  = $args{strftime} // do {
            my $has_hms;
            {
                if ($args{from}->hour || $args{from}->minute || $args{from}->second) {
                    $has_hms++; last;

lib/App/dateseq.pm  view on Meta::CPAN

                if (defined($args{to}) &&
                        ($args{to}->hour || $args{to}->minute || $args{to}->second)) {
                    $has_hms++; last;
                }
                if ($args{increment}->hours || $args{increment}->minutes || $args{increment}->seconds) {
                    $has_hms++; last;
                }
            }
            $has_hms ? '%Y-%m-%dT%H:%M:%S' : '%Y-%m-%d';
        };
        $formatter = DateTime::Format::Strftimeq->new(
            format => $strftime,
        );
    }

    my %seen_years;  # key=year (e.g. 2021), val=int
    my %seen_months; # key=year-mon (e.g. 2021-01), val=int
    my $num_dates = 0;
    my $code_filter = sub {
        my $dt = shift;
        if (defined $args{business}) {

lib/App/dateseq.pm  view on Meta::CPAN

        my $epoch_to   = $args{to}->epoch;
        $num_secs = $epoch_to-$epoch_from;
    }

    if ((defined $args{to} || defined $args{limit}) && !$random) {
        my @res;
        push @res, $args{header} if defined $args{header};
        my $dt = $args{from}->clone;
        while (1) {
            last if defined($args{limit}) && $num_dates >= $args{limit};
            #say "D:$dt vs $args{to}? ", DateTime->compare($dt, $args{to});
            if (defined $args{to}) {
                last if !$reverse && DateTime->compare($dt, $args{to}) > 0;
                last if  $reverse && DateTime->compare($dt, $args{to}) < 0;
            }
            if ($code_filter->($dt)) {
                push @res, $_format->($dt);
                $num_dates++;
            }
            $dt = $reverse ? $dt - $args{increment} : $dt + $args{increment};
        }
        return [200, "OK", \@res];
    } else {
        # stream

lib/App/dateseq.pm  view on Meta::CPAN

Only list business days (Mon-Fri), or non-business days.

=item * B<business6> => I<bool>

Only list business days (Mon-Sat), or non-business days.

=item * B<eval> => I<str>

Run perl code for each date.

Specified perl code will receive the date as DateTime object in C<$_>and expected
to return result to print.

=item * B<exclude_dow> => I<date::dow_nums>

Do not show dates with these day-of-weeks.

=item * B<exclude_month> => I<date::month_nums>

Do not show dates with these month numbers.

=item * B<format_class> => I<perl::modname>

Use a DateTime::Format::* class for formatting.

By default, L<DateTime::Format::Strptime> is used with pattern set from the
<strftime> option.

=item * B<format_class_attrs> => I<hash>

Arguments to pass to constructor of DateTime::Format::* class.

=item * B<from> => I<date>

Starting date.

=item * B<header> => I<str>

Add a header row.

=item * B<include_dow> => I<date::dow_nums>

lib/App/dateseq.pm  view on Meta::CPAN


Decrement instead of increment.

=item * B<strftime> => I<str>

strftime() format for each date.

Default is C<%Y-%m-%d>, unless when hour/minute/second is specified, then it is
C<%Y-%m-%dT%H:%M:%S>.

C<dateseq> actually uses L<DateTimeX::strftimeq>, so you can embed Perl code
for flexibility. For example:

 % dateseq 2019-11-19 2019-11-25 -f '%Y-%m-%d%( $_->day_of_week == 7 ? "su" : "" )q'

will print something like:

 2019-11-19
 2019-11-20
 2019-11-21
 2019-11-22

script/dateseq  view on Meta::CPAN

Can be specified multiple times.

=back

=head2 Formatting options

=over

=item B<--format-class-attrs-json>=I<s>

Arguments to pass to constructor of DateTime::Format::* class (JSON-encoded).

See C<--format-class-attrs>.

=item B<--format-class-attrs>=I<s>

Arguments to pass to constructor of DateTime::Format::* class.

=item B<--format-class>=I<s>

Use a DateTime::Format::* class for formatting.

By default, L<DateTime::Format::Strptime> is used with pattern set from the
<strftime> option.


=item B<--strftime>=I<s>, B<-f>

strftime() format for each date.

Default is C<%Y-%m-%d>, unless when hour/minute/second is specified, then it is
C<%Y-%m-%dT%H:%M:%S>.

C<dateseq> actually uses L<DateTimeX::strftimeq>, so you can embed Perl code
for flexibility. For example:

 % dateseq 2019-11-19 2019-11-25 -f '%Y-%m-%d%( $_->day_of_week == 7 ? "su" : "" )q'

will print something like:

 2019-11-19
 2019-11-20
 2019-11-21
 2019-11-22

script/dateseq  view on Meta::CPAN

=back

=head2 Output options

=over

=item B<--eval>=I<s>, B<-e>

Run perl code for each date.

Specified perl code will receive the date as DateTime object in C<$_>and expected
to return result to print.


=item B<--format>=I<s>

Choose output format, e.g. json, text.

Default value:

 undef

script/dateseq  view on Meta::CPAN

 2015-12-30
 2015-12-31

See also L<dateseq-idn> as alternative.


=head2 Use with fsql

 % dateseq 2010-01-01 2015-12-01 -f "%Y,%m" -i P1M --header "year,month" | fsql --add-csv - --add-csv data.csv -F YEAR -F MONTH 'SELECT year, month, data1 FROM stdin WHERE YEAR(data.date)=year AND MONTH(data.date)=month'

=head2 Use %q (see DateTimeX::strftimeq)

 % dateseq 2020-12-24 2021-01-15 -f '%Y-%m-%d%( $_->day_of_week == 7 ? "su" : "" )q'
 2020-12-24
 2020-12-25
 2020-12-26
 2020-12-27su
 2020-12-28
 ... 14 more lines ...
 2021-01-12
 2021-01-13



( run in 0.490 second using v1.01-cache-2.11-cpan-05444aca049 )