#pragma twice

KAB-studio > プログラミング > #pragma twice > 140 Version 7.20 時間あれこれ

#pragma twice 140 Version 7.20 時間あれこれ

前のページへ 表紙・目次へ 次のページへ

 Version 7.20
時間あれこれ

今回はちょっと横道にそれて、時間関係の話
ランダム使わないのー?
それは次回ね。それに、時計関係はよく使うことなんだけど、分かりにく
いからちゃんとやっといた方がいいよ
確かにそうよねー、今の時間とかを出せって言われても難しいかも
というわけで見ていきましょう。まずは何を使うか。ランタイム、 
API 、 MFC のどれでも時間は取得できます
この前はランタイムの time() を使ったんだよね
そう。まずはこのランタイムを使う方法から見てみようか

void CAnimeDlg::OnBDraw() 
{
    // まずはのべ秒を取得。
    time_t lTime_t;
    time( &lTime_t );

    // 次にローカル時間に変換します。
    tm *pstTm;
    pstTm = localtime( &lTime_t );

    // そしたら出力。
    TRACE
        ( "%d年%d月%d日%d曜日%d時%d分%d秒\n"
        , pstTm->tm_year
        , pstTm->tm_mon
        , pstTm->tm_mday
        , pstTm->tm_wday
        , pstTm->tm_hour
        , pstTm->tm_min
        , pstTm->tm_sec
        );
    // 101年11月22日6曜日19時38分38秒

    // 下のは前の。
    ::KillTimer( GetSafeHwnd(), 100 );
}

最初の time() は前回の〈現在時刻のべ秒〉ね
そう、時間の取得はこの値を取得するところから始まります。次に、これ
を〈ローカル時間〉に変換します
ろーかるじかん?
全部日本語に訳すなら【地域時間】かな
田舎のテレビとかローカル放送って言うのと同じ?
そうそう、それと同じ。テレビなんかと同じに、時間って国によって違う
でしょ
アメリカとか東の端と西の端でも違うよね
実は、最初に time() で取得したのべ秒は【グリニッジ標準時】っていう
世界基準になってる時間なんです
確かイギリスのだよね
だから日本の時間じゃないわけ。日本とか、アメリカの東海岸とか、そう
いう【地域】、つまりローカルな時間に変換してくれるのが localtime() 
ってランタイム
便利ねー。で、この関数の……
戻り値に tm 構造体のポインタが返ってきます。この構造体の中のメンバ
変数に、年とか時間とかが入ってます
それを TRACE() で表示してるわけね。でも……なんか値が変!
まず年が変だよね。これは、 tm::tm_year には実際の年から 1900 を引
いた値が入ってるから
げ、じゃあ 1900 を足さなきゃいけないの? めんどくさー
まぁそういうことになるかな……
それに、月が 1 少ないし、曜日なんて無茶苦茶変だし! なんかかなり
変だよー
月は 0 が1月に当たるから。曜日も、日曜日が 0 、月曜日が 1 ってい
うふうに割り当てられてるから
これもかなりめんどい……
というわけで、これを便利に変換するランタイムを使いましょう
げ、そういうのあるなら先に言ってよ!

void CAnimeDlg::OnBDraw() 
{
    // まずはのべ秒を取得。
    time_t lTime_t;
    time( &lTime_t );

    // 次にローカル時間に変換します。
    tm *pstTm;
    pstTm = localtime( &lTime_t );

    // そして文字列に変換。
    char pchDate[128];
    strftime
        ( pchDate
        , 128
        , "%Y年%m月%d日%A%p%I時%M分%S秒"
        , pstTm 
        );

    // そしたら出力。
    TRACE( "%s\n", pchDate );
    // 2001年12月22日SaturdayPM08時02分18秒

    // 下のは前の。
    ::KillTimer( GetSafeHwnd(), 100 );
}

 strftime() ってのがそう?
そう、このランタイムで tm 構造体に入ってる日時を自動的に変換してく
れるんです
なんか TRACE() とか sprintf() に似てるね。 TRACE() よりも便利か
も。あ、でもなんか表示がやっぱ変……
曜日と午前午後がねー、英語になっちゃうんだよね
それに時間、 0 が邪魔!
あ、これは

    strftime
        ( pchDate
        , 128
        , "%#Y年%#m月%#d日%A%p%#I時%#M分%#S秒"
        , pstTm 
        );

