|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T d
Length: 8068 (0x1f84) Types: TextFile Names: »date.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki └─⟦this⟧ »EUUGD11/euug-87hel/sec8/mcp/src/date.c«
#include <sys/types.h> #include <sys/time.h> #include <setjmp.h> #include <signal.h> #include <strings.h> #include "macros.h" #include "mem.h" #define DOOMYEAR 2010 #define STONEAGES 1975 #define DAY (4*21600) #define ISLEAPYEAR(y) (((y)%4==0) && (((y)%100!=0) || ((y)%400==0))) char *sprintf(), GET(); #ifdef sun #define sighandler (void (*)()) #else #define sighandler (int (*)()) #endif extern jmp_buf in_continue; #ifdef sun void tstp_cleanup(), input_continue(); #else int tstp_cleanup(), input_continue(); #endif static char *days[] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; static char *how_many[] = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eigth", "nine", "ten", "eleven", "twelve" }; static char *Months[12] = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; static int DaysInMonths[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; time_t tmtotime_t(); time_t choosedate(starttime) time_t starttime; { struct tm *t, newt; time_t time(); char prompt[MEDIUM_BUF], line[MEDIUM_BUF]; register int indx; int leapday; char c; err("Use SPACE to go forward, ^H or DELETE to go backwards."); err("Hit RETURN to select."); err(""); if (starttime == (time_t) 0) starttime = time((time_t *)0); t = localtime(&starttime); bcopy(&newt, t, sizeof (struct tm)); prompt[0] = '\0'; /* * Choose month */ indx = t->tm_mon; (void) strcpy(line, Months[indx]); cbreak(); (void) signal(SIGTSTP, tstp_cleanup); (void) signal(SIGCONT, input_continue); (void) setjmp(in_continue); redraw(prompt, line); while ((c = GET()) != '\r') { if (setjmp(in_continue) == SIGCONT) { redraw(prompt, line); continue; } switch (c) { case ' ': indx = (indx+1) % 12; (void) sprintf(line, "%-9s", Months[indx]); redraw(prompt, line); break; case '\b': case '\177': if (--indx < 0) indx = 11; (void) sprintf(line, "%-9s", Months[indx]); redraw(prompt, line); break; default: break; } } (void) strcpy(prompt, Months[indx]); (void) strcat(prompt, " "); newt.tm_mon = indx; indx = t->tm_mday; if (indx > DaysInMonths[newt.tm_mon]) indx = DaysInMonths[newt.tm_mon]; (void) sprintf(line, "%2d", indx); (void) setjmp(in_continue); redraw(prompt, line); /* * Choose day of the month. */ while ((c = GET()) != '\r') { if (setjmp(in_continue) == SIGCONT) { redraw(prompt, line); continue; } switch (c) { case ' ': if (++indx > DaysInMonths[newt.tm_mon]) indx = 1; (void) sprintf(line, "%2d", indx); redraw(prompt, line); break; case '\b': case '\177': if (--indx < 1) indx = DaysInMonths[newt.tm_mon]; (void) sprintf(line, "%2d", indx); redraw(prompt, line); break; default: break; } } (void) strcat(prompt, line); (void) strcat(prompt, ", "); newt.tm_mday = indx; leapday = (newt.tm_mon == 1 && newt.tm_mday == 29); indx = t->tm_year + 1900; if (leapday) indx = nextleapyear(indx); (void) sprintf(line, "%4d", indx); /* * Choose year */ (void) setjmp(in_continue); redraw(prompt, line); while ((c = GET()) != '\r') { if (setjmp(in_continue) == SIGCONT) { redraw(prompt, line); continue; } switch (c) { case ' ': if (leapday) indx = nextleapyear(indx); else if (++indx > DOOMYEAR) indx = DOOMYEAR; (void) sprintf(line, "%4d", indx); redraw(prompt, line); break; case '\b': case '\177': if (leapday) indx = lastleapyear(indx); else if (--indx < STONEAGES) indx = STONEAGES; (void) sprintf(line, "%4d", indx); redraw(prompt, line); break; default: break; } } newt.tm_year = indx - 1900; newt.tm_hour = 0; newt.tm_min = 0; newt.tm_sec = 0; (void) signal(SIGCONT, sighandler SIG_DFL); (void) signal(SIGTSTP, sighandler SIG_DFL); nocbreak(); err(""); return tmtotime_t(&newt); } time_t tmtotime_t(t) register struct tm *t; { time_t newtime; struct timezone tz; struct timeval tv; int year, newyear, i; newtime = (t->tm_year - 70) * 365 * DAY; for (i=0; i<t->tm_mon; i++) newtime += (DaysInMonths[i] * DAY); newtime += (t->tm_mday * DAY); newyear = t->tm_year + 1900; year = 1970; for (; year < newyear; year++) if (ISLEAPYEAR(year)) newtime += DAY; if (!ISLEAPYEAR(newyear) && t->tm_mon > 1) newtime -= DAY; /* set for midnight in this timezone and correct for dst shifts */ (void) gettimeofday(&tv, &tz); newtime += tz.tz_minuteswest * 60 - DAY; t = localtime(&newtime); switch (t->tm_hour) { case 23: newtime += 3600; break; case 1: newtime -= 3600; break; default: break; } return newtime; } int nextleapyear(startyear) int startyear; { register int year; year = startyear; while (++year <= DOOMYEAR) { if (ISLEAPYEAR(year)) return year; } return startyear; } int lastleapyear(startyear) int startyear; { register int year; year = startyear; while (--year >= STONEAGES) if (ISLEAPYEAR(year)) return year; return startyear; } char * when(then) time_t then; { static char tstr[LONG_BUF], descbuf[MEDIUM_BUF]; char *cp, *description, *ampm; struct tm *tt, tn, *localtime(); time_t time(), now, tilthen, indx, remainder; now = time((time_t *)0); tt = localtime(&now); bcopy(&tn, tt, sizeof (struct tm)); tt = localtime(&then); tilthen = then - now; if (then == 0) return "never"; if (tilthen >= 365 * DAY) description = "sometime in the distant future"; else if (tilthen >= 30 * DAY) { indx = tilthen / (30*DAY); remainder = (tilthen - indx * 30 * DAY) / DAY; description = sprintf(descbuf, "%smore than %s month%s hence", (remainder < 5) ? "a little " : "", how_many[indx], S(indx)); } else if (tilthen >= 7 * DAY) { indx = tilthen / (7*DAY); remainder = (tilthen - indx * 7 * DAY) / DAY; description = sprintf(descbuf, "%smore than %s week%s hence", (remainder < 3) ? "a little " : "", how_many[indx], S(indx)); } else if (tilthen > DAY) description = sprintf(descbuf, "this %s", days[tt->tm_wday]); else if (tilthen > -DAY) { if (tn.tm_wday == tt->tm_wday) if (tt->tm_hour < 7) description = "early this morning"; else if (tt->tm_hour < 12) description = "this morning"; else if (tt->tm_hour < 17) description = "this afternoon"; else if (tt->tm_hour < 22) description = "tonight"; else description = "late tonight"; else if (tilthen > 0) if (tt->tm_hour < 7) description = "early tomorrow morning"; else if (tt->tm_hour < 12) description = "tomorrow morning"; else if (tt->tm_hour < 17) description = "tomorrow afternoon"; else if (tt->tm_hour < 22) description = "tomorrow night"; else description = "late tomorrow night"; else if (tt->tm_hour < 7) description = "early yesterday morning"; else if (tt->tm_hour < 12) description = "yesterday morning"; else if (tt->tm_hour < 17) description = "yesterday afternoon"; else if (tt->tm_hour < 22) description = "last night"; else description = "late last night"; } else if (tilthen > -7 * DAY) { description = sprintf(descbuf, "last %s", days[tt->tm_wday]); } else if (tilthen > -30 * DAY) { indx = -tilthen / (7*DAY); remainder = (-tilthen % (7*DAY)) / DAY; description = sprintf(descbuf, "%sover %s week%s ago", remainder < 3 ? "a little " : "", how_many[indx], S(indx)); } else if (tilthen > -365 * DAY) { indx = -tilthen / (30*DAY); description = sprintf(descbuf, "over %s month%s ago", how_many[indx], S(indx)); } else description = "sometime during the Triassic..."; #ifdef sun cp = ctime((long *)&then); #else cp = ctime(&then); #endif ampm = (tt->tm_hour < 12) ? "am" : "pm"; if (tt->tm_hour > 12) tt->tm_hour -= 12; else if (tt->tm_hour == 0) tt->tm_hour = 12; (void) sprintf(tstr, "%d:%02d%s %.3s. %d, %.4s (%s)", tt->tm_hour, tt->tm_min, ampm, cp+4, tt->tm_mday, cp+20, description); return tstr; }