時間和日歷類的設計
C++通用框架的設計 作者:naven
1 介紹
時間和日歷以及時間的格式化處理在軟件的設計中起著非常重要的作用,但是目前C++的庫卻未有一個簡單易用的時間類,大部分都需要開發者直接調用操作系統的API來完成,而且很多API都不是線程安全的。某些大型的C++框架雖然提供一些時間類,但是卻不通用,也很難直接拿出來使用。下面介紹一下參考Java Framework中的時間相關的類來設計并實現C++版本的時間和日歷類。
主要有如下一些類
Time類,對應于Java的java.util.Date類,表示特定的瞬間,精確到毫秒(Linux可精確到微秒,Solaris可精確到十億分之一秒)。Time只表示某時某地的瞬間,從
Calendar 類,對應于Java的java.util.Calendar類,它既表示了Time的精確瞬間,還代表了此時的年、月、日、時區等。它為特定瞬間與一組諸如 YEAR、MONTH、DAY_OF_MONTH、HOUR 等 日歷字段之間的轉換提供了一些方法,并為操作日歷字段(例如獲得下星期的日期)提供了一些方法。瞬間可用微秒值來表示,它是距歷元(即格林威治標準時間
TimeFormat類,類似Java的java.text.SimpleDateFormat類,它用來將時間和日歷格式化成一個本地時間格式的文本形式,或者指定格式的文本形式。如果格式化時間,將缺省使用操作系統設定的本地(locale)時間格式處理。
TimeParser類,類似Java的java.text.SimpleDateFormat類,與TimeFormat相反,它用來將一個時間的文本轉化成一個本地時間Time,缺省使用操作系統設定的本地時間格式處理。
2 Hello World!
下面介紹一下它們的使用
















































編譯程序將輸入如下結果





















3 Time類
由于Time要精確到微秒,所以Time類使用timeval結構存儲時間,該結構包含兩個long整形,一個表示秒數(從
Time類的定義如下















Time類獲取當前精確到微秒的實現如下(Win32提供的API只能精確到豪秒)















































Time類提供很多方法如果構造方法和操作符等,可以在time_t和其他時間類型之間轉換,也可以單獨獲取和設置時間的秒和微秒。
4 Calendar類
Calendar類是一個表示日歷的類,它可以實現日歷的向前向后前進等所有功能。例如你可以設置,獲取,和操縱一個日期對象的各個部分,比方一個月的一天或者是一個星期的一天。舉例如下:

















程序輸出結果




Calendar類是建立在Time類的基礎上的,并加入了時區等信息,它的定義看起來如下所示:




























































Calendar類定義了很多方法和操作符用來在Time類和時區、年月日等之間轉換和設置、讀取等。Calendar類實現時間的生成、轉換等都是自己實現的,并不調用操作系統的API如mktime()等,并不使用CRT(C運行時)的全局變量如timezone等,所以它是線程安全的,每一個Calendar對象都是互相獨立的,擁有自己的時區等信息。
5 TimeFormat類
TimeFormat類主要實現了將時間格式化成一個時間文本,可以使用系統缺省的本地格式,也可以指定格式轉換。轉換的用法如下:




時間格式化pattern有如下幾種
%a The abbreviated weekday name according to the current locale.
%A The full weekday name according to the current locale.
%b The abbreviated month name according to the current locale.
%B The full month name according to the current locale.
%c The preferred date and time representation for the current locale.
%C The century number (year/100) as a 2-digit integer. (SU)
%d The day of the month as a decimal number (range 01 to 31).
%D Equivalent to %m/%d/%y. (Yecch - for Americans only.
Americans should note that in other countries
%d/%m/%y is rather common. This means that in international context
this format is ambiguous and should not be used.) (SU)
%e Like %d, the day of the month as a decimal number, but a leading
zero is replaced by a space. (SU)
%E Modifier: use alternative format, see below. (SU)
%G The ISO 8601 year with century as a decimal number. The 4-digit
year corresponding to the ISO week number (see %V). This has the
same format and value as %y, except that if the ISO week number
belongs to the previous or next year, that year is used instead. (TZ)
%g Like %G, but without century, i.e., with a 2-digit year (00-99). (TZ)
%h Equivalent to %b. (SU)
%H The hour as a decimal number using a 24-hour clock (range 00 to 23).
%I The hour as a decimal number using a 12-hour clock (range 01 to 12).
%j The day of the year as a decimal number (range 001 to 366).
%k The hour (24-hour clock) as a decimal number (range 0 to 23); single
digits are preceded by a blank. (See also %H.) (TZ)
%l The hour (12-hour clock) as a decimal number (range 1 to 12); single
digits are preceded by a blank. (See also %I.) (TZ)
%m The month as a decimal number (range 01 to 12).
%M The minute as a decimal number (range 00 to 59).
%n A newline character. (SU)
%O Modifier: use alternative format, see below. (SU)
%p Either `AM' or `PM' according to the given time value, or the
corresponding strings for the current locale. Noon is treated as `pm'
and midnight as `am'.
%P Like %p but in lowercase: `am' or `pm' or a corresponding string for
the current locale. (GNU)
%r The time in a.m. or p.m. notation. In the POSIX locale this is
equivalent to `%I:%M:%S %p'. (SU)
%R The time in 24-hour notation (%H:%M). (SU) For a version including the
seconds, see %T below.
%s The number of seconds since the Epoch, i.e., since 1970-01-01 00:00:00 UTC.
(TZ)
%S The second as a decimal number (range 00 to 61).
%t A tab character. (SU)
%T The time in 24-hour notation (%H:%M:%S). (SU)
%u The day of the week as a decimal, range 1 to 7, Monday being 1.
See also %w. (SU)
%U The week number of the current year as a decimal number, range 00 to 53,
starting with the first Sun? day as the first day of week 01.
See also %V and %W.
%V The ISO 8601:1988 week number of the current year as a decimal number,
range 01 to 53, where week 1 is the first week that has at least 4 days
in the current year, and with Monday as the first day of the week.
See also %U and %W. (SU)
%w The day of the week as a decimal, range 0 to 6, Sunday being 0. See also %u.
%W The week number of the current year as a decimal number, range 00 to 53,
starting with the first Mon? day as the first day of week 01.
%x The preferred date representation for the current locale without the time.
%X The preferred time representation for the current locale without the date.
%y The year as a decimal number without a century (range 00 to 99).
%Y The year as a decimal number including the century.
%z The time-zone as hour offset from GMT. Required to emit RFC822-conformant
dates (using "%a, %d %b %Y %H:%M:%S %z"). (GNU)
%Z The time zone or name or abbreviation.
%+ The date and time in date(1) format. (TZ)
%% A literal `%' character.
6 TimeParser類
TimeParser類實現與TimeFormat相反的功能,是將一個指定格式的時間文本轉換成時間Time對象或Calendar對象,它的設計與TimeFormat類似,目前還未全部完成,只實現了轉換Mime時間格式的文本的功能。
示例見上面的 Hello World 程序。
C++通用框架的設計 作者:naven 日期:
posted on 2006-03-10 10:56 Beginning to 編程 閱讀(637) 評論(0) 編輯 收藏 引用 所屬分類: 關鍵代碼