単純な変換ファミリの作成と単位の追加
計量単位の変換 への移動
変換ファミリを新規に作成し測定単位の種類を新規に追加することになるのは、たとえば、変換結果の精度が落ちるおそれがある長期間の単位間の変換(月から世紀への変換など)を実行するような場合です。
cbTime ファミリは、1日を基本単位として使用します。基本単位とは、そのファミリ内の変換で必ず使用される単位のことです。 そのため、この例では、変換は常に日換算で行う必要があります。 月以上の単位(月、年、10 年、世紀、千年期など)を使って変換を実行すると、誤りが生じるおそれがあります。日数から月数、日数から年数などの変換は正確には行えないからです。 月によって長さが違うだけでなく、年数についても、うるう年、うるう秒などの補正因子があります。
月以上の測定単位だけを使用する場合は、年を基本単位とするより正確な変換ファミリを作成できます。以下の例では、cbLongTime という変換ファミリを新規に作成しています。
変数の宣言
まず、識別子の変数を宣言する必要があります。これらの識別子は、新規作成する LongTime 変換ファミリと、そのメンバである測定単位で使用されます。
Delphi:
var
cbLongTime: TConvFamily;
ltMonths: TConvType;
ltYears: TConvType;
ltDecades: TConvType;
ltCenturies: TConvType;
ltMillennia: TConvType;
C++:
tConvFamily cbLongTime;
TConvType ltMonths;
TConvType ltYears;
TConvType ltDecades;
TConvType ltCenturies;
TConvType ltMillennia;
変換ファミリの登録
次に、以下のように、この変換ファミリを登録します。
Delphi:
cbLongTime := RegisterConversionFamily ('Long Times');
C++:
cbLongTime = RegisterConversionFamily("Long Times");
UnregisterConversionFamily 手続きが用意されてはいますが、変換ファミリが定義されているユニットを実行時に削除しない限り、それらの変換ファミリを登録解除する必要はありません。 アプリケーションが終了すると、変換ファミリは自動的にクリーンアップされます。
測定単位の登録
次に、新規作成した変換ファミリに属する測定単位を登録する必要があります。それには RegisterConversionType 関数を使用しますが、これは特定の変換ファミリに属する測定単位を登録します。基本単位(この例では年)を定義する必要があります。それ以外の単位は、この基本単位との関係を示す係数を使って定義します。LongTime ファミリの基本単位は年なので、ltMonths の係数は 1/12 になります。変換先の単位の記述も指定します。
測定単位を登録するコードを以下に示します。
Delphi:
ltMonths := RegisterConversionType(cbLongTime,'Months',1/12);
ltYears := RegisterConversionType(cbLongTime,'Years',1);
ltDecades := RegisterConversionType(cbLongTime,'Decades',10);
ltCenturies := RegisterConversionType(cbLongTime,'Centuries',100);
ltMillennia := RegisterConversionType(cbLongTime,'Millennia',1000);
C++:
ltMonths = RegisterConversionType(cbLongTime, " Months ", 1 / 12);
ltYears = RegisterConversionType(cbLongTime, " Years ", 1);
ltDecades = RegisterConversionType(cbLongTime, " Decades ", 10);
ltCenturies = RegisterConversionType(cbLongTime, " Centuries ", 100);
ltMillennia = RegisterConversionType(cbLongTime, " Millennia ", 1000);
新しい単位の使用
これで、新規登録した単位を使用して変換を実行できます。cbLongTime 変換ファミリに登録した単位どうしであれば、その間の変換はグローバル関数 Convert で実行できます。
そのため、次の Convert 呼び出しを使用するのではなく、
Delphi:
Convert(StrToFloat(Edit1.Text),tuMonths,tuMillennia);
C++:
Convert(StrToFloat(Edit1->Text), tuMonths, tuMillennia);
以下のコードを使用した方が、精度は高くなります。
Delphi:
Convert(StrToFloat(Edit1.Text),ltMonths,ltMillennia);
C++:
Convert(StrToFloat(Edit1->Text), ltMonths, ltMillennia);