jww@bonnie.UUCP (Joel West) (05/18/85)
The following shell archive includes all the necessary source to implement a UNIX-like time functionality for the Mac on the Megamax (and presumably other) C compilers. It also includes a bonus -- implementation of a function (comparable to ctime) that uses the Macintosh International Utilities to format the date in a country-specific fashion. I'll be glad to put this in the public domain and let anyone distribute it with any system that doesn't have it (I'm sending a copy back to Megamax). The only condition is that credit (in some form) is given where credit is due. #!/bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #!/bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # README # ctime.3 # time.c # time.h # timedemo.c # This archive created: Sat May 18 16:15:35 1985 export PATH; PATH=/bin:$PATH if test -f 'README' then echo shar: over-writing existing file "'README'" fi sed 's/^XX//' << \SHAR_EOF > 'README' XXUNIX time function emulation utilities for the Macintosh XXJoel West, May 18, 1985 XXihnp4!bonnie!jww, westjw@nosc.ARPA XX XXThe following files are defined: XX time.h: include file for time utilities XX time.c: library source for time utilities XX ctime.3: UNIX-like man(1) page for utitilies XX timedemo.c: demonstration program XX XXThese implement nearly the full suite of standard UNIX time XXutilities: XX time() - return current time in seconds XX ctime() - format time to 26-character string XX localtime() - decompose time into components XX asctime() - format component time to 26-character string XXThese functions are standard on System V, BSD 4.2, and the /usr/group XXcommon UNIX standard (although time() is emulated under BSD 4.2). XXThe UNIX systems also include gmtime(), but this doesn't make XXsense on a Mac, which doesn't know anything about time zones or XXgreenwich mean time. XX XXIn addition, the function XX iutime() - international-format time XXis similar to ctime (without the seconds), but uses the Macintosh XXInternational Utilities to produce a country-specific output. In XXthe US, this results in a 26 to 28-character string of the form: XX Sun, Sep 16, 1973, 1:03 AM\n\0 SHAR_EOF if test -f 'ctime.3' then echo shar: over-writing existing file "'ctime.3'" fi sed 's/^XX//' << \SHAR_EOF > 'ctime.3' XX XXCTIME(3) CTIME(3) XX XX XXNAME XX time, ctime, localtime, asctime, iutime -- get date and time XX XXSYNOPSIS XX #include <time.h> XX XX long time ( (long *) 0) XX XX long time (tloc) XX long *tloc; XX XX char *ctime (clock) XX long *clock; XX XX struct tm *localtime (clock) XX long *clock; XX XX char *asctime (tm) XX struct tm *tm; XX XX char *iutime (clock) XX long *clock; XX XXDESCRIPTION XX Time returns the value of time in seconds since 00:00:00 local XX time, January 1, 1904. This is the standard internal format for XX time representation on the Macintosh. If the pointer tloc is XX non-null, the return values is also stored at the location pointed to XX by tloc. XX XX Ctime converts a long integer system time (such as returned by XX time), and returns a pointer to a 26-character string in the XX following form. All fields have constant width, and leading zeros XX are always included: XX XX Wed May 15 21:02:21 1985\n\0 XX XX Localtime takes a pointer to a system time as an argument, and XX returns a pointer to a tm structure, described below. Asctime XX converts a tm structure to a 26-character string in the same XX format as ctime, and returns a pointer to the string. XX XX XXCTIME(3) CTIME(3) XX XX XX Declarations of all the functions and the tm structure, are in the XX <time.h> header file. The structure declaration is: XX XX struct tm { XX int tm_sec; /* 0-59 seconds */ XX int tm_min; /* 0-59 minutes */ XX int tm_hour; /* 0-23 hours */ XX int tm_mday; /* 1-31 day */ XX int tm_mon; /* 0-11 month */ XX int tm_year; /* add 1900 */ XX int tm_wday; /* Sunday=0 */ XX int tm_yday; /* day of year 0-365 */ XX int tm_isdst; /* <>0 on daylight */ XX }; XX XX Tm_isdst is non-zero if Daylight Savings Time is in effect. XX XX Iutime is similar to ctime in that it takes a system time as an XX argument and returns a human-readable character string. XX However, the routine uses Apple's international utilities package XX for formatting the date in a country-dependent manner. For the XX U.S., the result would be a string, such as the following: XX XX Wed, May 15, 1985, 9:22 PM\n\0 XX XX In the U.S., leading zeros are not included in either the day or the XX hour, so that the length can vary from 26 to 28 characters. The XX length of the result will be also differ if the country defined for XX your user's system is not the U.S. XX XXAUTHOR XX Joel West (ihnp4!bonnie!jww, westjw@NOSC.ARPA) XX XXSEE ALSO XX "Macintosh Packages: A Programmer's Guide" XX "The Operating System Utilities: A Programmer's Guide" XX (both contained in Inside Macintosh) XX XX XXCTIME(3) CTIME(3) XX XX XXNOTES XX The definition of system time differs by exactly 66 years from XX that found in UNIX systems, which base their calculations on the XX year 1970. The symbolic constant TIMEDIFF, defined in the XX <time.h> header file, gives the exact number of seconds that must XX be subtracted from a Macintosh system time to convert to a UNIX XX system time: XX XX #define TIMEDIFF 0x7c25b080 XX XX The return values point to static data whose content is XX overwritten by each call, and thus are probably not suitable for XX use in desk accessories. XX XX Although the Mac knows what country it's in, it has no standard XX way of indicating its current time zone, and so cannot make XX automatic time zone conversions for travel or the changes in XX daylight savings time. XX XX The algorithm for Daylight Savings Time understands changes on XX the last Sundays in April and October, but does not allow for XX one-time aberrations (1974), peculiar state customs, or the XX various observations of the practice outside North America. The XX indicator is also inaccurate for the first two hours of the XX changeover date, but this error only occurs in 0.046% of the cases. XX XX The routine time returns the value of the Macintosh system XX variable Time, so name confusion is possible. XX XX XX XX XX SHAR_EOF if test -f 'time.c' then echo shar: over-writing existing file "'time.c'" fi sed 's/^XX//' << \SHAR_EOF > 'time.c' XX/* time.c: XX time, ctime, localtime, asctime, iutime XX UNIX-like time functions XX see also <time.h> XX XX These procedures provide functionality similar to that on XX UNIX systems. On UNIX systems, include the line XX #define iutime(longptr) ctime(longptr) XX for a roughly comparable result XX XX (c) 1985 Joel West -- May 16, 1985 XX ihnp4!bonnie!jww, westjw@NOSC.ARPA XX Unlimited license granted if this notice retained in all source copies XX*/ XX XX#include <os.h> XX#include <pack.h> XX#include <time.h> XX XX/* long time(&long) XX returns Macintosh system time as seconds since 1/1/1904 XX returns value as a function and, optionally, to the specified loc XX XX UNIX uses exactly a 66-year-later starting point. However, since XX this time is most likely going to be passed to ctime() or localtime(), XX or used to calculate a period (difference in times), this distinction XX isn't likely to matter much. It does mean code that uses these XX functions will move transparently unless it uses absolute XX calculations (if so, use TIMEDIFF to convert) XX*/ XX XXlong time(ptr) XXlong *ptr; XX{ long secs; XX XX if (ptr==0) XX ptr = &secs; XX XX GetDateTime(ptr); XX return (*ptr); XX} XX XX/* char *asctime(&tm) XX Takes a pointer to a user <tm> structure and returns a 26-character XX string of the form: XX "Sun Sep 16 01:03:52 1973\n\0" XX*/ XX#define DIG(num) ('0' + (char)(num)) XX#define cvt2(buff, int) \ XX (ptr = &buff, num=int, *ptr++ = DIG(num/10), *ptr = DIG(num%10)) XX XXchar *asctime(utm) XXstruct tm *utm; XX{ static char *monstr = "JanFebMarAprMayJunJulAugSepOctNovDec"; XX static char *daystr = "SunMonTueWedThuFriSat"; XX static char *patstr = "Tue Jan 24 03:55:50 1984\n\0"; XX static char timstr[26]; XX register int num; XX register char *ptr; XX XX strcpy(timstr, patstr); /* set delimiters */ XX strncpy(&timstr[0], &daystr[3*(utm->tm_wday)], 3); XX strncpy(&timstr[4], &monstr[3*(utm->tm_mon)], 3); XX cvt2(timstr[8], utm->tm_mday); XX cvt2(timstr[11], utm->tm_hour); XX cvt2(timstr[14], utm->tm_min); XX cvt2(timstr[17], utm->tm_sec); XX XX num = utm->tm_year+1900; XX for (ptr=&timstr[23]; num; num=num/10) XX *ptr-- = DIG(num%10); XX XX return (timstr); XX} XX XX/* char *ctime(&long) XX Takes a time in seconds (such as returned by time()) and formats XX it into a 26-character static string. See time(), asctime() XX*/ XXchar *ctime(longptr) XXlong *longptr; XX{ XX return (asctime(localtime(longptr))); XX} XX XX XX/* struct tm *localtime(&long) XX Takes a Macintosh system time as an argument XX XX Builds a structure with everything you need to know XX (But handles only normal daylight time in most of the US) XX*/ XXstruct tm *localtime(longptr) XXlong *longptr; XX{ static struct tm stm; /* UNIX struct in memory */ XX DateTimeRec mactm; /* Mac struct on stack */ XX static int mlen[12] = {31,28,31,30,31,30,31,31,30,31,30,31}; XX register int i,yday; XX int leap; XX XX Secs2Date(*longptr, &mactm); XX XX stm.tm_sec = mactm.second; XX stm.tm_min = mactm.minute; XX stm.tm_hour = mactm.hour; XX stm.tm_mday = mactm.day; XX stm.tm_mon = mactm.month-1; XX stm.tm_year = mactm.year-1900; XX stm.tm_wday = mactm.dayOfWeek-1; XX XX leap = 0; XX yday = stm.tm_mday-1; /* remember, 1/1 is day #0 */ XX XX for (i=stm.tm_mon; (--i)>=0; yday += mlen[i]) XX { if (i==1 && (stm.tm_year%4 == 0)) XX leap++; /* leap year rule 1901-2099 */ XX }; XX stm.tm_yday = yday+leap; /* no effect on DST */ XX XX/* Daylight Savings Time: works in most of US under 1985 rules XX Ignores period of 12am-2am on changeover date XX*/ XX stm.tm_isdst = 0; XX yday -= stm.tm_wy < 297 ) XX/* April 24 Oct 25 */ XX stm.tm_isdst++; XX XX return (&stm); XX} XX XX XX/* char *iutime(&long) XX Choose date and time (without seconds) XX XX Somewhat like ctime(), but will produce a result compatible XX with the user's native date format. XX In the US, produces a 26 to 28-character string of the form: XX "Tue, Jan 24, 1985 3:55 AM\n\0" XX Will have different lengths (and orders) in different countries XX*/ XXchar *iutime(secsptr) XXlong *secsptr; XX{ register char *p; XX static char time_buff[64]; /* very verbose languages */ XX XX p = &time_buff[0]; XX IUDateString(*secsptr, abbrevDate, p); /* add date */ XX p += strlen(p); XX *p++ = ' '; /* leave a blank */ XX IUTimeString(*secsptr, 0, p); /* no seconds */ XX p += strlen(p); XX *p++ = '\n'; /* add a newline */ XX *p = '\0'; XX return (time_buff); XX} XX SHAR_EOF if test -f 'time.h' then echo shar: over-writing existing file "'time.h'" fi sed 's/^XX//' << \SHAR_EOF > 'time.h' XX/* time.h XX Joel West, ihnp4!bonnie!jww, May 18, 1985 XX*/ XX XX/* Time of UNIX base time (1/1/1970) in Macintosh units */ XX#define TIMEDIFF 0x7c25b080 XX XX XXlong time(); /* binary time (Mac-style) */ XXchar *asctime(); /* string from structure */ XXchar *ctime(); /* string from time */ XXchar *iutime(); /* like ctime, int'l, no seconds */ XX XXstruct tm { XX int tm_sec; /* 0-59 */ XX int tm_min; /* 0-59 */ XX int tm_hour; /* 0-23 */ XX int tm_mday; /* 1-31 */ XX int tm_mon; /* 0-11 */ XX int tm_year; /* add 1900 */ XX int tm_wday; /* Sunday=0 */ XX int tm_yday; /* 0-365 */ XX int tm_isdst; /* <>0 on daylight */ XX }; XX XXstruct tm *localtime(); /* structure from time */ SHAR_EOF if test -f 'timedemo.c' then echo shar: over-writing existing file "'timedemo.c'" fi sed 's/^XX//' << \SHAR_EOF > 'timedemo.c' XX/* timedemo.c = demonstrate XX time() - binary time value XX localtime() - return decoded time structure XX ctime() - formatted string from binary value XX iutime() - almost like ctime(), but in Mac "international" format XX*/ XX XX XX/* change the following for your location */ XX#define STDTIME "PST" XX#define DSTTIME "PDT" XX XX#include <stdio.h> XX#include <time.h> XXchar *tzname[2]; /* declare here for all to use */ XX XXmain() XX{ long tim; XX int dstflag; XX XX tzname[0] = STDTIME; XX tzname[1] = DSTTIME; XX XX tim = time(0); XX dstflag = ((localtime(&tim))->tm_isdst) ? 1 : 0; XX printf ("In the %3s time zone,\n\0", tzname[dstflag]); XX printf (" UNIX thinks it's %s", ctime(&tim)); XX printf (" ...while a US Mac calls it %s", iutime(&tim)); XX XX while (getchar() != '\n') XX ; /* just wait */ XX} XX SHAR_EOF # End of shell archive exit 0 -- Joel West (619) 457-9681 CACI, Inc. - Federal 3344 N. Torrey Pines Ct La Jolla 92037 jww@bonnie.UUCP (ihnp4!bonnie!jww) westjw@nosc.ARPA "The best is the enemy of the good" - A. Mullarney
jww@bonnie.UUCP (Joel West) (05/28/85)
A while back, I posted source for a mac-supported time(2), ctime(3), asctime(3), etc. There was one small bug. In a few days, asctime (and ctime) will say Sat Jun 01 01:23 1985 where the standard UNIX ctime says Sat Jun 1 01:23 1985 The patch below (note the "YY" instead of "XX") is a bit kludgey but does the job. Incidentally, this should answer the question of the obnoxious AT&T type who threatened to send the corporate lawyers after me for publishing UNIX source. I mean, geez, if I were going to steal code, at least I'd be able to type it in right! In case I wasn't clear enough before, I have never seen any UNIX source for these, the only thing they have in common with the UNIX version is the documentation, and I do not warrantee their use on a 3B20. :-) XXchar *asctime(utm) XXstruct tm *utm; XX{ static char *monstr = "JanFebMarAprMayJunJulAugSepOctNovDec"; XX static char *daystr = "SunMonTueWedThuFriSat"; XX static char *patstr = "Tue Jan 24 03:55:50 1984\n\0"; XX static char timstr[26]; XX register int num; XX register char *ptr; XX XX strcpy(timstr, patstr); /* set delimiters */ XX strncpy(&timstr[0], &daystr[3*(utm->tm_wday)], 3); XX strncpy(&timstr[4], &monstr[3*(utm->tm_mon)], 3); XX cvt2(timstr[8], utm->tm_mday); YY if (timstr[8] == '0') YY timstr[8] = ' '; XX cvt2(timstr[11], utm->tm_hour); XX cvt2(timstr[14], utm->tm_min); XX cvt2(timstr[17], utm->tm_sec); -- Joel West (619) 457-9681 CACI, Inc. - Federal 3344 N. Torrey Pines Ct La Jolla 92037 jww@bonnie.UUCP (ihnp4!bonnie!jww) westjw@nosc.ARPA And ye can tell the sheep from the men from their frequent use of (tm)....