App-datecalc

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN


0.06    2015-01-03  Released-By: PERLANCAR

	- No functional changes.

	- Rebuild (generate TODO.md).


0.05    2014-12-01  Released-By: PERLANCAR

	- [ux] Change DateTime rendering to include day of week.


0.04    2014-06-26  Released-By: SHARYANTO

        - Adjust to SHARYANTO::List::Util's 0.75 (uniq renamed to uniq_adj).

        - [ux] Add commands help/? and exit/quit.


0.03    2014-05-28  Released-By: SHARYANTO

META.json  view on Meta::CPAN

      "develop" : {
         "requires" : {
            "Pod::Coverage::TrustPod" : "0",
            "Test::Perl::Critic" : "0",
            "Test::Pod" : "1.41",
            "Test::Pod::Coverage" : "1.08"
         }
      },
      "runtime" : {
         "requires" : {
            "DateTime" : "0",
            "DateTime::Format::ISO8601" : "0",
            "File::HomeDir" : "0",
            "Getopt::Long" : "2.50",
            "IO::Stty" : "0",
            "List::Util::Uniq" : "0.003",
            "MarpaX::Simple" : "0",
            "Scalar::Util" : "0",
            "Term::ReadLine" : "0",
            "perl" : "5.010001",
            "strict" : "0",
            "warnings" : "0"

META.yml  view on Meta::CPAN

license: perl
meta-spec:
  url: http://module-build.sourceforge.net/META-spec-v1.4.html
  version: '1.4'
name: App-datecalc
provides:
  App::datecalc:
    file: lib/App/datecalc.pm
    version: '0.090'
requires:
  DateTime: '0'
  DateTime::Format::ISO8601: '0'
  File::HomeDir: '0'
  Getopt::Long: '2.50'
  IO::Stty: '0'
  List::Util::Uniq: '0.003'
  MarpaX::Simple: '0'
  Scalar::Util: '0'
  Term::ReadLine: '0'
  perl: '5.010001'
  strict: '0'
  warnings: '0'

Makefile.PL  view on Meta::CPAN

    "ExtUtils::MakeMaker" => 0
  },
  "DISTNAME" => "App-datecalc",
  "EXE_FILES" => [
    "script/datecalc"
  ],
  "LICENSE" => "perl",
  "MIN_PERL_VERSION" => "5.010001",
  "NAME" => "App::datecalc",
  "PREREQ_PM" => {
    "DateTime" => 0,
    "DateTime::Format::ISO8601" => 0,
    "File::HomeDir" => 0,
    "Getopt::Long" => "2.50",
    "IO::Stty" => 0,
    "List::Util::Uniq" => "0.003",
    "MarpaX::Simple" => 0,
    "Scalar::Util" => 0,
    "Term::ReadLine" => 0,
    "strict" => 0,
    "warnings" => 0
  },

Makefile.PL  view on Meta::CPAN

    "Test::More" => "0.98"
  },
  "VERSION" => "0.090",
  "test" => {
    "TESTS" => "t/*.t"
  }
);


