奈良県でソフトウェア開発・Webサイトの運営をしているフリーランスのエンジニアです

ロジカルアーツ研究所

C++Builder

C++Builder XE3では日付時刻関係のグローバル変数が廃止された

投稿日:2012年12月12日 更新日:

旧バージョンで作成したプロジェクトをC++Builder XE3に移植する場合、よく問題になるのが特殊なグローバル変数の扱いです。特に日付時刻の形式変換で用いられるDateSeparatorやTimeSeparatorなどグローバル変数はXE3では廃止されており、これらを使用していると「未定義の識別子」エラーになってしまいます。

これらはプロセス全体で共通なグローバル変数ですから、もし複数のスレッドから参照された場合はスレッドセーフではないという理由で非推奨とされてきましたが、XE3ではついに使用不可となったわけです(正確にどのバージョンから廃止されたのかはわかりません)。そのままではコンパイルエラーになってしまうので、とりあえず手っ取り早く修正するには、代わりに用意されたFormatSettingsグローバル変数を使うのが簡単です。


FormatSettingsというグローバル変数はTFormatSettings型の構造体であり、DateSeparatorやTimeSeparatorといったフィールドをメンバに持っています。ですから、

DateSeparator → FormatSettings.DateSeparator
TimeSeparator → FormatSettings.DateSeparator

のように書き換えるだけでOKです。これならエディタの一発置換でも可能でしょう。

ただし、FormatSettingsは従来と同じくグローバル変数ですから、スレッドセーフではありません。これでもコンパイルは通りますが、非推奨とされた理由は解消されていないわけです。そこでスレッドセーフを保証するためには、TFormatSettings型の引数を取る関数を使用します。

たとえば、文字列をTDateTime型に変換するStrToDateTimeという関数がありますが、

TDateTime __fastcall StrToDateTime(const UnicodeString S);

の代わりにもう一つの形式である

TDateTime __fastcall StrToDateTime(const UnicodeString S, const TFormatSettings& format);

の方を使います。このとき2番目の引数には自分でTFormatSettings型の変数を宣言して、そのメンバにパラメータを設定し、StrToDateTimeを呼び出すわけです。たとえば次のような要領です。

TFormatSettings format;
format.DateSeparator = '-';
format.TimeSeparator = ':';
TDateTime dt = StrToDateTime("2012-12-12 21:20:16", format);

-C++Builder

Copyright© ロジカルアーツ研究所 , 2024 All Rights Reserved Powered by STINGER.