📄 ptime.cxx
字号:
/* * * C++ Portable Types Library (PTypes) * Version 1.7.5 Released 9-Mar-2003 * * Copyright (c) 2001, 2002, 2003 Hovik Melikyan * * http://www.melikyan.com/ptypes/ * http://ptypes.sourceforge.net/ * */#ifdef WIN32# include <windows.h>#else# include <sys/time.h>#endif#include <time.h>#include <string.h>#include "ptime.h"PTYPES_BEGINdatetime mkdt(int days, int msecs){ return large(days) * msecsmax + msecs;}bool isvalid(datetime d){ return d >= 0 && d < datetimemax;}bool isleapyear(int year){ return year > 0 && year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);}int daysinmonth(int year, int month){ if (month < 1 || month > 12) return 0; static const int mdays[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int res = mdays[month - 1]; if (month == 2) if (isleapyear(year)) res++; return res;}int daysinyear(int year, int month){ if (month < 1 || month > 12) return 0; static const int ndays[12] = {31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365}; int res = ndays[month - 1]; if (month > 1) if (isleapyear(year)) res++; return res;}int dayofweek(datetime d){ return (days(d) + 1) % 7;}bool isdatevalid(int year, int month, int day){ return year >= 1 && year <= 9999 && month >= 1 && month <= 12 && day >= 1 && day <= daysinmonth(year, month);}datetime encodedate(int year, int month, int day){ if (!isdatevalid(year, month, day)) return invdatetime; int y = year - 1; return mkdt(day // days in this month + daysinyear(year, month - 1) // plus days since the beginning of the year + y * 365 // plus "pure" days + y / 4 - y / 100 + y / 400 // plus leap year correction - 1, 0); // ... minus one (guess why :)}bool decodedate(datetime date, int& year, int& month, int& day){ int d = days(date); if (d < 0 || d >= daysmax) // allowed date range is 01/01/0001 - 12/31/9999 { year = 0; month = 0; day = 0; return false; } const int d1 = 365; // number of days in 1 year const int d4 = d1 * 4 + 1; // ... in 4 year period const int d100 = d4 * 25 - 1; // ... in 100 year period const int d400 = d100 * 4 + 1; // ... in 400 year period year = (d / d400) * 400 + 1; d %= d400; int t = d / d100; d %= d100; if (t == 4) { t--; d += d100; } year += t * 100; year += (d / d4) * 4; d %= d4; t = d / d1; d %= d1; if (t == 4) { t--; d += d1; } year += t; month = d / 29; // approximate month no. (to avoid loops) if (d < daysinyear(year, month)) // month no. correction month--; day = d - daysinyear(year, month) + 1; month++; return true;}bool istimevalid(int hour, int min, int sec, int msec){ return hour >= 0 && hour < 24 && min >= 0 && min < 60 && sec >= 0 && sec < 60 && msec >= 0 && msec < 1000;}datetime encodetime(int hour, int min, int sec, int msec){ large res = large(hour) * 3600000 + large(min) * 60000 + large(sec) * 1000 + msec; if (!isvalid(res)) res = invdatetime; return res;}bool decodetime(datetime t, int& hour, int& min, int& sec, int& msec){ if (!isvalid(t)) { hour = 0; min = 0; sec = 0; msec = 0; return false; } int m = msecs(t); hour = m / 3600000; m %= 3600000; min = m / 60000; m %= 60000; sec = m / 1000; msec = m % 1000; return true;}bool decodetime(datetime t, int& hour, int& min, int& sec){ int msec; return decodetime(t, hour, min, sec, msec);}static tm* dttotm(datetime dt, tm& t){ memset(&t, 0, sizeof(tm)); if (!decodedate(dt, t.tm_year, t.tm_mon, t.tm_mday) || !decodetime(dt, t.tm_hour, t.tm_min, t.tm_sec)) return nil; t.tm_mon--; t.tm_yday = daysinyear(t.tm_year, t.tm_mon) + t.tm_mday - 1; t.tm_wday = dayofweek(dt); t.tm_year -= 1900; return &t;}string dttostring(datetime dt, const char* fmt){ char buf[128]; tm t; int r = strftime(buf, sizeof(buf), fmt, dttotm(dt, t)); buf[r] = 0; return string(buf);}datetime now(bool utc){#ifdef WIN32 SYSTEMTIME t; if (utc) GetSystemTime(&t); else GetLocalTime(&t); return encodedate(t.wYear, t.wMonth, t.wDay) + encodetime(t.wHour, t.wMinute, t.wSecond, t.wMilliseconds);#else // Unix // we can't use localtime() and gmtime() here as they don't return // milliseconds which are needed for our datetime format. instead, // we call gettimeofday() which have microsecond precision, and then // adjust the time according to timzone info returned by localtime() // on BSD and Linux, and global variables altzone/timezone on SunOS. // MacOS X: localtime() is always reentrant (?) // NOTE: at the moment of passing the DST adjustment (twice a year) // the local time value returned by now() may be incorrect. // the application should call tzupdate() from time to time if it // is supposed to be running infinitely, e.g. if it's a daemon. // always rely on UTC time inside your application whenever possible. timeval tv; gettimeofday(&tv, nil); int edays = tv.tv_sec / 86400 // days since Unix "Epoch", i.e. 01/01/1970 + 719162; // plus days between 01/01/0001 and Unix Epoch int esecs = tv.tv_sec % 86400; // the remainder, i.e. seconds since midnight datetime res = mkdt(edays, esecs * 1000 + tv.tv_usec / 1000); if (!utc) res += tzoffset() * 60 * 1000; return res;#endif}void tzupdate(){ tzset();}int tzoffset(){#if defined(WIN32) TIME_ZONE_INFORMATION tz; GetTimeZoneInformation(&tz); if (tz.DaylightDate.wMonth != 0) return - (tz.Bias + tz.DaylightBias); else return - tz.Bias;#elif defined(__sun__) if (timezone == 0) tzset(); if (daylight != 0) return - altzone / 60; else return - timezone / 60;#elif defined(__DARWIN__) time_t u; time(&u); tm* t = localtime(&u); return t->tm_gmtoff / 60;#else time_t u; time(&u); tm t; localtime_r(&u, &t); return t.tm_gmtoff / 60;#endif}static datetime uepoch = encodedate(1970, 1, 1);datetime utodatetime(time_t u){ return uepoch + large(u) * 1000;}PTYPES_END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -