Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

date arithmetic

by morgon (Priest)
on Jan 26, 2018 at 09:32 UTC ( [id://1207936]=perlquestion: print w/replies, xml ) Need Help??

morgon has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I am looking for a better way to do some rather simple date-arithmetic.

At the moment I am using the DateTime-Module but I just reinstalled it on a new system and I am shocked on how much dependencies it pulls in.

I know there is a plethora of date-modules on CPAN and as I am too lazy to check them all out myself I hope for some pointers for something more lightweight...

So my ideal solution would be using only core-modules while not getting too complicated or at least using modules that don't pull in half of cpan.

What I need is a logic that produces a date depending on the current day:

If the current day is a Thursday I want the date of the following day.
If the current day is a Friday I want the date of this day.
If the current day is anything else I want the date of the preceeding Friday.

Here is what I do at the monent:

use DateTime; my $td = DateTime->today; my $days_since_friday = ($td->day_of_week - 5) % 7; my $days_to_subtract = $days_since_friday == 6 ? -1 : $days_since_frid +ay; $td->subtract( days => $days_to_subtract ); print $td->strftime("%d%m%y");
Many thanks!

Replies are listed 'Best First'.
Re: date arithmetic
by hippo (Bishop) on Jan 26, 2018 at 10:14 UTC
    At the moment I am using the DateTime-Module but I just reinstalled it on a new system and I am shocked on how much dependencies it pulls in.

    Yes, DateTime is heavy but very full-featured. It is a trade-off (as is usual).

    Luckily Time::Piece is in core and is almost a drop-in replacement for your simple script. I might not write it this way from scratch but have kept your method to show how analogous the two modules are.

    #!/usr/bin/env perl use strict; use warnings; use Time::Piece; use Time::Seconds; my $td = localtime; my $days_since_friday = ($td->day_of_week - 5) % 7; my $days_to_subtract = $days_since_friday == 6 ? -1 : $days_since_frid +ay; $td -= $days_to_subtract * ONE_DAY; print $td->strftime("%d%m%y");
      I was looking for something similar and this worked perfect for me. Thank you hippo.
Re: date arithmetic
by QM (Parson) on Jan 26, 2018 at 10:00 UTC
    You should be able to use time with either gmtime or localtime, as you prefer. Either a simple if clause, or a lookup table, should suffice.

    -QM
    --
    Quantum Mechanics: The dreams stuff is made of

Re: date arithmetic
by thanos1983 (Parson) on Jan 26, 2018 at 10:17 UTC

    Hello morgon,

    My favorite is Date::Manip but it is not a core module, but the possibilities are infinite!

    If you like it and it looks a bit complicated let me know to help you.

    Update: Small sample of code to calculate Friday next week, two weeks after etc. etc...

    #!/usr/bin/perl use strict; use warnings; use Date::Manip; use feature 'say'; my $dateInTwoWeeks = ParseDate("Friday in 2 weeks"); my $unixDate1 = UnixDate($dateInTwoWeeks,"%d-%m-%y"); say $unixDate1; my $dateTwoWeeksAgo = ParseDate("Friday 2 weeks ago"); my $unixDate2 = UnixDate($dateTwoWeeksAgo,"%d-%m-%y"); say $unixDate2; my $dateNextFriday = ParseDate("next Friday"); my $unixDate3 = UnixDate($dateNextFriday,"%d-%m-%y"); say $unixDate3; __END__ $ perl test.pl 09-02-18 12-01-18 02-02-18

    Update 2: Sorry I just noticed your description to your problem. Solution is bellow:

    #!/usr/bin/perl use strict; use warnings; use Date::Manip; use feature 'say'; my $date = ParseDate("Today"); unless (UnixDate($date, "%A") eq "Friday"){ $date = ParseDate("next Friday"); } say UnixDate($date,"%d-%m-%y"); =different format my $date = ParseDate("Today"); $date = ParseDate("next Friday") unless (UnixDate($date, "%A") eq "Friday"); say UnixDate($date,"%d-%m-%y"); =cut __END__ $ perl test.pl 26-01-18

    Hope this helps, BR.

    Seeking for Perl wisdom...on the process of learning...not there...yet!
Re: date arithmetic
by poj (Abbot) on Jan 26, 2018 at 15:59 UTC
    #!perl use strict; use Time::Piece; use Time::Seconds; # Thursday I want the date of the following day. # Friday I want the date of this day. # anything else I want the date of the preceeding Friday. # sun mon tue wed thu fri sat my @offset = (-2,-3,-4,-5,1,0,-1); my $td = Time::Piece->localtime; for (0..30){ my $fri = $td + ONE_DAY * $offset[$td->day_of_week]; printf "%s %s\n", $td->strftime("%d/%m/%y"), $fri->strftime("%d/%m/%y"); $td += ONE_DAY; }
    poj
Re: date arithmetic
by ikegami (Patriarch) on Jan 26, 2018 at 17:44 UTC

    You're making false assumption. You're assuming that a lot of dependencies mean the module isn't lightweight, but there's no such relation. Virtually all the dependencies are dependencies of the modules used for testing.

Re: date arithmetic
by karlgoethebier (Abbot) on Jan 26, 2018 at 16:15 UTC

    Older modules aren't so bad:

    #!/usr/bin/env perl use strict; use warnings; use Date::Calc qw( Day_of_Week Today Day_of_Week_to_Text); use Try::Tiny; use feature qw(say); my %lookup = ( 'Friday' => \&acme ); my $day = Day_of_Week_to_Text( Day_of_Week(Today) ); say $day; $lookup{$day}->(); sub acme { try { ...; } catch { print $_; }; } __END__

    Untested. Please see Date::Calc for more.

    Update: Pretty print ;-)

    "...I am too lazy..."

    Lazy bum!

    Best regards, Karl

    «The Crux of the Biscuit is the Apostrophe»

    perl -MCrypt::CBC -E 'say Crypt::CBC->new(-key=>'kgb',-cipher=>"Blowfish")->decrypt_hex($ENV{KARL});'Help

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1207936]
Approved by Athanasius
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (6)
As of 2024-04-25 08:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found