Find First Date of A Calendar Month\Year

Discussion in 'Perl Misc' started by idgarad@gmail.com, Oct 5, 2006.

  1. Guest

    Very simple in description but tricky to implement so far. What I am
    after is given a year, say 2006, what is the First sunday's date on the
    calendar (For January). For instance in 2006 this would be january 1st
    2006. But in 2005 it would be Dec 26th 2004. Is there a simple module
    for getting this kind of date?

    Ken
     
    , Oct 5, 2006
    #1
    1. Advertising

  2. Paul Lalli Guest

    wrote:
    > Very simple in description but tricky to implement so far. What I am
    > after is given a year, say 2006, what is the First sunday's date on the
    > calendar (For January). For instance in 2006 this would be january 1st
    > 2006. But in 2005 it would be Dec 26th 2004. Is there a simple module
    > for getting this kind of date?


    I'm sure one of the hundreds of Date* modules available on CPAN can do
    this, but if you don't feel like installing a non-standard module just
    for this purpose, this seems to work for me:

    #!/usr/bin/perl
    use strict;
    use warnings;
    use POSIX qw/strftime/;
    use Time::Local;

    for my $y (2004, 2005, 2006) {
    my $first = first_sunday($y);
    print "$y: ", strftime("%C", localtime($first)), "\n";
    }

    sub first_sunday {
    my $y = shift;
    my $dow = strftime("%w", 0,0,0,1,0,$y-1900);
    my $time = timelocal(0,0,0,1,0,$y-1900);
    return $time - ($dow * 24 * 60 * 60);
    }
    __END__
    2004: Sun Dec 28 00:00:00 EST 2003
    2005: Sun Dec 26 00:00:00 EST 2004
    2006: Sun Jan 1 00:00:00 EST 2006

    Basically, find the day of the week of the first of the year (as an
    integer from 0 - 6). Then take that date, and subtract that number of
    days from it.

    Paul Lalli
     
    Paul Lalli, Oct 5, 2006
    #2
    1. Advertising

  3. <> wrote:
    > Very simple in description but tricky to implement so far. What I am
    > after is given a year, say 2006, what is the First sunday's date on the
    > calendar (For January). For instance in 2006 this would be january 1st
    > 2006. But in 2005 it would be Dec 26th 2004. Is there a simple module
    > for getting this kind of date?



    -----------------------------
    #!/usr/bin/perl
    use warnings;
    use strict;
    use Date::Calc qw/ Nth_Weekday_of_Month_Year /;

    my $year = 2006;
    my $first_Sunday = sprintf '%4d-%02d-%02d',
    Nth_Weekday_of_Month_Year($year,1,7,1);

    print "the first Sunday of $year is $first_Sunday\n";
    -----------------------------


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
     
    Tad McClellan, Oct 5, 2006
    #3
  4. -berlin.de Guest

    <> wrote in comp.lang.perl.misc:
    > Very simple in description but tricky to implement so far. What I am
    > after is given a year, say 2006, what is the First sunday's date on the
    > calendar (For January). For instance in 2006 this would be january 1st
    > 2006. But in 2005 it would be Dec 26th 2004. Is there a simple module
    > for getting this kind of date?


    Just one question: How is Dec 26th 2004 the first Sunday in 2005?

    Anno
     
    -berlin.de, Oct 5, 2006
    #4
  5. Guest

    -berlin.de wrote:
    > Just one question: How is Dec 26th 2004 the first Sunday in 2005?


    I think the OP means if you look at a calendar (where Sunday is the
    first column) and see which row holds Jan 1, what is the date of the
    first column of that row?

    --
    David Filmer (http://DavidFilmer.com)
     
    , Oct 5, 2006
    #5
  6. Guest

    wrote:
    > But in 2005 it would be Dec 26th 2004. Is there a simple module
    > for getting this kind of date?


    Date::Calc's perldocs show several examples which could be adapted,
    notably:

    7) How do I calculate the date of the Wednesday of the same week as the
    current date?

    10) How do I calculate the last and the next Saturday for any given
    date?

    --
    David Filmer (http://DavidFilmer.com)
     
    , Oct 5, 2006
    #6
  7. Idgarad Guest

    The solution worked great but I modified it to take a month parameter
    to ease the consecutive use of generating the calendars following
    January. i.e. first_sunday_of_calmonth(1,2005) and
    first_sunday_of_calmonth(4,2006).

    sub first_sunday_of_calmonth {
    my $m = shift;
    my $y = shift;

    my $dow = strftime("%w", 0,0,0,1,$m-1,$y-1900);
    my $time = timelocal(0,0,0,1,$m-1,$y-1900);
    return $time - ($dow * 24 * 60 * 60);
    }

    A latter poster was correct, I was seeking the upper left-most box on a
    calendar. I have posted below the finished product which was a simple
    pager rotation script that generates a calendar in Excel format. It is
    designed at this time only to handle 3 people as I have to fix the mod
    (%) math to handle a variable number of people properly. If anyone
    knows a good solution please let me know. Critiques welcome!

    --schedule.pl--
    #!/usr/bin/perl
    ###### List of People to be on rotation
    # --users, -u = "jeff,john,jack" with the person working evening that
    week covering the weekend
    # --year, -y = "2008" for instance.
    # You may need to set yout TZ environment variable if the script cannot
    # determine your time zone from the system.
    ######
    use Getopt::Long;
    use Date::Manip;
    use Spreadsheet::WriteExcel;
    use Calendar::Functions;
    use Date::Holidays::USFederal;

    use POSIX qw/strftime/;
    use Time::Local;

    my @users = ();

    $result = GetOptions ("users|u=s" => \@users,
    "year|y=s" => \$year);




    print "first sunday of week 1 is: ", ParseDate("sunday week 0
    $year"),"\n";
    @users = split(/,/,join(',',@users));
    print @users;
    #this would be used later in mod math to get things rotating properly
    #but it fails miserable due to the addition later
    $totalUsers=scalar(@users);

    my $first = first_sunday_of_calmonth(1,$year);
    $date=strftime("%m/%d/%Y", localtime($first));

    print ("Initial Offset is $date\n");


    #Make A SpreadSheet
    my $workbook = Spreadsheet::WriteExcel->new("alpha-pager-$year.xls"); #
    Step 1


    #Build Formats

    $fmtMonth=$workbook->add_format();
    $fmtMonth->set_align('center');
    $fmtMonth->set_align('Vcenter');
    $fmtMonth->set_border(1);
    $fmtMonth->set_bg_color('white');
    $fmtMonth->set_font('Times New Roman');
    $fmtMonth->set_size(24);
    $fmtMonth->set_bold(1);

    $fmtWeek=$workbook->add_format();
    $fmtWeek->set_align('center');
    $fmtWeek->set_align('Vcenter');
    $fmtWeek->set_border(1);
    $fmtWeek->set_bg_color('white');
    $fmtWeek->set_font('Times New Roman');
    $fmtWeek->set_size(14);
    $fmtWeek->set_bold(1);

    $fmtDate=$workbook->add_format();
    $fmtDate->set_align('left');
    $fmtDate->set_align('top');
    $fmtDate->set_left(1);
    $fmtDate->set_right(1);
    $fmtDate->set_bg_color('white');
    $fmtDate->set_font('Times New Roman');
    $fmtDate->set_size(12);
    $fmtDate->set_bold(1);

    $fmtText=$workbook->add_format();
    $fmtText->set_align('left');
    $fmtText->set_align('top');
    $fmtText->set_left(1);
    $fmtText->set_right(1);
    $fmtText->set_bg_color('white');
    $fmtText->set_font('Arial');
    $fmtText->set_size(10);
    $fmtText->set_bold(0);

    $fmtHoliday=$workbook->add_format();
    $fmtHoliday->set_align('right');
    $fmtHoliday->set_align('bottom');
    $fmtHoliday->set_text_wrap(1);
    $fmtHoliday->set_left(1);
    $fmtHoliday->set_right(1);
    $fmtHoliday->set_bottom(1);
    $fmtHoliday->set_bg_color('white');
    $fmtHoliday->set_font('Arial');
    $fmtHoliday->set_color('Blue');
    $fmtHoliday->set_size(8);
    $fmtHoliday->set_bold(1);

    $fmtDate2=$workbook->add_format();
    $fmtDate2->set_align('left');
    $fmtDate2->set_align('top');
    $fmtDate2->set_left(1);
    $fmtDate2->set_right(1);
    $fmtDate2->set_bg_color('silver');
    $fmtDate2->set_font('Times New Roman');
    $fmtDate2->set_color('grey');
    $fmtDate2->set_size(12);
    $fmtDate2->set_bold(1);

    $fmtText2=$workbook->add_format();
    $fmtText2->set_align('left');
    $fmtText2->set_align('top');
    $fmtText2->set_left(1);
    $fmtText2->set_right(1);
    $fmtText2->set_bg_color('silver');
    $fmtText2->set_font('Arial');
    $fmtText2->set_color('grey');
    $fmtText2->set_size(10);
    $fmtText2->set_bold(0);

    $fmtHoliday2=$workbook->add_format();
    $fmtHoliday2->set_align('right');
    $fmtHoliday2->set_align('bottom');
    $fmtHoliday2->set_left(1);
    $fmtHoliday2->set_right(1);
    $fmtHoliday2->set_bottom(1);
    $fmtHoliday2->set_bg_color('silver');
    $fmtHoliday2->set_font('Arial');
    $fmtHoliday2->set_color('plum');
    $fmtHoliday2->set_size(8);
    $fmtHoliday2->set_text_wrap(1);
    $fmtHoliday2->set_bold(1);

    @week=(
    UnixDate(DateCalc($date,"+0 days"),"%A"),
    UnixDate(DateCalc($date,"+1 days"),"%A"),
    UnixDate(DateCalc($date,"+2 days"),"%A"),
    UnixDate(DateCalc($date,"+3 days"),"%A"),
    UnixDate(DateCalc($date,"+4 days"),"%A"),
    UnixDate(DateCalc($date,"+5 days"),"%A"),
    UnixDate(DateCalc($date,"+6 days"),"%A"),
    );




    for($month=1;$month<13;$month++)
    {

    $first = first_sunday_of_calmonth($month,$year);
    $date=strftime("%m/%d/%Y", localtime($first));

    $workbook->add_worksheet((UnixDate("$month/1/$year","%B")));

    $workbook->sheets($month-1)->merge_range(0,0,0,6,UnixDate("$month/1/$year","%B")."
    - $year",$fmtMonth);

    $workbook->sheets($month-1)->set_column('A:A', 15);
    $workbook->sheets($month-1)->set_column('B:B', 15);
    $workbook->sheets($month-1)->set_column('C:C', 15);
    $workbook->sheets($month-1)->set_column('D:D', 15);
    $workbook->sheets($month-1)->set_column('E:E', 15);
    $workbook->sheets($month-1)->set_column('F:F', 15);
    $workbook->sheets($month-1)->set_column('G:G', 15);

    for($dow=0;$dow<7;$dow++){

    $workbook->sheets($month-1)->write(1,$dow,dotw($dow),$fmtWeek);
    }
    #Render the Calendar Entries

    for($row=2;$row < 30;$row+=5)
    {

    for($cols=0;$cols<7;$cols++)
    {

    #define the Roles, this is where mod math does
    if not just three
    $sunday=$users[($row)%$totalUsers];
    $saturday=$users[($row+2)%$totalUsers];
    $weekday=$users[($row+1)%$totalUsers];
    $weeknight=$users[($row+2)%$totalUsers];

    if (UnixDate($date,"%m") == $month) {


    $workbook->sheets($month-1)->write($row,$cols,UnixDate($date,"%d"),$fmtDate);

    $workbook->sheets($month-1)->write_blank($row+1,$cols,$fmtDate);
    SWITCH: {

    $cols==0 and do {

    $workbook->sheets($month-1)->write($row+2,$cols,"Primary:
    $sunday",$fmtText);

    $workbook->sheets($month-1)->write_blank($row+3,$cols,$fmtText);

    $workbook->sheets($month-1)->write($row+4,$cols,holidayCheck($date),$fmtHoliday);
    last;
    };

    $cols==6 and do {

    $workbook->sheets($month-1)->write($row+2,$cols,"Primary:
    $saturday",$fmtText);

    $workbook->sheets($month-1)->write_blank($row+3,$cols,$fmtText);

    $workbook->sheets($month-1)->write($row+4,$cols,holidayCheck($date),$fmtHoliday);
    last;
    };
    $cols!=6 || $cols!=0 and do {

    $workbook->sheets($month-1)->write($row+2,$cols,"Days:
    $weekday",$fmtText);

    $workbook->sheets($month-1)->write($row+3,$cols,"Evenings:
    $weeknight",$fmtText);

    $workbook->sheets($month-1)->write($row+4,$cols,holidayCheck($date),$fmtHoliday);
    last;
    }

    } #END OF SWITCH
    } else {

    $workbook->sheets($month-1)->write($row,$cols,UnixDate($date,"%d"),$fmtDate2);

    $workbook->sheets($month-1)->write_blank($row+1,$cols,$fmtDate2);
    SWITCH: {

    $cols==0 and do {

    $workbook->sheets($month-1)->write($row+2,$cols,"Primary:
    $sunday",$fmtText2);

    $workbook->sheets($month-1)->write_blank($row+3,$cols,$fmtText2);

    $workbook->sheets($month-1)->write($row+4,$cols,holidayCheck($date),$fmtHoliday2);
    last;
    };

    $cols==6 and do {

    $workbook->sheets($month-1)->write($row+2,$cols,"Primary:
    $saturday",$fmtText2);

    $workbook->sheets($month-1)->write_blank($row+3,$cols,$fmtText2);

    $workbook->sheets($month-1)->write($row+4,$cols,holidayCheck($date),$fmtHoliday2);
    last;
    };
    $cols!=6 || $cols!=0 and do {

    $workbook->sheets($month-1)->write($row+2,$cols,"Days:
    $weekday",$fmtText2);

    $workbook->sheets($month-1)->write($row+3,$cols,"Evenings:
    $weeknight",$fmtText2);

    $workbook->sheets($month-1)->write($row+4,$cols,holidayCheck($date),$fmtHoliday2);
    last;
    }

    } #END OF SWITCH


    }
    $date=DateCalc($date,"+1 day");


    }

    if(UnixDate($date,"%m") > $month) {last;}
    };

    #Set Up The Printer Settings
    $workbook->sheets($month-1)->center_horizontally();
    $workbook->sheets($month-1)->center_vertically();
    $workbook->sheets($month-1)->set_paper(1);
    $workbook->sheets($month-1)->set_margins(.6);
    $workbook->sheets($month-1)->set_landscape();

    $workbook->sheets($month-1)->print_area(0,0,$row+4, $cols-1)

    }
    $workbook->close();

    sub holidayCheck {
    my $t = shift;
    my $y = UnixDate($t,"%Y");
    my $m = UnixDate($t,"%m");
    my $d = UnixDate($t,"%d");

    my $checkDate = "$m/$d/$y";

    print "My CheckDate= $checkDate\n";

    SWITCH: {

    $checkDate eq "01/02/$y" and do {return "New Year's Day";};
    $checkDate eq "01/16/$y" and do {return "Martin Luther King, Jr.
    Day";};
    $checkDate eq "02/20/$y" and do {return "Presidents' Day";};
    $checkDate eq "05/29/$y" and do {return "Memorial Day";};
    $checkDate eq "07/04/$y" and do {return "Independence Day";};
    $checkDate eq "09/04/$y" and do {return "Labor Day";};
    $checkDate eq "10/09/$y" and do {return "Columbus Day";};
    $checkDate eq "11/11/$y" and do {return "Veterans' Day";};
    $checkDate eq "11/23/$y" and do {return "Thanksgiving Day";};
    $checkDate eq "12/25/$y" and do {return "Christmas Day";};

    } #END SELECT


    }

    sub first_sunday_of_calmonth {
    my $m = shift;
    my $y = shift;

    my $dow = strftime("%w", 0,0,0,1,$m-1,$y-1900);
    my $time = timelocal(0,0,0,1,$m-1,$y-1900);
    return $time - ($dow * 24 * 60 * 60);
    }

    --End Schedule--
    Paul Lalli wrote:
    > wrote:
    > > Very simple in description but tricky to implement so far. What I am
    > > after is given a year, say 2006, what is the First sunday's date on the
    > > calendar (For January). For instance in 2006 this would be january 1st
    > > 2006. But in 2005 it would be Dec 26th 2004. Is there a simple module
    > > for getting this kind of date?

    >
    > I'm sure one of the hundreds of Date* modules available on CPAN can do
    > this, but if you don't feel like installing a non-standard module just
    > for this purpose, this seems to work for me:
    >
    > #!/usr/bin/perl
    > use strict;
    > use warnings;
    > use POSIX qw/strftime/;
    > use Time::Local;
    >
    > for my $y (2004, 2005, 2006) {
    > my $first = first_sunday($y);
    > print "$y: ", strftime("%C", localtime($first)), "\n";
    > }
    >
    > sub first_sunday {
    > my $y = shift;
    > my $dow = strftime("%w", 0,0,0,1,0,$y-1900);
    > my $time = timelocal(0,0,0,1,0,$y-1900);
    > return $time - ($dow * 24 * 60 * 60);
    > }
    > __END__
    > 2004: Sun Dec 28 00:00:00 EST 2003
    > 2005: Sun Dec 26 00:00:00 EST 2004
    > 2006: Sun Jan 1 00:00:00 EST 2006
    >
    > Basically, find the day of the week of the first of the year (as an
    > integer from 0 - 6). Then take that date, and subtract that number of
    > days from it.
    >
    > Paul Lalli
     
    Idgarad, Oct 6, 2006
    #7
  8. Idgarad Guest

    Dead right David, that is what I was after. Effectivly what is the date
    in row 0, col 0 of the calendar. I posted the completed work. Thank you
    all for the help.


    wrote:
    > -berlin.de wrote:
    > > Just one question: How is Dec 26th 2004 the first Sunday in 2005?

    >
    > I think the OP means if you look at a calendar (where Sunday is the
    > first column) and see which row holds Jan 1, what is the date of the
    > first column of that row?
    >
    > --
    > David Filmer (http://DavidFilmer.com)
     
    Idgarad, Oct 6, 2006
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. tfsmag
    Replies:
    8
    Views:
    517
    Kim Quigley
    Jun 17, 2005
  2. =?Utf-8?B?SmFzb24gQ2hhbg==?=

    Get the month and year of Calendar that current displaying

    =?Utf-8?B?SmFzb24gQ2hhbg==?=, Nov 23, 2005, in forum: ASP .Net
    Replies:
    4
    Views:
    688
    Jason Chan
    Nov 23, 2005
  3. Laguna
    Replies:
    20
    Views:
    819
    John Machin
    Sep 15, 2005
  4. Replies:
    1
    Views:
    480
    Steve W. Jackson
    Dec 22, 2006
  5. Mufasa
    Replies:
    0
    Views:
    418
    Mufasa
    Sep 5, 2008
Loading...

Share This Page