POCO C++库学习和分析 -- 日期与时间
在Poco库中,与时间和日期相关的一些类,其内部实现是非常简单的。看相关文档时,比较有意思的倒是历史上的不同时间表示法。
1. 系统时间函数
在编程时,时间函数不可避免的会被使用。linux系统下相关时间的数据结构有time_t,timeval,timespec,tm,clock_t; windows下time_t,tm,SYSTEMTIME,clock_t。其中clock_t、timeval、timespec用于表示时间跨度,time_t、tm、SYSTEMTIME用于表示绝对时间。不同的数据结构之间,多少也有些差异。 首先 这些时间结构体的精度不同,Second(time_t/tm), microsecond(timeval/SYSTEMTIME), nanoSeconds(timespec)。
起始时间不同,time_t起始于1970年1月1日0时0分0秒,tm表示起始于1900年,SYSTEMTIME起始于1601年,clock起始于机器开机。
同这些数据结构相关联,C语言为tm,time_t提供了一组函数用于时间运算和数据结构转换:
[cpp] view plaincopy
1. // 日历时间(一个用time_t表示的整数) 2.
3. // 比较日历时间
4. double difftime(time_t time1, time_t time0); 5. // 获取日历时间
6. time_t time(time_t * timer); 7. // 转换日历时间为字符串
8. char * ctime(const time_t *timer);
9. // 转换日历时间为我们平时看到的把年月日时分秒分开显示的时间格式tm(GMT timezone) 10. struct tm * gmtime(const time_t *timer);
11. // 转换日历时间为我们平时看到的把年月日时分秒分开显示的时间格式tm(本地 timezone) 12. struct tm * localtime(const time_t * timer); 13. // 关于本地时间的计算公式:
14. localtime = utctime[Gmt time] + utcOffset()[时区偏移] + dst()[夏令时偏移] 15. 16.
17. // 把tm转换为字符串
18. char * asctime(const struct tm * timeptr); 19. // 把tm转换为日历时间
20. time_t mktime(struct tm * timeptr); 21. 22.
23. // 获取开机以来的微秒数 24. clock_t clock (void);
我们回想一下程序中的时间数据结构和函数的用法,可以发现主要是2个目的:
1. 获取绝对时间
2. 获取两个时间点的相对时间
2. Timestamp类
同C语言中函数类似,Poco中定义了自己的时间类。Timestamp类似于time_t,用于获取比较日历时间。Timestamp定义如下:
[cpp] view plaincopy
1. class Foundation_API Timestamp 2. { 3. public:
4. typedef Int64 TimeVal; /// monotonic UTC time value in microsecond resolution 5. typedef Int64 UtcTimeVal; /// monotonic UTC time value in 100 nanosecond resolution 6. typedef Int64 TimeDiff; /// difference between two timestamps in microseconds 7.
8. Timestamp();
9. /// Creates a timestamp with the current time. 10.
11. Timestamp(TimeVal tv);
12. /// Creates a timestamp from the given time value. 13.
14. Timestamp(const Timestamp& other); 15. /// Copy constructor. 16.
17. ~Timestamp();
18. /// Destroys the timestamp 19.
20. Timestamp& operator = (const Timestamp& other); 21. Timestamp& operator = (TimeVal tv); 22.
23. void swap(Timestamp& timestamp);
24. /// Swaps the Timestamp with another one. 25.
26. void update();
27. /// Updates the Timestamp with the current time. 28. 29.
30. bool operator == (const Timestamp& ts) const; 31. bool operator != (const Timestamp& ts) const; 32. bool operator > (const Timestamp& ts) const; 33. bool operator >= (const Timestamp& ts) const; 34. bool operator < (const Timestamp& ts) const; 35. bool operator <= (const Timestamp& ts) const; 36.
37. Timestamp operator + (TimeDiff d) const;
38. Timestamp operator - (TimeDiff d) const;
39. TimeDiff operator - (const Timestamp& ts) const; 40. Timestamp& operator += (TimeDiff d); 41. Timestamp& operator -= (TimeDiff d); 42.
43. std::time_t epochTime() const;
44. /// Returns the timestamp expressed in time_t. 45. /// time_t base time is midnight, January 1, 1970. 46. /// Resolution is one second. 47.
48. UtcTimeVal utcTime() const;
49. /// Returns the timestamp expressed in UTC-based 50. /// time. UTC base time is midnight, October 15, 1582. 51. /// Resolution is 100 nanoseconds. 52.
53. TimeVal epochMicroseconds() const;
54. /// Returns the timestamp expressed in microseconds 55. /// since the Unix epoch, midnight, January 1, 1970. 56.
57. TimeDiff elapsed() const;
58. /// Returns the time elapsed since the time denoted by 59. /// the timestamp. Equivalent to Timestamp() - *this. 60.
61. bool isElapsed(TimeDiff interval) const;
62. /// Returns true iff the given interval has passed 63. /// since the time denoted by the timestamp. 64.
65. static Timestamp fromEpochTime(std::time_t t); 66. /// Creates a timestamp from a std::time_t. 67.
68. static Timestamp fromUtcTime(UtcTimeVal val); 69. /// Creates a timestamp from a UTC time value. 70.
71. static TimeVal resolution();
72. /// Returns the resolution in units per second. 73. /// Since the timestamp has microsecond resolution, 74. /// the returned value is always 1000000. 75.
76. private:
77. TimeVal _ts; 78. };
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)

