/** * @file TimeCnv.h * @brief 時間関係(ファイル時間、年月日時分秒構造体等)の変換関係. * @author tenk* (Masashi Kitamura) * @note * - Win の SYSTEMTIME と C言語の struct tm 用のラッパー関数. * - SYSTEMTIME または struct tm に入っている値はローカル時間であることを * 前提にしている. * - Public Domain Software */ #ifndef TIMECNV_H #define TIMECNV_H #if defined _WIN32 #include <windows.h> #ifndef __cplusplus #define inline __inline #endif typedef SYSTEMTIME TimeCnv_Tm; ///< 年月日時分秒のようにメンバー化された構造体. typedef unsigned __int64 TimeCnv_time_t; ///< ファイル時間で使われている64bit整数な値. #else // linux(unix). #include <stdint.h> #include <time.h> typedef struct tm TimeCnv_Tm; ///< 年月日時分秒のようにメンバー化された構造体. typedef time_t TimeCnv_time_t; ///< ファイル時間で使われている整数な値. /** タイムゾーンの時間を取得. */ inline long TimeCnv_get_timeZone() { static long s_timeZone = (long)0x80000000; if (s_timeZone == (long)0x80000000) { tzset(); s_timeZone = timezone; } return s_timeZone; } #endif // _WIN32 /** utc時間をローカル時間に変換. */ inline TimeCnv_time_t TimeCnv_Utc_to_LocalTime(TimeCnv_time_t utcTime) { #if defined _WIN32 TimeCnv_time_t t = 0; return FileTimeToLocalFileTime((const FILETIME*)&utcTime, (FILETIME*)&t) ? t : (TimeCnv_time_t)(-1); #else // 手抜きでtimezoneのみを反映. long tz = TimeCnv_get_timeZone(); return utcTime + tz; #endif } /** ローカル時間をutc時間に変換. */ inline TimeCnv_time_t TimeCnv_Local_to_UtcTime(TimeCnv_time_t localTime) { #if defined _WIN32 TimeCnv_time_t t = 0; return LocalFileTimeToFileTime((const FILETIME*)&localTime, (FILETIME*)&t) ? t : (TimeCnv_time_t)(-1); #else // 手抜きでtimezoneのみを反映. long tz = TimeCnv_get_timeZone(); return localTime - tz; #endif } /** 年月日時分秒構造体をローカル時間として、ローカル時間を求める. */ inline TimeCnv_time_t TimeCnv_Tm_to_LocalTime(const TimeCnv_Tm* st) { #if defined _WIN32 TimeCnv_time_t localTim; return (SystemTimeToFileTime((const SYSTEMTIME*)st, (FILETIME*)&localTim)) ? localTim : (TimeCnv_time_t)(-1); #else TimeCnv_Tm tm0 = *st; return mktime(&tm0); #endif } /** 年月日時分秒構造体をローカル時間として、utc時間を求める. */ inline TimeCnv_time_t TimeCnv_Tm_to_UtcTime(const TimeCnv_Tm* st) { #if defined _WIN32 TimeCnv_time_t localTim; TimeCnv_time_t tim; return ( SystemTimeToFileTime((const SYSTEMTIME*)st, (FILETIME*)&localTim) && LocalFileTimeToFileTime((const FILETIME*)&localTim, (FILETIME*)&tim) ) ? tim : (TimeCnv_time_t)(-1); #else TimeCnv_time_t t = TimeCnv_Tm_to_LocalTime(st); return (t != (TimeCnv_time_t)-1) ? TimeCnv_Local_to_UtcTime(t) : t; #endif } /** utc時間から、ローカルな年月日時分秒構造体を求める. */ inline TimeCnv_Tm* TimeCnv_Tm_from_UtcTime(TimeCnv_Tm* st, TimeCnv_time_t utcTime) { #if defined _WIN32 TimeCnv_time_t localTim = 0; return FileTimeToLocalFileTime((const FILETIME*)&utcTime, (FILETIME*)&localTim) && FileTimeToSystemTime((const FILETIME*)&localTim, (SYSTEMTIME*)st) ? st : 0; #else return gmtime_r(&utcTime, st); #endif } /** ローカル時間から、ローカルな年月日時分秒構造体を求める. */ inline TimeCnv_Tm* TimeCnv_Tm_from_LocalTime(TimeCnv_Tm* st, TimeCnv_time_t localTime) { #if defined _WIN32 return FileTimeToSystemTime((const FILETIME*)&localTime, (SYSTEMTIME*)st) ? st : 0; #else return localtime_r(&localTime, st); #endif } // ======================================================================== // カレンダー時間の winの SYSTEMTIME と struct tm との辻褄合わせ用クラス. // ======================================================================== #ifdef __cplusplus #if defined _WIN32 /// tm と SYSTEMTIME のメンバー名のラッパークラス. class TimeCnv_TmEx : public TimeCnv_Tm { typedef TimeCnv_Tm BASE; public: explicit TimeCnv_TmEx(unsigned y=0, unsigned m=1, unsigned d=1, unsigned h=0, unsigned mi=0, unsigned sec=0, unsigned ms=0) { wYear=y, wMonth=m, wDayOfWeek=0, wDay=d, wHour=h, wMinute=mi, wSecond=sec, wMilliseconds=ms; } TimeCnv_TmEx(const TimeCnv_TmEx& r) { *(TimeCnv_Tm*)this = *(TimeCnv_Tm*)&r; } TimeCnv_TmEx(const TimeCnv_Tm& r) { *(TimeCnv_Tm*)this = r; } TimeCnv_TmEx& operator=(const TimeCnv_Tm& r) { *(TimeCnv_Tm*)this = *(TimeCnv_Tm*)&r; return *this; } TimeCnv_TmEx& operator=(const TimeCnv_TmEx& r) { *(TimeCnv_Tm*)this = *(TimeCnv_Tm*)&r; return *this; } void set(unsigned y=0, unsigned m=1, unsigned d=1, unsigned h=0, unsigned mi=0, unsigned sec=0, unsigned ms=0) { wYear=y, wMonth=m, wDayOfWeek=0, wDay=d, wHour=h, wMinute=mi, wSecond=sec, wMilliseconds=ms; } void set_date(unsigned y, unsigned m=1, unsigned d=1) { set_year(y); set_month(m); set_day(d); } void set_time(unsigned h, unsigned m=0, unsigned s=0, unsigned ms=0) { set_hour(h); set_minute(m); set_second(s); set_milliseconds(ms); } unsigned year() const { return wYear; } unsigned month() const { return wMonth; } unsigned dayOfWeek() const { return wDayOfWeek; } unsigned day() const { return wDay; } unsigned hour() const { return wHour; } unsigned minute() const { return wMinute; } unsigned second() const { return wSecond; } unsigned milliseconds() const { return wMilliseconds; } void set_year (unsigned y) { assert(y <= 0xffff); wYear = y ; } void set_month(unsigned m) { assert(m >= 1 && m <= 12); wMonth = m ; } void set_dayOfWeek(unsigned wd) { assert(wd <= 6); wDayOfWeek = wd ; } void set_day(unsigned d) { assert(1 <= d && d <= 31); wDay = d ; } void set_hour(unsigned h) { assert(h <= 23); wHour = h ; } void set_minute(unsigned mi) { assert(mi <= 59); wMinute = mi ; } void set_second(unsigned sec) { assert(sec <= 61); wSecond = sec; } void set_milliseconds(unsigned ms) { assert(ms <= 0xffff); wMilliseconds= ms ; } void tm_set(unsigned y=0, unsigned m=0, unsigned d=0, unsigned h=0, unsigned mi=0, unsigned sec=0, unsigned ms=0) { wYear=y+1900, wMonth=m+1, wDayOfWeek=0, wDay=d, wHour=h, wMinute=mi, wSecond=sec, wMilliseconds=ms; } unsigned tm_year() const { return wYear-1900; } unsigned tm_mon() const { return wMonth-(wMonth > 0); } unsigned tm_yday() const { return 0; } // dummy. unsigned tm_wday() const { return wDayOfWeek; } unsigned tm_mday() const { return wDay; } unsigned tm_hour() const { return wHour; } unsigned tm_min() const { return wMinute; } unsigned tm_sec() const { return wSecond; } int tm_isdst() const { return -1; } // dummy. void set_tm_year(unsigned y ) { assert(y <= 0xffff); wYear = y + 1900; } void set_tm_mon (unsigned m ) { assert(m >= 0 && m <= 11); wMonth = m + 1; } void set_tm_yday(unsigned ) { ; } /* dummy */ void set_tm_wday(unsigned wd ) { assert(wd <= 6); wDayOfWeek = wd ; } void set_tm_mday(unsigned d ) { assert(1 <= d && d <= 31); wDay = d ; } void set_tm_hour(unsigned h ) { assert(h <= 23); wHour = h ; } void set_tm_min (unsigned mi ) { assert(mi <= 59); wMinute = mi ; } void set_tm_sec (unsigned sec) { assert(sec <= 61); wSecond = sec; } void set_tm_isdst(int ) { ; } /* dummy */ }; #else /// tm と SYSTEMTIME のメンバー名のラッパークラス. class TimeCnv_TmEx : public TimeCnv_Tm { typedef TimeCnv_Tm BASE; public: explicit TimeCnv_TmEx(unsigned y=0, unsigned m=1, unsigned d=1, unsigned h=0, unsigned mi=0, unsigned sec=0, unsigned ms=0) { set(y,m,d,h,mi,sec,ms); } TimeCnv_TmEx(const TimeCnv_TmEx& r) { *(TimeCnv_Tm*)this = *(TimeCnv_Tm*)&r; } TimeCnv_TmEx(const TimeCnv_Tm& r) { *(TimeCnv_Tm*)this = r; } TimeCnv_TmEx& operator=(const TimeCnv_Tm& r) { *(TimeCnv_Tm*)this = *(TimeCnv_Tm*)&r; return *this; } TimeCnv_TmEx& operator=(const TimeCnv_TmEx& r) { *(TimeCnv_Tm*)this = *(TimeCnv_Tm*)&r; return *this; } void set(unsigned y=0, unsigned m=1, unsigned d=1, unsigned h=0, unsigned mi=0, unsigned sec=0, unsigned ms=0) { set_date(y,m,d); set_time(h,mi,sec,ms); } void set_date(unsigned y, unsigned m=1, unsigned d=1) { set_year(y); set_month(m); set_day(d); } void set_time(unsigned h, unsigned m=0, unsigned s=0, unsigned ms=0) { set_hour(h); set_minute(m); set_second(s); ms; } unsigned year() const { return BASE::tm_year+1900; } unsigned month() const { return BASE::tm_mon+1; } unsigned dayOfWeek() const { return BASE::tm_wday; } unsigned day() const { return BASE::tm_mday; } unsigned hour() const { return BASE::tm_hour; } unsigned minute() const { return BASE::tm_min; } unsigned second() const { return BASE::tm_sec; } unsigned milliseconds() const { return 0; } // だみー void set_year (unsigned y) { assert(y <= 0xffff); BASE::tm_year = y-1900; } void set_month(unsigned m) { assert(m >= 1 && m <= 12); BASE::tm_mon = m-1; } void set_dayOfWeek(unsigned wd) { assert(wd <= 6); BASE::tm_wday = wd ; } void set_day(unsigned d) { assert(1 <= d && d <= 31); BASE::tm_mday = d ; } void set_hour(unsigned h) { assert(h <= 23); BASE::tm_hour = h ; } void set_minute(unsigned mi) { assert(mi <= 59); BASE::tm_min = mi ; } void set_second(unsigned sec) { assert(sec <= 61); BASE::tm_sec = sec; } void set_milliseconds(unsigned ms) { assert(ms <= 0xffff); } // dummy. void tm_set(unsigned y=0, unsigned m=0, unsigned d=0, unsigned h=0, unsigned mi=0, unsigned sec=0, unsigned ms=0) { set_tm_year(y); set_tm_mon(m); set_tm_mday(d); set_tm_hour(h); set_tm_min(mi); set_tm_sec(sec); } unsigned tm_year() const { return BASE::tm_year ; } unsigned tm_mon() const { return BASE::tm_mon ; } unsigned tm_yday() const { return BASE::tm_yday ; } unsigned tm_wday() const { return BASE::tm_wday ; } unsigned tm_mday() const { return BASE::tm_mday ; } unsigned tm_hour() const { return BASE::tm_hour ; } unsigned tm_min() const { return BASE::tm_min ; } unsigned tm_sec() const { return BASE::tm_sec ; } int tm_isdst() const { return BASE::tm_isdst; } void set_tm_year(unsigned y ) { assert(y <= 0xffff); BASE::tm_year = y ; } void set_tm_mon (unsigned m ) { assert(m >= 0 && m <= 11); BASE::tm_mon = m ; } void set_tm_yday(unsigned yd ) { assert(yd>= 0 && yd<=365); BASE::tm_yday = yd ; } void set_tm_wday(unsigned wd ) { assert(wd <= 6); BASE::tm_wday = wd ; } void set_tm_mday(unsigned d ) { assert(1 <= d && d <= 31); BASE::tm_mday = d ; } void set_tm_hour(unsigned h ) { assert(h <= 23); BASE::tm_hour = h ; } void set_tm_min (unsigned mi ) { assert(mi <= 59); BASE::tm_min = mi ; } void set_tm_sec (unsigned sec) { assert(sec <= 61); BASE::tm_sec = sec; } void set_tm_isdst(int isdst) { BASE::tm_isdst=isdst;} }; #endif // _WIN32. #endif // __cplusplus #endif // TIMECNV_H