10 REM > BLib.Date 1.03 13-Mar-2007
   20 REM Time and date support functions
   30 REM (C)J.G.Harston, may be freely used and redistributed
   40 REM v1.00 12-Sep-1992 JGH: FromOrd(), DayOfWeek(), Day(), Mon() functions
   50 REM v1.01 18-Feb-1994 JGH: ToOrd() and Since() added
   60 REM v1.02 17-Sep-2005 JGH: ToOrd() debugged
   70 REM v1.03 13-Mar-2007 JGH: Added [To|From][Day|Month]() functions
   80 :
   90 :
  100 REM FNDay(day%)   - return 3-char day of week string
  110 REM FNMon(month%) - return 3-char month string
  120 REM ------------------------------------------------
  130 :
  140 DEFFNDay(A%):=MID$("000SunMonTueWedThuFriSat",A%*3+1,3)
  150 DEFFNMon(A%):=MID$("000JanFebMarAprMayJunJulAugSepOctNovDecDDDEEEFFF",A%*3+1,3)
  160 :
  170 :
  180 REM FNDate_FromDay(A$)   - return day number for supplied string
  190 REM FNDate_FromMonth(A$) - return month number for supplied string
  200 REM --------------------------------------------------------------
  210 :
  220 DEFFNDate_FromDay(A$):A$=FNuc(A$)
  230 A%=INSTR("SUNMONTUEWEDTHUFRISAT",LEFT$(A$,3))
  240 IF(A%-1)MOD3=0:=A%DIV3+1 ELSE =0
  250 :
  260 DEFFNDate_FromMonth(A$):A$=FNuc(A$)
  270 A%=INSTR("JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC",LEFT$(A$,3))
  280 IF(A%-1)MOD3=0:=A%DIV3+1 ELSE =0
  290 :
  300 :
  310 REM FNDate_ToDay(day%)     - return full-length day of week string
  320 REM FNDate_ToMonth(month%) - return full-length month string
  330 REM --------------------------------------------------------------
  340 :
  350 DEFFNDate_ToDay(A%)
  360 =MID$("SunMonTuesWednesThursFriSatur",VALMID$("01040711172225",A%*2-1,2),VALMID$("3346535",A%,1))+"day"
  370 :
  380 DEFFNDate_ToMonth(A%)
  390 =MID$("JanuaryFebruaryMarchAprilMayJuneJulyAugustSeptemberOctoberNovemberDecember",VALMID$("010816212629333743525967",A%*2-1,2),VALMID$("785534469788",A%,1))
  400 :
  410 :
  420 REM FNDate_DayOfWeek(day%,month%,year%) - return day of week for supplied date
  430 REM                                       1=Sunday, 7=Saturday
  440 REM --------------------------------------------------------------------------
  450 :
  460 DEFFNDate_DayOfWeek(d%,m%,y%):y%=y%MOD400
  470 =(y%*365.25+m%*30+d%+VALMID$("120112234455",m%,1)+((y%MOD4)=0)-((y%-1)DIV100)-(m%>2AND((y%MOD4)=0AND(y%MOD100)<>0ORy%=0))+3)MOD7+1
  480 :
  490 :
  500 REM PROCDate_FromOrd - convert time and date to 5-byte centi-second count
  510 REM On entry: mem%->five bytes of memory
  520 REM           day, month, year of the date
  530 REM           hours, minutes, seconds, centiseconds of the time
  540 REM On exit:  mem% to mem%+4 containes five-byte centisecond time since
  550 REM           00:00:00 on 1-Jan-1900.
  560 REM ---------------------------------------------------------------------
  570 :
  580 DEFPROCDate_FromOrd(mem%,d%,m%,y%,hr%,mn%,sc%,cs%):y%=y%MOD400
  590 d%=y%*365.25+m%*30+d%+VALMID$("120112234455",m%,1)+((y%MOD4)=0)-((y%-1)DIV100)-(m%>2AND((y%MOD4)=0AND(y%MOD100)<>0ORy%=0))+36493
  600 IFd%>146066:d%=d%-146097
  610 d%=d%*&41EB:mem%!1=d%+d%:d%=((hr%*60+mn%)*60+sc%)*100+cs%
  620 ?mem%=d%:mem%!1=mem%!1+d%DIV256:ENDPROC
  630 :
  640 :
  650 REM PROCDate_ToOrd - convert 5-byte centi-second count to time and date
  660 REM On entry: mem%->five bytes of memory containing five-byte centisecond
  670 REM           time since 00:00:00 on 1-Jan-1900.
  680 REM On exit:  day, month, year of the date
  690 REM           hours, minutes, seconds, centiseconds of the time
  700 REM ---------------------------------------------------------------------
  710 :
  720 DEFPROCDate_ToOrd(mem%):LOCAL A%,B%,C%,D%
  730 year%=0:month%=0:day%=0:hour%=0:minute%=0:second%=0:centi%=0
  740 IFmem%!1<0:ENDPROC:REM Problems with negatives ATM
  750 D%=mem%!1DIV&83D6+2447065:C%=mem%?0+256*(mem%!1MOD&83D6):centi%=C%MOD100
  760 C%=C%DIV100:second%=C%MOD60:C%=C%DIV60:minute%=C%MOD60:hour%=C%DIV60
  770 B%=((D%*4+3)MOD146097AND-4)+3:C%=B%MOD1461DIV4*5+2:D%=D%*4+3
  780 A%=C%DIV153+2:day%=C%MOD153DIV5+1:month%=A%MOD12+1
  790 year%=D%DIV146097*100+B%DIV1461+A%DIV12-4800
  800 ENDPROC
  810 :
  820 :
  830 REM FNDate_Since   - return number of days since a past date
  840 REM On entry: td%, tm% and ty% should be set to today's date, month and
  850 REM           year and pd%, pm% and py% should be set to the past date,
  860 REM           month and year.
  870 REM Requires  X%->5-byte control block
  880 REM -------------------------------------------------------------------
  890 :
  900 DEFFNDate_Since(td%,tm%,ty%,pd%,pm%,py%):LOCAL past%
  910 PROCDate_FromOrd(X%,pd%,pm%,py%,0,0,0,0):past%=X%!1
  920 PROCDate_FromOrd(X%,td%,tm%,ty%,0,0,0,0):=(X%!1-past%)DIV&83D6
  930 :