認識されている問題
システム日付を 2000 年以降に設定して MFC AppWizard ベースのプログラムを作成すると、自動生成される "バージョン情報" ダイアログ ボックス上の Copyright 文字列の年号部分が 1900 で生成されます。プログラムの機能には影響ありませんが、実際に作成された時期として正しい情報ではありませんので、リソース エディタで訂正してください。
下 2 桁の西暦の処理
下 2 桁の西暦は、表示専用です。西暦を下 2 桁のみで入力することはできません。
西暦 2000 年問題に対応するアプリケーションの開発に関する注意点
技術文書(ホワイトペーパー) にアクセスして、"ANSI Time および Visual C++ ライブラリ"、"Visual C++ と西暦 2000 年" および "CTime" を参照してください。
西暦 2000 年問題に関するよくある開発時のエラー
ユーザーが固有の日付処理ルーチンを採用している場合に、問題が起こる可能性が最も高くなります。
ANSI データ型: tm 構造体 および time_t
Microsoft C ランタイムでは、時間を追跡するために次の 2 つの ANSI-C データ構造体を備えています。
- tm 構造体
- time_t
ANSI C 規格で、これらのデータ型、その機能、およびそれぞれの基になるデータ型がある程度定められています。Visual C++ では、time_t は long 型であり ANSI C 関数で使用される場合、1970 年 1 月 1 日以降の秒数を保持しています。tm 構造体は、各メンバ変数に 1900 年以降の年数、月、曜日、年初来日数、時、分、秒に加えて、夏時間が有効かどうかを保持します。これらのメンバは int 型です。ANSI 関数は、これらのデータ型を使用して時間を操作、入力、および出力します。Visual C++ のドキュメントでは、これらのデータ型が詳細に説明されています。
ANSI 関数の動作によっては、アプリケーションに西暦 2000 年問題が発生する可能性があります。ANSI 関数を使用する場合、主に strftime 関数と wcsftime 関数を使用する場合、いくつかの簡単なガイドラインに従うことによって、西暦 2000 年対応のアプリケーションを作成し、混乱を引き起こすプログラム出力を回避できます。
- アプリケーションのユーザーに日付を表示する場合は、4 桁の西暦を表示します。strftime 関数と wcsftime 関数を使用している場合は、下 2 桁の西暦を表示する %y (小文字) ではなく、4 桁の西暦を表示する %Y を使用します。以下に例を示します。
#include <time.h>
#include <stdio.h>
const int BUFSIZE = 256;
char buf[BUFSIZE];
int main()
{
struct tm now;
time_t tmp = time(0); // get current time
now = *localtime(&tmp); // get components
// 2-digit vs. 4-digit year
char fmt[] = " %m/%d/%y \n %m/%d/%Y ";
strftime( buf, BUFSIZ, fmt, &now );
printf(buf);
return 0;
}
- アプリケーションで日付入力を受け取る場合は、アプリケーションのユーザーに対して、4 桁の西暦を使用する完全な形式での日付の入力を要求します。
- strftime 関数と wcsftime 関数を使用している場合は、%x または %c の形式を使用しないでください。この形式を使用する場合は、# を使用して長い日付形式のバージョンを取得します。%x および %c の書式設定コードでは、既定で下 2 桁の西暦を出力します。上のプログラムで、fmt の初期値を " %x \n %#x " に変更すると、その違いを理解できます。
- 時間は time_t 変数または tm 構造体変数に保存し、そこで操作します。ANSI C では、この操作を支援するほかの時間関数を用意しています。次は、これらの関数の一覧とその簡単な説明です。詳細については、Visual C++ のドキュメントを参照してください。
- time
- 現在のカレンダー時刻を time_t 型で取得します。
- difftime - 2 つの time_t 型の値の差を計算します。
- gmtime - 万国標準時 (UTC) に関して time_t 型を tm 構造体型に変換します。
- localtime - ローカル時刻に関して time_t 型を tm 構造体型に変換します。
- asctime、_wasctime - tm 構造体として格納された時間を文字列に変換します。文字列の形式は "DDD MMM dd HH:MM:SS YYYY\n\0" で、常に 26 文字です。
- ctime
、_wctime - time_t を受け取り、ローカル時刻を文字列の形式で返します。asctime( localtime( time_t_val )) とまったく同じです。
- mktime - tm 構造体型として格納された時刻を受け取り、ローカル時刻に調整して time_t 型で返します。値が更新され、適切な範囲に含まれます。以下に例を示します。
#include <time.h>
#include <stdio.h>
const int BUFSIZE = 1024;
char buf[BUFSIZE];
int main()
{
struct tm now;
time_t tmp = time(0); // current time
now = *localtime(&tmp);
size_t len = strftime(buf, BUFSIZE, "%#c\n", &now);
now.tm_hour += 48; //jump ahead two days
// should get a bogus hour value
len += strftime(buf+len, BUFSIZE-len, "%#c\n", &now);
mktime(&now); // mktime will correct
strftime(buf+len, BUFSIZE-len, "%#c\n", &now);
printf(buf);
return 0;
}
- ANSI 関数ではありませんが、_strdate 関数と _wstrdate 関数は、パラメータに指定されたポインタのバッファに 9 文字の文字列を生成します。出力の形式は "YY/MM/DD" です。代わりに、strftime 関数または wcsftime 関数を使用します。
ガイドラインと推奨事項
技術文書(ホワイトペーパー) の、"ANSI Time および Visual C++ ライブラリ"、"Visual C++ と西暦 2000 年"、"CTime" および "オートメーション ライブラリと西暦 2000 年" を参照してください。