|
|
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: 10983 (0x2ae7)
Types: TextFile
Names: »date.c«
└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit
└─⟦653021b30⟧ »EurOpenD3/utils/downtime.tar.Z«
└─⟦946c717da⟧
└─⟦this⟧ »date.c«
/*
* Copyright (c) 1988 Michael A. Cooper, University of Southern California.
* This program may be used, copied, modified, and redistributed freely
* for noncommercial purposes, so long as this notice remains intact.
*/
#ifndef lint
static char *RCSid = "$Header: date.c,v 4.5 88/07/05 15:58:58 mcooper Exp $";
#endif
/*
*------------------------------------------------------------------
*
* $Source: /usr/skat3/src/common/usc/etc/downtime/RCS/date.c,v $
* $Revision: 4.5 $
* $Date: 88/07/05 15:58:58 $
* $State: Exp $
*
*------------------------------------------------------------------
*
* Michael A. Cooper
* Research and Development Group
* University Computing Services
* University of Southern California
* (mcooper@oberon.USC.EDU)
*
*------------------------------------------------------------------
*
* $Log: date.c,v $
* Revision 4.5 88/07/05 15:58:58 mcooper
* Added copyright notice.
*
* Revision 4.4 88/05/24 14:28:10 mcooper
* More changes for buffers in timeleft()
* for stupid VAXen.
*
* Revision 4.3 88/05/24 14:04:09 mcooper
* Rearranged buffers in timeleft()
* to make VAXen happy.
*
* Revision 4.2 88/05/24 13:26:38 mcooper
* Another general cleanup sweep.
*
* Revision 4.1 88/05/23 15:40:22 mcooper
* All tm tm_mon members are now 0-11
* instead of 1-12 for compat. with
* the normal BSD time routines.
*
* Revision 4.0 88/04/20 15:41:55 mcooper
* Version 4.
*
* Revision 3.8 88/04/19 18:27:33 mcooper
* Major cleanup.
*
* Revision 3.7 88/04/11 19:48:04 mcooper
* Converted all dt_flags to use flag
* bits.
*
* Revision 3.6 88/03/02 16:10:08 mcooper
* Cleanup time.
*
* Revision 3.5 88/03/01 12:39:39 mcooper
* Fixed another ttol() bug. This
* one caused the month of feb
* to grow by one day during a
* leap year, each time a call was
* made to ttol().
*
* Revision 3.4 88/02/29 13:24:23 mcooper
* Fixed yeap year bug.
*
* Revision 3.3 88/02/04 15:44:05 mcooper
* Fixed bug in ttol(). Should not count this
* year as a leap year.
*
* Revision 3.2 87/12/16 14:27:25 mcooper
* Fixed bug in mkdate() that caused
* the same pointer to get returned.
*
* Revision 3.1 87/12/11 18:12:35 mcooper
* Added D_MOTD for /etc/motd style date.
*
* Revision 3.0 87/07/24 14:15:55 mcooper
* Version 3.
*
*------------------------------------------------------------------
*/
#include <stdio.h>
#include "defs.h"
/*
* date.c - Date functions
*/
char *days[] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
"Friday", "Saturday", NULL };
char *months[] = { "January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November",
"December", NULL };
int mon[] = {
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
char buf[BUFSIZ];
#define is_bad(x) ((x < 0) || (x > 10000))
/*
* mkdate - Return date in form:
*
* Tuesday July 2, 1986 at 11:04 - D_VERBOSE
* Jul 2, 11:04 - D_SHORTSHUT
* Tue Jul 2 11:04:10 1986 - D_DATE
* 11:04 Tue Jul 2, 1986 - D_LOGFILE
* Jul 2: - D_MOTD
* 11:04 - D_TIME
*/
char *
mkdate(t, do_format)
struct tm *t;
int do_format;
{
int d;
if (!t) {
return(NULL);
}
if (is_bad(t->tm_mday) || is_bad(t->tm_year) || is_bad(t->tm_mon) ||
is_bad(t->tm_hour) || is_bad(t->tm_min)) {
return(NULL);
}
if ((d = dow(t)) < 0) {
return(NULL);
}
switch (do_format) {
case D_VERBOSE:
sprintf(buf, "%s %s %d, %d at %2.2d:%2.2d",
days[d - 1],
months[t->tm_mon],
t->tm_mday,
(((t->tm_year - 1900) < 0) ? 1900 + t->tm_year : t->tm_year),
t->tm_hour,
t->tm_min
);
break;
case D_LOGFILE:
sprintf(buf, "%2.2d:%2.2d %3.3s %3.3s %2d, %4.4d",
t->tm_hour,
t->tm_min,
days[d - 1],
months[t->tm_mon],
t->tm_mday,
(((t->tm_year - 1900) < 0) ? 1900 + t->tm_year : t->tm_year)
);
break;
case D_SHORTSHUT:
sprintf(buf, "%3.3s %d %2.2d:%2.2d",
months[t->tm_mon],
t->tm_mday,
t->tm_hour,
t->tm_min
);
break;
case D_TIME:
sprintf(buf, "%2.2d:%2.2d",
t->tm_hour,
t->tm_min
);
break;
case D_CCMD:
sprintf(buf, "%s-%s-%d-%d-at-%d%2.2d",
days[d - 1],
months[t->tm_mon],
t->tm_mday,
(((t->tm_year - 1900) < 0) ? 1900 + t->tm_year : t->tm_year),
t->tm_hour,
t->tm_min
);
break;
case D_MOTD:
sprintf(buf, "%3.3s %2d",
months[t->tm_mon],
t->tm_mday
);
break;
default:
sprintf(buf, "%3.3s %3.3s %2d %2d:%2.2d:%2.2d %4.4d",
days[d - 1],
months[t->tm_mon],
t->tm_mday,
t->tm_hour,
t->tm_min,
t->tm_sec,
(((t->tm_year - 1900) < 0) ? 1900 + t->tm_year : t->tm_year)
);
}
return(newstr(buf));
}
/*
* ttod - Time To Date: Return ascii date string in form:
*
* MM/DD/YY-HH:MM
*/
char *
ttod(t)
struct tm *t;
{
if (!t) {
return(NULL);
}
sprintf(buf, "%2.2d/%2.2d/%2.2d-%2.2d:%2.2d",
t->tm_mon + 1,
t->tm_mday,
((t->tm_year > 1900) ? (t->tm_year - 1900) : t->tm_year),
t->tm_hour,
t->tm_min);
return(newstr(buf));
}
/*
* dtot - Date to Time: Return a time structure from
* a date string of form:
*
* MM/DD/YY-HH:MM
*/
struct tm *
dtot(str)
char *str;
{
struct tm *t;
if (!str) {
return(NULL);
}
t = (struct tm *) xmalloc(sizeof(struct tm));
t->tm_mon = 0;
t->tm_mday = 0;
t->tm_year = 0;
t->tm_hour = 0;
t->tm_min = 0;
t->tm_sec = 0;
t->tm_wday = 0;
t->tm_yday = 0;
t->tm_isdst = 0;
sscanf(str, "%d/%d/%d-%d:%d",
&t->tm_mon,
&t->tm_mday,
&t->tm_year,
&t->tm_hour,
&t->tm_min);
t->tm_mon -= 1;
return(t);
}
#define BASEYEAR 1970
#define BASELEAP 1972
/*
* ttol() - Given a "tm" time structure, ttol() will return
* the number of seconds since 00:00:00, Jan. 1, 1970
* in LOCAL (not GMT) time.
*/
long
ttol(t)
struct tm *t;
{
long secs;
int year, days_so_far;
register int x;
struct timeval tp;
struct timezone tzp;
static int first = TRUE;
secs = 0;
if (!t) {
return(-1);
}
if (t->tm_year > 0 && t->tm_year < 100)
year = t->tm_year + 1900;
else
year = t->tm_year;
if (year > BASEYEAR) {
secs += ((year - BASEYEAR) * 365 DAYS);
if (year > BASELEAP) {
secs += (((year - 1 - BASELEAP)/4) DAYS);
}
}
/*
* if this is a leap year, then add a day
* to feb.
*/
days_so_far = 0;
if (first) {
x = (year - BASELEAP) / 4;
if ((x % 4) == 0)
mon[1] = 29; /* 29 days in leap years in feb */
first = FALSE;
}
for (x = 0; x < t->tm_mon; x++)
days_so_far += mon[x];
days_so_far += t->tm_mday;
secs += (days_so_far DAYS);
secs += (t->tm_hour HOURS);
secs += (t->tm_min MINUTES);
secs += (t->tm_sec SECONDS);
if (gettimeofday(&tp, &tzp) < 0) {
perror("gettimeofday");
return(-1);
}
secs += tzp.tz_minuteswest * 60;
if (t->tm_isdst) {
dprintf("ttol: is DST\n");
secs -= (1 HOUR);
}
return(secs);
}
/*
* dow() returns the day of the week given
* the month, day of month, and year.
*
* RETURN VALUE: 1-7 indicating day of week.
* Returns -1 on error.
*/
dow(t)
struct tm *t;
{
int d, month, days_so_far, wday, today, year;
register int i = 0;
int jan1();
month = t->tm_mon;
today = t->tm_mday;
year = t->tm_year;
if (year < 100 && year > 0)
year += 1900;
d = jan1(year);
/*
* Is this a leap year?
*/
if ((year - 1900) % 4 == 0)
mon[1] = 29;
if (month < 0 || month > 12) {
fprintf(stderr, "dow(): received bad month %d.\n", month);
return(-1);
}
days_so_far = 0;
for (i = 0; i < month; i++) {
days_so_far += mon[i];
}
days_so_far += today;
wday = (days_so_far % 7) + d;
if (wday > 7)
wday -= 7;
return(wday);
}
/*
* return day of the week
* of jan 1 of given year
*/
jan1(yr)
{
register y, d;
/*
* normal gregorian calendar
* one extra day per four years
*/
y = yr;
d = 4+y+(y+3)/4;
/*
* julian calendar
* regular gregorian
* less three days per 400
*/
if (y > 1800) {
d -= (y-1701)/100;
d += (y-1601)/400;
}
/*
* great calendar changeover instant
*/
if (y > 1752)
d += 3;
return(d%7);
}
/*
* timeleft - Given an integer for the number of seconds left
* till the downtime, make a human readable string.
*/
char *
timeleft(secs)
int secs;
{
char buf2[BUFSIZ];
int m;
if (debug)
printf("timeleft %d secs\n", secs);
strcpy(buf, "");
strcpy(buf2, "");
if (secs <= 1) {
sprintf(buf, NOW);
} else if (secs < (1 HOUR)) { /* minutes and seconds */
if (secs >= (1 MINUTE)) {
sprintf(buf, "%d minute%s",
secs / (1 MINUTE),
(secs / (1 MINUTE) == 1) ? "" : "s");
}
if (secs % (1 MINUTE) && secs <= (6 MINUTES)) {
sprintf(buf2, "%s%d second%s",
(secs >= (1 MINUTE)) ? " " : "",
secs % (1 MINUTE),
(secs % (1 MINUTE) == 1) ? "" : "s");
strcat(buf, buf2);
}
} else if (secs >= (1 DAY)) { /* days and hours */
m = (secs % (1 DAY) / (1 HOUR));
if (m > 0) {
sprintf(buf, "%d day%s %d hour%s",
secs / (1 DAY),
(secs / (1 DAY) == 1) ? "" : "s",
m,
(m == 1) ? "" : "s");
} else {
sprintf(buf, "%d day%s",
secs / (1 DAY),
(secs / (1 DAY) == 1) ? "" : "s");
}
} else { /* hours and minutes */
m = (secs % (1 HOUR)) / (1 MINUTE);
if (m > 0) {
sprintf(buf, "%d hour%s %d minute%s",
secs / (1 HOUR),
(secs / (1 HOUR) == 1) ? "" : "s",
m,
(m == 1) ? "" : "s");
} else {
sprintf(buf, "%d hour%s",
secs / (1 HOUR),
(secs / (1 HOUR) == 1) ? "" : "s");
}
}
return(newstr(buf));
}
/*
* getdelta - Return the number of seconds between now and then.
*/
getdelta(now, then)
struct tm *then, *now;
{
int tim;
long t, n;
/*
* check to see if DST is set in either
* "now" or "then". If it's only set
* in one structure, we assume it is
* suppose to be set in the other.
*/
if (now->tm_isdst && !then->tm_isdst)
then->tm_isdst = 1;
else if (then->tm_isdst && !now->tm_isdst)
now->tm_isdst = 1;
t = ttol(then);
n = ttol(now);
tim = t - n;
return(tim);
}
/*
* getplus - Given num minutes, return a time structure, num minutes away.
*/
struct tm *
getplus(num)
int num;
{
long mynowl, nowl;
time(&nowl);
mynowl = nowl + ((long) num MINUTES);
return(localtime(&mynowl));
}
/*
* dom - Days in Month "m".
*/
dom(m)
int m;
{
extern int mon[];
register int x;
for (x = 0; x != 12; x++) {
if (x == m)
return(mon[x]);
}
return(0);
}