[comp.databases] Calendar Algorithm

jasonf@cetemp.Eng.Sun.COM (Jason Freund) (08/08/90)

	I need to be able to change dates in a database cell with commands like
"+4w" == "Find the closest weekday to the day 4 weeks from a certain date", 
"-12d" == "Find the closest weekday 12 days earlier than this date.", and so 
on.  I'll be writing in Pascal -- the code is no problem -- I'll give my 
function a "+/-", a number, and a "d/w/m" (day, week, month), and a date 
"MMDDYY".  The function returns the closes weekday by adding/subtracting 
according to its parameters.  Does anyone know of a general algorithm for 
dealing with calendars?  It must that take into account leap years and be able 
to find what day of the week it is (MTWRF) so that it can make approximations 
to weekdays. I've seen some good ones before, (for computing how many days old 
you are and what day of the week you were born on) but I can't find any now.  

BTW, when is the next leap year?

Thanks,
Jason Freund, Sun Microsystems,  jasonf@cetemp.Corp.sun.com  <== summer address
Deprtmnt of Computer Science, Univ California, Davis. freund@sakura.ucdavis.edu
Quantum Link: JasonF5,  Compu$erve: 72007,244, 690 Erie Dr, Sunnyvale, CA 94087
-------------------------------------------------------------------------------
STOLEN QUOTES -- Please give the authors credit if you know who they are!    
"To understand recursion, you need to understand recursion."
"Wow!  Virtual memory!  Now I'm gonna build me a REALLY big ram disk!"
"My other computer is a SUN3/50."  "E. Pluribus UNIX"   -- authors unkown 

awd@dbase.A-T.COM (Alastair Dallas) (08/10/90)

In article <140352@sun.Eng.Sun.COM>, jasonf@cetemp.Eng.Sun.COM (Jason Freund) writes:
> 	I need to be able to change dates in a database cell with commands like
> "+4w" == "Find the closest weekday to the day 4 weeks from a certain date", 
> "-12d" == "Find the closest weekday 12 days earlier than this date.", and so 
> on.  I'll be writing in Pascal -- the code is no problem -- I'll give my 
> function a "+/-", a number, and a "d/w/m" (day, week, month), and a date 
> "MMDDYY".  The function returns the closes weekday by adding/subtracting 
> according to its parameters.  Does anyone know of a general algorithm for 
> dealing with calendars?  It must that take into account leap years and be able 
> to find what day of the week it is (MTWRF) so that it can make approximations 
> to weekdays. I've seen some good ones before, (for computing how many days old 
> you are and what day of the week you were born on) but I can't find any now.  

The collected algorithms of the ACM has an algorithm for converting
m-d-y into an integer number of days from some start point a long time
ago, and back again.  That makes it easy to add days or weeks.  For
months, you're pretty much stuck adding to your m-d-y months and 
dealing with overflow into years.  The ACM book describes the weekday
values for the resulting integer modulus 7.  (That is, if no_of_days % 7
equals 0, it's Sunday, or Saturday, or something like that.)

> BTW, when is the next leap year?

That's easy.  Leap years occur every four years, except years evenly
divisible by 100.  The last exeception is that years evenly divisible
by 400 _are_ leap years.  Therefore, '92 and '96 are leap years and
for the first time in four hundred years, the turn of the century will
be a leap year.  All because the solar year isn't exactly 365-1/4 days.

/alastair/

news@root.fiu.edu (08/11/90)

In article <140352@sun.Eng.Sun.COM> jasonf@cetemp.Eng.Sun.COM (Jason Freund) writes:
>
>	I need to be able to change dates in a database cell with commands like
>"+4w" == "Find the closest weekday to the day 4 weeks from a certain date", 
>"-12d" == "Find the closest weekday 12 days earlier than this date.", and so 
>on.  I'll be writing in Pascal -- the code is no problem -- I'll give my 
>function a "+/-", a number, and a "d/w/m" (day, week, month), and a date 
>"MMDDYY".  The function returns the closes weekday by adding/subtracting 
>according to its parameters.  Does anyone know of a general algorithm for 
>dealing with calendars?  It must that take into account leap years and be able 
>to find what day of the week it is (MTWRF) so that it can make approximations 
>to weekdays. I've seen some good ones before, (for computing how many days old 
>you are and what day of the week you were born on) but I can't find any now.  
>


   function canonical_day_number( date: YMD_date ) return integer is
      -- Expects a year, month, day combination and returns an integer
      -- which is the number of days since a very long time ago.  To
      -- find the number of days between two dates, subtract these numbers.
      -- To find the day of the week, take the result mod 7.
      year2  : integer := date.year;
      month2 : integer := date.month;
   begin
      if month2 < 3 then 
         month2 := month2 + 12; 
         year2 := year2 - 1; 
      end if;
      -- The following code avoids using floating point or really big numbers.
      return year2 * 365 + year2 / 4 - year2 / 100 + year2 / 400
            +( month2 * 306 + 17 )/ 10 + date.day;
   end canonical_day_number;

