Delphi Programming / Object Pascal
サイトのトップページへ リンクのページへ ロゴマーク
[掲載 2003年07月20日] [更新 2019年05月04日] 元号選択式日付時刻入力コンポーネント
元号選択式日付時刻入力コンポーネント
使用方法等
動作確認等 図は Windows 7 U64(SP1) + Delphi XE(UP1) Pro で作成







使用方法


フォームに配置し、各プロパティを設定します。キーボードから入力する方式です。
[BackSpace] と [Delete] が使用できます。スピンボタンなどはありません。[↓] [↑] キーでの数値変更はサポートしていません。
また [←] [→] での入力コントロール間の移動もサポートしていません。Windows 標準の [Tab] または [Shift] + [Tab] による移動です。EnterNext プロパティを True (デフォルト) にすると [Enter] または [Shift] + [Enter] で移動可能となります。


図1
元号の選択リスト
  • 空白の時は西暦と解釈する
  • 入力済みの元号文字列は [Delete] でクリア
  • 年月日の値はキーボードからタイプ




斜体フォントの使用


このコンポーネントは、斜体フォントを考慮して作成していません。
表示に斜体フォントを使用すると、表示が崩れます。再度「標準」に戻しても表示位置が正常になりません。できる限り斜体フォントの使用を避けてください。




エラーの検出方法


日付関係のプロパティ等を取得する際、エラーがあると、サイレント例外が発生します。この例外処理で、以下の様に処理を行って下さい。また、ExitCheck プロパティを True にすると、本コンポーネントがフォーカスを失う時にチェックさせることができます。なお、エラーが発生した場合は、フォーカスが空白の入力コントロールに移動するようになっています。


リスト1
例外でエラーを検出する。エラーを無視するなら except~end で何もしない。
try
  //日付関係の取得プロパティなら何でもチェック可能
  plDateEdit1.DateTime;
except
  //ダイアログ表示などのエラー発生時の処理
  //ErrorKindsでエラーの内容を知ることが可能
end;


リスト2
入力が全て空白の時に別の処理をする場合の例
if plDateEdit1.IsEmpty then begin
  //入力が全て空白の時の処理
end else begin
  //そうでない時の処理
  //例えば、日付関係のプロパティを取得して処理
end;




0 は 1899 年 12 月 30 日 0 時 0 分 0 秒


TDateTime で日付を扱う場合、DateTime = 0 の値は 1899年12月30日 です。利用に当たっては十分に注意して下さい。1899 年 (明治 32 年) は、現在のグレゴリオ暦となった年です。なお、このコンポーネントで扱う下限の日付である 1873年1月1日は、BaseDate プロパティで取得できます。

日付や時刻に空白や nil、あるいは Null 値は代入できませんか、データベースの項目、フィールドの値は、次のように nil 値が代入できます。


リスト3
  Table1.FieldByName('項目名').Assign(nil);


パラメータを使用するクエリーのコードで null を代入するには以下のような方法があります。

リスト4
  Params[0].Value    := System.Variants.NULL;
  Params[0].DataType := ftDateTime;

リスト5
  Params[0].clear;
  Params[0].Bound := True;
  Params[0].DataType := ftDate;




和暦と西暦に関する注意


Delphi では太陽暦のみ和暦に換算します。太陰暦から現在の和暦になったのは1873年1月1日 (明治6年1月1日) です。したがって、このコンポーネントは、この日付より前は変換しません。

