C:\home\SVGCats_src\src\TIMEDATE.C
1|/************************************************************************ 2| 1. <<< 時間/日付 (TimeDate) >>> 3|【補足】 4| 2. <<< 標準ライブラリの簡易ヘルプ >>> 5| 標準ライブラリ time.h には、以下の関数があります。 6|・time_t time( time_t* n ); // システムの時刻を n に格納する 7|・double difftime( time_t finish, time_t start ); // 時刻差を返す 8|・struct tm* localtime( time_t* ); // 日、時などを参照する(構造体から) 9|・ファイルのタイムスタンプは、FileX_getUpdate 関数から取得できます。 10|*************************************************************************/ 11| 12|#include "mixer_precomp.h" 13| 14|#define STDLIBS_INCLUDE 15|#define STDLIBS_INCLUDE_STRING_H 16|#define STDLIBS_INCLUDE_STDIO_H 17|#define STDLIBS_INCLUDE 18|#include <locale.h> 19|#include <math.h> 20|#include <time.h> 21|#ifdef USES_MXP_AUTOINC 22| #include <timedate.ah> /* Auto include header, Look at mixer-... folder */ 23|#endif 24| 25|void TimeDate_setLocaleByOS(); 26|void TimeDate_wait001_forV830_O1(); 27| 28|/* 3. <<< [TimeDate_MonthStr] >>> */ 29|char* TimeDate_MonthStr[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", 30| "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; 31| 32| 33| 34|/*-------------------------------------------------------------------------*/ 35|/* 4. <<< ◆基本操作 >>> */ 36|/*-------------------------------------------------------------------------*/ 37| 38| 39| 40|/************************************************************************ 41| 5. <<< [TimeDate_set] 日時を m へ設定する >>> 42|【引数】 43| ・time_t* m; 設定を格納する変数へのアドレス 44| ・int year; 年(西暦)[1970〜2036] 45| ・int month; 月 [1〜12] 46| ・int day; 日 [1〜31] 47| ・int hour; 時 [0〜23] 48| ・int min; 分 [0〜59] 49| ・int sec; 秒 [0〜59] 50| ・int 返り値; 0=正常, 1=範囲外 51|【補足】 52|・西暦 1970 年 1 月 1 日 0 時から 2036 年 2 月 5 日 0 時まで設定できます。 53|・指定した日や時などが範囲外の場合、自動的に計算して正規化します。 54|*************************************************************************/ 55|int TimeDate_set( time_t* m, int year, int month, int day, 56| int hour, int min, int sec ) 57|{ 58| struct tm xmas; 59| time_t holiday; 60| 61| TimeDate_setLocaleByOS(); 62| xmas.tm_sec = sec; 63| xmas.tm_min = min; 64| xmas.tm_hour = hour; 65| xmas.tm_mday = day; 66| xmas.tm_mon = month - 1; 67| xmas.tm_year = year - 1900; 68| xmas.tm_isdst = -1; 69| 70| holiday = mktime( &xmas ); 71| if ( holiday == (time_t)-1 ) return 1; 72| 73| *m = holiday; 74| return 0; 75|} 76| 77| 78| 79|/************************************************************************ 80| 6. <<< [TimeDate_setDiff] 時間を m へ設定する >>> 81|【引数】 82| ・time_t* m; 設定を格納する変数へのアドレス 83| ・int year; 年(西暦)[0〜64] 84| ・int month; 月 [0〜12] 85| ・int day; 日 [0〜31] 86| ・int hour; 時 [0〜23] 87| ・int min; 分 [0〜59] 88| ・int sec; 秒 [0〜59] 89| ・int 返り値; 0=正常, 1=範囲外 90|【補足】 91|・時間は、time_t 型の時刻に対して、加減算するときに使います。 92|*************************************************************************/ 93|int TimeDate_setDiff( time_t* m, int year, int month, int day, 94| int hour, int min, int sec ) 95|{ 96| time_t f; 97| int r; 98| 99| r = TimeDate_set( m, year + 1970, month + 1, day + 2, hour, min, sec ); 100| TimeDate_set( &f, 1970, 1, 2, 0,0,0 ); 101| *m -= f; 102| 103| return r; 104|} 105| 106|/************************************************************************ 107| 7. <<< [TimeDate_getOldest] 最も古い日付を取得する >>> 108|【補足】 109|・time_t 型で表現できる最も古い日付の値を取得します。 110|【内部補足】 111|・time_t は、約 136年、つまり 2106年まで表現できます。 112|(Visual C++4.0 のヘルプ・時間管理より) 113| メ モ Microsoft C/C++ 7.0 以外のすべての Microsoft C/C++ バージョン 114| および Microsoft Visual C++ のすべてのバージョンでは、time 関数が返す 115| 現在時刻は、1970 年 1 月 1 日の午前 0 時 0 分 0 秒から経過した秒数です。 116| Microsoft C/C++ 7.0 の time 関数は、1899 年 12 月 31 日の午前 0 時 0 分 117| 0 秒からの経過秒数を現在時刻として返していました。 118|*************************************************************************/ 119|void TimeDate_getOldest( time_t* time ) 120|{ 121| *time = (time_t)0; 122|} 123| 124| 125| 126|/************************************************************************ 127| 8. <<< [TimeDate_cmp] 2つの日付とそれぞれの存在から比較する >>> 128|【補足】 129|・ファイルの存在と更新日時に対する返り値の関係は次の通りです。 130| [fNameA] [更新日時] [fNameB] [返り値] [fNameA] 131| 存在 == 存在 0 TimeDate_Equal(同一) 132| 存在 > 存在 1 TimeDate_Update (更新) 133| 存在 < 存在 -1 TimeDate_Resume(復旧) 134| 存在 なし 2 TimeDate_Create(生成) 135| なし 存在 -2 TimeDate_Delete(削除) 136| なし なし 0 TimeDate_Equal(同一) 137|・existA == false の場合、timeA は無視されます。timeB も同様です。 138|・存在を考慮しない場合、標準ライブラリの difftime 関数を用います。 139|・引数にファイル名を指定する場合、FileX_cmpTime 関数を用います。 140|*************************************************************************/ 141|int TimeDate_cmp( time_t* timeA, bool existA, time_t* timeB, bool existB ) 142|{ 143| if ( ! existA ) { 144| if ( ! existB ) return 0; 145| else return -2; 146| } 147| else { 148| if ( ! existB ) return 2; 149| else { 150| double diff = difftime( *timeA, *timeB ); 151| if ( diff == 0.0 ) return 0; 152| else if ( diff > 0.0 ) return 1; 153| else return -1; 154| } 155| } 156|} 157| 158| 159| 160|/************************************************************************ 161| 9. <<< [TimeDate_setFromDouble] double 型経過秒数から日時を取得する >>> 162|【補足】 163|・月と年は取得できません。time_t 型または struct tm 型の 164| 年と月を直接参照して計算してください。 165|*************************************************************************/ 166|void TimeDate_setFromDouble( struct tm* t, double diff ) 167|{ 168| double diff2; 169| 170| TimeDate_setLocaleByOS(); 171| 172| diff2 = floor(diff / 60); t->tm_sec = (int)(diff - diff2 * 60); 173| diff = floor(diff2/ 60); t->tm_min = (int)(diff2 - diff * 60); 174| diff2 = floor(diff / 24); t->tm_hour = (int)(diff - diff2 * 24); 175| t->tm_mday = (int)diff2; 176| t->tm_mon = 0; 177| t->tm_year = 0; 178| t->tm_isdst = -1; 179|} 180| 181| 182| 183|/*-------------------------------------------------------------------------*/ 184|/* 10. <<< ◆文字列変換 >>> */ 185|/*-------------------------------------------------------------------------*/ 186| 187| 188| 189|/************************************************************************ 190| 11. <<< [TimeDate_getStr] 指定した日時を短い形式で取得する >>> 191|【引数】 192| ・char* str; 現在の時刻を格納するバッファのアドレス 193| ・int str_sizeof; str のメモリサイズ 194|【補足】 195|・OS の地域設定の「短い形式」を取得します。 196| 例=98/03/23 19:44:02(日本の場合) 197|*************************************************************************/ 198|char* TimeDate_getStr( time_t* time, char* str, int str_sizeof ) 199|{ 200| struct tm* t2; 201| 202| TimeDate_setLocaleByOS(); 203| t2 = localtime( time ); 204| #ifdef _CHECKER 205| if ( t2 == NULL ) error(); /* time が不正な値 */ 206| #endif 207| strftime( str, str_sizeof, "%c", t2 ); 208| 209| return str; 210|} 211| 212| 213| 214|/************************************************************************ 215| 12. <<< [TimeDate_getStrF] 指定した日時を指定した形式で取得する >>> 216|【引数】 217| ・const char* fmt; 日時の書式(TimeDate_fmt 書式、後記) 218| ・char* str; 現在の時刻を格納するバッファのアドレス 219| ・int str_sizeof; str のメモリサイズ 220|【補足】 221|・USES_STRX が定義されていないと、拡張書式を指定できません。 222|*************************************************************************/ 223|char* TimeDate_getStrF( time_t* time, const char* fmt, char* str, 224| int str_sizeof ) 225|{ 226| struct tm* time2; 227| static char fmtX[256]; 228| 229| ASSERT( str_sizeof <= sizeof(fmtX) ); 230| 231| TimeDate_setLocaleByOS(); 232| time2 = localtime( time ); 233| 234| #ifdef USES_STRX 235| strcpy( fmtX, fmt ); 236| StrX_rep( fmtX, sizeof(fmtX), "%n", 237| TimeDate_MonthStr[time2->tm_mon] ); 238| strftime( str, str_sizeof, fmtX, time2 ); 239| #else 240| strftime( str, str_sizeof, fmt, time2 ); 241| #endif 242| 243| return str; 244|} 245| 246| 247| 248|/************************************************************************ 249| 13. <<< [TimeDate_getNowStr] 現在の日時を短い形式で取得する >>> 250|【補足】 251|・OS の地域設定の「短い形式」を取得します。 252| 例=98/03/23 19:44:02(日本の場合) 253|・返される文字列は、変更しないでください。 254|・ファイルに保存することに使う場合は、TimeDate_saveStr を用います。 255|*************************************************************************/ 256|char* TimeDate_getNowStr() 257|{ 258| time_t t; 259| struct tm* t2; 260| static char buf[30]; /* 文字列領域を内部に持っています */ 261| 262| TimeDate_setLocaleByOS(); 263| time( &t ); 264| t2 = localtime( &t ); 265| strftime( buf, sizeof(buf), "%c", t2 ); 266| 267| return buf; 268|} 269| 270| 271| 272|/************************************************************************ 273| 14. <<< [TimeDate_getNowStrF] 現在の日時を指定した書式で取得する >>> 274|【引数】 275| ・const char* fmt; 日時の書式(TimeDate_fmt 書式、後記) 276|【補足】 277|・返される文字列は、変更しないでください。 278|*************************************************************************/ 279|char* TimeDate_getNowStrF( const char* fmt ) 280|{ 281| time_t t; 282| struct tm * t2; 283| static char buf[80]; /* 文字列領域を内部に持っています */ 284| 285| TimeDate_setLocaleByOS(); 286| time( &t ); 287| t2 = localtime( &t ); 288| strftime( buf, sizeof(buf), fmt, t2 ); 289| 290| return buf; 291|} 292| 293| 294| 295|/************************************************************************ 296| 15. <<< [TimeDate_getCompileStrF_imp] コンパイルした日時を指定した書式で取得する >>> 297|【引数】 298| ・char* __date__; __DATE__ 組み込みマクロ 299| ・char* __time__; __TIME__ 組み込みマクロ 300| ・char* fmt; 日時の書式(TimeDate_fmt 書式、後記) 301|【補足】 302|・TimeDate_getCompileStrF マクロの実装部です。 303|*************************************************************************/ 304|char* TimeDate_getCompileStrF_imp( char* __date__, char* __time__, 305| char* fmt ) 306|{ 307| #define STR_SIZE 100 308| char** pMonth; 309| time_t tim; 310| int y,m,d,hh,mm,ss; 311| static char str[STR_SIZE]; 312| 313| TimeDate_setLocaleByOS(); 314| 315| /* __DATE__ を解析する */ 316| sscanf( __date__, "%s %d %d", str, &d, &y ); 317| pMonth = TimeDate_MonthStr; 318| for ( m = 1; m <= 12; m++ ) { 319| if ( strcmp( *pMonth, str ) == 0 ) break; 320| pMonth ++; 321| } 322| 323| /* __TIME__ を解析する */ 324| sscanf( __time__, "%d:%d:%d", &hh, &mm, &ss ); 325| 326| /* 文字列を作る */ 327| TimeDate_set( &tim, y, m, d, hh, mm, ss ); 328| TimeDate_getStrF( &tim, fmt, str, sizeof(str) ); 329| 330| return str; 331|} 332| 333| 334| 335|/************************************************************************ 336| 16. <<< [TimeDate_saveStr] 日時情報をテキスト形式にする >>> 337|【機能】 338|・テキストファイルに保存できる形式の文字列を str に格納します。 339|【補足】 340|・str のメモリサイズは TimeDate_loadBuf_size 以上にしてください。 341|・このテキスト形式は、TimeDate_loadStr で日時情報を取得することができます。 342|・西暦 1970 年 1 月 1 日 0 時から 2036 年 2 月 5 日 0 時まで設定できます。 343| (2000 年問題に対応) 344|*************************************************************************/ 345|char* TimeDate_saveStr( time_t* t, char* str ) 346|{ 347| TimeDate_getStrF( t, "%Y/%m/%d-%H:%M:%S", str, TimeDate_loadBuf_size ); 348| return str; 349|} 350| 351| 352| 353|/************************************************************************ 354| 17. <<< [TimeDate_loadStr] 日時情報をテキスト形式から取得する >>> 355|【機能】 356|・テキストファイルに保存できる形式の文字列を str に格納します。 357|【引数】 358| ・int 返り値; 0=正常, 1=範囲外, 2=書式ミス 359|【補足】 360|・TimeDate_saveStr で取得したテキスト形式から、日時情報を取得することが 361| できます。 362|・ユーザにテキスト形式を入力させる場合、"%Y/%m/%d-%H:%M:%S" という 363| TimeDate_fmt 書式(年は4桁、他は頭に0の付いた2桁または1桁)に従う 364| よう、表示してください。区切り文字('/','-',':')は、数字以外なら 365| 何でも(空白、タブ、改行、コンマ、他でも)構いませんが、1バイトに 366| してください。 367|・西暦 1970 年 1 月 1 日 0 時から 2036 年 2 月 5 日 0 時まで設定できます。 368| (2000 年問題に対応) 369|*************************************************************************/ 370|#ifdef USES_STRX 371|int TimeDate_loadStr( time_t* t, const char* str ) 372|{ 373| int i; 374| static int n[6]; 375| const char* p; 376| 377| for ( i = 0; i < 6; i++ ) { 378| p = StrX_scanInt( str, &n[i] ); 379| if ( p == '\0' ) return 2; 380| str = p + 1; 381| } 382| 383| return TimeDate_set( t, n[0], n[1], n[2], n[3], n[4], n[5] ); 384|} 385|#endif /* USES_STRX */ 386| 387| 388| 389|/*-------------------------------------------------------------------------*/ 390|/* 18. <<< ◆待ち >>> */ 391|/*-------------------------------------------------------------------------*/ 392| 393| 394| 395|/************************************************************************ 396| 19. <<< [TimeDate_wait] msec ミリ秒経ったらこの関数から抜ける >>> 397|*************************************************************************/ 398|void TimeDate_wait( int msec ) 399|{ 400| int i; 401| msec /= 10; 402| for ( i = 0; i < msec; i++ ) 403| TimeDate_wait001_forV830_O1(); 404|} 405| 406| 407| 408|/*-------------------------------------------------------------------------*/ 409|/* 20. <<< ◆内部用 >>> */ 410|/*-------------------------------------------------------------------------*/ 411| 412| 413| 414|/************************************************************************ 415| 21. <<< [TimeDate_wait001_forV830_O1] 0.01 秒経ったらこの関数から抜ける (for V830) >>> 416| Optimize=-O1 417|*************************************************************************/ 418|static void TimeDate_wait001_forV830_O1() 419|{ 420| int i; 421| for ( i = 0; i < 4060; i++ ) 422| { i=i*3; i=i/3; } 423|} 424| 425| 426| 427|/************************************************************************ 428| 22. <<< [TimeDate_setLocaleByOS] 地域設定を OS の設定に合わせる >>> 429|*************************************************************************/ 430|static void TimeDate_setLocaleByOS() 431|{ 432| static bool bFirst = true; 433| 434| if ( bFirst ) { 435| setlocale( LC_ALL, "" ); 436| _tzset(); 437| bFirst = false; 438| } 439|} 440| 441| 442| 443|/*-------------------------------------------------------------------------*/ 444|/* 23. <<< ◆資料 >>> */ 445|/*-------------------------------------------------------------------------*/ 446| 447| 448| 449|/************************************************************************ 450| 24. <<< [TimeDate_fmt] 日時の書式 >>> 451| 452|(Microsoft Developer studio の Info Viewer の strftime 関数より抜粋・修正) 453| format は、1 以上のコードで構成されます。 454| printf 関数と同じように、書式コードの前にはパーセント (%) 記号を 455| 付けます。% 記号が先頭に付かない文字は、変更されずにそのまま string 456| にコピーされます。strftime 関数の出力書式は現在のロケールの LC_TIME 457| カテゴリに影響されます。LC_TIME の詳細については、setlocale 関数を 458| 参照してください。以下に、strftime 関数の書式指定コードを示します。 459| ただし、strftime に対応していない拡張書式もいっしょに示しています。 460| 461| 例: 462| ・Jan.1.1998 ... "%n.%#d.%Y" 463| ・98.07.04 ... "%y.%m.%d" 464| ・23:09:59 ... "%H.%M.%S" 465| 466| 一覧: 467| コード 意味 必要バイト数 468| ------------------------------------------------------------------- 469| %c ロケールに応じた日付と時間の表現 470| 471| %x 現在のロケールの日付表示 472| %Y 10 進数で表す 4 桁の西暦 4 473| %y 10 進数で表す西暦の下 2 桁 (00〜99) 2 474| %m 10 進数で表す月 (01〜12) 2 475| %b 月の省略名 (ex:Jan) 3 476| %B 月の正式名 (ex:September) 9 477| %n %b の強制英語(%b では地域によって変わる)(拡張書式) 478| %d 10 進数で表す日付 (01〜31) 2 479| %a 曜日の省略名 (ex:Sun) 3 480| %A 曜日の正式名 (ex:Wednesday) 9 481| %w 10 進数で表す曜日。日曜日を 0 とする (0〜6)。 1 482| 483| %X 現在のロケールの時刻表示 484| %H 24 時間表記の時間 (00〜23) 2 485| %I 12 時間表記の時間 (01〜12) 2 486| %p 現在のロケールの AM/PM 2 487| %z、%Z 3 488| 時間帯の名前またはその省略名。時間帯が 489| わからない場合には文字を入れない。(ex:Jst,Dst) 490| %M 10 進数で表す分 (00〜59) 2 491| %S 10 進数で表す秒 (00〜59) 2 492| 493| %j 10 進数で表す年頭からの日数 (001〜366) 3 494| %U 10 進数で表す週の通し番号 2 495| 日曜日を週の最初の日とする (00〜51)。 496| %W 10 進数で表す週の通し番号 2 497| 月曜日を週の最初の日とする (00〜51)。 498| %% パーセント記号 499| 500| 501| 25. <<< # フラグ >>> 502| 503| printf 関数と同じように、# フラグを書式指定コードの前に付けられます。 504| その場合、書式指定コードの意味は以下のようになります。 505| 506| %#c 507| 現在のロケールに応じた日付と時刻の長い表現。 508| "Tuesday、March 14、1995、12:41:29" など。 509| %#x 510| 現在のロケールに応じた長い日付表現。"Tuesday、March 14、1995" など。 511| %#d、%#H、%#I、%#j、%#m、%#M、%#S、%#U、%#w、%#W、%#y、%#Y 512| 先行ゼロがあれば削除。 513| 514| 515| 26. <<< 地域設定「ロケール」 >>> 516| 517| TimeDate コンポーネントは、OS の設定した地域に、自動的に設定します。 518| 日時の書式に影響します。 519|*************************************************************************/ 520| 521|