Wright_RJ@cc.curtin.edu.au (Robert Wright) (08/13/90)

Excuse the ancient, shouted, UPPERCASE Fortran, but this still works to the
best of my knowledge. This is really a very flexible algorithm.

(cut after this signature block...)
 /-------------------------\ /-----------------------------------------------\
| Rob Wright                |psi%050529452300070:Wright_RJ                    |
| Curtin University         |Wright_RJ@cc.curtin.edu.au                       |
| Perth, Western Australia  |Wright_RJ@cc.cut.oz.au                           |
| Voice:+61 9 351 7385      |Wright_RJ%cc.curtin.edu.au@cunyvm.bitnet         |
| FAX:     09-351-2673      |uunet!munnari.oz!cc.curtin.edu.au!Wright_RJ      |
 \-------------------------/ \-----------------------------------------------/


	SUBROUTINE JULIAN(D1,M1,Y1,D2,M2,Y2,F,J2,W2,T2)
	IMPLICIT INTEGER*4 (A-Z)
	REAL FD1,FM1,FY1,FD2,FM2,FY2,FF,FJ2,FW2,FT2
C
C	ALGORITHM DERIVED FROM HART: SOFTWARE - PRACTICE AND EXPERIENCE
C				       VOL 10, 405-417 (1980)
C	WHERE A MOST COMPLETE SYNTHESIS IS GIVEN.
C	
C	CONVERTED FROM HART'S BASIC TO FORTRAN BY R.J.WRIGHT
C	(WAIT COMPUTING CENTRE, SEPTEMBER 1980)
C
C	LANGUAGE-CONVERSION PROBLEM:
C		BASIC STORES ALL NUMBERS IN FLOATING POINT AND
C		TRULY TRUNCATES WHEN CONVERTING TO INTEGER.
C		FORTRAN IN MANY IMPLEMENTATIONS ROUNDS WHEN
C		DOING THIS CONVERSION. THUS THIS ROUTINE FIRSTLY
C		CONVERTS ALL ARGUMENTS TO FLOATING POINT, WORKS
C		IN FLOATING POINT, AND DELIBERATELY TRUNCATES
C		USING THE AINT FUNCTION. THIS IS NOT QUITE AS EFFICIENT
C		AS MAY BE DESIRED, BUT IT WORKS!
C
C	THE OTHER SIGNIFICANT CHANGE MADE WAS TO RE-ORDER THE M-D-Y
C	DATE CONVENTION TO THE MORE INTERNATIONALLY ACCEPTIBLE D-M-Y.
C
C	***** THE FOLLOWING COMMENTS ARE REPRODUCED ALMOST VERBATIM FROM HART *****
C
C	Julian conversion and inverse -- takes into account
C	leap years and the omission of February 29 in years evenly
C	divisible by 100 but not by 400 (the Gregorian convention).
C
C	J2, the Julian date, is the exact number of days since
C	BC 4714 December 31. Noon on 1981 January 1 marks the
C	beginning of JD 2444606.
C
C	D-M-Y, the Gregorian calendar, was adapted in the United
C	States on 1752 September 14 (JD 2361222). Prior to this
C	date the algorithm has no real meaning although it will
C	calculate imaginary dates back to AD 0 March 1.
C
C	In the United States daylight saving time begins at 2:00 AM
C	the last Sunday of April and extends to 2:00 AM the last
C	Sunday of October. (These are respectively the first Sunday
C	beginning day 55, and the first Sunday beginning day 239).
C	This algorithm provides T2=0 during standard time and T2=1
C	during daylight saving time.
C	Today's T2 minus yesterday's T2 is the daily adjustment to
C	the clock at 2:00 AM.
C	
C	Input arguments:
C			D1	day	usually 0..31, can also be any integer
C			M1	month	0,1..12,13,14
C			Y1	year	1753..future, must be 4 digits 
C					(xx means 19xx)
C
C	Output arguments:
C			D2	day	1..31
C			M2	month	1..12
C			Y2	year	1753..future
C			F	flag	1=Jan,Feb; 0=Mar..Dec
C			J2	JD	2361222..future; 2444606=1-1-1981
C				NOTE: J2 IS RETURNED AS 0 FOR INVALID DATE.
C			W2	weekday	0..6; Sunday..Saturday; (J2+1) MOD 7
C			T2	time	0=standard; 1=daylight saving time
C			2:00 AM adjustment = today's T2 minus yesterday's T2
C
C
C	SOME POSSIBLE USES:
C		LAST MONTH
C			first day = JULIAN(1,M-1,Y,.......)
C			last day = JULIAN(0,M,Y,...)
C
C		THIS MONTH
C			first day = JULIAN(1,M,Y,...)
C			last day = JULIAN(0,M+1,Y,...)
C
C		NEXT MONTH
C			first day = JULIAN(1,M+1,Y,...)
C			last day = JULIAN(0,M+2,Y,...)
C
C		X OR -X DAYS FROM D-M-Y
C			JULIAN(D+X,M,Y,...)
C
C		DATE FOR THE XTH DAY OF THE YEAR
C			JULIAN(X,1,Y,...)
C
C		DAYS BETWEEN TWO DATES
C			JULIAN(D1,M1,Y1,...,J1,...)
C			JULIAN(D2,M2,Y2,...,J2,...)
C			then take J2-J1
C
C		DAY OF THE YEAR
C			JULIAN(M,D,Y,...,J1,...)
C			JULIAN(0,1,Y,...,J2,...)
C			then take J2-J1
C
C
C		COPY AND FLOAT THE INPUT INTEGER ARGUMENTS
	FD1=D1
	FM1=M1
	FY1=Y1
