ack/lang/cem/libcc.ansi/time/misc.c
1989-06-12 15:22:14 +00:00

143 lines
2.8 KiB
C

/*
* misc - data and miscellaneous routines
*/
/* $Header$ */
#include <time.h>
#include <stdlib.h>
#include <string.h>
#ifdef __BSD4_2
#include <sys/time.h>
#elif !defined(__USG)
struct timeb
{
timez_t time;
unsigned short millitm;
short timezone;
short dstflag;
};
#endif
#include "loc_incl.h"
#ifdef __USG
long timezone = -1 * 60;
int daylight = 1;
char *tzname[] = {"MET", "MDT",};
#endif
long __timezone = -1 * 60;
static int __daylight = 1;
char *__tzname[] = {"MET", "MDT",};
const char *_days[] = {
"Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"
};
const char *_months[] = {
"January", "February", "March",
"April", "May", "June",
"July", "August", "September",
"October", "November", "December"
};
const int _ytab[2][12] = {
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
};
int
_leap(int year)
{
return (!(year % 4) && ((year % 100) || !(year % 400)));
}
long
_tzone(void)
{
register char *p = getenv("TZ");
register int n = 0;
int sign = 1;
#ifdef __BSD4_2
struct timeval tv;
struct timezone tz;
gettimeofday(&tv, &tz);
__daylight = tz.tz_dsttime;
__timezone = tz.tz_minuteswest * 60;
#elif !defined(__USG)
struct timeb time;
ftime(&time);
__timezone = time.timezone * 60L;
__daylight = time.dstflag;
#endif
if (p && *p) {
strncpy(__tzname[0], p, 3);
p += 3;
if (*p == '-') {
sign = -1;
p++;
}
while (*p >= '0' && *p <= '9')
n = 10 * n + (*p++ - '0');
n *= sign;
__timezone = ((long)(n * 60)) * 60;
__daylight = (*p != '\0');
strncpy(__tzname[1], p, 3);
}
#ifdef __USG
timezone = __timezone;
daylight = __daylight;
tzname[0] = __tzname[0];
tzname[1] = __tzname[1];
#endif
return __timezone;
}
static int
last_sunday(register int day, register struct tm *timep)
{
int first = FIRSTSUNDAY(timep);
if (day >= 58 && LEAPYEAR(1900 + timep->tm_year)) day++;
if (day < first) return first;
return day - (day - first) % 7;
}
unsigned
_dstget(struct tm *timep)
{
int begindst, enddst;
if(__daylight == -1)
_tzone();
timep->tm_isdst = __daylight;
if (!__daylight) return 0;
begindst = last_sunday(89, timep); /* last Sun before Apr */
enddst = last_sunday(272, timep); /* last Sun in Sep */
/* The rules for daylight saving time differ for different coutries.
* Implemented here are heuristics that got it right in Holland for
* the last couple of years. There is, of course, no universal
* algorithm. Only tables would work perfect.
*/
if ( (timep->tm_yday>begindst
|| (timep->tm_yday == begindst && timep->tm_hour >= 2))
&& (timep->tm_yday<enddst
|| (timep->tm_yday == enddst && timep->tm_hour < 3))) {
/* it all happens between 2 and 3 */
return 60*60;
}
timep->tm_isdst = 0;
return 0;
}