TIMEDATE.C

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|