> Is there a module that I can use that will tell me the number of Saturdays,
> or any weekday, if I give it the month and year.
>
> The Date::Manip module has methods for calculating recurring dates (like
"every Saturday"). If you can get a list of dates, then the count of the
list is the number that you want.
--
Robert Wohlfarth
Yes, indeed. :-) Bugs are included. See below for my comments.
>
> #!/usr/bin/perl
>
> use Time::Local;
> use strict;
>
You should add use warnings;
> sub day_in_a_month {
> my ($week_day, $month, $year ) = @_;
> my ($day, $hour, $min, $sec, $time);
> my ($mon, $wday_count);
>
> $day = 1;
> $hour = $min = $sec = 0;
> $month--;
> $year -= 1900;
>
> $time = timelocal($sec, $min, $hour, $day, $month, $year);
>
> for ($mon = $month; $mon == $month; $time += 86400) {
86400 is a magic number which some people may not be familiar with. You should
assign it to a constant. Furthermore, it's not a very robust way to go a day
forward. You should use POSIX::mktime() instead.
> my ($wday);
> ($mon, $wday) = (localtime($time))[4, 6];
> if ($wday == $week_day) {
> $wday_count++;
> }
> }
> return($wday_count);
> }
>
Here is my version that uses DateTime (a non-core module, but highly
recommended) and seems to work. One can do it more efficiently in an O(1) (=
constant time) manner by futzing with the initial day-of-week in Month day #1
and the number of days in a month, but I didn't get to it yet. My version
works from what I tried:
<<<<<<<<<<<<<<<<<
#!/usr/bin/perl
use strict;
use warnings;
use DateTime;
sub day_in_a_month
{
# week_day is:
# 1-7 (Monday is 1) - also dow, wday
# From http://search.cpan.org/dist/DateTime/lib/DateTime.pm
my ($week_day, $month, $year ) = @_;
my $start = DateTime->new( year => $year, month => $month, day => 1);
my $end = $start->clone();
$end->add( months => 1);
my $running = $start->clone();
my $count = 0;
while (DateTime->compare($end, $running) != 0)
{
if ($running->day_of_week() == $week_day)
{
$count++;
}
}
continue
{
$running->add (days => 1);
}
return $count;
}
print day_in_a_month(@ARGV), "\n";
>>>>>>>>>>>>>>>>>
<<<<<<<<<<
shlomi:~$ perl num_days.pl 7 12 2009
4
shlomi:~$ perl num_days.pl 7 11 2009
5
shlomi:~$ perl num_days.pl 6 11 2009
4
shlomi:~$ perl num_days.pl 6 12 2009
4
>>>>>>>>>>
Regards,
Shlomi Fish
> # 0 - sunday 6- saturday
> print day_in_a_month(6, 12, 2009), "\n";
>
>
> with warm regards,
> Venkat Saranathan
> Gulf Breeze Software.
>
>
> On Tue, Dec 22, 2009 at 9:51 AM, Johnson, Reginald (GTS) <
>
> reggie_...@ml.com> wrote:
> > Is there a module that I can use that will tell me the number of
> > Saturdays, or any weekday, if I give it the month and year.
> >
> > Reginald Johnson
> >
> > TSM Backup & Restore Services
> >
> > [image: Picture (Device Independent Bitmap)]
> >
> > Jacksonville, FL
> >
> > 904.218.4620
> >
> > ------------------------------
> > This message w/attachments (message) may be privileged, confidential or
> > proprietary, and if you are not an intended recipient, please notify the
> > sender, do not use or share it and delete it. The information contained
> > in this e-mail was obtained from sources believed to be reliable;
> > however, the accuracy or completeness of this information is not
> > guaranteed. Unless specifically indicated, this message is not an offer
> > to sell or a solicitation of any investment products or other financial
> > product or service, an official confirmation of any transaction, or an
> > official statement of Merrill Lynch. Subject to applicable law, Merrill
> > Lynch may monitor, review and retain e-communications (EC) traveling
> > through its networks/systems. The laws of the country of each
> > sender/recipient may impact the handling of EC, and EC may be archived,
> > supervised and produced in countries other than the country in which you
> > are located. This message cannot be guaranteed to be secure or
> > error-free. References to "Merrill Lynch" are references to any company
> > in the Merrill Lynch & Co., Inc. group of companies, which are
> > wholly-owned by Bank of America Corporation. Securities and Insurance
> > Products: * Are Not FDIC Insured * Are Not Bank Guaranteed * May Lose
> > Value * Are Not a Bank Deposit * Are Not a Condition to Any Banking
> > Service or Activity * Are Not Insured by Any Federal Government Agency.
> > Past performance is no guarantee of future results. Attachments that are
> > part of this E-communication may have additional important disclosures
> > and disclaimers, which you should read. This message is subject to terms
> > available at the following link:
> > http://www.ml.com/e-communications_terms/. By messaging with Merrill
> > Lynch you consent to the foregoing.
> > ------------------------------
>
--
-----------------------------------------------------------------
Shlomi Fish http://www.shlomifish.org/
Parody on "The Fountainhead" - http://shlom.in/towtf
Bzr is slower than Subversion in combination with Sourceforge.
( By: http://dazjorz.com/ )
for ($mon = $month; $mon == $month; $time += 86400) {
my ($wday);
($day, $mon, $wday) = (localtime($time))[3,4, 6];
if ($wday == $week_day) {
$wday_count++;
if ($wday_count == 5) {
$mon = $mon +1;
$year += 1900;
if ($day ne 1) {
return("$mon/$day/$year");
}
}
}
<<<<<<<<<<<<<<<<<
#!/usr/bin/perl
use strict;
use warnings;
use DateTime;
my $count = 0;
return $count;
}
print day_in_a_month(@ARGV), "\n";
>>>>>>>>>>>>>>>>>
Regards,
Shlomi Fish
--------------------------------------------------------------------------
You can code a simple time logic to calculate this. Here is a sample code.
(Bugs included :))
#!/usr/bin/perl
use Time::Local;
use strict;
sub day_in_a_month {
my ($week_day, $month, $year ) = @_;
my ($day, $hour, $min, $sec, $time);
my ($mon, $wday_count);
$day = 1;
$hour = $min = $sec = 0;
$month--;
$year -= 1900;
$time = timelocal($sec, $min, $hour, $day, $month, $year);
for ($mon = $month; $mon == $month; $time += 86400) {
my ($wday);
($mon, $wday) = (localtime($time))[4, 6];
if ($wday == $week_day) {
$wday_count++;
}
}
return($wday_count);
}
# 0 - sunday 6- saturday
print day_in_a_month(6, 12, 2009), "\n";
Hello Venkat,
There is a bug in the the 'for' loop above. :-)
The test to end the loop has to occur just after the line
($mon, $wday) = (localtime($time))[4, 6];
Otherwise, it would be possible to be in a new month at this point in the
code. If the day of week you're seeking is that day, $wday_count would be
incorrectly incremented. Try adding this line after the one above:
last unless $mon == $month;
That will allow you to exit the loop when a new month is reached. The for
loop could then be:
for (;;$time += 86400) {
.............
}
However, I have heard it over and over from good programmers on lists that
date arithmetic can be tricky. Sometimes a carefully designed module can
help.
Chris