📄 opexdatetime.c
字号:
////////////////////////////////////////////////
// OPEXdateTime.c
// (C) 2004 Steve Childress stevech@san.rr.com
////////////////////////////////////////////////
#include "OPEX.h"
const unsigned char __attribute__((progmem)) MONTHNAMES[] = {
"JanFebMarAprMayJunJulAugSepOctNovDec" };
const unsigned char __attribute__((progmem)) DAYNAMES[] = {
"SunMonTueWedThuFriSat" };
int IsLeapYear(int);
int8_t GMT_offset; // GMT offset hours signed
///////////////////////////////////////////
void OPEX_init_dateTime(void)
{
if (time.year == 0) {
OPEX_date_stuff(&time, 0, 1, 1, 0, 0, 0, 0); // jan 1 of 2000
}
}
//////////////////////////////////////////////
// return a formatted string for the date passed
void OPEX_format_date(char *p, DATE_TIME *buf)
{
char mmm[4];
char ddd[4];
buf->weekday = OPEX_DayOfWeek((int)buf->year, (int)buf->month, (int)buf->day);
memcpy_P(&mmm, &MONTHNAMES[(buf->month-1) * 3], 3); // three letter monthname
memcpy_P(&ddd, &DAYNAMES[buf->weekday * 3], 3); // three letter dayname
mmm[3] = 0;
ddd[3] = 0;
sprintf_P(p, PSTR(" %s %02d %s %02d "), ddd, (int)buf->day, mmm, (int)buf->year);
}
///////////////////////////////////////////////////////////
// return a formatted string for the time passed
void OPEX_format_time(char *p, DATE_TIME *buf)
{
int frac;
frac = (int)buf->tick;
frac *= 10; // mul by 100 yields linker error __mulhi3
frac = (frac * 10) / TicksPerSecond;
*p = '\0';
sprintf_P(p, PSTR( " %02d:%02d:%02d.%02d "), buf->hour, buf->minute, buf->second, frac);
}
///////////////////////////////////////////////////////////
// return a formatted string for the date and time passed
void OPEX_format_date_time(char *p, DATE_TIME *buf)
{
char ddd[16]; // large enough to hold: mmm dd, yyyy\0
OPEX_format_time(p, buf); // put time into passed string buf
OPEX_format_date(ddd, buf); // put date into local string
strcat(p, ddd); // join strings
}
///////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
extern const unsigned char __attribute__((progmem)) MAX_DAY[];
extern const unsigned char __attribute__((progmem)) MAX_DAYLEAP[];
///////////////////////////////////////////////
// get a copy of the current time of day
void OPEX_now(DATE_TIME *buf)
{
cli();
memcpy(buf, &time, sizeof(time));
sei();
}
///////////////////////////////////////////////
// store date time in the structure passed
void OPEX_date_stuff(DATE_TIME *t, BYTE year, BYTE month, BYTE day, BYTE hour, BYTE minute, BYTE second, BYTE tick)
{
cli(); // don't let ISR alter if this is the system time being altered
t->year = year;
t->month = month;
t->day = day;
t->hour = hour;
t->minute = minute;
t->second = second;
t->tick = tick;
t->weekday = OPEX_DayOfWeek((int)t->year+2000, (int)t->month, (int)t->day);
sei();
}
///////////////////////////////////////////////
// compute new date and time given a delta
void OPEX_date_add(DATE_TIME *t, BYTE days, BYTE hours, BYTE minutes, BYTE seconds, BYTE ticks)
{
int n;
// add ticks
n = (int) t->tick + (int) ticks; // add ticks
if (n >= (int) TicksPerSecond) { // assumed to be byte-sized
t->tick = 0;
++t->second;
}
else
t->tick = (BYTE) n; // is modulo, from the above
// add seconds, minutes, hours, days
t->second += seconds;
if (t->second >= 60) {
t->second = 0;
++t->minute;
}
t->minute += minutes;
if (t->minute >= 60) {
t->minute = 0;
++t->hour;
}
t->hour += hours;
if (t->hour >= 24) {
t->hour = 0;
++t->day;
}
t->day += days;
// add months, years
if (!IsLeapYear(t->year + 2000)) {
//if((t->year & 3) != 0) { // leap year ignore 2099?
if((int)t->day > (int)PRG_RDB(&MAX_DAY[t->month])) { // 1..12
t->day = 1; // enough days for this month?
if(++t->month > 12) {
t->month = 1; // another year gone by..
++t->year;
}
}
}
else {
if((int)t->day > (int)PRG_RDB(&MAX_DAYLEAP[t->month])) { // 1..12
t->day = 1; // enough days for this month?
if(++t->month > 12) {
t->month = 1; // another year gone by..
++t->year;
}
}
}
t->weekday = OPEX_DayOfWeek((int)t->year+2000, (int)t->month, (int)t->day);
}
// /////////////////////////////////////////////////
// Compare two date/time structures
// return -1 if t1 < t2
// return 0 if t1 == t2
// return 1 if t1 > t2er
int OPEX_compare_dt(DATE_TIME *t1, DATE_TIME *t2)
{
unsigned char *p1, *p2, i;
int ret;
p1 = (unsigned char *)t1;
p2 = (unsigned char *)t2;
// compare two date blocks
// don't need to block interrupts, since time values changes in the ISR are monotonic/ascending?
ret = 0; //assume equality
cli(); // one may be volatile real time date
for (i = 0; i < sizeof(DATE_TIME); i++) { // bytes are in decending order yr/mo/day/hour/min/sec/frac
if (*p1 < *p2) {
ret = -1;
break;
}
if (*p1 > *p2) {
ret = 1;
break;
}
++p1;
++p2;
}
sei();
return(ret);
}
///////////////////////////////////////////////////////////////////////////
// THE CODE BELOW, MODIFIED FROM THE BELOW SOURCE:
/*
begin : Sunday July 7 11:13:38 GMT+8 2002
copyright : (C) 2002 by Jerry Jenkins
email : Jerry_J_Jenkins@hotmail.com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
*/
/////////////////////////////////////////////////////////////
int IsLeapYear( int nYear )
{
if( nYear % 4 != 0 ) return 0;
if( nYear % 100 != 0 ) return 1;
return ( nYear % 400 == 0 );
}
/////////////////////////////////////////////////////////////
/*
* Count of days, which is Feb 29, from Jan 1, 0 to Jan 1, nYear
* There is no Feb 29 between Jan 1, 0 and Jan 1, -3, one between Jan 1, 0 and Jan 1, -4
* one between Jan 1, 0 and Jan 1, 3 AD, one between Jan 1, 0 and Jan 1, 4
*/
int CountOfFeb29( int nYear )
{
int nCount = 0;
if( nYear > 0 ) {
nCount = 1; /* Year 0 is a leap year */
nYear--;/* Year nYear is not in the period */
}
nCount += nYear / 4 - nYear / 100 + nYear / 400;
return nCount;
}
static int pnDaysBeforeMonth[] = {
0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365
};
////////////////////////////////////////////////////////////
// returns day of week, 0 = Sunday
int OPEX_DayOfWeek( int nYear, int nMonth, int nDay )
{
int nDayOfWeek;
#if 0 // don't error check to save code space
if ( nDay < 0 || nMonth < 0 || nMonth > 12 )
return(-1);
if (
( nDay <= ( pnDaysBeforeMonth[ nMonth+1 ] - pnDaysBeforeMonth[ nMonth ] ) )
|| ( nMonth == 2 && nDay == 29 && IsLeapYear(nYear) ) )
return(-1);
#endif
/* the day of Jan 1, nYear */
nDayOfWeek = 6 + nYear % 7 + CountOfFeb29(nYear) % 7 + 14; /* + 14 : makes nDayOfWeek >= 0 */
/* the day of nMonth 1, nYear */
nDayOfWeek += pnDaysBeforeMonth[ nMonth ];
if( nMonth > 2 && IsLeapYear(nYear) ) nDayOfWeek++;
/* the day of nMonth nDay, nYear */
nDayOfWeek += nDay - 1;
nDayOfWeek %= 7;
return nDayOfWeek;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -