—#!perl
## no critic (InputOutput::RequireBriefOpen)
use
5.010;
use
strict;
use
warnings;
#use Log::Any '$log';
our
$AUTHORITY
=
'cpan:PERLANCAR'
;
# AUTHORITY
our
$DATE
=
'2023-02-18'
;
# DATE
our
$DIST
=
'App-datecalc'
;
# DIST
our
$VERSION
=
'0.090'
;
# VERSION
sub
get_options {
my
%opts
;
Getopt::Long::GetOptions(
'--help|h|?'
, \
$opts
{help},
'--version|v'
, \
$opts
{version},
);
if
(
$opts
{help}) {
<<_;
Usage:
datecalc [OPTIONS]
Options:
--help, -h, -?
--version, -v
_
exit
0;
}
elsif
(
$opts
{version}) {
say
"datecalc version $::VERSION"
;
exit
0;
}
}
sub
eval_loop {
my
$calc
= App::datecalc->new;
my
$term
= Term::ReadLine->new(
'datecalc'
);
my
$prompt
=
"> "
;
my
$OUT
=
$term
->OUT || \
*STDOUT
;
my
$histfile
= File::HomeDir->my_home .
"/.datecalc_history"
;
# load history from file
if
(
$term
->Features->{setHistory} && (-r
$histfile
)) {
#$log->tracef("Loading history from %s ...", $histfile);
open
(
my
$fh
,
'<'
,
$histfile
)
or
die
"Can't open history file $histfile: $!\n"
;
chomp
(
my
@history
= <
$fh
>);
$term
->SetHistory(
@history
);
}
my
$sub_save_hist
=
sub
{
if
(
$term
->Features->{getHistory}) {
my
$fh
;
if
(
open
$fh
,
">"
,
$histfile
) {
$fh
"$_\n"
for
List::Util::Uniq::uniq_adj(
grep
{
length
}
$term
->GetHistory
);
}
}
};
local
$SIG
{INT} =
sub
{
# save history when we are interrupted
$sub_save_hist
->();
STDERR
"Interrupted\n"
;
if
(
$term
->ReadLine eq
'Term::ReadLine::Gnu'
) {
IO::Stty::stty(\
*STDIN
,
'echo'
);
}
exit
1;
};
#local $SIG{__DIE__} = sub {
# IO::Stty::stty(\*STDIN, 'echo');
# die @_;
#};
# some workaround for Term::ReadLine
my
$attribs
=
$term
->Attribs;
if
(
$term
->ReadLine eq
'Term::ReadLine::Gnu'
) {
# TR::Gnu traps our INT handler
$attribs
->{catch_signals} = 0;
}
elsif
(
$term
->ReadLine eq
'Term::ReadLine::Perl'
) {
# TR::Perl messes up colors
# doesn't do anything?
#$term->ornaments(0);
#$attribs->{term_set} = ["", "", "", ""];
}
while
(
defined
(
$_
=
$term
->
readline
(
$prompt
)) ) {
my
$res
;
if
(
$_
eq
'help'
||
$_
eq
'?'
) {
say
"Type date expression into the prompt, e.g.: 2014-06-26 + 2 week."
;
say
"For more details on available features, 'man datecalc'."
;
say
""
;
next
;
}
elsif
(
$_
eq
'exit'
||
$_
eq
'quit'
) {
last
;
}
eval
{
$res
=
$calc
->
eval
(
$_
) };
if
($@) {
warn
"Error: $@\n"
;
}
else
{
$OUT
$res
,
"\n"
;
}
# double?
#$term->addhistory($_) if /\S/;
}
$sub_save_hist
->();
}
### main
get_options();
eval_loop();
# ABSTRACT: Date calculator
# PODNAME: datecalc
__END__
=pod
=encoding UTF-8
=head1 NAME
datecalc - Date calculator
=head1 VERSION
This document describes version 0.090 of datecalc (from Perl distribution App-datecalc), released on 2023-02-18.
=head1 SYNOPSIS
% datecalc
> today
2014-05-13#Tue
> tomorrow
2014-05-14#Wed
> today + 2 days
2014-05-15#Thu
> 2014-05-13 - 2014-02-14
P2M3W6D
> days(2014-05-13 - 2014-02-14)
4
> totdays(2014-05-13 - 2014-02-14)
88
> 2 months 3 weeks 6 days
P2M3W6D
> P10D
P1W3D
> 2014-05-13 + P2D
2014-05-15#Thu
> 2 * 2 days 10 hours
P4DT20H
> P10D / 2
P5D
> 6d + 8d + 13 min
P2WT13M
> month(today)
5
> days(P8D)
1
> weeks(P8D)
1
> P8D
P1W1D
=head1 DESCRIPTION
This is a command-line utility to perform date calculations.
For now, for more details, see L<App::datecalc>.
=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
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 AUTHOR
perlancar <perlancar@cpan.org>
=head1 CONTRIBUTING
To contribute, you can send patches by email/via RT, or send pull requests on
GitHub.
Most of the time, you don't need to build the distribution yourself. You can
simply modify the code, then test via:
% prove -l
If you want to build the distribution (e.g. to try to install it locally on your
system), you can install L<Dist::Zilla>,
L<Dist::Zilla::PluginBundle::Author::PERLANCAR>,
L<Pod::Weaver::PluginBundle::Author::PERLANCAR>, and sometimes one or two other
Dist::Zilla- and/or Pod::Weaver plugins. Any additional steps required beyond
that are considered a bug and can be reported to me.
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2023, 2018, 2016, 2015, 2014 by perlancar <perlancar@cpan.org>.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
=head1 BUGS
Please report any bugs or feature requests on the bugtracker website L<https://rt.cpan.org/Public/Dist/Display.html?Name=App-datecalc>
When submitting a bug or request, please include a test-file or a
patch to an existing test-file that illustrates the bug or desired
feature.
=cut