
/* 
 * File: offset.c
 *       Part of the ever expanding tea time library.
 *
 * Decsription: This file contains routines to play with date manipulation.
 *              tt_sec_offset():  offset a date by n seconds
 *              tt_min_offset():  offset a date by n minutes
 *              tt_hour_offset(): offset a date by n hours
 *              tt_day_offset():  offset a date by n days
 *              tt_week_offset(): offset a date by n weeks
 *              tt_tmtoseconds(): convert tm to seconds since 1970
 *
 * Author: Tom Coppeto  11/10/89 
 *
 * $Source: /afs/.net.mit.edu/tools/src/tea/RCS/offset.c,v $
 * $Author: tom $ 
 * $Locker: tom $
 * $Log:	offset.c,v $
 * Revision 2.2  90/07/22  18:54:09  tom
 * fixed bug with ultrix: ftime()'s timezone offset is measured in minutes
 * and the opposite sign that... do they do this to intentionally screw people?
 * 
 * Revision 2.1  90/05/23  13:59:58  tom
 * ulcerix needs types.h
 * 
 * Revision 2.0  90/05/23  13:02:43  tom
 * fixed tt_tmtoseconds to not add an extra day on leap year
 * 
 * Revision 1.4  90/05/21  17:10:55  tom
 * added kludge to tt_tmtoseconds() for ultrix
 * 
 * Revision 1.3  90/04/27  15:16:55  tom
 * initialized year in tt_tmtosecs()
 * 
 * Revision 1.2  90/02/15  19:34:12  tom
 * ifdeffed tz stuff
 * 
 * Revision 1.1  89/11/13  20:50:05  tjcoppet
 * Initial revision
 * 
 * $Header: /afs/.net.mit.edu/tools/src/tea/RCS/offset.c,v 2.2 90/07/22 18:54:09 tom Exp Locker: tom $
 */



#include <teatime.h>
#if defined(ultrix)
#include <sys/types.h>
#include <sys/timeb.h>
#define EPOCH_YEAR 1970
#define TM_YEAR_BASE 1900
#else
#include <tzfile.h>
#endif 

void
tt_sec_offset(tm, ret, offset)
     struct tm *tm, *ret;
     int offset;
{
  long t;
  struct tm *temp;

  t    = tt_tmtoseconds(tm) + offset;
  temp = localtime(&t);
  bcopy(temp, ret, sizeof(struct tm));
}


void 
tt_min_offset(tm,ret,offset) 
     struct tm *tm, *ret;
     int offset;
{
  tt_sec_offset(tm, ret, offset * SECONDS_IN_MINUTE);
}


void
tt_hour_offset(tm,ret,offset) 
     struct tm *tm, *ret;
     int offset;
{
  tt_sec_offset(tm, ret, offset * SECONDS_IN_MINUTE * MINUTES_IN_HOUR);
}


void
tt_day_offset(tm,ret,offset) 
     struct tm *tm, *ret;
     int offset;
{
  tt_sec_offset(tm, ret, offset * SECONDS_IN_MINUTE * MINUTES_IN_HOUR 
	     * HOURS_IN_DAY);
}


void
tt_week_offset(tm,ret,offset) 
     struct tm *tm, *ret;
     int offset;
{
  tt_sec_offset(tm, ret, offset * SECONDS_IN_MINUTE * MINUTES_IN_HOUR 
	     * HOURS_IN_DAY * DAYS_IN_WEEK);
}


long
tt_tmtoseconds(tm)
     struct tm *tm;
{
#if defined(ultrix)
  struct timeb tb;
#endif
  int total = 0;
  int year  = 0;

  if(tm->tm_year != TMNULL)
    year = tm->tm_year;

  year += TM_YEAR_BASE;
  for (--year;year >= EPOCH_YEAR;--year)
    total+= isleap(year) ? 366 : 365;

  total *= SECONDS_IN_DAY;
  
  if(tm->tm_yday != TMNULL)
    total += tm->tm_yday  * SECONDS_IN_DAY;

  if(tm->tm_hour != TMNULL)
    total += tm->tm_hour * SECONDS_IN_MINUTE * MINUTES_IN_HOUR;

  if(tm->tm_min != TMNULL)
    total += tm->tm_min  * SECONDS_IN_MINUTE;

  if(tm->tm_sec != TMNULL)
    total += tm->tm_sec;

#ifndef sgi
  if(tm->tm_gmtoff != TMNULL)
    total -= tm->tm_gmtoff;
#endif

  return(total);
}


