mirror of
https://github.com/fsender/readguy.git
synced 2025-12-12 13:08:11 +08:00
158 lines
6.6 KiB
C++
158 lines
6.6 KiB
C++
/**
|
|
* @file ctg_timelib.h
|
|
* @author FriendshipEnder (Q:3253342798)
|
|
* @brief 时间兼容库文件. 旨在替代原有的, 过时的 TimeLib.h 文件(用于AVR设备)
|
|
* 本库依赖 GLibC 的 time.h 文件.
|
|
* 本库兼容 TimeLib.h 文件
|
|
* 为了确保名称无冲突, 使用名称空间命名避免函数名冲突
|
|
* @version 1.0.0
|
|
* @date 2024-11-16
|
|
*
|
|
* @copyright Copyright (c) 2024
|
|
*
|
|
*/
|
|
#ifndef _CTG_TimeLib_H_FILE
|
|
#define _CTG_TimeLib_H_FILE
|
|
|
|
#define CTG_DEFAULT_LOCAL_TIMEZONE ("CST-8") //默认时区
|
|
#define CTG_DEFAULT_LOCAL_OFFSET (8*3600) //默认时区偏移值
|
|
#define CTG_USE_tmElements_t //使用 tmElements_t (强兼容, 但是没什么用)
|
|
|
|
#include <stdlib.h>
|
|
#include <stdint.h>
|
|
#include <time.h>
|
|
#include <lwip/apps/sntp.h> //settimeofday
|
|
|
|
namespace CTG_TimeLib {
|
|
|
|
extern time_t tOffset;
|
|
extern struct tm m;
|
|
|
|
/// @brief return the current local time as seconds since Jan 1 1970
|
|
inline time_t now() {return time(NULL)+tOffset;}
|
|
/// @brief the hour for the given time
|
|
inline int hour(time_t t){gmtime_r(&t, &m);return m.tm_hour;}
|
|
/// @brief the hour now
|
|
inline int hour(){return hour(now());}
|
|
/// @brief the minute for the given time
|
|
inline int minute(time_t t){gmtime_r(&t, &m);return m.tm_min;}
|
|
/// @brief the minute now
|
|
inline int minute(){return minute(now());}
|
|
/// @brief the second for the given time
|
|
inline int second(time_t t){gmtime_r(&t, &m);return m.tm_sec;}
|
|
/// @brief the second now
|
|
inline int second(){return second(now());}
|
|
/// @brief the day for the given time
|
|
inline int day(time_t t){gmtime_r(&t, &m);return m.tm_mday;}
|
|
/// @brief the day now
|
|
inline int day(){return day(now());}
|
|
/// @brief the weekday for the given time (Sunday is day 1)
|
|
inline int weekday(time_t t){gmtime_r(&t, &m);return m.tm_wday+1;}
|
|
/// @brief the weekday now (Sunday is day 1)
|
|
inline int weekday(){return weekday(now());}
|
|
/// @brief the month for the given time (Jan is month 1)
|
|
inline int month(time_t t){gmtime_r(&t, &m);return m.tm_mon+1;}
|
|
/// @brief the month now (Jan is month 1)
|
|
inline int month(){return month(now());}
|
|
/// @brief the year for the given time
|
|
inline int year(time_t t){gmtime_r(&t, &m);return m.tm_year+1900;}
|
|
/// @brief the full four digit year: (2009, 2010 etc)
|
|
inline int year(){return year(now());}
|
|
/// @brief set the time-zone
|
|
/// @param z (string) timezone name (like 'CST-8', 'EST+5', etc)
|
|
/// @param offset (time_t) how many seconds offset (+8 == 8*3600)
|
|
inline void setTimezone(const char *z, time_t offset){
|
|
tOffset = offset;
|
|
setenv("TZ", z, 1); //设置时区变量 (当前设置为北京时间)
|
|
tzset();
|
|
}
|
|
|
|
/// @brief set the time (input UTC time,not local time)
|
|
/// @param t (time_t): correct UTC time
|
|
/// @param fit_zone_cn (bool): Set timezone to UTC+8 (Beijing)
|
|
inline void setUTCTime(time_t t, bool fit_local = true){
|
|
if(tOffset != CTG_DEFAULT_LOCAL_OFFSET && fit_local)
|
|
setTimezone(CTG_DEFAULT_LOCAL_TIMEZONE, CTG_DEFAULT_LOCAL_OFFSET);
|
|
timeval tm_now={t, 0};
|
|
settimeofday(&tm_now,nullptr);// need #include <lwip/apps/sntp.h>
|
|
}
|
|
|
|
/// @brief set the time (input local time)
|
|
/// @param t (time_t): correct local time (UTC+8 = Beijing)
|
|
inline void setTime(time_t t){
|
|
if(tOffset != CTG_DEFAULT_LOCAL_OFFSET)
|
|
setTimezone(CTG_DEFAULT_LOCAL_TIMEZONE, CTG_DEFAULT_LOCAL_OFFSET);
|
|
timeval tm_now={t-CTG_DEFAULT_LOCAL_OFFSET, 0};
|
|
settimeofday(&tm_now,nullptr);// need #include <lwip/apps/sntp.h>
|
|
}
|
|
|
|
#ifdef CTG_USE_tmElements_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;
|
|
int16_t Year; // offset from 1970;
|
|
} tmElements_t;
|
|
|
|
#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)
|
|
|
|
/* Useful Constants */
|
|
#define SECS_PER_MIN ((time_t)(60UL))
|
|
#define SECS_PER_HOUR ((time_t)(3600UL))
|
|
#define SECS_PER_DAY ((time_t)(SECS_PER_HOUR * 24UL))
|
|
#define DAYS_PER_WEEK ((time_t)(7UL))
|
|
#define SECS_PER_WEEK ((time_t)(SECS_PER_DAY * DAYS_PER_WEEK))
|
|
#define SECS_PER_YEAR ((time_t)(SECS_PER_DAY * 365UL)) // TODO: ought to handle leap years
|
|
#define SECS_YR_2000 ((time_t)(946684800UL)) // the time at the 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) // the number of seconds since last midnight
|
|
// The following macros are used in calculating alarms and assume the clock is set to a date later than Jan 1 1971
|
|
// Always set the correct time before settting alarms
|
|
#define previousMidnight(_time_) (((_time_) / SECS_PER_DAY) * SECS_PER_DAY) // time at the start of the given day
|
|
#define nextMidnight(_time_) (previousMidnight(_time_) + SECS_PER_DAY) // time at the end of the 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 the start of the week for the given time
|
|
#define nextSunday(_time_) (previousSunday(_time_)+SECS_PER_WEEK) // time at the end of the week for the 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)
|
|
|
|
/// @brief set the time (input local time)
|
|
/// @param hr,min,sec,day,month,yr: correct local time (UTC+8 = Beijing)
|
|
void setTime(int16_t hr,int16_t min,int16_t sec,int16_t day,int16_t month,int16_t yr);
|
|
|
|
/// @brief break time_t into elements
|
|
void breakTime(time_t time, tmElements_t &tm);
|
|
|
|
/// @brief convert time elements into time_t
|
|
time_t makeTime(const tmElements_t &tm);
|
|
|
|
#endif // CTG_USE_tmElements_t
|
|
} //namespace
|
|
#endif // _CTG_TimeLib_H_FILE
|