Re: Getting Weekly Dates
by oakley (Scribe) on Mar 09, 2001 at 01:01 UTC
|
Like Coyote said, use Date::Manip - it'a a darn good module and it will do alot more than what you would probably expect.
Now though - to get a list of the first Monday in every month starting Jan 2001 - Dec 2001, I used the following snippet of code and got every single one:
#!/usr/bin/perl -w
use strict;
use Date::Manip;
my $base = "2000123123:59:59";
my $start = "2001010100:00:00";
my $stop = "2001123123:59:59";
my $syntax = "0:1*1:1:0:0:0";
my @dates = &ParseRecur($syntax,$base,$start,$stop);
foreach my $day (@dates)
{
print "\$day is [$day]\n";
}
This prints out:
$day is [2001010100:00:00]
$day is [2001020500:00:00]
$day is [2001030500:00:00]
$day is [2001040200:00:00]
$day is [2001050700:00:00]
$day is [2001060400:00:00]
$day is [2001070200:00:00]
$day is [2001080600:00:00]
$day is [2001090300:00:00]
$day is [2001100100:00:00]
$day is [2001110500:00:00]
$day is [2001120300:00:00]
And yes, I did verify the dates :)
Update:You may want to use substr($day,0,8); to get the first 8 characters which is the date - anything after that is the time
- oakley
Embracing insanity - one twitch at a time >:) | [reply] [d/l] [select] |
|
|
I think you're working at that too hard:
use Date::Manip;
print map UnixDate($_, "%g\n"), ParseRecur("first monday of every mont
+h in 2001");
which yields
Mon, 01 Jan 2001 00:00:00 -0800
Mon, 05 Feb 2001 00:00:00 -0800
Mon, 05 Mar 2001 00:00:00 -0800
Mon, 02 Apr 2001 00:00:00 -0800
Mon, 07 May 2001 00:00:00 -0800
Mon, 04 Jun 2001 00:00:00 -0800
Mon, 02 Jul 2001 00:00:00 -0800
Mon, 06 Aug 2001 00:00:00 -0800
Mon, 03 Sep 2001 00:00:00 -0800
Mon, 01 Oct 2001 00:00:00 -0800
Mon, 05 Nov 2001 00:00:00 -0800
Mon, 03 Dec 2001 00:00:00 -0800
Date::Manip does everything. From the docs:
I'm trying to build a library which can do _EVERY_ con-
ceivable date/time manipulation that you'll run into in
everyday life.
-- Randal L. Schwartz, Perl hacker | [reply] [d/l] [select] |
|
|
...If only Date::Manip wouldn't whine about not being able to figure out my timezone. :( (on NT4WS)
| [reply] |
|
|
|
|
Re: Getting Weekly Dates
by japhy (Canon) on Mar 09, 2001 at 01:11 UTC
|
use Time::Local;
sub getFirstNonWeekend {
my ($month, $year) = @_; # (7,2001) for July 2001
# noon on the 1st of the month
my $first = timelocal(0,0,12, 1, $month-1, $year-1900);
my $shift = ((localtime $first)[6] + 1) % 7;
if ($shift < 2) {
$first += 86400 * (2 - $shift) if $shift < 2;
return ($first, 3 - $shift, 1);
}
return ($first, 1, $shift - 1);
}
That will give you the time for (around) noon on the first day of a given month that is NOT a weekend, the day of the month, and a number representing the day of the week (1 = Monday, 5 = Friday). That's probably the hardest part.
What's left is the partitioning of this month and the next. Since you know the day of the month and the day of the week, this shouldn't be too hard. I wouldn't mind showing you the code for it though, if you ask.
japhy --
Perl and Regex Hacker | [reply] [d/l] |
|
|
perl -MTime::Local -wle '
for ($x = timelocal(0,0,0,1,0,2001); $x < timelocal(0,0,0,1,0,2002)
+; $x += 24*60*60) {
(localtime($x))[6] % 6 and print substr(localtime($x),0,10)
}'
Very neat!
p | [reply] [d/l] |
|
|
Wow. Succinct, beautiful, and far less involving. I'm impressed. But you might want to use (0,0,12) instead of (0,0,0) for the time -- just in case you run into the daylight savings time switch.
japhy --
Perl and Regex Hacker
| [reply] |
|
|
|
|
Under request of mothra, I'm posting my code to show the partitioning of a month into weekday weeks. It is not the entire solution to the problem, since mothra wants two-month spans, but that can be done with little effort. It's in the Code Catacombs, Week Partitioner.
japhy --
Perl and Regex Hacker
| [reply] |
Re: Getting Weekly Dates
by Tuna (Friar) on Mar 09, 2001 at 00:31 UTC
|
See Date::Calc, for starters.
UPDATE:
I cooked up a solution that would work for my personal file naming convention.
Consider a directory full of files like: summary.interfaces.yyyymmdd
I could run the following code, and simply grep this directory for all files ending in "$period".
#!/usr/local/bin/perl -w
use strict;
#Usage: $0 <yyyy> <1 2 3> #period 1,2,3, that is
die "Usage: $0 <yyyy> <1 2 3>, #period 1,2,3, that is\n" unless @ARGV
+==2;
my $prepend = $ARGV[0];
my $per = $ARGV[1];
my @period;
my @files;
if ($per eq 1) {
@period = ("$prepend"."0101", "$prepend"."0630");
}
elsif ($per eq 2) {
@period = ("$prepend"."0701", "$prepend"."0831");
}
elsif ($per eq 3) {
@period = ("$prepend"."0901", "$prepend"."1231");
}
else {die "Usage: $0 <yyyy> <1 2 3>, #period 1,2,3, that is\n";}
foreach my $element(@period) {
print "$element\n";
}
my $from = $period[0];
my $to = $period[1];
while ( $from < $to ) {
print "$from\n";
} continue {
$from++;
}
Certainly not the prettiest, but it would work for me.
HTH,
Steve
update again:corrected typo | [reply] [d/l] |
|
|
Good try, but the year is not constant. :)
| [reply] |
(tye)Re: Getting Weekly Dates
by tye (Sage) on Mar 09, 2001 at 00:35 UTC
|
for example, "July - August", I need to start reporting from the first Monday's date in July, to the last Friday's date in August
Not Perl-related but, under that scheme you will never report for weeks that cross the first of September. You probably want from the first Monday in July through the Friday after the last Monday in August, for example.
-
tye
(but my friends call me "Tye")
| [reply] |
|
|
| [reply] |
Re: Getting Weekly Dates
by Coyote (Deacon) on Mar 09, 2001 at 00:37 UTC
|
Tuna alread mentioned Date::Calc. You also might want to check out Date::Manip. I've used it fairly extensively for problems like you mentioned above and its always done the job.
----
Coyote | [reply] |
Re: Getting Weekly Dates
by merlyn (Sage) on Mar 09, 2001 at 06:13 UTC
|
You know, I'll have to say I was initially disappointed in the content of this node having read such a promising subject line. I was thinking Perl could help me with
my social life finally!
{grin}
-- Randal L. Schwartz, Perl hacker | [reply] |