;;; -*- Mode:gate; Fonts:(HL12 HL12I HL12B CPTFONTB HL12BI HL12B HL12I ) -*- =Node: Introduction =Text: 3INTRODUCTION* The 2time* package contains a set of functions for manipulating dates and times: finding the current time, reading and printing dates and times, converting between formats, and other miscellany regarding peculiarities of the calendar system. It also includes functions for accessing the Lisp Machine's microsecond timer. Times are represented in two different formats by the functions in the 2time* package. One way is to represent a time by many numbers, indicating a year, a month, a date, an hour, a minute, and a second (plus, sometimes, a day of the week and timezone). If a year less than 100 is specified, a multiple of 100 is added to it to bring it within 50 years of the present. Year numbers returned by the time functions are greater than 1900. The month is 1 for January, 2 for February, etc. The date is 1 for the first day of a month. The hour is a number from 0 to 23. The minute and second are numbers from 0 to 59. Days of the week are fixnums, where 0 means Monday, 1 means Tuesday, and so on. A timezone is specified as the number of hours west of GMT; thus in Massachusetts the timezone is 5. Any adjustment for daylight savings time is separate from this. This ``decoded'' format is convenient for printing out times into a readable notation, but it is inconvenient for programs to make sense of these numbers and pass them around as arguments (since there are so many of them). So there is a second representation, called Universal Time, which measures a time as the number of seconds since January 1, 1900, at midnight GMT. This ``encoded'' format is easy to deal with inside programs, although it doesn't make much sense to look at (it looks like a huge integer). So both formats are provided; there are functions to convert between the two formats; and many functions exist in two versions, one for each format. The Lisp Machine hardware includes a timer that counts once every microsecond. It is controlled by a crystal and so is fairly accurate. The absolute value of this timer doesn't mean anything useful, since it is initialized randomly; what you do with the timer is to read it at the beginning and end of an interval, and subtract the two values to get the length of the interval in microseconds. These relative times allow you to time intervals of up to an hour (32 bits) with microsecond accuracy. The Lisp Machine keeps track of the time of day by maintaining a 1timebase*, using the microsecond clock to count off the seconds. On the CADR, when the machine first comes up, the timebase is initialized by querying hosts on the Chaosnet to find out the current time. The Lambda has a calendar clock which never stops, so it normally does not need to do this. You can also set the time base using 2time:set-local-time*, described below. There is a similar timer that counts in 60ths of a second rather than microseconds; it is useful for measuring intervals of a few seconds or minutes with less accuracy. Periodic housekeeping functions of the system are scheduled based on this timer. =Node: 4Getting and Setting the Time* =Text: 3GETTING AND SETTING THE TIME get-decoded-time* 3time:get-time* Gets the current time, in decoded form. Return seconds, minutes, hours, date, month, year, day-of-the-week, and daylight-savings-time-p, with the same meanings as 2decode-universal-time* (see 4(DATETIME-1)Time Conversions*). If the current time is not known, 2nil* is returned. The name 2time:get-time* is obsolete. 3get-universal-time* Returns the current time in Universal Time form. 3time:set-local-time* &optional 1new-time* Sets the local time to 1new-time*. If 1new-time* is supplied, it must be either a universal time or a suitable argument to 2time:parse-universal-time* (see 4(DATETIME-1)Reading Dates and Times*). If it is not supplied, or if there is an error parsing the argument, you are prompted for the new time. Note that you will not normally need to call this function; it is useful mainly when the timebase gets screwed up for one reason or another. =Node: 4Elapsed Time in 60ths of a Second* =Text: 3ELAPSED TIME IN 60THS OF A SECOND* The following functions deal with a different kind of time. These are not calendrical date/times, but simply elapsed time in 60ths of a second. These times are used for many internal purposes where the idea is to measure a small interval accurately, not to depend on the time of day or day of month. 3time* Returns a number that increases by 1 every 60th of a second. The value wraps around roughly once a day. Use the 2time-lessp* and 2time-difference* functions to avoid getting in trouble due to the wrap-around. 2time* is completely incompatible with the Maclisp function of the same name. Note that 2time* with an argument measures the length of time required to evaluate a form. See 4(MISCELL-2)Utility Programs*. 3get-internal-run-time* 3get-internal-real-time* Returns the total time in 60ths of a second since the last boot. This value does not wrap around. Eventually it becomes a bignum. The Lisp Machine does not distinguish between run time and real time. 3internal-time-units-per-second* 1Constant* According to Common Lisp, this is the ratio between a second and the time unit used by values of 2get-internal-real-time*. On the Lisp Machine, the value is 60. The value may be different in other Common Lisp implementations. 3time-lessp* 1time1* 1time2* 2t* if 1time1* is earlier than 1time2*, compensating for wrap-around, otherwise 2nil*. 3time-difference* 1time1* 1time2* Assuming 1time1* is later than 1time2*, returns the number of 60ths of a second difference between them, compensating for wrap-around. 3time-increment* 1time* 1interval* Increments 1time* by 1interval*, wrapping around if appropriate. =Node: 4Elapsed Time in Microseconds* =Text: 3ELAPSED TIME IN MICROSECONDS time:microsecond-time* Returns the value of the microsecond timer, as a bignum. The values returned by this function wrap around back to zero about once per hour. 3time:fixnum-microsecond-time* Returns as a fixnum the value of the low 23 bits of the microsecond timer. This is like 2time:microsecond-time*, with the advantage that it returns a value in the same format as the 2time* function, except in microseconds rather than 60ths of a second. This means that you can compare fixnum-microsecond-times with 2time-lessp* and 2time-difference*. 2time:fixnum-microsecond-time* is also a bit faster, but has the disadvantage that since you only see the low bits of the clock, the value can wrap around more quickly (about every eight seconds). Note that the Lisp Machine garbage collector is so designed that the bignums produced by 2time:microsecond-time* are garbage-collected quickly and efficiently, so the overhead for creating the bignums is really not high. =Node: 4Printing Dates and Times* =Text: 3PRINTING DATES AND TIMES* The functions in this section create printed representations of times and dates in various formats and send the characters to a stream. To any of these functions, you may pass 2nil* as the 1stream* parameter and the function will return a string containing the printed representation of the time, instead of printing the characters to any stream. The three functions 2time:print-time*, 2time:print-universal-time*, 2time:print-brief-universal-time* and 2time:print-current-time* accept an argument called 1date-print-mode*, whose purpose is to control how the date is printed. It always defaults to the value of 2time:*default-date-print-mode**. Possible values include: 2:dd//mm//yy* Print the date as in `3/16/53'. 2:mm//dd//yy* Print as in `16/3/53'. 2:dd-mm-yy* Print as in `16-3-53'. 2:dd-mmm-yy* Print as in `16-Mar-53'. 2:|dd mmm yy|* Print as in `16 Mar 53'. 2:ddmmmyy* Print as in `16Mar53'. 2:yymmdd* Print as in `530316'. 2:yymmmdd* Print as in `53Mar16'. 3time:print-current-time* &optional 1(stream* 1*standard-output*)* Prints the current time, formatted as in 211/25/80 14:50:02*, to the specified stream. The date portion may be printed differently according to the argument 1date-print-mode*. 3time:print-time* 1seconds* 1minutes* 1hours* 1date* 1month* 1year* &optional 1(stream* 1*standard-output*)* 1date-print-mode* Prints the specified time, formatted as in 211/25/80 14:50:02*, to the specified stream. The date portion may be printed differently according to the argument 1date-print-mode*. 3time:print-universal-time* 1universal-time* &optional 1(stream* 1*standard-output*)* 1(timezone* 3time:*timezone*1)** 1date-print-mode* Prints the specified time, formatted as in 211/25/80 14:50:02*, to the specified stream. The date portion may be printed differently according to the argument 1date-print-mode*. 3time:print-brief-universal-time* 1universal-time* &optional 1(stream* 1*standard-output*)* 1reference-time* 1date-print-mode* This is like 2time:print-universal-time* except that it omits seconds and only prints those parts of 1universal-time* that differ from 1reference-time*, a universal time that defaults to the current time. Thus the output is in one of the following three forms: 302:50 ;2the same day** 33/4 14:01 ;2a different day in the same year** 38/17/74 15:30 ;2a different year** The date portion may be printed differently according to the argument 1date-print-mode*. 3time:*default-date-print-mode** 1Variable* Holds the default for the 1date-print-mode* argument to each of the functions above. Initially the value here is 2:mm//dd/yy*. 3time:print-current-date* &optional 1(stream* 1*standard-output*)* Prints the current time, formatted as in 2Tuesday the twenty-fifth of November, 1980;* 23:50:41 pm*, to the specified stream. 3time:print-date* 1seconds* 1minutes* 1hours* 1date* 1month* 1year* 1day-of-the-week* &optional 1(stream* 1*standard-output*)* Prints the specified time, formatted as in 2Tuesday the twenty-fifth of November, 1980;* 23:50:41 pm*, to the specified stream. 3time:print-universal-date* 1universal-time* &optional 1(stream* 1*standard-output*)* 1(timezone* 3time:*timezone*1)** Prints the specified time, formatted as in 2Tuesday the twenty-fifth of November, 1980;* 23:50:41 pm*, to the specified stream. =Node: 4Reading Dates and Times* =Text: 3READING DATES AND TIMES* These functions accept most reasonable printed representations of date and time and convert them to the standard internal forms. The following are representative formats that are accepted by the parser. Note that slashes are escaped with additional slashes, as is necessary if these strings are input in traditional syntax. 3"March 15, 1960" "3//15//60" "3//15//1960"* 3"15 March 1960" "15//3//60" "15//3//1960"* 3"March-15-60" "3-15-60" "3-15-1960"* 3"15-March-60" "15-3-60" "15-3-1960"* 3"15-Mar-60" "3-15" "15 March 60"* 3"Fifteen March 60" "The Fifteenth of March, 1960;"* 3"Friday, March 15, 1980"* 3"1130." "11:30" "11:30:17" "11:30 pm"* 3"11:30 AM" "1130" "113000"* 3"11.30" "11.30.00" "11.3" "11 pm"* 3"12 noon" "midnight" "m" "6:00 gmt" "3:00 pdt"* 3 2any date format may be used with any time format** 3"One minute after March 3, 1960"* 3 2meaning one minute after midnight** 3"Two days after March 3, 1960"* 3"Three minutes after 23:59:59 Dec 31, 1959"* 3"Now" "Today" "Yesterday" "five days ago"* 3"two days after tomorrow" "the day after tomorrow" * 3"one day before yesterday" "BOB@OZ's birthday" time:parse* 1string* &optional 1(start* 10)* 1(end* 1nil)* 1(futurep* 1t)* 1base-time* 1must-have-time* 1date-must-have-year* 1time-must-have-second* 1(day-must-be-valid* 1t)* Interpret 1string* as a date and/or time, and return seconds, minutes, hours, date, month, year, day-of-the-week, daylight-savings-time-p, and relative-p. 1start* and 1end* delimit a substring of the string; if 1end* is 2nil*, the end of the string is used. 1must-have-time* means that 1string* must not be empty. 1date-must-have-year* means that a year must be explicitly specified. 1time-must-have-second* means that the second must be specified. 1day-must-be-valid* means that if a day of the week is given, then it must actually be the day that corresponds to the date. 1base-time* provides the defaults for unspecified components; if it is 2nil*, the current time is used. 1futurep* means that the time should be interpreted as being in the future; for example, if the base time is 5:00 and the string refers to the time 3:00, that means the next day if 1futurep* is non-2nil*, but it means two hours ago if 1futurep* is 2nil*. The 1relative-p* returned value is 2t* if the string included a relative part, such as `one minute after' or `two days before' or `tomorrow' or `now'; otherwise, it is 2nil*. If the input is not valid, the error condition 2sys:parse-error* is signaled (see 4(IOSYSTEM-4)Rubout Handling*). 3time:parse-universal-time* 1string* &optional 1(start* 10)* 1(end* 1nil)* 1(futurep* 1t)* 1base-time* 1must-have-time* 1date-must-have-year* 1time-must-have-second* 1(day-must-be-valid* 1t)* This is the same as 2time:parse* except that it returns two values: an integer, representing the time in Universal Time, and the 1relative-p* value. =Node: 4Reading and Printing Time Intervals* =Text: 3READING AND PRINTING TIME INTERVALS* In addition to the functions for reading and printing instants of time, there are other functions specifically for printing time intervals. A time interval is either a number (measured in seconds) or 2nil*, meaning `never'. The printed representations used look like `3 minutes 23 seconds' for actual intervals, or `Never' for 2nil* (some other synonyms and abbreviations for `never' are accepted as input). 3time:print-interval-or-never* 1interval* &optional 1(stream* 1*standard-output*)* 1interval* should be a non-negative fixnum or 2nil*. Its printed representation as a time interval is written onto 1stream*. 3time:parse-interval-or-never* 1string* &optional 1start* 1end* Converts 1string*, a printed representation for a time interval, into a number or 1nil*. 1start* and 1end* may be used to specify a portion of 1string* to be used; the default is to use all of 1string*. It is an error if the contents of string do not look like a reasonable time interval. Here are some examples of acceptable strings: 3"4 seconds" "4 secs" "4 s"* 3"5 mins 23 secs" "5 m 23 s" "23 SECONDS 5 M"* 3 "3 yrs 1 week 1 hr 2 mins 1 sec"* 3"never" "not ever" "no" ""* Note that several abbreviations are understood, the components may be in any order, and case (upper versus lower) is ignored. Also, ``months'' are not recognized, since various months have different lengths and there is no way to know which month is being spoken of. This function always accepts anything that was produced by 2time:print-interval-or-never*; furthermore, it returns exactly the same fixnum (or 2nil*) that was printed. 3time:read-interval-or-never* &optional 1(stream* 1*standard-input*)* Reads a line of input from 1stream* (using 2readline*) and then calls 2time:parse-interval-or-never* on the resulting string. =Node: 4Time Conversions* =Text: 3TIME CONVERSIONS decode-universal-time* 1universal-time* &optional 1(timezone* 1time:*timezone*)* Converts 1universal-time* into its decoded representation. The following values are returned: seconds, minutes, hours, date, month, year, day-of-the-week, daylight-savings-time-p, and the timezone used. 1daylight-savings-time-p* tells you whether or not daylight savings time is in effect; if so, the value of 1hour* has been adjusted accordingly. You can specify 1timezone* explicitly if you want to know the equivalent representation for this time in other parts of the world. 3encode-universal-time* 1seconds* 1minutes* 1hours* 1date* 1month* 1year* &optional 1timezone* Converts the decoded time into Universal Time format, and return the Universal Time as an integer. If you don't specify 1timezone*, it defaults to the current timezone adjusted for daylight savings time; if you provide it explicitly, it is not adjusted for daylight savings time. If 1year* is less than 100, it is shifted by centuries until it is within 50 years of the present. 3time:*timezone** 1Variable* The value of 2time:*timezone** is the time zone in which this Lisp Machine resides, expressed in terms of the number of hours west of GMT this time zone is. This value does not change to reflect daylight savings time; it tells you about standard time in your part of the world. =Node: 4Internal Functions* =Text: 3INTERNAL FUNCTIONS* These functions provide support for those listed above. Some user programs may need to call them directly, so they are documented here. 3time:initialize-timebase* Initializes the timebase by querying Chaosnet hosts to find out the current time. This is called automatically during system initialization. You may want to call it yourself to correct the time if it appears to be inaccurate or downright wrong. See also 2time:set-local-time*, 4(DATETIME-1)Getting and Setting the Time*. 3time:daylight-savings-time-p* 1hours* 1date* 1month* 1year* Returns 2t* if daylight savings time is in effect for the specified hour; otherwise, return 2nil*. If 1year* is less than 100, it is shifted by centuries until it is within 50 years of the present. 3time:daylight-savings-p* Returns 2t* if daylight savings time is currently in effect; otherwise, returns 2nil*. 3time:month-length* 1month* 1year* Returns the number of days in the specified 1month*; you must supply a 1year* in case the month is February (which has a different length during leap years). If 1year* is less than 100, it is shifted by centuries until it is within 50 years of the present. 3time:leap-year-p* 1year* Returns 2t* if 1year* is a leap year; otherwise return 2nil*. If 1year* is less than 100, it is shifted by centuries until it is within 50 years of the present. 3time:verify-date* 1date* 1month* 1year* 1day-of-the-week* If the day of the week of the date specified by 1date*, 1month*, and 1year* is the same as 1day-of-the-week*, returns 2nil*; otherwise, returns a string that contains a suitable error message. If 1year* is less than 100, it is shifted by centuries until it is within 50 years of the present. 3time:day-of-the-week-string* 1day-of-the-week* &optional 1(mode* 1:long)* Returns a string representing the day of the week. As usual, 20* means Monday, 21* means Tuesday, and so on. Possible values of 1mode* are: 2:long* Returns the full English name, such as 2"Monday"*, 2"Tuesday"*, etc. This is the default. 2:short* Returns a three-letter abbreviation, such as 2"Mon"*, 2"Tue"*, etc. 2:medium* Returns a longer abbreviation, such as 2"Tues"* and 2"Thurs"*. 2:french* Returns the French name, such as 2"Lundi"*, 2"Mardi"*, etc. 2:german* Returns the German name, such as 2"Montag"*, 2"Dienstag"*, etc. 2:italian* Returns the Italian name, such as 2"Lunedi"*, 2"Martedi"*, etc. 3time:month-string* 1month* &optional 1(mode* 1:long)* Returns a string representing the month of the year. As usual, 21* means January, 22* means February, etc. Possible values of 1mode* are: 2:long* Returns the full English name, such as 2"January"*, 2"February"*, etc. This is the default. 2:short* Returns a three-letter abbreviation, such as 2"Jan"*, 2"Feb"*, etc. 2:medium* Returns a longer abbreviation, such as 2"Sept"*, 2"Novem"*, and 2"Decem"*. 2:roman* Returns the Roman numeral for 1month* (this convention is used in Europe). 2:french* Returns the French name, such as 2"Janvier"*, 2"Fevrier"*, etc. 2:german* Returns the German name, such as 2"Januar"*, 2"Februar"*, etc. 2:italian* Returns the Italian name, such as 2"Gennaio"*, 2"Febbraio"*, etc. 3time:timezone-string* &optional 1(timezone* 1time:*timezone*)* 1(daylight-savings-p* 1(time:daylight-savings-p))* Return the three-letter abbreviation for this time zone. For example, if 1timezone* is 25*, then either 2"EST"* (Eastern Standard Time) or 2"CDT"* (Central Daylight Time) is used, depending on 1daylight-savings-p*.