good chemistry is complicated,and a little bit messy -LW PerlMonks

### What is the best way to get a list of all Mondays until the end of the year?

 on Aug 19, 2008 at 10:44 UTC Need Help??
wenD has asked for the wisdom of the Perl Monks concerning the following question:

2008-08-25, 2008-09-01, 2008-09-08...

I'd like to be able to specify a start date and an end date and get just the Mondays (or whatever weekday I happen to need) within that range.

I can think of ways to go about it but I'm sure there are better solutions out there; and maybe someday someone else will find this node and be happy.
• Comment on What is the best way to get a list of all Mondays until the end of the year?

Replies are listed 'Best First'.
Re: What is the best way to get a list of all Mondays until the end of the year?
by grinder (Bishop) on Aug 19, 2008 at 11:34 UTC
What is the best way...

Perhaps something using Date::Calc. The idea would be to take a date in the year, find the next monday, and if the year is the same, print it out. Then, keep adding 7 days until the year changes.

```#! /usr/bin/perl

use strict;
use warnings;

my (\$day, \$month, \$year, \$dow) = (localtime)[3, 4, 5, 6];
\$year  += 1900;
\$month += 1;

my \$this_year = \$year;
(\$year, \$month, \$day) = Add_Delta_Days(\$year, \$month, \$day, (8 - \$dow)
+ % 7);

while (\$this_year == \$year) {
printf "%04d-%02d-%02d\n", \$year, \$month, \$day;
(\$year, \$month, \$day) = Add_Delta_Days(\$year, \$month, \$day, 7);
}

update: it occurs to me that it may not be obvious how this calculates Mondays, since it uses a magic number. It would be a little clearer had I written:

```my %day = qw(
Sun 0
Mon 1
Tue 2
Wed 3
Thu 4
Fri 5
Sat 6
);

(\$year, \$month, \$day) = Add_Delta_Days(\$year, \$month, \$day, (7 + \$day{
+Mon} - \$dow) % 7);

• another intruder with the mooring in the heart of the Perl

Re: What is the best way to get a list of all Mondays until the end of the year?
by Krambambuli (Curate) on Aug 19, 2008 at 11:21 UTC
Date::Manip is quite convenient for such queries:

```perl -e 'use Date::Manip; \$dt = ParseDate("now"); while(\$dt lt "200812
+31") { \$dt = Date_GetNext(\$dt,"Mon", 0); print UnixDate( \$dt, "%Y-%m-
+%d"), "\n"; }'
Update: shortened the line a bit.

Krambambuli
---
Re: What is the best way to get a list of all Mondays until the end of the year?
by ForgotPasswordAgain (Deacon) on Aug 19, 2008 at 11:06 UTC

Play with this:

```perl -MDateTime -le'\$min=DateTime->now;\$max=DateTime->new(year=>2008,m
```#!/usr/bin/perl --

use strict;
use warnings;

use DateTime::Event::Recurrence;

{
my \$dt1 = new DateTime( year => 2008 );
my \$dt2 = new DateTime( year => 2009 );
my \$der = DateTime::Event::Recurrence->weekly;
print \$_->ymd, ' ', ,\$/ for
\$der->as_list( start => \$dt1, end => \$dt2 );
}

# http://datetime.perl.org/index.cgi?FAQDurationsSetsSpans

__END__
2008-01-07 2008-01-14 2008-01-21 2008-01-28 2008-02-04 2008-02-11 2008-02-18 2008-02-25 2008-03-03 2008-03-10 2008-03-17 2008-03-24 2008-03-31 2008-04-07 2008-04-14 2008-04-21 2008-04-28 2008-05-05 2008-05-12 2008-05-19 2008-05-26 2008-06-02 2008-06-09 2008-06-16 2008-06-23 2008-06-30 2008-07-07 2008-07-14 2008-07-21 2008-07-28 2008-08-04 2008-08-11 2008-08-18 2008-08-25 2008-09-01 2008-09-08 2008-09-15 2008-09-22 2008-09-29 2008-10-06 2008-10-13 2008-10-20 2008-10-27 2008-11-03 2008-11-10 2008-11-17 2008-11-24 2008-12-01 2008-12-08 2008-12-15 2008-12-22 2008-12-29
one-liner version
```
perl -MDateTime::Event::Recurrence -le "  print \$_->ymd, chr(32) for
+DateTime::Event::Recurrence->weekly->as_list( start => DateTime->new
+( year => 2008 ), end => DateTime->new ( year => 2009 ) ); "

perl -MDateTime::Event::Recurrence -le '  print \$_->ymd, chr(32) for
+DateTime::Event::Recurrence->weekly->as_list( start => DateTime->new
+( year => 2008 ), end => DateTime->new ( year => 2009 ) ); '

