DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T d

⟦f97f6d608⟧ TextFile

    Length: 10983 (0x2ae7)
    Types: TextFile
    Names: »date.c«

Derivation

└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit
    └─⟦653021b30⟧ »EurOpenD3/utils/downtime.tar.Z« 
        └─⟦946c717da⟧ 
            └─⟦this⟧ »date.c« 

TextFile

/* 
 * 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);
}