program timesun(output); (* timesun: test time on the Sun compiler Tom Schneider NCI/FCRDC Bldg 469. Room 144 P.O. Box B Frederick, MD 21702-1201 (301) 846-5581 (-5532 for messages) toms@ncifcrf.gov http://www.lecb.ncifcrf.gov/~toms/ National Cancer Institute Laboratory of Mathematical Biology *) label 1; (* end of program *) const (* begin module version *) version = 1.10; (* of timesun.p 2002 Oct 9 2002 Oct 9, 1.10: make link to module.p 2001 Jan 2, 1.09: upgrade readdatetime 2000 Oct 11, 1.07: upgrade documentation and timeseed 2000 Jul 25, 1.06: upgrade documentation 2000 Jul 20, 1.04: renamed timesun 2000 Jul 17, 1.02: remove irrelevant book reading defs. 1999 Mar 3, 1.02: previous version origin 1997 Jan 11 *) updateversion = 1.00; (* defines lowest acceptable current parameter file *) (* end module version *) (* begin module describe.timesun *) (* name timesun: test time on the Sun compiler synopsis timesun(output: out) files output: show the current time. description The time function returned by various computers is different. Show the time function to figure out how to modify the getdatetime procedure. This program contains routines for obtaining the date and time for Delila programs compiled with the Sun compiler. examples Times should look like this: 1980/06/09 18:49:11 ye mo da ho mi se documentation see also {The module program, used to transfer the modules is:} module.p {Related date/time programs:} timegpc.p timep2c.p {General discussion on compiling Delila programs:} http://www.lecb.ncifcrf.gov/~toms/delila.html#How.To.Compile author Thomas Dana Schneider bugs technical notes *) (* end module describe.timesun *) (* begin module datetime.const *) datetimearraylength = 19; (* length of dataarray for dates, It is just long enough to include the 4 digit year - solving the year 2000 problem: 1980/06/09 18:49:11 123456789 123456789 1 2 *) (* end module datetime.const version = 7.40; {of delmod.p 2000 Feb 18} *) type (* begin module datetime.type *) (* array for dates *) datetimearray = packed array[1..datetimearraylength] of char; (* end module datetime.type version = 7.40; {of delmod.p 2000 Feb 18} *) (* begin module package.datetime *) (* ************************************************************************ *) (* begin module getdatetime *) (* end module getdatetime *) (* begin module readdatetime *) (* end module readdatetime *) (* begin module writedatetime *) (* end module writedatetime *) (* begin module timeseed *) (* end module timeseed *) (*[[*) (* begin module limitdate *) (* end module limitdate *) (*]]*) (* ************************************************************************ *) (* end module package.datetime *) (* begin module halt *) procedure halt; (* stop the program. the procedure performs a goto to the end of the program. you must have a label: label 1; declared, and also the end of the program must have this label: 1: end. examples are in the module libraries. this is the only goto in the delila system. *) begin writeln(output,' program halt.'); goto 1 end; (* end module halt version = 7.40; {of delmod.p 2000 Feb 18} *) (* begin module getdatetime *) procedure getdatetime(var adatetime: datetimearray); (* get the date and time into a single array from the system clock. adatetime contains the date: 1980/06/09 18:49:11 ye mo da ho mi se (year, month, day, hour, minute, second). As of 2000 February 18, the Sun Pascal compiler requires a formatting statement. This statement allows the date to be generated in this standard Delila format in a single call. Information about the formatting statement is available on the manual page for date in Unix. If a computer does not have this method, see the 'oldgetdatetime' routine in delmod.p (http://www.lecb.ncifcrf.gov/~toms/delila/delmod.html) for some conversion code. *) begin date(adatetime,'%Y/%m/%d %H:%M:%S'); end; (* end module getdatetime version = 7.40; {of delmod.p 2000 Feb 18} *) (* begin module readdatetime *) procedure readdatetime (var thefile: text; var adatetime: datetimearray); (* read the date and time from the file. It must have this format: 123456789 123456789 1 1980/06/09 18:49:11 *) (* 2001 Jan 2: thefile is not written to! Force 4 digit years. 2000 Oct 11: upgraded so that the p2c compiler does not object to writing out the adatetime; added checks for the date. *) var index: integer; (* to the udatetime *) (* the following is an unpacked date time array, to avoid reading into a packed array. reading into a packed array is not transportable *) udatetime: array[1..datetimearraylength] of char; begin for index:=1 to datetimearraylength do read(thefile,udatetime[index]); pack(udatetime, 1, adatetime); if (adatetime[3]='/') and (adatetime[12]=':') then begin writeln(output,'You have an old datetime (only 2 year digits): '); for index:=1 to datetimearraylength do write(output,adatetime[index]); writeln(output); writeln(output,'Convert your database to 4 digit years.'); halt; end; (* check the adatetime format. Note that further checks for the other positions in the array could be done to be sure that they are numbers. But this should be pretty good. *) if (adatetime[ 5]<>'/') or (adatetime[ 8]<>'/') or (adatetime[14]<>':') or (adatetime[17]<>':') then begin writeln(output,'readdatetime: bad date time read:'); for index:=1 to datetimearraylength do write(output,adatetime[index]); writeln(output); halt end; end; (* end module readdatetime *) (* begin module writedatetime *) procedure writedatetime(var thefile: text; adatetime: datetimearray); (* expand the date and time out and print in the file *) var index: integer; (* index of datetime *) begin for index:=1 to datetimearraylength do write(thefile,adatetime[index]) end; (* end module writedatetime version = 7.40; {of delmod.p 2000 Feb 18} *) (* begin module timeseed *) (* Read the computer date and time. Reverse the order of the digits and put a decimal point in front. This gives a fraction between zero and one that varies quite quickly, and is always unique (if the computer has sufficient accuracy). It is to be used as a seed to a random number generator. This has the nice property that the seed changes every second and does not repeat for thousands of years! *) procedure addtoseed(var seed, power: real; c: char); (* add the digit represented by c to the seed at the power position *) var n: integer; (* the character represented by c *) begin (* addtoseed *) power := power/10; { writeln(output,'addtoseed, c = ',c); writeln(output,'addtoseed, ord(c) = ',ord(c)); } n := ord(c) - ord('0'); if (n < 0) or (n > 9) then begin writeln(output,'timeseed: error in datetime'); writeln(output,'it contains "',c,'" which is not a number.'); writeln(output,'The getdatetime routine must be fixed.'); halt; end; seed := seed + power*n end; (* addtoseed *) procedure makeseed(adatetime: datetimearray; var seed: real); (* convert adatetime to a real number in seed, reversed order Here is the standard adatetime format: 123456789 123456789 1 1980/06/09 18:49:11 *) var power: real; (* a digit of the seed such as 0.01 *) begin seed := 0.0; power := 1.0; addtoseed(seed, power, adatetime[19]); addtoseed(seed, power, adatetime[18]); (* : *) addtoseed(seed, power, adatetime[16]); addtoseed(seed, power, adatetime[15]); (* : *) addtoseed(seed, power, adatetime[13]); addtoseed(seed, power, adatetime[12]); (* *) addtoseed(seed, power, adatetime[10]); addtoseed(seed, power, adatetime[ 9]); (* / *) addtoseed(seed, power, adatetime[ 7]); addtoseed(seed, power, adatetime[ 6]); (* / *) addtoseed(seed, power, adatetime[ 4]); addtoseed(seed, power, adatetime[ 3]); addtoseed(seed, power, adatetime[ 2]); addtoseed(seed, power, adatetime[ 1]); end; procedure orderseed(adatetime: datetimearray; var seed: real); (* convert adatetime to a real number in seed, normal order *) var power: real; (* a digit of the seed such as 0.01 *) begin seed := 0.0; power := 1.0; addtoseed(seed, power, adatetime[ 3]); addtoseed(seed, power, adatetime[ 4]); addtoseed(seed, power, adatetime[ 6]); addtoseed(seed, power, adatetime[ 7]); (* / *) addtoseed(seed, power, adatetime[ 9]); addtoseed(seed, power, adatetime[10]); (* / *) addtoseed(seed, power, adatetime[12]); addtoseed(seed, power, adatetime[13]); (* *) addtoseed(seed, power, adatetime[15]); addtoseed(seed, power, adatetime[16]); (* : *) addtoseed(seed, power, adatetime[18]); addtoseed(seed, power, adatetime[19]); end; procedure timeseed(var seed: real); (* read the computer date and time. reverse the order of the digits and put a decimal point in front. this gives a fraction between zero and one that varies quite quickly, and is always unique (if the computer has sufficient accuracy). it is to be used as a seed to a random number generator. *) var adatetime: datetimearray; (* a date and time *) begin (* timeseed *) getdatetime(adatetime); { writeln(output,'timeseed: adatetime: ',adatetime); } makeseed(adatetime, seed); end; (* timeseed *) (* end module timeseed version = 1.01; (@ of testtime.p 1997 Jan 11 *) (*[[*) (* begin module limitdate *) procedure limitdate(a,b,c,d: char; limitdatetime: datetimearray); (* test whether the current time is before the limit. If it is later, halt the program *) var adatetime: datetimearray; (* a date and time *) Dday: real; (* the critical day *) now: real; (* this very moment *) begin getdatetime(adatetime); { writeln(output,'adatetime:',adatetime); writeln(output,'adatetime[1]: ', adatetime[1]); writeln(output,'adatetime[2]: ', adatetime[2]); writeln(output,'adatetime[3]: ', adatetime[3]); writeln(output,'adatetime[4]: ', adatetime[4]); writeln(output,'adatetime[5]: ', adatetime[5]); } orderseed(adatetime, now); if (limitdatetime[1] <> ' ') or (limitdatetime[2] <> ' ') or (limitdatetime[3] <> ' ') or (limitdatetime[4] <> ' ') then halt; limitdatetime[1] := a; limitdatetime[2] := b; limitdatetime[3] := c; limitdatetime[4] := d; orderseed(limitdatetime, Dday); { writeln(output,'now: ',now:20:10); writeln(output,'Dday: ',Dday:20:10); } if now > Dday then begin writeln(output,'This program expired on ',limitdatetime); writeln(output,'See: http://www.lecb.ncifcrf.gov/~toms/walker/contacts.html'); halt end end; (* end module limitdate *) (*]]*) (* begin module demo.time *) procedure demotime(var fout: text); (* write the time to file fout *) var dateandtime: datetimearray; (* the date and time *) seed: real; (* a seed for a random number generater, made from the date and time written backwards *) begin (* demotime *) getdatetime(dateandtime); writeln(fout); writeln(fout,'The date and time is: '); writedatetime(fout, dateandtime); writeln(fout,' <- This should be the current time and date.'); write (fout,'1980/06/09 18:49:11'); writeln(fout,' <- Times and dates should look like this'); writeln(fout,'year mo da ho mi se <- with parts in these positions'); writeln(fout); timeseed(seed); writeln(fout,'A timeseed is ',seed:16:14); writeln(fout,'Timeseeds can be used to start random number generators.') end; (* demotime *) (* end module demo.time version = 7.40; {of delmod.p 2000 Feb 18} *) (* begin module timesun.themain *) procedure themain; (* the main procedure of the program *) begin writeln(output,'timesun ',version:4:2); demotime(output); end; (* end module timesun.themain *) begin themain; 1: end.