Re: What is the best way to get a list of all Mondays until the end of the year?
by merlyn (Sage) on Aug 19, 2008 at 16:54 UTC
```use Date::Manip;
for my \$date (ParseRecur("every monday", "", ParseDate("today"), Parse
+Date("dec 31"))) {
print "\$date\n"; # or format it using UnixDate(\$date, \$format)
}
Re: What is the best way to get a list of all Mondays until the end of the year?
by johngg (Abbot) on Aug 19, 2008 at 10:59 UTC
You could have a look at Date::Manip to see if it can be applied to your problem.

Cheers,

JohnGG

Re: What is the best way to get a list of all Mondays until the end of the year?
by BrowserUk (Pope) on Aug 19, 2008 at 17:47 UTC
```[0] Perl> \$t = time();
while( \$_=localtime( \$t ) and m[2008] ) {
m[^Mon] and print scalar localtime( \$t );
\$t+=86400;
}
Mon Aug 25 18:45:13 2008
Mon Sep  1 18:45:13 2008
Mon Sep  8 18:45:13 2008
Mon Sep 15 18:45:13 2008
Mon Sep 22 18:45:13 2008
Mon Sep 29 18:45:13 2008
Mon Oct  6 18:45:13 2008
Mon Oct 13 18:45:13 2008
Mon Oct 20 18:45:13 2008
Mon Oct 27 17:45:13 2008
Mon Nov  3 17:45:13 2008
Mon Nov 10 17:45:13 2008
Mon Nov 17 17:45:13 2008
Mon Nov 24 17:45:13 2008
Mon Dec  1 17:45:13 2008
Mon Dec  8 17:45:13 2008
Mon Dec 15 17:45:13 2008
Mon Dec 22 17:45:13 2008
Mon Dec 29 17:45:13 2008

Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
++

I had one that was equivalent in length to my other code post that did the same thing (just looked at every day) - but I thought I'd avoid doing the extra un-needed calculations by going a week at a time. But most use cases probably wouldn't care about the extra 300 (at most) iterations.
my @a=qw(random brilliant braindead); print \$a[rand(@a)];
Re: What is the best way to get a list of all Mondays until the end of the year?
by Rhandom (Curate) on Aug 19, 2008 at 16:14 UTC
Golfing - with no modules:
```perl -e '@N=gmtime;\$t=time+86400*(1-\$N[6]);while(1){@n=gmtime(\$t+=7*86
+400);last if \$n[5]!=\$N[5]; printf("%d-%02d-%02d\n",\$n[5]+1900,\$n[4]+1
+,\$n[3])}'
```perl -e '
my @N = gmtime;     # today (calculations in gmtime to avoid tz offset
+s)

my \$t = time + 86400 * (1 - \$N[6]);    # calculate the time of Monday
+(1)

while(1) {
my @n = gmtime(\$t += 7*86400); # advance a week at a time

last if \$n[5] != \$N[5];           # done if the year doesn't mat
+ch today's

printf ("%d-%02d-%02d\n", \$n[5]+1900, \$n[4]+1, \$n[3]); # print re
+sult
}'

Really you should look at DateTime or Date::Manip or Date::Calc or ... - but sometimes it makes sense not to.
my @a=qw(random brilliant braindead); print \$a[rand(@a)];
Just a side node; this would work most of the time, but not always. A week is _not_ always 7*86400 seconds, a day is _not_ always 86400 seconds - when daylight saving comes to play, this offset may give you a false Monday (if you're making the calculation at a unwise chosen time ;) )

Update: daylight saving changes.

Krambambuli
---
What you say is true for localtime, but not for gmtime (which is what the Rhandom's example uses). As the doc says, there is no DST for GMT.
Re: What is the best way to get a list of all Mondays until the end of the year?
by dragonchild (Archbishop) on Aug 19, 2008 at 15:36 UTC
In other words, there are three excellent and several dozen mediocre date modules on CPAN. CPAN is your friend. Look there first and you will find pretty much most of what you'd ever need.

My criteria for good software:
1. Does it work?
2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?

Create A New User
Node Status?
node history
Node Type: perlquestion [id://705164]
Approved by toolic
help
Chatterbox?
 [Corion]: marto: Oh, I'm jealous. I'm going to see DM in Frankfurt, but it's a stadium full of people, so, rather a big thing where you mostly get to see the band on screens ;) [marto]: yes, the last time I saw them was in Berlin a few years ago, at the old Olympic stadium [marto]: After Sunday I don't think I'll go see them again :) [LanX]: Corion: come on, people are people! ;) [Corion]: Naah, I think it's still an OK show so far. Their new songs aren't exactly great, but I'm not going there for new material anyway ;)

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (14)
As of 2017-03-24 11:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
Should Pluto Get Its Planethood Back?

Results (301 votes). Check out past polls.