BNAMEb TIME - Time and date functions BDESCRIPTIONb BASIC IV (on the Master) and V (on the Archimedes) have a =BTIME$b function to read the real-time clock (RTC). However, other systems may have a RTC, but be running a version of BASIC without the =BTIME$b function, such as BASIC II (on the B/B+). Also, the 6502 second processor only reads 24 bytes instead of 25, and so loses the terminator. In addition, the OSWORD 14 system call, that =BTIME$b uses, is not guaranteed to return the correct date. Some systems do not have an OSWORD 14 call. Some systems such as the Master Compact have no RTC and return a fixed string. Some systems read the date from an external server, but get the overflow arithmetic on the date and year wrong so 1997 is returned as 1981. Also, most systems have a hardwired '19' at the beginning of the year, so the year 2000 is returned as 1900. In general, =BTIME$b should never be used, and programs should use one of the following functions: BFNtimeb BFNtimeb will read the RTC regardless of what machine it is running on, and will correct for years after 1996 and 1999, or return a null string if no time is available. The 'Acorn Era' is defined as starting in 1981, so the century range is 1981-2080. B DIM ctrl% 30 DEFFNtime:LOCALX%,Y%,A%:X%=ctrl% Y%=X%DIV256:?X%=0:A%=14:CALL&FFF1:IF?X%=0:="" X%?25=13:X%?15=13:A%=VALMID$($X%,5,2)DIV32 $(X%+11)=STR$(VAL$(X%+11)+16*A%-100*(VAL$(X%+11)<1981)) IFA%:X%?6=13:$(X%+4)=RIGHT$("0"+STR$(VAL$(X%+4)-32),2):X%?6=32 X%?15=46:=$X%b BPROCtimeb PROCtime will read the RTC and set the variables day%, month% and year% to the current date and hour%, minute% and second% to the current time, or to zero if no RTC is present. B DIM ctrl% 30 DEFPROCtime:LOCALX%,Y%,A%:X%=ctrl%:Y%=X%DIV256 year%=0:month%=0:day%=0:hour%=0:minute%=0:second%=0 A%=14:!X%=1:CALL&FFF1:IF!X%=1:ENDPROC FORA%=0TO7:X%?A%=VALSTR$~X%?A%:NEXT ?X%=?X%+((X%?2)AND&E0)DIV2:X%?2=X%?2 AND31:IF?X%<81:?X%=?X%+100 year%=?X%:month%=X%?1:day%=X%?2:hour%=X%?4:minute%=X%?5:second%=X%?6 ENDPROCb BFNdateb The function BFNdateb returns the current date in the format &yyyymmdd. So, if it is called with BT%=FNdateb, then for example, B(T%AND&FFFF0000)DIV65536b would give the current year. B DIM ctrl% 30 DEFFNdate:LOCALX%,Y%,A%:X%=ctrl%:Y%=X%DIV256 A%=14:!X%=1:CALL&FFF1:IF!X%=1:=0 ?X%=(VALSTR$~?X%+(((VALSTR$~X%?2)DIV2)AND&F0))MOD100 =(VALSTR$~X%?2 AND31)+256*VALSTR$~X%?1+65536*(1900+?X%-100*(?X%<80))b BTIME AND DATE SUPPORT FUNCTIONSb BFNDayOfWeekb The function BFNDayOfWeekb returns the day of the week for the given date, month and year. It works correctly with dates from 1753 onwards. B DEFFNDayOfWeek(d%,m%,y%) y%=y%MOD400:=(y%*365.25+m%*30+d%+VALMID$("120112234455",m%,1)+ ((y%MOD4)=0)-((y%-1)DIV100)-(m%>2 AND((y%MOD4)=0 AND (y%MOD100)<>0 ORy%=0))+3)MOD7+1 REM Returns 1..7 for Sun..Satb BPROCConvDateb BPROCConvDateb converts the given time and date to a centi-second count from 00:00:00 on 1st Jan 1900, as used for Archimedes time-stamps. B DEFPROCConvDate(mem%,d%,m%,y%,hr%,mn%,sc%,cs%) y%=y%MOD400:d%=y%*365.25+m%*30+d%+VALMID$("120112234455",m%,1)+ ((y%MOD4)=0)-((y%-1)DIV100)-(m%>2AND((y%MOD4)=0AND(y%MOD100)<>0 OR y%=0))+36493:IFd%>146096:d%=d%-146097 d%=d%*&41EB:mem%!1=d%+d%:d%=((hr%*60+mn%)*60+sc%)*100+cs% ?mem%=d%:mem%!1=mem%!1+d%DIV256:ENDPROCb On entry: mem%->five bytes of memory day, month, year of the date hours, minutes, seconds, centiseconds of the time On exit: mem% to mem%+4 containes five-byte centisecond time since 00:00:00 on 1-Jan-1900. The d%+d% is deliberate. It prevents a 'Too big' error happening when &7Fxxxxxxxx overflows to &80xxxxxxxx. The five-byte time range ends at 06:57:57.75, 04/06/2248. The five-byte time can be used to set the load and exec addresses on a file with OSFILE with B PROCConvDate(ctrl%+6,.......) ctrl%!2=ctrl%?10 OR type%*&100 OR &FFF00000b where ctrl% is an OSFILE control block, or: B PROCConvDate(mem%,.......) exec%=!mem%:load%=mem%?4 OR type%*&100 OR &FFF00000b to get load and exec addresses separately. BFNDaysSinceb BFNDaysSinceb returns the number of days since a past date. On entry td%, tm% and ty% should be set to today's date, month and year and pd%, pm% and py% should be set to the past date, month and year. B DIM ctrl% 5 DEFFNDaysSince(td%,tm%,ty%,pd%,pm%,py%):LOCAL past% PROCConvDate(ctrl%,pd%,pm%,py%,0,0,0,0):past%=ctrl%!1 PROCConvDate(ctrl%,td%,tm%,ty%,0,0,0,0):=(ctrl%!1-past%)DIV&83D6b BSEE ALSOb Osword14