# 13.6 存儲和使用日期和時間
wxWidgets提供了一個功能強大的類wxDateTime來進行時間和日期相關的操作,包括:格式化輸出,時區,時間和日期計算等等.還提供了一些靜態函數來提供當前的日期和時間以及查詢某個給定的年份是不是閏年等.注意即使你只想操作日期或者是時間,你仍然可以使用wxDateTime類型. wxTimeSpan和wxDateSpan類型提供了修改一個wxDateTime值的合適的方法.
wxDateTime
wxDateTime類擁有很多的成員函數,每個函數的含義都很清晰.完整的API可以參考wxWidgets的相關手冊,下面只對其中使用最頻繁的函數進行一些介紹.
注意盡管時間在其內部總是以格林威治時間(GMT)存儲的,但是你通常關心的是本地時區的時間而不是格林威治時間,因此, wxDateTime的構造函數以及更改函數中各個組成時間的要素(比如小時,分鐘和秒鐘)等都指的是本地時區的時間.所有用于獲取時間和日期的函數返回的要素(月,日,小時,分,秒等)也都是本地時間.因此,如果這是你需要的,你不需要作任何額外的操作,如果你希望操作不同時區的時間,請參考相關的文檔.
wxDateTime類的構造和更改
wxDateTime可以通過Unix時間戳,僅包含時間的信息,僅包含日期的信息,完整的時間日期信息等途徑創建.對于每一個構造函數,都有一個對應的Set函數用來更改已經設置了值的wxDateTime對象.也可以通過類似SetMonth或者SetHour等函數更改時間或者日期中的某個要素.
wxDateTime(time_t)函數根據一個指定的Unix時間戳來構造對象.
wxDateTime(const struct tm&)函數根據一個指定的C語言標準tm結構構造對象.
wxDateTime(wxDateTime_t hour, wxDateTime_t minute = 0, wxDateTime_t second = 0, wxDateTime_t millisec = 0)根據指定的時間要素構造對象.
wxDateTime(wxDateTime_t day, Month month = Inv_Month, int year = Inv_Year, wxDateTime_t hour = 0, wxDateTime_t minute = 0, wxDateTime_t second = 0, wxDateTime_t millisec = 0) 根據指定的時間和日期要素構造對象
wxDateTime訪問方法
大多數wxDateTime類的訪問函數都是自解釋的,比如: GetYear, GetMonth, Getday, GetWeekDay, GetHour, GetMinute, GetSecond, GetMillisecond, GeTDayOfYear, GetWeekOfYear, GetWeekOfMonth和GetYearDay等. wxDateTime還提供了下列一些訪問函數:
* GetTicks返回一個Unix時間戳(也就是自從1970年1月1日午夜以來的秒數).
* IsValid返回時間日期類是不是已經被初始化(類自使用默認構造函數創建以后始終未被賦值).
獲取當前時間
wxDateTime提供了兩個靜態函數返回當前時間:
* wxDateTime::Now 返回精度為秒的當前時間.
* wxDateTime::UNow 返回精度為毫秒的當前時間.
時間和字符串的轉換
下面介紹的這些函數用來實現時間和字符串的相互轉換.將時間轉化成字符串的方法是比較簡單的:你可以將時間轉換成本地格式的字符串 (FormatDate和FormatTime函數),或者以定義在ISO 8601中的國際標準格式來顯示(FormatISODate函數和FormatISOTime函數),也可以以自定義的格式來顯示(Format函數).
而從文本到時間的轉換則顯得更復雜些,因為可能的時間格式太多了.最簡單的函數是ParseFormat函數,它用來解析那些指定格式的時間文本.ParseRfc822Date函數用來解析那些定義在RFC822中的時間表示方法,這種方法在email或者互聯網上使用比較普遍.
最有趣的文本到時間轉換函數是ParseTime,ParseDate和ParseDateTime函數,它們將盡量匹配各種格式的時間文本.除了預定義的那些標準格式以外,ParseDateTime函數甚至可以支持那些類似"tomorrow"(明天), "March first"(三月一日)以及"next Sunday"(下個星期天)這樣的時間.
日期比較
兩個wxDateTime對象可以通過各種函數進行比較,這些函數都返回bool類型的值.這些函數包括:IsEqualTo, IsEarlierThan, IsLaterThan, IsSameDate和IsSameTime等.
而IsStrictlyBetween和IsBetween則用來比較某個日期是不是在兩個日期之間.這兩個函數的區別在于,如果要比較的時間剛好等于其中的與其比較的邊界值的時候,前者返回False而后者返回True.
日期計算
wxWidgets提供了兩個非常靈活的類wxTimeSpan和wxDateSpan來輔助進行日期和時間的計算. wxTimeSpan用來計算那些以毫秒為單位的,跨度不大的,快速的和精確的計算,而wxDateSpan則用來進行跨度比較大的比如幾周或者幾個月的計算.wxDateSpan將盡可能使用更自然的方法來進行計算,因此其含義有時候并不象它看上去的那樣精確.比如1月31日加上一個月將返回二月28日 (或29日),也就是說是二月的最后一天,而不是永遠不可能存在的二月31日.通常,你比較喜歡這樣的結果,不過有時候相應的減法運算可能也會把你搞糊涂,比如二月28日減去一個月的結果的一月28日而不是一月31日.
日期類型可以進行的操作很多,但是這些操作的組合卻未必是有效的.比如:對一個日期進行乘法運算是無效的,而對于任何一個表示時間間隔的類(wxTimeSpan或wxDateSpan)進行乘法運算則沒有任何問題.
* 加法: wxTimeSpan或wxDateSpan可以和wxDateTime進行加法運算,返回一個新的wxDateTime對象. 兩個相同類型的時間間隔類也可以進行加法運算,返回一個新的同樣類型的對象.
* 減法: 減法適用和加法同樣的規則,額外的一個規則是兩個wxDateTime對象相減返回一個wxTimeSpan對象.
* 乘法: wxTimeSpan或wxDateSpan對象可以乘以一個整數,返回一個同樣類型的對象.
* Unary相減:wxTimeSpan或wxDateSpan對象可以定義為負數,導致相反的時間方向上的同樣的間隔.
下面的例子演示了wxDateSpan和wxTimeSpan的用法,更多的用法請參考wxWidgets的相關手冊.
```
void TimeTests()
{
// 獲取當前時間和日期
wxDateTime DT1 = wxDateTime::Now();
// 創建一個2星期零1天,或者說15天的間隔
wxDateSpan Span1(0, 0, 2, 1);
// 今天減去15天
wxDateTime DT2 = DT1 - Span1;
// 用靜態方法創建一天的間隔
wxDateSpan Span2 = wxDateSpan::Day();
// Span3將代表14天的間隔
wxDateSpan Span3 = Span1 - Span2;
// 0 天 (這個間隔將用2周來表示)
int Days = Span3.GetDays();
// 14 天 (2 周)
int TotalDays = Span3.GetTotalDays();
// 之前兩周
wxDateSpan Span4 = -Span3;
// 3個月的間隔
wxDateSpan Span5 = wxDateSpan::Month() * 3;
// 10小時5分6秒的間隔
wxTimeSpan Span6(10, 5, 6, 0);
// DT2增加固定的間隔Span6
wxDateTime DT3 = DT2 + Span6;
// Span7是相反方向上的3倍Span6的間隔.
wxTimeSpan Span7 = (-Span6) * 3;
// SpanNeg將返回True, 這個間隔是負方向的.
bool SpanNeg = Span7.IsNegative();
// 適用靜態方法創建一個1小時的間隔
wxTimeSpan Span8 = wxTimeSpan::Hour();
// 1小時當然小于30小時(這里使用絕對值)
bool Longer = Span8.IsLongerThan(Span7);
}
```
- 第一章 介紹
- 1.1 為什么要使用wxWidgets?
- 1.2 wxWidgets的歷史
- 1.3 wxWidgets社區
- 1.4 wxWidgets和面向對象編程
- 1.5 wxWidgets的體系結構
- 1.6 許可協議
- 第一章小結
- 第二章 開始使用
- 2.1 一個小例子
- 2.2 應用程序類
- 2.3 Frame窗口類
- 2.4 事件處理函數
- 2.5 Frame窗口的構造函數
- 2.6 完整的例子
- 2.7 wxWidgets程序一般執行過程
- 2.8 編譯和運行程序
- 第二章小結
- 第三章 事件處理
- 3.1 事件驅動編程
- 3.2 事件表和事件處理過程
- 3.3 過濾某個事件
- 3.4 掛載事件表
- 3.5 動態事件處理方法
- 3.6 窗口標識符
- 3.7 自定義事件
- 第三章小結
- 第四章 窗口的基礎知識
- 4.1 窗口解析
- 4.2 窗口類概覽
- 4.3 基礎窗口類
- 4.4 頂層窗口
- 4.5 容器窗口
- 4.6 非靜態控件
- 4.7 靜態控件
- 4.8 菜單
- 4.9 控制條
- 第四章小結
- 第五章繪畫和打印
- 5.1 理解設備上下文
- 5.2 繪畫工具
- 5.3 設備上下文中的繪畫函數
- 5.4 使用打印框架
- 5.5 使用wxGLCanvas繪制三維圖形
- 第五章小節
- 第六章處理用戶輸入
- 6.1 鼠標輸入
- 6.2 處理鍵盤事件
- 6.3 處理游戲手柄事件
- 第六章小結
- 第七章使用布局控件進行窗口布局
- 7.1 窗口布局基礎
- 7.2 窗口布局控件
- 7.3 使用布局控件進行編程
- 7.4 更多關于布局的話題
- 第七章小結
- 第八章使用標準對話框
- 8.1信息對話框
- 8.2 文件和目錄對話框
- 8.3 選擇和選項對話框
- 8.4 輸入對話框
- 8.5 打印對話框
- 第八章小結
- 第九章創建定制的對話框
- 9.1 創建定制對話框的步驟
- 9.2 一個例子:PersonalRecordDialog
- 9.3 在小型設備上調整你的對話框
- 9.4 一些更深入的話題
- 9.5 使用wxWidgets資源文件
- 第九章小結
- 第十章使用圖像編程
- 10.1 wxWidgets中圖片相關的類
- 10.2 使用wxBitmap編程
- 10.3 使用wxIcon編程
- 10.4 使用wxCursor編程
- 10.5 使用wxImage編程
- 10.6 圖片列表和圖標集
- 10.7 自定義wxWidgets提供的小圖片
- 第十章小結
- 第十一章剪貼板和拖放操作
- 11.1 數據對象
- 11.2 使用剪貼板
- 11.3 實現拖放操作
- 第十一章小結
- 第十二章高級窗口控件
- 12.1 wxTreeCtrl
- 12.2 wxListCtrl
- 12.3 wxWizard
- 12.4 wxHtmlWindow
- 12.5 wxGrid
- 12.6 wxTaskBarIcon
- 12.7 編寫自定義的控件
- 第十二章小結
- 第十三章數據結構類
- 13.1 為什么沒有使用STL?
- 13.2 字符串類型
- 13.3 wxArray
- 13.4 wxList和wxNode
- 13.5 wxHashMap
- 13.6 存儲和使用日期和時間
- 13.7 其它常用的數據類型
- 第十三章小結
- 第十四章文件和流操作
- 14.1 文件類和函數
- 14.2 流操作相關類
- 第十四章小結
- 第十五章內存管理,調試和錯誤處理
- 15.1 內存管理基礎
- 15.2 檢測內存泄漏和其它錯誤
- 15.3 構建自防御的程序
- 15.4 錯誤報告
- 15.5 提供運行期類型信息
- 15.6 使用wxModule
- 15.7 加載動態鏈接庫
- 15.8 異常處理
- 15.9 調試提示
- 第十五章小結
- 第十六章編寫國際化程序
- 16.1 國際化介紹
- 16.2 從翻譯說起
- 16.3 字符編碼和Unicode
- 16.4 數字和日期
- 16.5 其它媒介
- 16.6 一個小例子
- 第十六章小結
- 第十七章編寫多線程程序
- 17.1 什么時候使用多線程,什么時候不要使用
- 17.2 使用wxThread
- 17.3 用于線程同步的對象
- 17.4 多線程的替代方案
- 第十七章小結
- 第十八章使用wxSocket編程
- 18.1 Socket類和功能概覽
- 18.2 Socket及其基本處理介紹
- 18.3 Socket標記
- 18.4 使用Socket流
- 18.5 替代wxSocket
- 第十八章小結
- 第十九章使用文檔/視圖框架
- 19.1 文檔/視圖基礎
- 19.2 文檔/視圖框架的其它能力
- 19.3 實現Undo/Redo的策略
- 第十九章小結
- 第二十章完善你的應用程序
- 20.1 單個實例和多個實例
- 20.2 更改事件處理機制
- 20.3 降低閃爍
- 20.4 實現聯機幫助
- 20.5 解析命令行參數
- 20.6 存儲應用程序資源
- 20.7 調用別的應用程序
- 20.8 管理應用程序設置
- 20.9 應用程序安裝
- 20.10 遵循用戶界面設計規范
- 20.11 全書小結