time.h
#inclde <time.h>
/*H*******************************************************
  time.h - low level time and date functions
********************************************************/

/********************************************************
  July 3 2011 - fixed elapsedSecsThisWeek macro (thanks Vincent Valdy for this)
              - fixed  daysToTime_t macro (thanks maniacbug)
********************************************************/     

/*H********************************************************************
*
**********************************************************************/
#ifndef _Time_h
#define _Time_h
#include <inttypes.h>

typedef unsigned long time_t;

typedef enum {timeNotSet, timeNeedsSync, timeSet }timeStatus_t;

typedef enum {
	dowInvalid, 
	dowSunday, 
	dowMonday, 
	dowTuesday, 
	dowWednesday, 
	dowThursday,
	dowFriday, 
	dowSaturday 
	}timeDayOfWeek_t;

typedef enum {
    tmSecond, tmMinute, tmHour, tmWday, tmDay,tmMonth, tmYear, tmNbrFields
}tmByteFields;	   

typedef struct  { 
  uint8_t Second; 
  uint8_t Minute; 
  uint8_t Hour; 
  uint8_t Wday;   // DAY OF WEEK, SUNDAY IS DAY 1
  uint8_t Day;
  uint8_t Month; 
  uint8_t Year;   // OFFSET FROM 1970; 
}tmElements_t, TimeElements, *tmElementsPtr_t;

                       // CONVENIENCE MACROS TO CONVERT TO AND FROM TM YEARS 
#define  tmYearToCalendar(Y) ((Y) + 1970)            // FULL FOUR DIGIT YEAR
#define  CalendarYrToTm(Y)   ((Y) - 1970)
#define  tmYearToY2k(Y)      ((Y) - 30)               // OFFSET IS FROM 2000
#define  y2kYearToTm(Y)      ((Y) + 30)   

typedef time_t(*getExternalTime)();
//typedef void  ( *setExternalTime)(const time_t);// NOT USED IN THIS VERSION

/*====================================================================*/
/* Useful Constants */
#define SECS_PER_MIN  (60UL)
#define SECS_PER_HOUR (3600UL)
#define SECS_PER_DAY  (SECS_PER_HOUR * 24UL)
#define DAYS_PER_WEEK (7UL)
#define SECS_PER_WEEK (SECS_PER_DAY * DAYS_PER_WEEK)
#define SECS_PER_YEAR (SECS_PER_WEEK * 52UL)
#define SECS_YR_2000  (946684800UL) // time at start of y2k
 
/* Useful Macros for getting elapsed time */
#define numberOfSeconds(_time_) (_time_ % SECS_PER_MIN)  
#define numberOfMinutes(_time_) ((_time_ / SECS_PER_MIN) % SECS_PER_MIN) 
#define numberOfHours(_time_) (( _time_% SECS_PER_DAY) / SECS_PER_HOUR)
#define dayOfWeek(_time_)  ((( _time_ / SECS_PER_DAY + 4)  % DAYS_PER_WEEK)+1) // 1 = Sunday
#define elapsedDays(_time_) ( _time_ / SECS_PER_DAY)  // this is number of days since Jan 1 1970
#define elapsedSecsToday(_time_)  (_time_ % SECS_PER_DAY)   // number of seconds since last midnight 
// The following macros are used in calculating alarms and assume clock is set to a date later than Jan 1 1971
// Always set correct time before settting alarms
#define previousMidnight(_time_) (( _time_ / SECS_PER_DAY) * SECS_PER_DAY)  // time at start of given day
#define nextMidnight(_time_) ( previousMidnight(_time_)  + SECS_PER_DAY )   // time at end of given day 
#define elapsedSecsThisWeek(_time_)  (elapsedSecsToday(_time_) +  ((dayOfWeek(_time_)-1) * SECS_PER_DAY) )   // note that week starts on day 1
#define previousSunday(_time_)  (_time_ - elapsedSecsThisWeek(_time_))      // time at start of week for given time
#define nextSunday(_time_) ( previousSunday(_time_)+SECS_PER_WEEK)          // time at end of week for given time


/* Useful Macros for converting elapsed time to a time_t */
#define minutesToTime_t ((M)) ( (M) * SECS_PER_MIN)  
#define hoursToTime_t   ((H)) ( (H) * SECS_PER_HOUR)  
#define daysToTime_t    ((D)) ( (D) * SECS_PER_DAY) // fixed on Jul 22 2011
#define weeksToTime_t   ((W)) ( (W) * SECS_PER_WEEK)   

/*==================================================================*/
/*  time and date functions   */
int     hour();            // HOUR NOW 
int     hour(time_t t);    // HOUR FOR GIVEN TIME
int     hourFormat12();    // HOUR NOW IN 12 HOUR FORMAT
int     hourFormat12(time_t t); // HOUR FOR GIVEN TIME IN 12 HOUR FORMAT
uint8_t isAM();            // RETURNS TRUE IF TIME NOW IS AM
uint8_t isAM(time_t t);    // RETURNS TRUE GIVEN TIME IS AM
uint8_t isPM();            // RETURNS TRUE IF TIME NOW IS PM
uint8_t isPM(time_t t);    // RETURNS TRUE GIVEN TIME IS PM
int     minute();          // THE MINUTE NOW 
int     minute(time_t t);  // MINUTE FOR GIVEN TIME
int     second();          // SECOND NOW
int     second(time_t t);  // SECOND FOR GIVEN TIME
int     day();             // DAY NOW
int     day(time_t t);     // DAY FOR GIVEN TIME
int     weekday();         // WEEKDAY NOW (Sunday IS DAY 1) 
int     weekday(time_t t); // WEEKDAY FOR GIVEN TIME 
int     month();           // MONTH NOW  (Jan IS MONTH 1)
int     month(time_t t);   // MONTH FOR GIVEN TIME
int     year();            // FULL FOUR DIGIT YEAR: (2009, 2010 etc) 
int     year(time_t t);    // YEAR FOR GIVEN TIME

time_t now();              // RETURN CURRENT TIME AS SECONDS SINCE jAN 1 1970 
void    setTime( time_t t );
void    setTime( int hr,int min,int sec,int day, int month, int yr );
void    adjustTime( long adjustment );

/* date strings */ 
#define dt_MAX_STRING_LEN 9      // LONGEST DATE STRING LEN (EXCLUDING NULL)
char* monthStr( uint8_t month );
char* dayStr( uint8_t day );
char* monthShortStr( uint8_t month );
char* dayShortStr( uint8_t day );
	
// TIME SYNC FUNCTIONS
timeStatus_t timeStatus(); // INDICATES IF TIME IS SET AND RECENTLY SYNCHED
void    setSyncProvider( getExternalTime getTimeFunction); // IDENTIFY EXT TIME SERVER
void    setSyncInterval( time_t interval);// SET NUMBER OF SECONDS BETWEEN RE-SYNC
                   // LOW LEVEL FUNCTIONS TO CONVERT TO AND FROM SYSTEM TIME
void breakTime( time_t time, tmElements_t &tm );// BREAK TIME_T INTO ELEMENTS
time_t makeTime( tmElements_t &tm );    // CONVERT TIME ELEMENTS INTO time_t

#endif /* _Time_h */