Ok, here's the scoop. I've always wanted to know how to calculate a weekday name from a date, but I never quite get it. I've looked at a few 'methods', but they don't make sense.
Truth be known, I'd like to write a perl script to determine this.
Can someone help me put together a script that will figure out the date from any day from 1900 and up?
I would appreciate it!
I have some code, but there are some flaws in it somewhere, and I don't know where. I'm actually embarassed to even post it, because it's so sloppy and yucky.
Thanks a bunch!
YaRness
07-02-2001, 02:42 PM
research research research.
there's supposed to be some trick algorithm such that you can figure it out in your head... prolly something good to apply to perl.
seems to me you can hardcode the day of the week that 01 Jan 1900 is, figure out the number of days between your query date and the origin date, and figure out the day by using division and that funky operator that gives you the remainder (mod or something like that).
YaRness
07-02-2001, 02:43 PM
and there are prolly system functions/proggies that you can [ab]use to do some of the work.
TheLinuxDuck
07-02-2001, 03:56 PM
I've already done research, and tried writing out a program to do this... that's why I'm asking for help.
I've found two different methods for doing it, but neither one makes sense to me, so I'm having a hard time putting it into form in a script.
I wouldn't ask if I wasn't at my wits end. (^=
YaRness
07-02-2001, 04:04 PM
well, is there a standard *nix function (i'd be surprised if there weren't) to tell you how many days it is between day X and day Y... or at lesat how many days since day X.
or is that the part you are trying to figure out how to do?
the things i guess you hafta account for are:
-what day is 01 Jan 1900 (origin date)
-number of days based on 365 day year between date X and the origin
-how to figure in number of leap days between data X and the origin
and then follow the math i described above. maybe it's harder than i'm making it out to be.
if yer code is turning out sloppy and buggy, then maybe you should work out the algorithm by hand (pseudocode or whatever) before trying to code it. or, in true programming tradition, steal someone else's algorithm and grok it thoroughly before writing it.
*shrug*
are you trying to use a unix util to help, or do you have the weekday for 01 jan 1900 in your code (i don't happen to know it off hand....)?
jemfinch
07-02-2001, 04:08 PM
You just want a solution, not an understanding, right?
Write a function that, given a month/day, returns which day of the year it is. (That is, given january 3, it would return 3, and given December 27, it would return 361.)
Write a function that, given a year, returns the number of days since Epoch (that is, Jan 1 1970) on which that year began (thus, you know how many days Jan 1 <year> is from Jan 1 1970.)
Sum those two results, multiply by (60*60*24*365), and you've got something that converts a date (Month, Day, Year) into Epoch time. Then just use your operating systems's "strftime" or similar function to format that epoch time. Let the OS's C library handle the complicated stuff :)
Jeremy
YaRness
07-02-2001, 04:12 PM
jeremey: i'm not that familiar with the functions for abusing the 1970 epoch... would that solution work for dates between 1970 and 1900?
i get the feeling TLD is doing this to figure it out as well, not just to get it done. s'why i keep asking about hardcoding the weekday for 01/01/1900
EyesWideOpen
07-02-2001, 04:39 PM
You may want to look into the Date::Calc (http://www.cpan.org/modules/by-module/Date/Date-Calc-4.3.tar.gz) module. This will get you dates all the way back to 1 A.D..
I did some testing with it here at work about a year and a half ago. Here is an old test script you may want to take a look at (sorry if it's ugly -- I didn't feel like cleaning it up):
foreach $date (keys %dates)
{
print "At $date we have $dates{$date}\n";
}
print "$mon/$day/$year was a $days[$wday]\n";
print "$mon2/$day2/$year was a $days[$wday2]\n";
print "$m2[-1]/$d2[-1]/$y2[-1] is 6 days after $mon/$day/$year\n";
[ 02 July 2001: Message edited by: EyesWideOpen ]
TheLinuxDuck
07-02-2001, 05:23 PM
jemfinch:
That's a good idea. There are a few points, though, that are worth mentioning.
To calculate the year day from a month and day, you also need to know if it is a leap year to account for the extra day in Feb, thus making it necessary to also pass in the year. That in itself isn't difficult to do:
--warning-- perl code alert -- avert your eyes! --
sub yday($$$)
{
my($month)=shift;
my($day)=shift;
my($year)=shift;
As for returning the number of days since the epoch, that, in theory, is a good idea, except that the amount of effort required to parse that info out would be not much less than needed to simply derive the weekday from a date.
Look at it this way... when you go to calculate the number of days since the epoch, you have to know how many of those years are leap years, and will, AFAIK, have to loop through each year since then to determine number of days. Based on the above code, I would say something like:
sub daysSinceEpoch($)
{
# This does not include the current year,
# since we've already determined that
#
my($year)=shift;
my($total)=0;
return 0 if($year<=1970);
You now have the number of days since the epoch. And since we know that Jan 1, 1970 is a Thursday, all it takes to find out what the date given is, we just mod that number by 7 (to determine how many days off from the epoch day it is), and then using an anonymous array, we can determine todays day, without having to do much more math, nor use the cstr or localtime functions:
print "Jan 1, 1970 is a Thursday, the date given is a ",
(qw(Mon Tues Wed Thurs Fri Sat Sun))[(3+($allDays%7))%7], "\n";
:which is exactly what I was wanting in the first place.
So, I must say this... although what you had originally considered wasn't totally needed, your perspective was exactly what I needed to solve the dilemma.
Therefore, without that, I wouldn't have a clue... needless-to-say, I've got the solution now.
Thanks dood!
jemfinch
07-02-2001, 11:01 PM
Good! Now that you've proven it can work (and provided a perl version,) I'm definitely feeling the urge to whip this up in O'Caml :D
Jeremy
jemfinch
07-03-2001, 12:50 AM
Oh my.
The integer division of the number of seconds since epoch by 86400 (that's 60*60*24, the number of seconds in a day) gives you the number of days since epoch. I can't believe I missed that. Mod that by 7 and add 3, and you've got the index into your array.
Jeremy
TheLinuxDuck
07-03-2001, 02:12 PM
jemfinch:
Something is wrong with the format.
::sigh::
I think it's something to do with the way that I add up the days in a year, but I'm not sure.
Wait! I just had an idea! --- *time passes* ---
WWWWWWOOOOOOOOOOOOOO!!!!!!!!!!!!
WWWWWOOOOOOOOOOOOOO!!!!!!!!!!
I fingered it out!!!!!!!!!!!!!!!!!
Ok, so I'm a little excited. (^=
The trouble came about when I converted the function into a package. I created two new functions to do all the real work, so you only have to call dayOfWeek with a date, and it returns the right number of day in the week, and pass that to nameofDay to determine what the correct day will be.
However, when I was checking for the leap year, I was only checking for the leap years, and making a change to February based on that...
But, if a leap year was hit, then Feb stayed at 29, even if it wasn't a leap year!
So, I fixed that and it works!!!
YYYYEEEEEEEEEE-HHHHAAAAAAWWWWWWW!!!!!!!!!!
Ok, so I'm really excited. This is something I've wanted to do for a long time! And now I have, thanks to your insight.. actually, reading back, it looks like YaR suggeted the same thing, but I didn't catch it, so thanks YaR! (^=
Wonk.
jemfinch
07-03-2001, 04:25 PM
Did you see my post above?
You don't have to count the number of days in a month/year/whatever, and you don't have to remember which years are leap years and which Februaries have 29 days. Just do what I mentioned above and you'll have your answer in two lines (one, if you feel like squishing stuff.)
Jeremy
justlinux.com
Copyright Internet.com Inc. All Rights Reserved.