my %FallbackPrereqs = (
  "DateTime" => 0,
  "DateTime::Format::ISO8601" => 0,
  "File::HomeDir" => 0,
  "File::Spec" => 0,
  "Getopt::Long" => "2.50",
  "IO::Handle" => 0,
  "IO::Stty" => 0,
  "IPC::Open3" => 0,
  "List::Util::Uniq" => "0.003",
  "MarpaX::Simple" => 0,
  "Scalar::Util" => 0,
  "Term::ReadLine" => 0,

README  view on Meta::CPAN

  eval
HOMEPAGE
    Please visit the project's homepage at
    <https://metacpan.org/release/App-datecalc>.

SOURCE
    Source repository is at
    <https://github.com/perlancar/perl-App-datecalc>.

SEE ALSO
    DateTime and DateTime::Format::ISO8601, the backend modules used to do
    the actual date calculation.

    Marpa::R2 is used to generate the parser.

    Date::Calc another date module on CPAN. No relation except the
    similarity of name.

    <http://en.wikipedia.org/wiki/ISO_8601> for more information about the
    ISO 8601 format.

dist.ini  view on Meta::CPAN

:version=0.606

[Prereqs / TestRequires]
Test::Exception=0
Test::More=0.98

[Prereqs]
perl=5.010001
strict=0
warnings=0
DateTime=0
DateTime::Format::ISO8601=0
File::HomeDir=0
Getopt::Long=2.50
IO::Stty=0
List::Util::Uniq=0.003
MarpaX::Simple=0
Scalar::Util=0
Term::ReadLine=0

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

package App::datecalc;

use 5.010001;
use strict;
use warnings;

use DateTime;
use DateTime::Format::ISO8601;
use MarpaX::Simple qw(gen_parser);
use Scalar::Util qw(blessed);

our $AUTHORITY = 'cpan:PERLANCAR'; # AUTHORITY
our $DATE = '2023-02-18'; # DATE
our $DIST = 'App-datecalc'; # DIST
our $VERSION = '0.090'; # VERSION

# XXX there should already be an existing module that does this
sub __fmtduriso {

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


:discard               ~ ws
ws                     ~ [\s]+
ws_opt                 ~ [\s]*

_
        actions => {
            datelit_iso => sub {
                my $h = shift;
		my @date = split /-/, $_[0];
                DateTime->new(year=>$date[0], month=>$date[1], day=>$date[2]);
            },
            date_sub_date => sub {
                my $h = shift;
                $_[0]->delta_days($_[2]);
            },
            datelit_special => sub {
                my $h = shift;
                if ($_[0] eq 'now') {
                    DateTime->now;
                } elsif ($_[0] eq 'today') {
                    DateTime->today;
                } elsif ($_[0] eq 'yesterday') {
                    DateTime->today->subtract(days => 1);
                } elsif ($_[0] eq 'tomorrow') {
                    DateTime->today->add(days => 1);
                } else {
                    die "BUG: Unknown date literal '$_[0]'";
                }
            },
            date_add_dur => sub {
                my $h = shift;
                if ($_[1] eq '+') {
                    $_[0] + $_[2];
                } else {
                    $_[0] - $_[2];

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

            dur_add_dur => sub {
                my $h = shift;
                $_[0] + $_[2];
            },
            dur_mult_num => sub {
                my $h = shift;
                if (ref $_[0]) {
                    my $d0 = $_[0];
                    if ($_[1] eq '*') {
                        # dur*num
                        DateTime::Duration->new(
                            years   => $d0->years   * $_[2],
                            months  => $d0->months  * $_[2],
                            weeks   => $d0->weeks   * $_[2],
                            days    => $d0->days    * $_[2],
                            hours   => $d0->hours   * $_[2],
                            minutes => $d0->minutes * $_[2],
                            seconds => $d0->seconds * $_[2],
                        );
                    } else {
                        # dur/num
                        DateTime::Duration->new(
                            years   => $d0->years   / $_[2],
                            months  => $d0->months  / $_[2],
                            weeks   => $d0->weeks   / $_[2],
                            days    => $d0->days    / $_[2],
                            hours   => $d0->hours   / $_[2],
                            minutes => $d0->minutes / $_[2],
                            seconds => $d0->seconds / $_[2],
                        );
                    }
                } else {
                    my $d0 = $_[2];
                    # num * dur
                    DateTime::Duration->new(
                        years   => $d0->years   * $_[0],
                        months  => $d0->months  * $_[0],
                        weeks   => $d0->weeks   * $_[0],
                        days    => $d0->days    * $_[0],
                        hours   => $d0->hours   * $_[0],
                        minutes => $d0->minutes * $_[0],
                        seconds => $d0->seconds * $_[0],
                    );
                }
            },

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

                my $h = shift;
                local $_ = $_[0];
                my %params;
                $params{years} = $1 if /(-?\d+(?:\.\d+)?)\s*(years?|y)/;
                $params{months} = $1 if /(-?\d+(?:\.\d+)?)\s*(mons?|months?)/;
                $params{weeks} = $1 if /(-?\d+(?:\.\d+)?)\s*(weeks?|w)/;
                $params{days} = $1 if /(-?\d+(?:\.\d+)?)\s*(days?|d)/;
                $params{hours} = $1 if /(-?\d+(?:\.\d+)?)\s*(hours?|h)/;
                $params{minutes} = $1 if /(-?\d+(?:\.\d+)?)\s*(mins?|minutes?)/;
                $params{seconds} = $1 if /(-?\d+(?:\.\d+)?)\s*(s|secs?|seconds?)/;
                DateTime::Duration->new(%params);
            },
            durlit_iso => sub {
                my $h = shift;
                # split between date and time
                my $d = $_[0] =~ /P(.+?)(?:T|\z)/ ? $1 : '';
                my $t = $_[0] =~ /T(.*)/ ? $1 : '';
                #say "D = $d, T = $t";
                my %params;
                $params{years} = $1 if $d =~ /(-?\d+(?:\.\d+)?)Y/i;
                $params{months} = $1 if $d =~ /(-?\d+(?:\.\d+)?)M/i;
                $params{weeks} = $1 if $d =~ /(-?\d+(?:\.\d+)?)W/;
                $params{days} = $1 if $d =~ /(-?\d+(?:\.\d+)?)D/;
                $params{hours} = $1 if $t =~ /(-?\d+(?:\.\d+)?)H/i;
                $params{minutes} = $1 if $t =~ /(-?\d+(?:\.\d+)?)M/i;
                $params{seconds} = $1 if $t =~ /(-?\d+(?:\.\d+)?)S/i;
                DateTime::Duration->new(%params);
            },
            func_inum_onum => sub {
                my $h = shift;
                my $fn = $_[0];
                my $num = $_[1];
                if ($fn eq 'abs') {
                    abs($num);
                } elsif ($fn eq 'round') {
                    sprintf("%.0f", $num);
                } else {

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

        trace_values => $ENV{DEBUG},
    );

    bless {parser=>$parser}, shift;
}

sub eval {
    my ($self, $str) = @_;
    my $res = $self->{parser}->($str);

    if (blessed($res) && $res->isa('DateTime::Duration')) {
        __fmtduriso($res);
    } elsif (blessed($res) && $res->isa('DateTime')) {
        $res->ymd . "#".$res->day_abbr;
    } else {
        "$res";
    }
}

1;
# ABSTRACT: Date calculator

__END__

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

=head1 HOMEPAGE

Please visit the project's homepage at L<https://metacpan.org/release/App-datecalc>.

=head1 SOURCE

Source repository is at L<https://github.com/perlancar/perl-App-datecalc>.

=head1 SEE ALSO

L<DateTime> and L<DateTime::Format::ISO8601>, the backend modules used to do the
actual date calculation.

L<Marpa::R2> is used to generate the parser.

L<Date::Calc> another date module on CPAN. No relation except the similarity of
name.

L<http://en.wikipedia.org/wiki/ISO_8601> for more information about the ISO 8601
format.

script/datecalc  view on Meta::CPAN

=head1 FAQ

=head2 Why is date addition/subtraction with fractional duration incorrect?

For example:

 > 2001-01-01 + P1.5M
 2001-02-01#Thu

One would expect something closer to C<2001-02-16>. But this is how
L<DateTime::Duration> works. Instead of using fractions in larger units, try
using smaller units instead. For example:

 > 2001-01-01 + P1M2W
 2001-02-15#Thu

=head1 FILES

=head2 ~/.datecalc_history

=head1 HOMEPAGE



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