C
	FJ2=1.				! 1=no error
	IF(FY1.LT.0. .OR. FM1.LT.-1. .OR. FM1.GT.14.) FJ2=0.	! 0=error
	IF(FJ2.NE.1.)GOTO 1000
C
	FY2=FY1			! year
	IF(FY2.LE.99.)FY2=FY2+1900.	!assume 20th century
	FF=AINT((14.-FM1)/12.)		! 1=Jan,Feb; 0=Mar...Dec
	FJ2=AINT(30.61*(FM1+1.+FF*12.))+FD1+AINT(365.25*(FY2-FF))
	FJ2=FJ2-AINT((((FY2-FF)/100.)+1.)*.75)+1720997.	! Julian day
	FW2=AINT(FJ2+1.-AINT((FJ2+1.)/7.)*7.)		! weekday: 0...6; Sun...Sat
	FY2=FJ2-1721119.1+AINT(.75*AINT((FJ2-1684594.75)/36524.25))
	FD2=AINT(FY2-AINT(365.25*AINT(FY2/365.25))+122.2)	! 123...488
	FY2=AINT(FY2/365.25)+AINT(FD2/429.)			!year
	FM2=AINT(FD2/30.61)-1.-AINT(FD2/429.)*12.		!month
	FD2=FD2-AINT(30.61*AINT(FD2/30.61))			!day
	FT2=INT(30.61*(FM2+1.+FF*12.))+FD2-FW2+1000.
	FT2=AINT(FT2/1177.)-AINT(FT2/1361.)			! 0=standard;1=daylight
	IF(FJ2.LT.2361222.)FJ2=0		!error if date < 14-Sep-1752
