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]
// 日歷時間(一個用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);
// 日歷時間(一個用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);
我們回想一下程序中的時間數據結構和函數的用法,可以發現主要是2個目的:
1. 獲取絕對時間
2. 獲取兩個時間點的相對時間
2. Timestamp類
同C語言中函數類似,Poco中定義了自己的時間類。Timestamp類似於time_t,用於獲取比較日歷時間。Timestamp定義如下:
[cpp]
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;
};
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)
增加或減小一個時間偏移值
下面來看一個例子:
[cpp]
#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;
}
#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類似。下面是它的定義:
[cpp]
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;
};
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的一個例子:
[cpp]
#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;
}
#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時間
下面是一個例子:
[cpp]
#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;
}
#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
返回時間跨度總的微秒數
下面是一個例子:
[cpp]
#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;
}
#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的混合例子:
[cpp]
#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;
}
#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. 時區名的返回依賴於操作系統,並且名稱不具有移植性,僅作顯示用。
下面是一個使用的例子:
[cpp]
#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;
}
#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函數都是靜態的。
下面是一個使用的例子:
[cpp]
#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;
}
#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用來從字符串中解析時間和日期。下面是其一個例子:
[cpp]
#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;
}
#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用來測量時間差值,精度為微秒.下面是其定義:
[cpp]
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;
};
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;
};