tags:

views:

204

answers:

2

I need a function in php that will calculate the business week in a specific format within a given date range. Example:

startDate = 02-03-2009

endDate = 31-12-2010

Mar 2-6

Mar 9-13

Mar 16-20

Mar 23-27

Mar 30 - Apr 3

Apr 6 - 10

and so on...

+1  A: 

I think your answer exists between this post:

Calculating days of week given a week number

and this post:

Calculate business days in PHP

GregD
I can appreciate this answer. I will examine both and see what I can come up with. Thanks.
ricbax
+2  A: 

This isn't the direct answer - it's written in Perl (and Perl has some quirks of its own in this area). However, it does, I think, produce the required output.

#!/bin/perl -w
#
# Given two Unix-style timestamps (smaller, larger), produce a range of weeks.
# SO 613337

use strict;
use POSIX;

my($t1) = $ARGV[0];
my($t2) = $ARGV[1];

# Split given times into pieces
my($sec1,$min1,$hour1,$mday1,$mon1,$year1,$wday1) = localtime($t1);
my($sec2,$min2,$hour2,$mday2,$mon2,$year2,$wday2) = localtime($t2);

# Determine midday on Monday for starting week.
# Determine midday on Friday for ending week.
# Saturday rounds backwards; Sunday rounds upwards.
my($t3) = mktime(0, 0, 12, $mday1 - ($wday1 - 1) + 0, $mon1, $year1);
my($t4) = mktime(0, 0, 12, $mday2 - ($wday2 - 1) + 5, $mon2, $year2);

my($sec3,$min3,$hour3,$mday3,$mon3,$year3,$wday3) = localtime($t3);
my($sec4,$min4,$hour4,$mday4,$mon4,$year4,$wday4) = localtime($t4);

print "t1 = %10d; %04d-%02d-%02d (%d)\n", $t1+1900, $year1, $mon1+1, $mday1, $wday1;
print "t2 = %10d; %04d-%02d-%02d (%d)\n", $t2+1900, $year2, $mon2+1, $mday2, $wday2;
print "t3 = %10d; %04d-%02d-%02d (%d)\n", $t3+1900, $year3, $mon3+1, $mday3, $wday3;
print "t4 = %10d; %04d-%02d-%02d (%d)\n", $t4+1900, $year4, $mon4+1, $mday4, $wday4;

use constant secs_per_week  => 24 * 3600 * 7;
use constant secs_to_friday => 24 * 3600 * 4;

for (my($t) = $t3; $t < $t4; $t += secs_per_week)
{
    my($mon) = strftime("%b %e", localtime($t));
    my($fri) = strftime("%b %e", localtime($t + secs_to_friday));
    my($ans) = "$mon - $fri";
    $ans =~ s/^(\w\w\w)\s+(\d+) - (\1)\s+(\d+)$/$1 $2-$4/;
    $ans =~ s/  +/ /g;
    print "$ans\n";
}

Edited: fix month numbers in range 0..11 printed as 01..12. Change handling of years, too.

Using midday on Monday and Friday and otherwise dealing only with days, I can ignore issues to do with switching between winter and summer (standard and daylight saving) time.

For example:

$ perl weekdays.pl 1234567890 1324567890
t1 = 1234567890; 2009-02-13 (5)
t2 = 1324567890; 2011-12-22 (4)
t3 = 1234209600; 2009-02-09 (1)
t4 = 1324756800; 2011-12-24 (6)
Feb 9-13
Feb 16-20
Feb 23-27
Mar 2-6
Mar 9-13
Mar 16-20
Mar 23-27
Mar 30 - Apr 3
Apr 6-10
Apr 13-17
Apr 20-24
Apr 27 - May 1
May 4-8
May 11-15
May 18-22
May 25-29
Jun 1-5
Jun 8-12
Jun 15-19
Jun 22-26
Jun 29 - Jul 3
Jul 6-10
Jul 13-17
Jul 20-24
Jul 27-31
Aug 3-7
Aug 10-14
Aug 17-21
Aug 24-28
Aug 31 - Sep 4
Sep 7-11
Sep 14-18
Sep 21-25
Sep 28 - Oct 2
Oct 5-9
Oct 12-16
Oct 19-23
Oct 26-30
Nov 2-6
Nov 9-13
Nov 16-20
Nov 23-27
Nov 30 - Dec 4
Dec 7-11
Dec 14-18
Dec 21-25
Dec 28 - Jan 1
Jan 4-8
Jan 11-15
Jan 18-22
Jan 25-29
Feb 1-5
Feb 8-12
Feb 15-19
Feb 22-26
Mar 1-5
Mar 8-12
Mar 15-19
Mar 22-26
Mar 29 - Apr 2
Apr 5-9
Apr 12-16
Apr 19-23
Apr 26-30
May 3-7
May 10-14
May 17-21
May 24-28
May 31 - Jun 4
Jun 7-11
Jun 14-18
Jun 21-25
Jun 28 - Jul 2
Jul 5-9
Jul 12-16
Jul 19-23
Jul 26-30
Aug 2-6
Aug 9-13
Aug 16-20
Aug 23-27
Aug 30 - Sep 3
Sep 6-10
Sep 13-17
Sep 20-24
Sep 27 - Oct 1
Oct 4-8
Oct 11-15
Oct 18-22
Oct 25-29
Nov 1-5
Nov 8-12
Nov 15-19
Nov 22-26
Nov 29 - Dec 3
Dec 6-10
Dec 13-17
Dec 20-24
Dec 27-31
Jan 3-7
Jan 10-14
Jan 17-21
Jan 24-28
Jan 31 - Feb 4
Feb 7-11
Feb 14-18
Feb 21-25
Feb 28 - Mar 4
Mar 7-11
Mar 14-18
Mar 21-25
Mar 28 - Apr 1
Apr 4-8
Apr 11-15
Apr 18-22
Apr 25-29
May 2-6
May 9-13
May 16-20
May 23-27
May 30 - Jun 3
Jun 6-10
Jun 13-17
Jun 20-24
Jun 27 - Jul 1
Jul 4-8
Jul 11-15
Jul 18-22
Jul 25-29
Aug 1-5
Aug 8-12
Aug 15-19
Aug 22-26
Aug 29 - Sep 2
Sep 5-9
Sep 12-16
Sep 19-23
Sep 26-30
Oct 3-7
Oct 10-14
Oct 17-21
Oct 24-28
Oct 31 - Nov 4
Nov 7-11
Nov 14-18
Nov 21-25
Nov 28 - Dec 2
Dec 5-9
Dec 12-16
Dec 19-23
$
Jonathan Leffler
This looks great, thanks for your time and effort. I will try to port this to php.
ricbax