C	FIX THE WORKING VALUES BACK TO INTEGERS AND RETURN
C
1000	D1=FD1
	M1=FM1
	Y1=FY1
	D2=FD2
	M2=FM2
	Y2=FY2
	F=FF
	J2=FJ2
	W2=FW2
	T2=FT2
	RETURN
	END

devine@shodha.dec.com (Bob Devine) (08/14/90)

In article <3091.26c69b52@cc.curtin.edu.au>, Wright_RJ@cc.curtin.edu.au (Robert Wright) writes:
> Excuse the ancient, shouted, UPPERCASE Fortran, but this still works to the
> best of my knowledge. This is really a very flexible algorithm.
> 
> C	In the United States daylight saving time begins at 2:00 AM
> C	the last Sunday of April and extends to 2:00 AM the last
> C	Sunday of October.

Be very careful with hardcoding DST rules; the rules change unexpectantly
The current start of DST is the _first_ Sunday in April.

Bob Devine / DEC DB Engineering

paul@unhtel.uucp (Paul S. Sawyer) (08/14/90)

In article <1547@shodha.dec.com> devine@shodha.dec.com (Bob Devine) writes:
>
>Be very careful with hardcoding DST rules; the rules change unexpectantly
>The current start of DST is the _first_ Sunday in April.
>
>Bob Devine / DEC DB Engineering

As those of us well know who are stuck in UNIX SysV.2....

-- 
Paul S. Sawyer              uunet!unh!unhtel!paul     paul@unhtel.UUCP
UNH Telecommunications        attmail!psawyer       p_sawyer@UNHH.BITNET
Durham, NH  03824-3523      VOX: +1 603 862 3262    FAX: +1 603 862 2030

balden@van-bc.wimsey.bc.ca (Bruce Balden) (08/15/90)

Keywords: 

>	SUBROUTINE JULIAN(D1,M1,Y1,D2,M2,Y2,F,J2,W2,T2)
>C	ALGORITHM DERIVED FROM HART: SOFTWARE - PRACTICE AND EXPERIENCE
>C	Julian conversion and inverse -- takes into account
>C	J2, the Julian date, is the exact number of days since
>C	D-M-Y, the Gregorian calendar, was adapted in the United

Most elegant calendar algorithms depend on the fact that the calendar is
much more regular if years are viewed as beginning in March, i.e. the 
zero'th day of the year is March 1 and the last day of the year is 
Feb 28 or 29.  This allows the simple formula floor(30.6*MONTH+0.5) to
calculate the day displacement.  This "simple" formula can be complicated
a little to avoid floating point arithmetic.  On this simple observation and
the idea of using Julian day numbers hang all elegant calendar algorithms.

The usefulness of this approach is no accident: The year orginally really
did begin on March 1.  Look at the names of the months of the year:

November "ninth month", September "seventh month", etc.





Bruce Balden

Grand Thaumaturge.


Have a nice one.

koerberm@nixsin.UUCP (Mathias Koerber) (08/15/90)

Howdy,

In article <669@dbase.A-T.COM> awd@dbase.A-T.COM (Alastair Dallas) writes:
>In article <140352@sun.Eng.Sun.COM>, jasonf@cetemp.Eng.Sun.COM (Jason Freund) writes:
>> 	I need to be able to change dates in a database cell with commands like
>> "+4w" == "Find the closest weekday to the day 4 weeks from a certain date", 
[... stuff deleted ]
>The collected algorithms of the ACM has an algorithm for converting
[...]
>dealing with overflow into years.  The ACM book describes the weekday

What is the ACM (guess: American Computing Monthly?,A magazine or so?).
And what about the book?. Could anyone please e-mail me a short description
of what it contains, and maybe an ISBN, price etc?

Thx,

Mathias

-- 
Mathias Koerber           |Tel:   +65 / 7473828 ext 1852|Fax: +65 / 7474331
Nixdorf Computer Singapore|EUnet: koerber.sin@nixpbe    |nerv:  koerber.sin
2 Kallang Sector          |uunet: uunet!linus!nixbur!koerber.sin
Singapore 1334            |[Standard-disclaimer:All views personal...     ]

mitchell@chance.uucp (George Mitchell) (08/27/90)

