Download text file
  Hi,

  These routines are Y5M compliant!

  This code was reworked from code I was given by Eustice Frilingos so most of
  the credit goes to him.

  These two functions pack the three date elements (Y,M,D) into a long integer
  by counting the number of days since 1-1-0001 then unpacking that number into
  the three date elements. The last possible date is in the year 5.8M so it's
  safe to say that the Y2K thingie isn't a problem!

  The fly in the ointment is that somewhere in the 12th century 11 days were
  cut or added to the calendar (don't remember which) so if you're an historian
  you'll need to modify the routines to work around that little chronological
  blip. The reason I've not messed with it is two fold:
    1) I don't plan on going back that far
    2) that 11 day blip is ONLY good in so many countries.
  Other countries and/or religious and/or ethnic groups did things differently
  so the whole sheebang gets totally mind boggling if one wants to make this
  routine work 100% for all conditions.

  The benefits of storing dates in this manner are many fold and not limited to
  the list below:
    1) DayOfTheWeek = (Days MOD 7) ' Sunday = 0 and Saturday = 6
    2) The system is country independent
    3) ToDay +  7 = SameDay_NextWeek
       ToDay + 28 = SameDay_NextMonth (4 weeks)
    4) Validation of an incoming date is fast and quick using the same
       two routines and comparing the returned Y,M,D with what was
       sent. (You need to build such a checking routine)

  fYMD2Days&  returns the number of days since 1-1-0001
  fDays2YMD%  returns the year, month, day and day of the week for a day number
  fJulianDay& returns the day number in a given year
  fLeapYear%  returns 0 or 1 if the year is, in fact, a leap year.

  Hope these routines help you out.

  d83)

---------------------------------------------------------------
-----------------------------------------------------
---------------------------------------------------------------

DEFINT A-Z
DECLARE FUNCTION fLeapYear% (Year%)
DECLARE FUNCTION fYMD2Days& (Year%, Month%, Day%)
DECLARE FUNCTION fDays2YMD% (Days&, Year%, Month%, Day%)

CLS

T1! = TIMER
FOR Y1% = 400 TO 2400
  PRINT USING "#,###"; Y1%
  DoM& = &H3DFF7F9F
  IF fLeapYear%(Y1%) THEN DoM& = (DoM& + 32)
  FOR M1% = 1 TO 12
    FOR D1% = 1 TO (DoM& AND 31)
      IF LEN(INKEY$) THEN GOTO BailOut
      Dz1& = fYMD2Days&(Y1%, M1%, D1%)
      DoW% = fDays2YMD%(Dz1&, Y2%, M2%, D2%)
      IF (Y1% <> Y2%) OR (M1% <> M2%) OR (D1% <> D2%) THEN PRINT "ERROR": END
    NEXT
    DoM& = DoM& \ 32
    IF DoM& = 0 THEN DoM& = &H3FEFFBFF
  NEXT
NEXT

BailOut:
  T1! = TIMER - T1!
  PRINT
  PRINT USING "###.####"; T1!
  PRINT "<>";
END

FUNCTION fDays2YMD% (Daze&, Year%, Month%, Day%)

  Year% = 1
  Month% = 1
  Days& = Daze& - 1

  IF Days& > 146096 THEN
    Year% = Year% + (Days& \ 146097) * 400
    Days& = (Days& MOD 146097)
  END IF
  IF Days& > 36523 THEN
    D% = (Days& \ 36524)
    IF D% < 4 THEN
        Year% = Year% + (D% * 100)
        Days& = (Days& MOD 36524)
      ELSE
        Year% = Year% + 300
        Days& = 36524
    END IF
  END IF
  IF Days& > 1460 THEN
    Year% = Year% + (Days& \ 1461) * 4
    Days& = (Days& MOD 1461)
  END IF
  IF Days& > 364 THEN
    D% = (Days& \ 365)
    IF D% < 4 THEN
        Year% = Year% + D%
        Days& = (Days& MOD 365)
      ELSE
        Year% = Year% + 3
        Days& = 365
    END IF
  END IF

  Day% = Days& + 1
  DoM& = &H3DFF7F9F
  IF Day% > 58 AND fLeapYear%(Year%) THEN DoM& = (DoM& + 32)
  DO
    D% = (DoM& AND 31)
    IF D% >= Day% THEN EXIT DO
    Day% = Day% - D%
    Month% = Month% + 1
    DoM& = (DoM& \ 32)
    IF DoM& = 0 THEN DoM& = &H3FEFFBFF
  LOOP

  fDays2YMD% = (Daze& MOD 7)

END FUNCTION

FUNCTION fLeapYear% (Year%)

  IF ((Year% MOD 4) = 0) AND ((Year% MOD 100) > 0) OR ((Year% MOD 400) = 0) THEN fLeapYear% = 1

END FUNCTION

FUNCTION fYMD2Days& (Y%, M%, D%)

  Days& = D%

  IF M% > 1 THEN
    Month% = M%
    DoM& = &H3DFF7F9F
    IF Month% > 2 AND fLeapYear%(Y%) THEN DoM& = (DoM& + 32)
    DO
      Days& = Days& + (DoM& AND 31)
      IF Month% = 2 THEN EXIT DO
      Month% = Month% - 1
      DoM& = DoM& \ 32
      IF DoM& = 0 THEN DoM& = &H3FEFFBFF
    LOOP
  END IF

  Year% = (Y% - 1)
  Days& = Days& + (CLNG(Year%) * 365) + (Year% \ 4) - (Year% \ 100) + (Year% \ 400)

  fYMD2Days& = Days&

END FUNCTION