このツールで「マイクロソフト西暦 2000 年対応」に準拠するアプリケーションを構築できますか ?
可能
メモ : ただし、適切なソフトウェアの修正プログラムおよびサービスパックが適用されていることを前提とします。
日付の処理
Visual C++
1.51
では、以下のデータ型が使用されます。
データ型 |
範囲 |
time_t |
1970 年 1 月 1 日から 2038 年 1 月 18 日まで |
_dosdate_t |
1980 年 1 月 1 日から 2099 年 12 月 31 日まで
|
struct tm |
1601 年から 58,457,005 年まで (64ビット値) 100 ナノ秒間隔 |
既知の問題
システム クロックが2000年に設定されている場合に、MFC (Microsoft Foundation Class) AppWizardアプリケーションを作成すると、バージョン情報ダイアログ上の Copyright情報が “1900” になります。この問題は、作成されたプログラムの動作には直接影響しませんが、不要な混乱を避けるためにリソースエディタを使用して修正してください。
MFC サンプル chkbook で問題が見つかりました。Visual C++ 6.0 に収録されていたサンプルが MSDN ライブラリ 2000 年 1 月版でアップデートされます。chkbook の問題は、日付を 4 桁の西暦を処理するための領域がない文字列として保存されるため、日付が 2 桁の西暦で作成されることです。
下 2 桁の西暦の処理
この製品では、西暦の下 2 桁の日付は表示にのみ使用されます。
ANSI データ型: tm 構造体 および time_t
Microsoft C ランタイムでは、時間を追跡するために次の 2 つの ANSI-C データ構造体を備えています。
1. tm 構造体
2. time_t
ANSI C 規格で、これらのデータ型、その機能、およびそれぞれの基になるデータ型が定められています。Visual C++ では、time_t は long 型であり ANSI C 関数で使用される場合、1970 年 1 月 1 日以降の秒数を保持しています。tm 構造体 は、各メンバ変数に 1900 年以降の年数、月、曜日、年初来日数、時、分、秒に加えて、夏時間が有効かどうかを保持します。これらのメンバは int 型です。ANSI 関数は、これらのデータ型を使用して時間を操作、入力、および出力します。Visual C++ のドキュメントでは、これらのデータ型が詳細に説明されています。
ANSI の時間関数に伴う問題の回避
ANSI 関数をそのまま使用すると、アプリケーションで西暦 2000 年問題を起こす可能性があります。簡単なガイドラインを守ることで、プログラムがあいまいな日付を出力することを回避して、西暦 2000 年対応のアプリケーションを作成することができます。注意を要するのは、strftime 関数と wcsftime 関数です。
- アプリケーションのユーザーに対して日付を表示するときは、4 桁の西暦を使用します。strftime 関数と wcsftime 関数を使用するときは、下 2 桁の西暦を表示する %y (小文字) ではなく、%Y を使用して 4
桁の西暦を表示します。次の例を参照してください。
#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 関数を使用します。
マイクロソフト以外のコンポーネント (このページでは説明しません)
Oracle ODBC ドライバ
InstallShield
プログラム開発における一般的な西暦2000年問題について
ガイドラインと推奨事項
以下のホワイトペーパーをご覧ください。
「Cランタイム ライブラリと西暦2038年問題」「ANSI TimeおよびVisual C++ ライブラリ」「Visual C++ と西暦2000年」「CTime」「オートメーションライブラリと西暦 2000 年」
|