POCO C++库学习和分析 -- 日期与时间
POCO C++库学习和分析 -- 日期与时间
在Poco库中,与时间和日期相关的一些类,其内部实现是非常简单的。看相关文档时,比较有意思的倒是历史上的不同时间表示法。
1. 系统时间函数
在编程时,时间函数不可避免的会被使用。linux系统下相关时间的数据结构有time_t,timeval,timespec,tm,clock_t; windows下time_t,tm,SYSTEMTIME,FILETIME,clock_t。其中clock_t、timeval、timespec用于表示时间跨度,time_t、tm、SYSTEMTIME,FILETIME用于表示绝对时间。不同的数据结构之间,多少也有些差异。首先这些时间结构体的精度不同,Second(time_t/tm), microsecond(timeval/SYSTEMTIME), 100nanoSeconds(FILETIME),nanoSeconds(timespec)。还有一些结构和操作系统相关,如clock_t,windows下为1毫秒,POSIX 下为1微秒,对应clock_t,不同平台的差异,可以用宏CLOCKS_PER_SEC解决。
起始时间不同,time_t起始于1970年1月1日0时0分0秒,tm表示起始于1900年,SYSTEMTIME/FILETIME起始于1601年,clock起始于机器开机。
上面各个时间的定义如下:
typedef struct _FILETIME { DWORD dwLowDateTime; DWORD dwHighDateTime; } FILETIME, *PFILETIME; typedef struct _SYSTEMTIME { WORD wYear; WORD wMonth; WORD wDayOfWeek; WORD wDay; WORD wHour; WORD wMinute; WORD wSecond; WORD wMilliseconds; // 毫秒 } SYSTEMTIME, *PSYSTEMTIME; struct tm { int tm_sec; /* 秒 – 取值区间为[0,59] */ int tm_min; /* 分 - 取值区间为[0,59] */ int tm_hour; /* 时 - 取值区间为[0,23] */ int tm_mday; /* 一个月中的日期 - 取值区间为[1,31] */ int tm_mon; /* 月份(从一月开始,0代表一月) - 取值区间为[0,11] */ int tm_year; /* 年份,其值等于实际年份减去1900 */ int tm_wday; /* 星期 – 取值区间为[0,6],其中0代表星期天,1代表星期一,以此类推 */ int tm_yday; /* 从每年的1月1日开始的天数 – 取值区间为[0,365],其中0代表1月1日,1代表1月2日,以此类推 */ int tm_isdst; /* 夏令时标识符,实行夏令时的时候,tm_isdst为正。不实行夏令时的进候,tm_isdst为0;不了解情况时,tm_isdst()为负。*/ }; typedef __time64_t time_t; // 秒 struct timeval { long tv_sec; /* seconds */ long tv_usec; /* and microseconds 毫秒*/ }; struct timespec { __time_t tv_sec; /*seconds 秒*/ long int tv_nsec; /*nanoseconds 纳秒*/ } typedef unsigned long clock_t; // 毫秒
同这些数据结构相关联,C语言为tm,time_t提供了一组函数用于时间运算和数据结构转换:
// 日历时间(一个用time_t表示的整数) // 比较日历时间 double difftime(time_t time1, time_t time0); // 获取日历时间 time_t time(time_t * timer); // 转换日历时间为字符串 char * ctime(const time_t *timer); // 转换日历时间为我们平时看到的把年月日时分秒分开显示的时间格式tm(GMT timezone) struct tm * gmtime(const time_t *timer); // 转换日历时间为我们平时看到的把年月日时分秒分开显示的时间格式tm(本地 timezone) struct tm * localtime(const time_t * timer); // 关于本地时间的计算公式: localtime = utctime[Gmt time] + utcOffset()[时区偏移] + dst()[夏令时偏移] // 把tm转换为字符串 char * asctime(const struct tm * timeptr); // 把tm转换为日历时间 time_t mktime(struct tm * timeptr); // 获取开机以来的微秒数 clock_t clock (void);
Windows下特有的时间转换函数包括:
GetLocalTime能够得到本地电脑设置时区的时间,得到的类型是SYSTEMTIME的类型。
void GetSystemTime(LPSYSTEMTIME lpSystemTime); // GetSystemTime函数获得当前的UTC时间 void GetLocalTime(LPSYSTEMTIME lpSystemTime); // GetLocalTime获得当前的本地时间 BOOL SystemTimeToFileTime(const SYSTEMTIME* lpSystemTime, LPFILETIME lpFileTime); BOOL FileTimeToSystemTime(const FILETIME* lpFileTime, LPSYSTEMTIME lpSystemTime); BOOL LocalFileTimeToFileTime(const FILETIME* lpLocalFileTime, LPFILETIME lpFileTime); BOOL FileTimeToLocalFileTime(const FILETIME* lpFileTime, LPFILETIME lpLocalFileTime);
Windows下特有的获取时间精度的函数包括(精度微秒):
BOOL QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency); BOOL QueryPerformanceCounter(LARGE_INTEGER *lpCount);
1. 获取绝对时间
2. 获取两个时间点的相对时间
2. Timestamp类
同C语言中函数类似,Poco中定义了自己的时间类。Timestamp类似于time_t,用于获取比较日历时间。Timestamp定义如下:
class Foundation_API Timestamp { public: typedef Int64 TimeVal; /// monotonic UTC time value in microsecond resolution typedef Int64 UtcTimeVal; /// monotonic UTC time value in 100 nanosecond resolution typedef Int64 TimeDiff; /// difference between two timestamps in microseconds Timestamp(); /// Creates a timestamp with the current time. Timestamp(TimeVal tv); /// Creates a timestamp from the given time value. Timestamp(const Timestamp& other); /// Copy constructor. ~Timestamp(); /// Destroys the timestamp Timestamp& operator = (const Timestamp& other); Timestamp& operator = (TimeVal tv); void swap(Timestamp& timestamp); /// Swaps the Timestamp with another one. void update(); /// Updates the Timestamp with the current time. bool operator == (const Timestamp& ts) const; bool operator != (const Timestamp& ts) const; bool operator > (const Timestamp& ts) const; bool operator >= (const Timestamp& ts) const; bool operator < (const Timestamp& ts) const; bool operator <= (const Timestamp& ts) const; Timestamp operator + (TimeDiff d) const; Timestamp operator - (TimeDiff d) const; TimeDiff operator - (const Timestamp& ts) const; Timestamp& operator += (TimeDiff d); Timestamp& operator -= (TimeDiff d); std::time_t epochTime() const; /// Returns the timestamp expressed in time_t. /// time_t base time is midnight, January 1, 1970. /// Resolution is one second. UtcTimeVal utcTime() const; /// Returns the timestamp expressed in UTC-based /// time. UTC base time is midnight, October 15, 1582. /// Resolution is 100 nanoseconds. TimeVal epochMicroseconds() const; /// Returns the timestamp expressed in microseconds /// since the Unix epoch, midnight, January 1, 1970. TimeDiff elapsed() const; /// Returns the time elapsed since the time denoted by /// the timestamp. Equivalent to Timestamp() - *this. bool isElapsed(TimeDiff interval) const; /// Returns true iff the given interval has passed /// since the time denoted by the timestamp. static Timestamp fromEpochTime(std::time_t t); /// Creates a timestamp from a std::time_t. static Timestamp fromUtcTime(UtcTimeVal val); /// Creates a timestamp from a UTC time value. static TimeVal resolution(); /// Returns the resolution in units per second. /// Since the timestamp has microsecond resolution, /// the returned value is always 1000000. private: TimeVal _ts; };
Timestamp内部定义了一个Int64的变量_ts。存储了一个基于utc时间的64位int值,理论上可以提供微秒级的精度(实际精度依赖于操作系统)。由于Poco::Timestamp是基于UTC(世界标准时间或世界協調時間)的,所以它是独立于时区设置的。Poco::Timestamp实现了值语义,比较和简单的算术操作。
1. UTC (Coordinated Universal Time)是从1582年10月15日深夜开始计时的. Poco库中精度为100纳秒。
2. epoch time指是从1970年1月1日深夜开始计时的(指unix诞生元年)。Poco库中精度为1秒。
数据类型:
Poco::Timestamp内部定义了下列数据类型:
1. TimeVal
一个64位的int整数值,保存utc时间,精度微秒
2. UtcTimeVal
一个64位的int整数值,保存utc时间,精度100纳秒(真实精度仍然是微秒)
3. TimeDiff
一个64位的int整数值,保存两个Timestamp的差值,精度微秒
构造函数:
1. 默认构造函数会以当前时间初始化一个Timestamp值,基于UTC时间(从1582年10月15日开始计时,精度为100纳秒)
2. 提供了两个静态函数用于创建Timestamp对象,
a) Timestamp fromEpochTime(time_t time)。这个函数从time_t构建,内部会把EpochTime(从1970年1月1日深夜开始计时的,精度为1秒)的时间转换成为UTC时间。
b) Timestamp fromUtcTime(UtcTimeVal val)。这个函数从一个UtcTimeVal构建。
Timestamp的成员函数:
1. time_t epochTime() const
返回一个以epoch time计算的日历时间(精度秒)。(函数内部会把基于UTC时间的值转为基于epoch time的值)
2. UtcTimeVal utcTime() const
返回一个以UTC时间计算的日历时间(精度100纳秒)。
3. TimeVal epochMicroseconds() const
返回一个以epoch time计算的日历时间(精度微秒)
4. void update()
取当前的时间更新
5. TimeDiff elapsed() const
返回当前时间与Timestamp内部时间_ts的一个时间差值(精度微秒)
6. bool isElapsed(TimeDiff interval) const
如果当前时间与Timestamp内部时间_ts的一个时间差值大于interval时间,返回true。(精度微秒)
Timestamp算术计算:
1. Timestamp operator + (TimeDiff diff) const
增加一个时间偏移,并返回值。(精度微秒)
2. Timestamp operator - (TimeDiff diff) const
减掉一个时间偏移,并返回值。(精度微秒)
3. TimeDiff operator - (const Timestamp& ts) const
返回两个Timestamp对象的时间偏移。(精度微秒)
4. Timestamp& operator += (TimeDiff d)
Timestamp& operator -= (TimeDiff d)
增加或减小一个时间偏移值
下面来看一个例子:
#include "Poco/Timestamp.h" #include <ctime> using Poco::Timestamp; int main(int argc, char** argv) { Timestamp now; // the current date and time std::time_t t1 = now.epochTime(); // convert to time_t ... Timestamp ts1(Timestamp::fromEpochTime(t1)); // ... and back again for (int i = 0; i < 100000; ++i) ; // wait a bit Timestamp::TimeDiff diff = now.elapsed(); // how long did it take? Timestamp start(now); // save start time now.update(); // update with current time diff = now - start; // again, how long? return 0; }
3. DateTime类
Poco中提供了DateTime类,作用和tm类似。下面是它的定义:class Foundation_API DateTime { public: enum Months /// Symbolic names for month numbers (1 to 12). { JANUARY = 1, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER }; enum DaysOfWeek /// Symbolic names for week day numbers (0 to 6). { SUNDAY = 0, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY }; DateTime(); /// Creates a DateTime for the current date and time. DateTime(const Timestamp& timestamp); /// Creates a DateTime for the date and time given in /// a Timestamp. DateTime(int year, int month, int day, int hour = 0, int minute = 0, int second = 0, int millisecond = 0, int microsecond = 0); /// Creates a DateTime for the given Gregorian date and time. /// * year is from 0 to 9999. /// * month is from 1 to 12. /// * day is from 1 to 31. /// * hour is from 0 to 23. /// * minute is from 0 to 59. /// * second is from 0 to 59. /// * millisecond is from 0 to 999. /// * microsecond is from 0 to 999. DateTime(double julianDay); /// Creates a DateTime for the given Julian day. DateTime(Timestamp::UtcTimeVal utcTime, Timestamp::TimeDiff diff); /// Creates a DateTime from an UtcTimeVal and a TimeDiff. /// /// Mainly used internally by DateTime and friends. DateTime(const DateTime& dateTime); /// Copy constructor. Creates the DateTime from another one. ~DateTime(); /// Destroys the DateTime. DateTime& operator = (const DateTime& dateTime); /// Assigns another DateTime. DateTime& operator = (const Timestamp& timestamp); /// Assigns a Timestamp. DateTime& operator = (double julianDay); /// Assigns a Julian day. DateTime& assign(int year, int month, int day, int hour = 0, int minute = 0, int second = 0, int millisecond = 0, int microseconds = 0); /// Assigns a Gregorian date and time. /// * year is from 0 to 9999. /// * month is from 1 to 12. /// * day is from 1 to 31. /// * hour is from 0 to 23. /// * minute is from 0 to 59. /// * second is from 0 to 59. /// * millisecond is from 0 to 999. /// * microsecond is from 0 to 999. void swap(DateTime& dateTime); /// Swaps the DateTime with another one. int year() const; /// Returns the year. int month() const; /// Returns the month (1 to 12). int week(int firstDayOfWeek = MONDAY) const; /// Returns the week number within the year. /// FirstDayOfWeek should be either SUNDAY (0) or MONDAY (1). /// The returned week number will be from 0 to 53. Week number 1 is the week /// containing January 4. This is in accordance to ISO 8601. /// /// The following example assumes that firstDayOfWeek is MONDAY. For 2005, which started /// on a Saturday, week 1 will be the week starting on Monday, January 3. /// January 1 and 2 will fall within week 0 (or the last week of the previous year). /// /// For 2007, which starts on a Monday, week 1 will be the week startung on Monday, January 1. /// There will be no week 0 in 2007. int day() const; /// Returns the day witin the month (1 to 31). int dayOfWeek() const; /// Returns the weekday (0 to 6, where /// 0 = Sunday, 1 = Monday, ..., 6 = Saturday). int dayOfYear() const; /// Returns the number of the day in the year. /// January 1 is 1, February 1 is 32, etc. int hour() const; /// Returns the hour (0 to 23). int hourAMPM() const; /// Returns the hour (0 to 12). bool isAM() const; /// Returns true if hour < 12; bool isPM() const; /// Returns true if hour >= 12. int minute() const; /// Returns the minute (0 to 59). int second() const; /// Returns the second (0 to 59). int millisecond() const; /// Returns the millisecond (0 to 999) int microsecond() const; /// Returns the microsecond (0 to 999) double julianDay() const; /// Returns the julian day for the date and time. Timestamp timestamp() const; /// Returns the date and time expressed as a Timestamp. Timestamp::UtcTimeVal utcTime() const; /// Returns the date and time expressed in UTC-based /// time. UTC base time is midnight, October 15, 1582. /// Resolution is 100 nanoseconds. bool operator == (const DateTime& dateTime) const; bool operator != (const DateTime& dateTime) const; bool operator < (const DateTime& dateTime) const; bool operator <= (const DateTime& dateTime) const; bool operator > (const DateTime& dateTime) const; bool operator >= (const DateTime& dateTime) const; DateTime operator + (const Timespan& span) const; DateTime operator - (const Timespan& span) const; Timespan operator - (const DateTime& dateTime) const; DateTime& operator += (const Timespan& span); DateTime& operator -= (const Timespan& span); void makeUTC(int tzd); /// Converts a local time into UTC, by applying the given time zone differential. void makeLocal(int tzd); /// Converts a UTC time into a local time, by applying the given time zone differential. static bool isLeapYear(int year); /// Returns true if the given year is a leap year; /// false otherwise. static int daysOfMonth(int year, int month); /// Returns the number of days in the given month /// and year. Month is from 1 to 12. static bool isValid(int year, int month, int day, int hour = 0, int minute = 0, int second = 0, int millisecond = 0, int microsecond = 0); /// Checks if the given date and time is valid /// (all arguments are within a proper range). /// /// Returns true if all arguments are valid, false otherwise. protected: // ... private: // ... Timestamp::UtcTimeVal _utcTime; short _year; short _month; short _day; short _hour; short _minute; short _second; short _millisecond; short _microsecond; };
Poco::DateTime是基于格里高利历(Gregorian calendar)(就是公历啦)设计的。它除了可以用来保存日历时间外,还可以被用于日期计算。如果只是为了日历时间的存储,Timestamp类更加适合。在DateTime的内部,DateTime类用两种格式维护了日期和时间。第一种是UTC日历时间。第二种是用年、月、日、时、分、秒、微秒、毫秒。为了进行内部时间日期之间的换算,DateTime使用了儒略日(Julian day)历法。
格里高利历(Gregorian calendar)
格里高利历就是我们通常讲的公历。它以耶稣的诞生为初始年份,也就是公元0001年。格里高利历以日为基本单位,1年有365或366天,分成12个月,每个月时长不等。由于不同国家采用格里高利历时间不同(德国1582, 英国1752),所以格里高利历日期和旧式的日期有差别,即使是用来表示历史上相同的一件事。一个耶稣像,^_^。
_ xxxx _
/_;-.__ / _\ _.-;_\
`-._`'`_/'`.-'
`\ /`
| /
/-.(
\_._\
\ \`;
> |/
/ //
|//
\(\
儒略日和儒略日日期
儒略日的起点订在公元前4713年(天文学上记为 -4712年)1月1日格林威治时间平午(世界时12:00),即JD 0指定为UT时间B.C.4713年1月1日12:00到UC时间B.C.4713年1月2日12:00的24小时。注意这一天是礼拜一。每一天赋予了一个唯一的数字,顺数而下,如:1996年1月1日12:00:00的儒略日是2450084。这个日期是考虑了太阳、月亮的轨道运行周期,以及当时收税的间隔而订出来的。Joseph Scliger定义儒略周期为7980年,是因28、19、15的最小公倍数为28×19×15=7980。
日期的注意事项:
1. 0是一个合法数字(根据ISO 8691和天文年编号)
2. 0年是一个闰年。
3. 负数是不支持的。比如说公元前1年。
4. 格里高利历同历史上的日期可能不同,由于它们采用的日历方式不同。
5. 最好只是用DateTime用来计算当前的时间。对于历史上的或者天文日历的时间计算,还是使用其他的特定软件。
构造DateTime:
1. 可以从一个已有的DateTime构造
2. 当前的时间和日期
3. 一个Timestamp对象
4. 用年、月、日、时、分、秒、微秒、毫秒构造
5. 使用一个儒略日日期构造(用double形式保存)
成员函数:
1. int year() const
返回年
2. int month() const
返回月(1-12)
3. int week(int firstDayOfWeek = DateTime::MONDAY) const
返回所在的周,根据ISO 8601标准(第一周是1月4日所在的周),一周的第一天是礼拜一或者礼拜天。
4. int day() const
返回月中的所在天(1 - 31)
5. int dayOfWeek() const
返回周中的所在天 0为周日,1为周一,.....
6. int dayOfYear() const
返回年中的所在天(1 - 366)
7. int hour() const
返回天中所在小时(0 - 23)
8. int hourAMPM() const
返回上下午所在小时(0 - 12)
9. bool isAM() const
如果上午返回真
10. bool isPM() const
如果下午返回真
11. int minute() const
返回分钟数(0 - 59)
12. int second() const
返回秒数(0 - 59)
13. int millisecond() const
返回毫秒数(0 - 999)
14. int microsecond() const
返回微秒数(0 - 999)
15. Timestamp timestamp() const
返回用Timestamp保存的日历时间(精度微秒)
16. Timestamp::UtcTimeVal utcTime() const
返回用Timestamp保存的日历时间(精度100纳秒)
17. DateTime支持关系运算符(==, !=, >, >=, <, <=).
18. DateTime支持算术操作(+, -, +=, -=)
静态函数:
1. bool isLeapYear(int year)
所给年是否闰年
2. int daysOfMonth(int year, int month)
所给年和月的天数
3. bool isValid(int year, int month, int day, int hour, int minute, int second, int millisecond, int microsecond)
判断所给年月日是否合法
下面是DateTime的一个例子:
#include "Poco/DateTime.h" using Poco::DateTime; int main(int argc, char** argv) { DateTime now; // the current date and time in UTC int year = now.year(); int month = now.month(); int day = now.day(); int dow = now.dayOfWeek(); int doy = now.dayOfYear(); int hour = now.hour(); int hour12 = now.hourAMPM(); int min = now.minute(); int sec = now.second(); int ms = now.millisecond(); int us = now.microsecond(); double jd = now.julianDay(); Poco::Timestamp ts = now.timestamp(); DateTime xmas(2006, 12, 25); // 2006-12-25 00:00:00 Poco::Timespan timeToXmas = xmas - now; DateTime dt(1973, 9, 12, 2, 30, 45); // 1973-09-12 02:30:45 dt.assign(2006, 10, 13, 13, 45, 12, 345); // 2006-10-13 12:45:12.345 bool isAM = dt.isAM(); // false bool isPM = dt.isPM(); // true bool isLeap = DateTime::isLeapYear(2006); // false int days = DateTime::daysOfMonth(2006, 2); // 28 bool isValid = DateTime::isValid(2006, 02, 29); // false dt.assign(2006, DateTime::OCTOBER, 22); // 2006-10-22 00:00:00 if (dt.dayOfWeek() == DateTime::SUNDAY) { // ... } return 0; }
4. LocalDateTime类
Poco::LocalDateTime同Poco::DateTime类似,不同的是Poco::LocalDateTime存储一个本地时间。关于本地时间和UTC时间有如下计算公式:(UTC时间 = 本地时间 - 时区差).
构造函数:
1. 通过当前时间构造
2. 通过Timestamp对象
3. 通过年、月、日、时、分、秒、微秒、毫秒构造
4. 通过儒略日时间构造(儒略日时间用double存储)
5. 作为可选项。时区可作为构造时第一个参数被指定。(如果没有指定的话,会使用系统当前的时区)
成员函数:
1. LocalDateTime支持所有的DateTime的函数。
2. 在进行比较之前,所有的关系操作符函数会把时间都换算为UTC时间
3. int tzd() const
返回时区差
4. DateTime utc() const
转换本地时间到utc时间
下面是一个例子:
#include "Poco/LocalDateTime.h" using Poco::LocalDateTime; int main(int argc, char** argv) { LocalDateTime now; // the current date and local time int year = now.year(); int month = now.month(); int day = now.day(); int dow = now.dayOfWeek(); int doy = now.dayOfYear(); int hour = now.hour(); int hour12 = now.hourAMPM(); int min = now.minute(); int sec = now.second(); int ms = now.millisecond(); int us = now.microsecond(); int tzd = now.tzd(); double jd = now.julianDay(); Poco::Timestamp ts = now.timestamp(); LocalDateTime dt1(1973, 9, 12, 2, 30, 45); // 1973-09-12 02:30:45 dt1.assign(2006, 10, 13, 13, 45, 12, 345); // 2006-10-13 12:45:12.345 LocalDateTime dt2(3600, 1973, 9, 12, 2, 30, 45, 0, 0); // UTC +1 hour dt2.assign(3600, 2006, 10, 13, 13, 45, 12, 345, 0); Poco::Timestamp nowTS; LocalDateTime dt3(3600, nowTS); // construct from Timestamp return 0; }
5. Timespan类
Poco::Timespan能够提供一个微秒精度的时间间隔,也可以用天、小时、分钟、秒、微秒、毫秒来表示。在其内部这个时间间隔用一个64-bit整形来表示。构造函数:
1. 一个TimeStamp::TimeDiff对象(微秒精度)
2. 秒+微秒
主要用于从timeval结构体构建
3. 通过日、时、分、秒、微秒构造
操作符:
1. Poco::Timespan支持所有的关系操作符
(==, !=, <, <=, >, >=)
2. Poco::Timespan支持加法和减法操作
(+, -, +=, -=)
成员函数:
1. int days() const
返回时间跨度的天
2. int hours() const
返回时间跨度的小时(0 - 23)
3. int totalHours() const
返回时间跨度总的小时数
4. int minutes() const
返回时间跨度的分钟(0 - 59)
5. int totalMinutes() const
返回时间跨度总的分钟数
6. int seconds() const
返回时间跨度的秒(0 - 60)
7. int totalSeconds() const
返回时间跨度总的秒数
8. int milliseconds() const
返回时间跨度的毫秒((0 - 999)
9. int totalMilliseconds() const
返回时间跨度总的毫秒数
10. int microseconds() const
返回时间跨度的微秒( (0 - 999)
11. int totalMicroseconds() const
返回时间跨度总的微秒数
下面是一个例子:
#include "Poco/Timespan.h" using Poco::Timespan; int main(int argc, char** argv) { Timespan ts1(1, 11, 45, 22, 123433); // 1d 11h 45m 22.123433s Timespan ts2(33*Timespan::SECONDS); // 33s Timespan ts3(2*Timespan::DAYS + 33*Timespan::HOURS); // 3d 33h int days = ts1.days(); // 1 int hours = ts1.hours(); // 11 int totalHours = ts1.totalHours(); // 35 int minutes = ts1.minutes(); // 45 int totalMins = ts1.totalMinutes(); // 2145 int seconds = ts1.seconds(); // 22 int totalSecs = ts1.totalSeconds(); // 128722 return 0; }
下面来看一个DateTime, LocalDateTime和Timespan的混合例子:
#include "Poco/DateTime.h" #include "Poco/Timespan.h" using Poco::DateTime; using Poco::Timespan; int main(int argc, char** argv) { // what is my age? DateTime birthdate(1973, 9, 12, 2, 30); // 1973-09-12 02:30:00 DateTime now; Timespan age = now - birthdate; int days = age.days(); // in days int hours = age.totalHours(); // in hours int secs = age.totalSeconds(); // in seconds // when was I 10000 days old? Timespan span(10000*Timespan::DAYS); DateTime dt = birthdate + span; return 0; }
6. Timezone类
Poco::Timezone提供静态函数用于获取时区信息和夏令时信息。1. 时区差
2. 是否采用夏时制(daylight saving time (DST))
3. 时区名
成员函数:
1. int utcOffset()
返回本地时间相对于UTC时间的差值(精度秒)。不包括夏令时偏移:
(local time = UTC + utcOffset())
2. int dst()
返回夏令时偏移。通常是固定值3600秒。0的话表示无夏令时。
3. bool isDst(const Timestamp& timestamp)
对于给定的timestamp时间测试,是否使用夏令时
4. int tzd()
返回本地时间相对于UTC时间的差值(精度秒)。包括夏令时偏移:
(tzd = utcOffset() + dst())
5. std::string name()
返回当前的时区名
6. std::string standardName()
返回当前的标准时区名(如果不采用夏令时)
7. std::string dstName()
返回当前的时区名(如果采用夏令时)
8. 时区名的返回依赖于操作系统,并且名称不具有移植性,仅作显示用。
下面是一个使用的例子:
#include "Poco/Timezone.h" #include "Poco/Timestamp.h" using Poco::Timezone; using Poco::Timestamp; int main(int argc, char** argv) { int utcOffset = Timezone::utcOffset(); int dst = Timezone::dst(); bool isDst = Timezone::isDst(Timestamp()); int tzd = Timezone::tzd(); std::string name = Timezone::name(); std::string stdName = Timezone::standardName(); std::string dstName = Timezone::dstName(); return 0; }
6. Poco::DateTimeFormatter类
Poco::DateTimeFormatter用来定义当Timestamp, DateTime, LocalDateTime and Timespan转换为字符串时所需的日期和事件格式。Poco::DateTimeFormatter的作用和strftime()是类似的。Poco::DateTimeFormat内部定义了一些约定的格式。1. ISO8601_FORMAT (2005-01-01T12:00:00+01:00)
2. RFC1123_FORMAT (Sat, 1 Jan 2005 12:00:00 +0100)
3. SORTABLE_FORMAT (2005-01-01 12:00:00)
4. For more information, please see the reference documentation.
成员函数:
所有的DateTimeFormatter函数都是静态的。
下面是一个使用的例子:
#include "Poco/Timestamp.h" #include "Poco/Timespan.h" #include "Poco/DateTimeFormatter.h" #include "Poco/DateTimeFormat.h" using Poco::DateTimeFormatter; using Poco::DateTimeFormat; int main(int argc, char** argv) { Poco::DateTime dt(2006, 10, 22, 15, 22, 34); std::string s(DateTimeFormatter::format(dt, "%e %b %Y %H:%M")); // "22 Oct 2006 15:22" Poco::Timestamp now; s = DateTimeFormatter::format(now, DateTimeFormat::SORTABLE_FORMAT); // "2006-10-30 09:27:44" Poco::Timespan span(5, 11, 33, 0, 0); s = DateTimeFormatter::format(span, "%d days, %H hours, %M minutes"); // "5 days, 11 hours, 33 minutes" return 0; }
7. Poco::DateTimeParser类
Poco::DateTimeParser用来从字符串中解析时间和日期。下面是其一个例子:#include "Poco/DateTimeParser.h" #include "Poco/DateTime.h" #include "Poco/DateTimeFormat.h" #include "Poco/LocalDateTime.h" #include "Poco/Timestamp.h" using Poco::DateTimeParser; using Poco::DateTimeFormat; using Poco::DateTime; int main(int argc, char** argv) { std::string s("Sat, 1 Jan 2005 12:00:00 GMT"); int tzd; DateTime dt; DateTimeParser::parse(DateTimeFormat::RFC1123_FORMAT, s, dt, tzd); Poco::Timestamp ts = dt.timestamp(); Poco::LocalDateTime ldt(tzd, dt); bool ok = DateTimeParser::tryParse("2006-10-22", dt, tzd); ok = DateTimeParser::tryParse("%e.%n.%Y", "22.10.2006", dt, tzd); return 0; }
8. Stopwatch类
Stopwatch用来测量时间差值,精度为微秒.下面是其定义:class Foundation_API Stopwatch /// A simple facility to measure time intervals /// with microsecond resolution. /// /// Note that Stopwatch is based on the Timestamp /// class. Therefore, if during a Stopwatch run, /// the system time is changed, the measured time /// will not be correct. { public: Stopwatch(); ~Stopwatch(); void start(); /// Starts (or restarts) the stopwatch. void stop(); /// Stops or pauses the stopwatch. void reset(); /// Resets the stopwatch. void restart(); /// Resets and starts the stopwatch. Timestamp::TimeDiff elapsed() const; /// Returns the elapsed time in microseconds /// since the stopwatch started. int elapsedSeconds() const; /// Returns the number of seconds elapsed /// since the stopwatch started. static Timestamp::TimeVal resolution(); /// Returns the resolution of the stopwatch. private: Stopwatch(const Stopwatch&); Stopwatch& operator = (const Stopwatch&); Timestamp _start; Timestamp::TimeDiff _elapsed; bool _running; };
附录:
1. The Gregorian Calendar: http://en.wikipedia.org/wiki/Gregorian_calendar2. The Julian Calendar:http://en.wikipedia.org/wiki/Julian_calendar
3. The Julian Day:http://en.wikipedia.org/wiki/Julian_day
4. Coordinated Universal Time (UTC):http://en.wikipedia.org/wiki/UTC
5. ISO 8601:http://en.wikipedia.org/wiki/ISO_8601