In article <1115@nixsin.UUCP> koerberm@nixsin.UUCP (Mathias Koerber) writes:
`What is the ACM (guess: American Computing Monthly?,A magazine or so?).
`And what about the book?. Could anyone please e-mail me a short description
`of what it contains, and maybe an ISBN, price etc?

Would it be appropriate to post a periodic (monthly?) welcome
message for comp.software.eng that contains some pointers to
news.announce.newusers and provides some of the information we
expect most readers (and more posters) to possess?
--
George Mitchell, MITRE, MS Z676, 7525 Colshire Dr, McLean, VA  22102
email: gmitchel@mitre.org  [alt: mitchell@community-chest.mitre.org]
vmail: 703/883-6029         FAX: 703/883-5519

mcgregor@hemlock.Atherton.COM (Scott McGregor) (08/28/90)

> What is the ACM (guess: American Computing Monthly?,A magazine or so?).
> And what about the book?. Could anyone please e-mail me a short description
> of what it contains, and maybe an ISBN, price etc?


ACM is the Association for Computer Machinery.  It is one of the two
major professional societies for people working in the computer
field.  (The IEEE (Institute of Electrical and Electronics Engineers)
Computer Society is the other major professional society).  Both
societies publish
many important books (such as Collected Algorithms mentioned above) and
magazines (such as Communications of the ACM, IEEE Computer, IEEE
Software...).  They sponsor many conferences and special interest groups
(SIGs).  Both are based in the US, and sponsor most activities there,
but have international arms.  Much time and effort can be saved be
reusing work already
done by others and published by these societies.  Good technical libraries
well have many of their publications available, so they are accessible if
you want them, probably even in Singapore.

Note, I posted this rather than replying privately, because I have
found a number of US educated engineers don't know about or refer to the
Collected Algorithms of the ACM and other useful ACM and IEEE books
and journals.  I believe that this may be a defect in our current
computer science engineering programs, where we often encourage reinvention
rather than library research and and reuse.  Later when these engineers
move from the halls of academia into industry becomes the dreaded
Not Invented Here syndrome that undermines reuse strategies).  The number
of people who are unfamiliar with Ivan Sutherland's Sketchpad, Doug
Engelbart's NLS Augment system, and other contributions of the 60s is
staggering, yet many people are trying to reinvent this same technology
today.  A historical perspective can often help one to develop "new"
technology more quickly.  We should at least be thankful that the
many people are once again "rediscovering" virtual memory--now for personal
computers.

Scott McGregor 

norm@oglvee.UUCP (Norman Joseph) (08/29/90)

In <1115@nixsin.UUCP> koerberm@nixsin.UUCP (Mathias Koerber) writes:

>>The collected algorithms of the ACM has an algorithm for converting [...]

>What is the ACM (guess: American Computing Monthly?,A magazine or so?).

ACM is The Association for Computing Machinery,  a professional society
of the computing community founded in 1947.  For membership information,
write to their headquarters:

        ACM
        Membership and Marketing Services
        11 West 42nd Street
        New York, NY  10036
        Tel: 212 869-7440
        Telex: 421686

>And what about the book?.

The Collected Algorithms of the ACM are in four volumes, with updates
quarterly, and costs US $150 for ACM members.
-- 
Norm Joseph - (amanue!oglvee!norm)           cgh!amanue!oglvee!norm@dsi.com, or
  Oglevee Computer Systems, Inc.             ditka!oglvee!norm@daver.bungi.com
                                   ---<*>---
      "Shucking Usenet oysters in pursuit of a pearl."  --  Bill Kennedy

torkil@Pacesetter.COM (Torkil Hammer) (08/31/90)

# 
# The Collected Algorithms of the ACM are in four volumes, with updates
# quarterly, and costs US $150 for ACM members.

I really hope that the ACM algorithm is identical to the Julian Day Number
used by astronomers.  We don't need another day by day calendar.

Mon, Jan 1, 1990 in the gregorian calendar we use is JD 2447893, though
the definition really is that JD 0 is Mon, Jan 1, 4713 BC in the (proleptic)
julian calendar, that was used before the gregorian.  Specifically JD 0.0 is
defined to be noon GMT on that day.

Can anyone with knowledge of the ACM algorithm confirm?

Torkil Hammer