C/C++ 日付と時刻
C/C++ 日付と時刻
「日付・時刻」の取り扱い準備
C言語 と C++ では、「時付・時刻」の関数が若干異なるようで、C言語用関数を cpp で #include <iostream> で使用すると、実行出来ない訳ではないが warning err が発生する。
※localtime(), gmtime() で発生。time() では発生しない。
例えば localtime_s() とする場合でも、変数の使用方法(宣言)や、パラメータが異なるなどなんとも厄介。
取り合えず、C言語の「日付・時刻」関数に慣れてから、C++ の関数を見て行こうと思う。
※MS の説明ではかなり関数が増殖しているようである。.NET/MS独自拡張?の区別も現状把握していない。
※MS では、localtime_s() 推奨のようであるが、linux 等では localtime_r() などというのも有るらしく 何が標準なのやら・・・。
※C言語仕様では、構造体 tm 変数利用上のセキュリティ的な問題があるらしい。
▲上へ
「日付・時刻」関数
※要 #include <time.h>※cpp で iostream をインクルードすると Warning C4996: が出て localtime_s 等、_s 拡張関数使用指示が出るが、実行は可能。stdio.h なら cpp でも Warning 出ず。
※注:_s 付き関数は、MS拡張?のため移植性が無い。
- 現在の日時を取得
- time ・・・ システムの日時を取得
- time_t=time(*time_t); // cpp worning 無し。
- clock ・・・ システムタイムを取得
- clock_t=clock(void); // cpp Warning 無し。
- time ・・・ システムの日時を取得
- 取得日時を tm(構造体) へ代入
- gmtime ・・・ time_tを GMT 変換し 構造体(tm)へ代入
- tm=gmtime(*time_t); // warning C4996:
- localtime ・・・ time_tを構造体(tm)へ代入
- tm=localtime(*time_t); // warning C4996:
- gmtime ・・・ time_tを GMT 変換し 構造体(tm)へ代入
- tm(構造体)データを time_t型へ変換
- mktime ・・・ 構造体(tm)データを time_t型へ変換する
- time_t=mktime(*tm) // cpp Warning 無し。
- mktime ・・・ 構造体(tm)データを time_t型へ変換する
- 取得日時を文字列へ変換
- asctime ・・・ 構造体(tm)を定型フォーマットの文字列へ変換
- s=asctime(*tm); // warning C4996:
- ctime ・・・ time_t を定型フォーマットの文字列へ変換
- s=ctime(*time_t); // warning C4996:
- strftime ・・・ 指定書式文字列へ変換する
- size_t=strftime(*s, size_t, *fm, *tm); // cpp Warning 無し。
- asctime ・・・ 構造体(tm)を定型フォーマットの文字列へ変換
- 時刻の差分を求める
- difftime ・・・ 時刻の差を秒で得る
- double=difftime(time_t2, time_t1); // cpp Warning 無し。
- difftime ・・・ 時刻の差を秒で得る
※注:かなりてきと〜。
▲上へ [ 編集 ]
※参考
function | comment | |
---|---|---|
標準lib | char *asctime(const struct tm *tsp); | 定型文字列変換 |
- | errno_t asctime_s(char* s, size_t mel, const struct tm *tsp) | ms拡張 |
- | char *asctime_r(const struct tm *tsp, char *s); | linux拡張? |
※構造体渡し、戻値:文字列ポインタ | ||
標準lib | char *ctime(const time_t *ttp); | 定型文字列変換 |
- | errno_t ctime_s(char* s, size_t mel, const time_t *ttp); | ms拡張 |
- | char *ctime_r(const time_t *ttp, char *s); | linux拡張? |
※time_t型渡し、戻値:文字列ポインタ | ||
標準lib | struct tm *gmtime(const time_t *ttp); | GMT変換、tm代入 |
- | gmtime_s()??MSDN 無い?が動く(爆) msdn -> _gmtime_s()有り。 | ms拡張 |
- | struct tm *gmtime_r(const time_t *ttp, struct tm *tsp); | linux拡張? |
※構造体渡し、戻値:構造体ポインタ | ||
標準lib | struct tm *localtime(const time_t *ttp); | tm代入 |
- | errno_t localtime_s(struct tm *tsp, const time_t *ttp); | MS拡張 |
- | struct tm *localtime_r(const time_t *ttp, struct tm *tsp); | linux拡張? |
※構造体渡し、戻値:構造体ポインタ | ||
標準lib | clock_t clock(void); | プロセッサ time |
標準lib | time_t time(time_t *ttp); | システム日時 |
※精度に違い有り | ||
標準lib | double difftime(time_t time2, time_t time1); | time2 - time1 |
標準lib | time_t mktime(struct tm *tsp); | tm ---> time_t |
標準lib | size_t strftime(char *s, size_t mln, const char *fm, struct tm *tsp); | 整形出力 |
※時刻の差 ※構造体->time_t変換 ※指定フォーマット整形出力 | ||
※GMT=グリニッジ標準時 ※***_r -> linux 拡張の模様 ※***_s -> MS拡張? ※*ttp -> time_t value ※*tsp -> struct tm ※*fm -> format ※mel -> numberOfElements |
※***_s() MSDN より引用。一部表記が異なる。
strftime(), wcsftime() 整形子
format 整形子 | 表示内容 | 表示形式と値 | |
---|---|---|---|
%y, %Y | 年(year) | 0-99 or 0-9999 | |
%b, %B | 月[省略,完全] | Jan~, January | 1-12, 1月-12月 |
%m | 月(month) | 1-12(注:VC?0-11) | |
%d | 日(day) | 1-31 | |
%H, %I | 時(hour) | 24(0-23) / 12(1-12) | |
%M | 分(minute) | 0-59 | |
%S | 秒(second) | 0-59 | |
%p | 午前・午後 | AM / PM | 午前 / 午後 |
%a, %A | 曜日[省略,完全] | Mon~, Monday~ | 月~ , 月曜日~ |
%w | 曜日の通番 | 0-6 (Sun=0 ~) | |
%c | 日付と時刻 | DD/YY/ HH:MM:SS | |
%x | 標準日付表記 | MM/DD/YY | YYYY/MM/DD |
%X | 標準時間表記 | HH:MM:SS | |
%j | 1/1->経過日数 | 1-366 | |
%U, %W | 週の通番(注) | 0-53 | |
%Z | time zone | 「・・・東京・・・」とか | |
%% | パーセント表示 | % | |
▲上へ [ 編集 ]
構造体 tm と構造体メンバ
構造体 tm は time.h で宣言され、以下の構造体メンバを持つ。
struct tm { // --- 時刻関連メンバ -------------------------------- int tm_sec; // 秒 0-60(閏秒考慮) int tm_min; // 分 0-59 int tm_hour; // 時 0-23 // --- 日付関連メンバ -------------------------------- int tm_mday; // 日 1-31 int tm_mon; // 月 0-11(注:1月からの通算月数) int tm_year; // 年 1900年から通算年数(0なら1900年) // --- その他のメンバ -------------------------------- int tm_wday; // 日曜〜土曜まで 0-6 int tm_yday; // 1/1 からの通算日数 int tm_isdst; // サマータイム有効>0、無効=0,それ以外は意味無し };※tm_mon tm_year の扱い注意。
▲上へ [ 編集 ]
「日付・時刻」取得、計算(サンプル)
※結論:_s は、MS 独自拡張。移植性皆無。※結論2:worning は表示されても標準関数、又は C++ の代替関数を利用する。
※参考:_s は、「日付・日時」以外も多岐に渡り、30以上の MS独自関数が存在する。セキュリティ的に向上するが、標準化されている訳でなく、更にソース記述も大幅に異なる物と思われ移植性が困難と予想される。
※注:_s の使用は、使う側の判断である。
C++ では、バッファオーバーラン関連の簸弱製関連(CRT?) のセキュリティ強化版?関数として MS では「_s」版、linux等では「_r」版関数があるらしく、特に「_s」付き関数仕様では、大きくソースが異なってしまうようである。
これは「日付・時刻」に限ったことでなく、30以上の各種関数に修正バージョンがある模様。
MS 専用コードを書きたくない、又は、デバッグ時の worning 大量発生で困る場合・・・
// warning C4996: のメッセージを強制的に無効化。 #pragma warning (disable:4996) // (注:これも移植性ない)・・・又は、
// 一般的に推奨されている記述。#pragma とどう違うかは不明。 #define _CRT_SECURE_NO_DEPRECATE // sorce 先頭挿入(1 を指定する場合もあり)・・・を入れると Worning が表示されない。
一般的に #pragma は、コンパイラ固有の指示となる場合が多く、VC のみならず移植性を困難にする場合が多い。他に代替できない場合を除き、極力使用を控えたい記述である。
C++ での日付と時刻を取得する
C++ sample ***_s() への修正版
※asctime() ctime() gmtime() localtime() -> ***_s()
#include <iostream> #include <time.h> // 日付・時刻関連 using namespace std; void main() { errno_t err_t; // (追加) time_t now, gmt_t, jp_t; struct tm gmtTime; // struct tm *gmtTime; (修正) struct tm jpTime; // struct tm *jpTime; (修正) time(&now); // ■グリニッジ標準時:セキュリティ強化版 gmtime_s() 使用 err_t = gmtime_s(&gmtTime, &now); // gmtTime = gmtime(&now); (修正) gmt_t = mktime(&gmtTime); // gmt_t = mktime(gmtTime);(修正) cout << "GMT = " << gmt_t << endl; // ■日本時間:セキュリティ強化版 localtime_s() 使用 err_t = localtime_s(&jpTime, &now); // jpTime = localtime(&now); (修正) jp_t = mktime(&jpTime); // jp_t = mktime(jpTime); (修正) cout << "jp = " << jp_t << endl; printf("GMT-JP 時間差(秒):%-12.2f \n", float(difftime(gmt_t, jp_t))); }※セキュリティ強化版使用は、(これほど)ソース全体の修正が必要になる。
※***_s() の記述は ANSI準拠?らしいが、VC++ 以外見受けられず、移植性に甚だ疑問。
▲上へ [ 編集 ]
C言語の場合
sample 時刻差を計算する
※グリニッジ標準時と日本時間の差を求める。
#include <iostream> //#include <stdio.h> #include <time.h> using namespace std; void main() { time_t nowDateTime, gmt_t, jp_t; struct tm *gmtTime; struct tm *localTime; time(&nowDateTime); // 現在の日付と時刻を取得する gmtTime = gmtime(&nowDateTime); // グリニッジ標準時(GMT) gmt_t = mktime(gmtTime); cout << "GMT = " << gmt_t << endl; localTime = localtime(&nowDateTime); // 日本時間 jp_t = mktime(localTime); cout << "jp = " << jp_t << endl; printf("GMT-JP 時間差(秒):%-12.2f \n", float(difftime(gmt_t, jp_t))); }※面倒なので cpp でテスト。difftime() は Wornint 出ず。
sample 実行結果
GMT = 1213595259 jp = 1213627659 GMT-JP 時間差(秒):-32400.00 // = 9時間差 続行するには何かキーを押してください . . .
[ 編集 ]
▲上へ
sample 書式付き文字列へ変換
#include <iostream> //#include <stdio.h> #include <time.h> #include <locale.h> // 何故かなくても... #define MAX_LEN 25 void main() { // setlocale(LC_ALL, "japanese"); // 何故か "ja" 不可。""=system(ja) char s_date[MAX_LEN], s_time[MAX_LEN]; time_t nowDateTime; struct tm *localTime; time(&nowDateTime); localTime = localtime(&nowDateTime); // 書式設定 strftime(s_date,MAX_LEN,"%y.%B.%d (%a) ", localTime); strftime(s_time,MAX_LEN,"%H:%M:%S", localTime); printf("%s %s \n", s_date, s_time); }※iostream なら locale.h なくても動くようである。stdio.h -> locale.h 必須。(この場合でも何故か"ja"不可)
▲上へ
sample 定型文字列へ変換
※asctime(), ctime(), mktime(), localtime() 使用
//#include <iostream> #include <stdio.h> #include <time.h> void main() { time_t nowDateTime; struct tm *localTime; // 日時の取得と構造体への代入 time(&nowDateTime); localTime = localtime(&nowDateTime); // 定型書式文字列へ変換 printf("1)asctime = %s", asctime(localTime)); // 1),2),3) ともに printf("2)ctime = %s", ctime(&nowDateTime)); // 実行した・・・ printf("nowDateTime = %ld \n",nowDateTime); bk = mktime(localTime); // 構造体->time_t型 printf("bk = %ld \n",bk); printf("3)ctime2 = %s", ctime(&bk)); // 結果は同じ }※cpp iostream -> worning. asctime_s, ctime_s, localtime_s 推奨表示. mktime -> worning 出ず。
sample 実行結果表示
1)asctime = Mon Jun 16 18:27:52 2008 // (\n) 2)ctime = Mon Jun 16 18:27:52 2008 // (\n) nowDateTime = 1213608472 bk = 1213608472 3)ctime2 = Mon Jun 16 18:27:52 2008 // (\n) 続行するには何かキーを押してください . . .
[ 編集 ]
▲上へ
sample 処理時間の計測
※clock() 使用
//#include <iostream> #include <stdio.h> #include <time.h> void main() { clock_t start, end; start = clock(); // <------------ 計測開始 for(int i=0; i<65535 ;i++) { printf("i=%d \n",i); } end = clock(); // <------------ 計測終了 printf("処理時間(秒):%-12.4f \n", (float(end-start)/CLOCKS_PER_SEC)); }※cpp iostream でも worning 出ず。
※cast の仕方に注意。
▲上へ
sample GMT/jp 時間表示
※localtime(), gmtime(), time() 使用。
//#include <iostream> #include <stdio.h> #include <time.h> void prnDateTime(struct tm* local) { char *weekday[] = { "Sun","Mon","Tue","Wed","Thu","Fri","Sat" }; // または、 char weekday[][4] = { "Sun", ・・・ ,"Sat" }; でも可 printf("%02d:%02d:%02d " , local->tm_hour // hour , local->tm_min // min , local->tm_sec // sec ); printf("%4d/%02d/%02d (%s) \n" , local->tm_year + 1900 // year + 1900 , local->tm_mon + 1 // mon + 1 , local->tm_mday // day , weekday[local->tm_wday] // week ); } void main() { time_t nowDateTime; struct tm *gmtTime; struct tm *localTime; time(&nowDateTime); // 現在の日付と時刻を取得する gmtTime = gmtime(&nowDateTime); // グリニッジ標準時(GMT) prnDateTime(gmtTime); // GMT 表示 localTime = localtime(&nowDateTime); // 日本時間 prnDateTime(localTime); // jp 表示 }※cpp #include <iostream> では、gmtime localtime -> worning
▲上へ
リンク
内部リンク
- C/C++ C++/CLI C# 関連
- VC++ 2005 Express のインストール
- C/C++ の簡単なプログラム例
- C/C++ ソート(並べ替え)
- C/C++ テストの実行
- C/C++ STL(Standard Template Library)
- C/C++ 日付と時刻
- 変数・定数
- プログラムの分割/ダイナミックリンクライブラリ など
- その他
- C/C++ その他::書式文字/ESC code など
- VB2005リファレンス(覚え書き)
- SQL文:SQLステートメント
- VBA(VisualBasic for Applications)
外部リンク
- 現在ありません
▲上へ
2008年06月17日(火) 11:02:55 Modified by cafeboy1