128. Date compression
~~~~~~~~~~~~~~~~
When large numbers of dates need to be stored in a database, file space can
very quickly be used up unless some economies are made. The first Function
below accepts a date as its input, in the form of a six-character string, (eg
230286 for 23rd Feb 1986), checks that the date is valid, and compresses it
to an integer. The Function returns the value zero (or FALSE) if an
impossible date is entered, (eg 310985 or 290286), and this should be tested
by the program.
If the date is OK the resulting integer can be stored in just two bytes, (it
ranges from 33 to 51103), and can easily be sorted chronologically. (NB This
routine does not do this conversion for you.) The date as a string needs six
bytes, and would not sort properly unless it had been entered backwards! (eg
860225.) The second Function converts the stored integer back to a
six-character string.
1000 DEFFNdate_to_number(Z$):LOCAL D%,M%,Y%,N%
1010 IF LEN(Z$)<>6 THEN=FALSE
1020 D%=VAL(LEFT$(Z$,2)):M%=VAL(MID$(Z$,3,2)):Y%=VAL(RIGHT$(Z$,2))
1030 IF M%>12 OR M%<1 THEN=FALSE
1040 N%=30-(M%<8)*(M%MOD2)-(M%>7)*((M%+1)MOD2)
1050 IF M%=2 THEN N%=28-(Y%MOD4=0)
1060 IF D%<1 OR D%>N% THEN=FALSE ELSE=D%+32*M%+512*Y%
1070 :
2000 DEF FNnumber_to_date(Z%):LOCAL D%,M%,Y%
2010 D%=Z%MOD32:Z%=Z%DIV32:M%=Z%MOD16:Y%=Z%DIV16:Z%=D%*10000+M%*100+Y%
2020 =RIGHT$("0"+STR$(Z%),6)