Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Date to Day

by JoeJaz (Monk)
on Aug 25, 2004 at 21:23 UTC ( [id://385829]=perlquestion: print w/replies, xml ) Need Help??

JoeJaz has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I am trying to convert a date into a weekday without using any extermal modules (modules that don't normally come with perl by default). Basically, I would like to feed a function a string like "01-23-2004" and have it return the weekday that the date falls on. I know that I can issue a statement like this:
my ($sec, $min, $hour, $mday, $month, $year, $wday, $isdst) = localtim +e(time); return $wday;
... but, this function does not allow me to enter custom values for dates. Yes, I know that I can subtract or add the number of seconds in a day times the number of days difference from the current day to have it return a value other than the current day. (ex. localtime(time + (68400 * 2))). However, this becomes difficult if I want to find the weekday of a day far into the future. (since I would have to calculate the number of days between the target date and the current date). Is there a simpler way to find the weekday from a date string without a module? If anyone has any input, I would be very greatful. Thanks for taking the time to read this. Joe

Replies are listed 'Best First'.
Re: Date to Day
by jmcnamara (Monsignor) on Aug 25, 2004 at 21:42 UTC

    See the following snippet: Day of the week.
    ################################################################## +######### # # day_of_week($year, $month, $day) # # Valid from 14 September 1752 onwards. $month and $day are 1 inde +xed. # # Returns: 0 .. 6 where 0 is Sunday. # # Algorithm by Tomohiko Sakamoto from the C FAQ, section 20.31. # sub day_of_week { my ($year, $month, $day) = @_; my @offset = (0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4); $year -= $month < 3; return ($year + int($year/4) - int($year/100) + int($year/400) + $offset[$month-1] + $day) % 7; }

    --
    John.

      Nice code! Great solution to this problem. Thank you for providing it. Joe
Re: Date to Day
by TrekNoid (Pilgrim) on Aug 25, 2004 at 21:43 UTC
    Is there a simpler way to find the weekday from a date string without a module?

    Dr Math's Calendar Fun

    There's two algorithms on this page for deducing the day of the week for any Gregorian calendar date.

    Trek

      Another very nice algorithm page. I'll be sure to look through this page carefully. Thanks!
Re: Date to Day
by ysth (Canon) on Aug 25, 2004 at 21:46 UTC
    Unlike Date::Calc, Time::Local comes with perl. Untested:
    use Time::Local "timelocal"; my ($month, $mday, $year) = split /-/, "01-23-2004"; my $wday = (localtime(timelocal(0, 0, 0, $mday, $month-1, $year-1900)) +)[6];
    But if you are doing much date work, it's worthwhile to learn how to use Date::Calc or DateTime.

    Update: adjusted year and month to be localtimey. Thanks isotope.

      Watch those values there, ysth. The range for $month and the math for $year are the same as localtime().


      --isotope
Re: Date to Day
by CountZero (Bishop) on Aug 25, 2004 at 21:40 UTC
    Here you find the algorithm to calculate the Julian Day number which is very easy to calculate the day of the week from.

    CountZero

    "If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law

      Very interesting! I'll be bookmarking this page. Thanks for the help. Joe
Re: Date to Day
by Your Mother (Archbishop) on Aug 25, 2004 at 21:33 UTC

    It's a little involved but it should get you going. There are *many* more excellent and speedy routines in Date::Calc.

    use Date::Calc qw( Today Add_Delta_Days Day_of_Week_to_Text Day_of_Week ); my @today = Today(); my $days_in_the_future = shift || 0; my @then = Add_Delta_Days( @today, $days_in_the_future ); print Day_of_Week_to_Text( Day_of_Week( @then ) ), "\n";

      Well, if the OP already has the number of days in the future, it can be a lot simpler:
      my $today_wday = (localtime)[6]; my $then_wday = ($today_wday + $days_in_the_future) % 7;
      Update: But it sounds like he's just given a date string. If it's a simple MM-DD-YYYY, I'd suggest Time::Local+localtime, since it's core.
      use Time::Local; my $string = "01-01-2015"; my ($m, $d, $y) = split /-/, $string; my $epoch = timelocal 0, 0, 0, $d, $m-1, $y-1900; my $wday = (localtime $epoch)[6];
      To do any of the other algorithms suggested, you'll need to parse out the day, month, year values anyway.. If this is a problem, you will need a beefier date module like Date::Calc.

      blokhead

        Wow! I didn't know that you could use the localtime function in that way. This is very useful. Thanks! Joe
      I'll have a look into that. Though I generally try to shy away from modules, this one seems worth the extra install. Thanks for pointing me to it. I appreciate your help. Joe

        If you want to install a Date and Time handling module then you should really be looking at the ones from the DateTime Project as they aim to cover all of the functionality of the current diverse set of modules with one coherent set of modules.

        --
        <http://www.dave.org.uk>

        "The first rule of Perl club is you do not talk about Perl club."
        -- Chip Salzenberg

        *sigh* Ignore this.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://385829]
Approved by PERLscienceman
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others contemplating the Monastery: (3)
As of 2024-04-16 20:56 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found