DateTime.cpp
#include <DateTime.h>
 
/*H*******************************************************
DateTime.cpp - Arduino Date and Time library
Copyright (c) Michael Margolis.  All right reserved.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
********************************************************/
extern "C" {
// AVR LibC Includes
}
//#include  // for memset
#include "DateTime.h"
#include <wiring.h>
//************************* DEFINES ************************************
#define LEAP_YEAR(_year) ((_year%4)==0)
//************************* PROTOTYPES ************************************
//************************* VARIABLES ************************************
//extern unsigned long _time;
static  byte monthDays[]={31,28,31,30,31,30,31,31,30,31,30,31};
/*F********************************************************************
* private methods
**********************************************************************/
/*F********************************************************************
*
**********************************************************************/
void DateTimeClass::
setTime( time_t time )
{
	// SET SYSTEM TIME TO GIVEN TIME VALUE (AS SECONDS SINCE Jan 1 1970)
	this->sysTime = time;  
	this->prevMillis = millis();
}
//******************************************************************************
//* DateTime Public Methods
//******************************************************************************
/*F********************************************************************
*
**********************************************************************/
DateTimeClass::
DateTimeClass()
{
	this->status = dtStatusNotSet;
}
/*F********************************************************************
*
**********************************************************************/
time_t DateTimeClass::
now()
{
	while( millis() - prevMillis >= 1000)
	{
		this->sysTime++;
		this->prevMillis += 1000;
	}
	return sysTime;
}
/*F********************************************************************
*
**********************************************************************/
void DateTimeClass:: 
sync( time_t time) 
{
	setTime( time ); 
	// status.isSynced = true;   // THIS WILL BE SET TO FALSE IF CLOCK RESETS 
	//status.isSet = true; // IF TRUE AND ISsYNCED FALSE THEN CLOCK RESET USING EEPROM -- TODO
	this->status = dtStatusSync;
}
/*F********************************************************************
*
**********************************************************************/
boolean DateTimeClass::
available()
{  
	// REFRESH TIME COMPONENTS IF CLOCK IS SET (EVEN IF NOT SYNCED), JUST RETURN FALSE IF NOT SET
	if( this->status != dtStatusNotSet) 
	{ 
		this->now(); // REFRESH SYStIME   
		this->localTime( &this->sysTime, &Second, &Minute, &Hour, &Day
			, &DayofWeek, &Month, &Year );
		return( true );
	}
	else
		return false;
}
/*F********************************************************************
*
**********************************************************************/
void DateTimeClass::
localTime( time_t *timep, byte *psec, byte *pmin, byte *phour, byte *pday
	, byte *pwday, byte *pmonth, byte *pyear) 
{
	// CONVERT GIVEN TIME_T TO TIME COMPONENTS
	// THIS IS A MORE COMPACT VERSION OF THE c LIBRARY LOCALTIME FUNCTION
	time_t long epoch = *timep;
	byte year;
	byte month, monthLength;
	unsigned long days;
	*psec = epoch % 60;
	epoch /= 60;                                        // NOW IT IS MINUTES
	*pmin = epoch%60;
	epoch /= 60;                                          // NOW IT IS HOURS
	*phour = epoch%24;
	epoch /= 24;                                           // NOW IT IS DAYS
	*pwday = (epoch + 4) % 7;
	year = 70;
	days = 0;
	while( (unsigned)(days += (LEAP_YEAR( year ) ? 366 : 365)) <= epoch) 
	{
		year++;
	}
	*pyear = year;                  // *PYEAR IS RETURNED AS YEARS FROM 1900
	days -= LEAP_YEAR(year) ? 366 : 365;
	epoch -= days; // now it is days in this year, starting at 0
	//*pdayofyear =epoch;  // days since jan 1 this year
	days =0;
	month =0;
	monthLength =0;
	for( month =0; month < 12; month++) 
	{
		if( month == 1) 
		{ // FEBRUARY
			if( LEAP_YEAR( year )) 
				monthLength = 29;
			else 	
				monthLength = 28;
		} 
		else 
			monthLength = monthDays[month];
		if( epoch >= monthLength ) 
			epoch -= monthLength;
		else
			break;
	}
	*pmonth=month;  // jan is month 0
	*pday=epoch+1;  // day of month
}
/*F********************************************************************
*
**********************************************************************/
time_t DateTimeClass::
makeTime( byte sec, byte min, byte hour, byte day, byte month, int year )
{
	// converts time components to time_t 
	// note year argument is full four digit year (or digits since 2000)
	//, i.e.1975, (year 8 is 2008)
	int i;
	time_t seconds;
	if( year < 69) 
		year+= 2000;
	// SECONDS FROM 1970 TILL 1 Jan 00:00:00 THIS YEAR
	seconds= (year -1970) * (60*60*24L*365);
	// ADD EXTRA DAYS FOR LEAP YEARS
	for( i =1970; i < year; i++) 
	{
		if( LEAP_YEAR(i) ) 
			seconds += 60*60*24L;
	}
	// ADD DAYS FOR THIS YEAR
	for( i =0; i < month; i++) 
	{
		if( i == 1 && LEAP_YEAR( year ) )
			seconds += 60*60*24L*29;
		else
			seconds += 60 * 60 * 24L * monthDays[i];
	}
	seconds += (day-1)*3600*24L;
	seconds += hour*3600L;
	seconds += min*60L;
	seconds += sec;
	return seconds; 
}
// MAKE ONE INSTANCE FOR DateTime CLASS USER
DateTimeClass DateTime = DateTimeClass();