|
|
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;
}