明治5年までは太陰暦でした。1873年1月1日に改暦して太陽暦に変わりました。
太陰暦は明治5年12月2日で終わり、太陽暦は明治5年12月3日を明治6年1月1日として始まりました。
当時の 1 年は 閏月がある場合は13ヶ月で 384 日でした。そこで、一年間で 13 ヶ月の給与を支払いことを問題とした大隈重信は、ひっぱくする政府財政問題の解決策として、明治5年11日9日、急遽12月の2日分の給与は支給せずに年を変更し、太陽暦にして、財政を問題をなんとか保ったという話があります。
ただし、この時は、ユリウス暦を元にした日本独自の太陽暦でしたが、明治32年 (1899 年) に現在のグレゴリオ暦となったようです。グレゴリオ暦は、「西暦の年数が 100 で割り切れ、400 で割り切れない年を閏年としない」という太陽暦のことです。
当時の西暦と和暦の関係は次のようになっています。
  • 1872年 1月 1日は 明治4年11月21日
  • 1872年12月31日は 明治5年12月 2日 (太陽暦に変わる前日)
  • 1873年 1月 1日は 明治6年 1月 1日 (ここで和暦と西暦の月日が一致した)
下表は、明治以降の和暦の開始と最終日の日付の一覧です。
歴史関係の文書を読む時は、明治6年1月1日よりも前の場合、和暦と西暦の月日が違うことになるわけですから、結構面倒です。


元号 開始日 最終日 備考
明治 明治1年9月8日
西暦1868年1月1日
明治45年7月29日
西暦1912年7月29日
明治5年12月3日~明治5年12月31日
という日付は存在しない
大正 大正1年7月30日
西暦1912年7月30日
大正15年12月24日
西暦1926年12月24日
-
昭和 昭和1年12月25日
西暦1926年12月25日
昭和64年1月7日
西暦1989年1月7日
-
平成 平成1年1月8日
西暦1989年1月8日
平成31年4月30日
西暦2019年4月30日
-
令和 令和1年5月1日
西暦2019年5月1日
- -


[備考]
可能性の有無は別として、タイムマシンで江戸時代に旅行される方は、事件発生の年月日については注意が必要です。例えば、赤穂浪士の討ち入りは、元禄15年12月14日ですが、西暦では 1703年1月30日 となります。12月14日に合わせて出かけてしまうと、1ヶ月以上待たされることになります。

旧暦について興味のある方は、「太陰暦 うるう月」あるいは「太陰暦 うるう月 天保」等の語句でインターネットを検索してみてください。




元号が変わった場合 - Windows 7 以降


このコンポーネントには対応コードはありません。
元号の情報は、Delphi XE4 までは、SysUtils.EraNames という配列と、SysUtils.EraYearOffsets という配列から取得しています。これは、Windows のシステムからの情報によるものです。したがって、元号が変わった場合、Windows の更新の形で提供されると思いますが、古いバージョンの Windows は、サポートが終了しているかも知れません。

元号の情報は、Windows 7 以降では、レジストリの以下の場所に格納されています。ここに新しい元号の情報を追加すれば利用可能となります。実行ファイルの再コンパイルは必要ありません。実際に、レジストリのこの場所に、下図のように「神武」という年号を追加して動作確認してみました。

元号が問題となるのは、おそらく、官公庁関係ではないかと思われます。


HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\Calendars\Japanese\Eras


図2
元号のりストの格納場所




元号が変わった場合 - Windows 2000 / XP / Vista


サポート期限が終了した Windows は、新しい元号になっても更新プログラムの提供を受けることかできませんが、Windows 7 以降であればレジストリを操作することで対応できます。
Windows Vista 以前の Windows の元号情報は、System32 フォルダ内の locale.nls ファイルにあります。このファイルを書き換えれば対応可能です。ただし、このファイルの操作は、現実的には少し問題があります。
以下のページに、Windows XP の locale.nls ファイルの操作方法とテスト結果を掲載しています。






Delphi XE3 と Delphi XE5 への対応コード


2013年12月27日の Ver 9.03 で、Delphi XE3, XE4, XE5 に対応しましたが、コンポーネントのソースコードは山本隆氏が修正してくださったものを、筆者も動作確認したものです。そのまま利用させて頂くことにしました。したがって、ソースコードの先頭部分のコメント文以外は全く同じです。
リンク先の記事に詳しい説明があります。山本隆氏に感謝いたします。