って感じに # を入れれば、自動的に 0 を取ってくれるから
おー。でもやっぱ曜日とかがねー
じゃ、一番便利なのを紹介しようか

void CAnimeDlg::OnBDraw() 
{
    char pchDate[128];
    // まず日付を取得。
    GetDateFormat
        ( LOCALE_SYSTEM_DEFAULT
        , 0
        , NULL
        , NULL
        , pchDate
        , 127
        );
    // 日付だけ出力。
    TRACE( "%s", pchDate );
    // 次に時間を取得。
    GetTimeFormat
        ( LOCALE_SYSTEM_DEFAULT
        , 0
        , NULL
        , NULL
        , pchDate
        , 127
        );
    // 時間を出力。
    TRACE( "%s\n", pchDate );
    // 2001/12/22 (土)午後 8:45:27

    // 下のは前の。
    ::KillTimer( GetSafeHwnd(), 100 );
}

おおっ、これは綺麗じゃなーい
これまではずっとランタイムを使ってたけど、今度は API 
 GetDateFormat() と GetTimeFormat() ね
ウィンドウズのコントロールパネルに【地域】ってあるでしょ。そのダイ
アログの【時刻】と【日付】のページで指定した通りに表示されるから
ホントだ! こっちを変えると表示も変わる! すごーい! でも、なん
でこれ先に教えてくんなかったの?
いや、だって前回の srand() には使えないし
あ、そっか……
それに、ランタイムの方にもメリットが結構あるから。 API はウィンド
ウズ専用だけど、ランタイムは他の OS でも使えるから
そんな先のこと言われても……
まーね。でもそういう違いを気にしておくのは重要だからね。【地域】
って設定もウィンドウズ特有だし
ってことは他の OS だとそういう設定ってどーなってるの?
そうそう、そういう部分が難しくなってくるからねー。ランタイムだとそ
の辺はとりあえず気にしなくていいから
そういう便利さねー
それと、ランタイムみたく time() でのべ秒から取ると便利な使い方がで
きるから。たとえば、3時間後の日時を取得する場合
ん? ランタイムなら tm::tm_hour に 3 を足すだけでいいんじゃない
の?
今が夜の23時だったら?
あ、超えちゃうんだ。そしたら日にちを1日増やして
それで31日になっちゃったら?
そしたら月を
でも11月みたいに30日で終わる月だったら?
げ、月を調べてそれで……あーでも2月とか閏年とか……はいはい分かり
ましたよー大変だねー
でも、のべ秒って関係ないでしょ
あ……そっか、 time() で取得したのに3時間分、だから 3 * 60 * 60 
を足せば
それを localtime() に渡せば、難しいことを考えなくていいわけ

void CAnimeDlg::OnBDraw() 
{
    time_t lTime_t;
    time( &lTime_t );
    tm *pstTm;
    pstTm = localtime( &lTime_t );
    TRACE
        ( "%d年%d月%d日%d曜日%d時%d分%d秒\n"
        , pstTm->tm_year, pstTm->tm_mon
        , pstTm->tm_mday, pstTm->tm_wday
        , pstTm->tm_hour, pstTm->tm_min
        , pstTm->tm_sec
        );
    // 101年11月22日6曜日21時1分16秒

    // 3時間進めます。
    lTime_t += 3 * 60 * 60;
    pstTm = localtime( &lTime_t );
    TRACE
        ( "%d年%d月%d日%d曜日%d時%d分%d秒\n"
        , pstTm->tm_year, pstTm->tm_mon
        , pstTm->tm_mday, pstTm->tm_wday
        , pstTm->tm_hour, pstTm->tm_min
        , pstTm->tm_sec
        );
    // 101年11月23日0曜日0時1分16秒

    // 下のは前の。
    ::KillTimer( GetSafeHwnd(), 100 );
}

おおっ、ちゃんと日付が変わってる!
ま、この辺は API でもできるだろうけど、ランタイムの方が簡単ってこ
とで

/*
    Preview Next Story!
*/
今回のって実用的〜
でも次回は使わないんだよねー
げ。ホントに余談って感じね
でもそういうのの方が重要かも
ってことは次回は重要じゃない?
ううん、かなり重要。というわけで次回
< Version 7.21 タイマーの限界 >
につづく! って、タイトルが厳しい!
簡単そう見えて結構難しいっていう例かも
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。