元号選択式日付時刻入力コンポーネント
ヒント・検討事項・バグ等 |
| 動作確認等 |
- |
このページは、主に、コンポーネントを利用された方からの情報等を掲載しています。
掲載記事は順不同です。更新日のもっとも古いのは、このページの作成日となっています。各項目の記事は予告なしに変更、削除する場合があります。 |
[掲載 2012年08月01日] [更新 2012年08月01日]
環境 Windows XP(SP3) + Delphi 7 + DBISAM |
| TplDateEdit.CheckDateError の中で、入力欄が全部空であるかをチェック しているところで、空ではないと判定されてしまう現象です。 |
| Delphi XE2 の 64 ビット版アプリでの例外発生 |
[掲載 2012年08月01日] [更新 2012年08月01日]
環境 Windows 7 U64 + Delphi XE2 |
新規作成のプロジェクトのフォームに、コンポを配置して、コンパイルしただけで access violation
が発生してしまう現象です。
この現象は、筆者の環境では確認できていません。 |
| 平成 1 年の入力と元号と西暦を切り替えた時の動作 |
| [掲載 2012年12月02日] [更新 2012年12月02日] |
| タイトル通りです。検討したいと思っています。特に、和暦入力で平成 1 年が入力できないのはマズイかなと思っています。 |
| 2015年04月25日現在、以下のようなサンプルがあります。 |
| [掲載 2015年04月25日] [更新 2015年04月25日] |
|
日付や時刻の値の処理、あるいは変換等の参考リンクです。
[780_ファイル情報の取得と日時・属性の変更等] には、TFileTime 型の値を TDateTime 型への変換と、その逆の変換をする自作の関数、FileTimeToDateTime、DateTimeToFileTime があります。
[816] [04_Shell オブジェクトを使用 - 構造化ストレージの値] には、TTimeZoneInformation からタイムゾーンのオフセット (バイアス) を取得する自作の関数 UTCTimeDateTimeOffset があります。
[898] [05_日付時刻型プロパティの処理例 - TDateTime 型に変換]
には、WMI の CIM_DATETIME 型の値を、Delphi の TDateTime 型の値に変換するコードがあります。
|
| Unix 時間と協定世界時とローカル時刻 ( 日本標準時 ) の相互変換 |
[掲載 2016年01月03日] [更新 2016年01月07日]
動作確認環境 : Windows 7 U64(SP1) + Delphi 6 以降 |
|
TDateTime 型の値を Unix 時間の値に変換するには、 DateTimeToUnix 関数が使用できます。その逆の変換には UnixToDateTime 関数が使用できます。
ただし、そのまま変換しただけではローカルな日時 (日本の場合は日本標準時) にはなりません。
TTimeZoneInformation を使用すると、協定世界時とローカルな時刻とのオフセット (バイアス) 値が取得できます。これを利用して変換できます。TTimeZoneInformation は Delphi 6 以降で使用可能です。次のコードはこれを利用したサンプルです。
クジラ机ブログさんのコードでも同じ処理が可能です。そのコード中の SecsPerDay, UnixDateDelta 定数は、SysUtils ユニットに定義があります。
一口に日付時刻型の値と言っても、山本隆の開発日誌の記事にあるように、いろいろな種類と値があることに注意してください。
|
[備考 1]
Delphi XE5 以前の DateTimeToUnix, UnixToDateTime 関数には、第 2 引数はありません。 |
[備考 2]
Unix 時間には 64 ビットの整数型を使用します。
|
 |
図1
作成した EXE を起動して Button2 クリック
- Unix 時間が 0 の時の 日本標準時 (JST) は
1970年1月1日 9時0分0秒
- つまり、協定世界時と日本標準時とは 9 時間の差がある
|
 |
図2
TDateTime 型の値を Unix 時間の値に変換
Unix 時間の値を TDateTime 型の値に変換 |
リスト1
日本標準時を Unix 時間に変換、および Unix 時間を日本標準時に変換
Delphi 6 以降用 |
implementation
uses
DateUtils;
{$R *.dfm}
//=============================================================================
// フォーム生成時の処理
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
Panel1.Caption := '0';
end;
//=============================================================================
// TDateTime型の値をUnix時間に変換
// TTimeZoneInformationを使用するコード
//
// Delphi 6 以降で使用可能なコード
// DateTimeToUnixの使用には,usesにDateUtilsが必要
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
LDateTime : TDateTime;
LUnixTime : Int64;
LTimeZoneInfo : TTimeZoneInformation;
begin
Panel2.Caption := '';
LDateTime := StrToDateTime('2016/01/03 08:09:10');
GetTimeZoneInformation(LTimeZoneInfo);
//TTimeZoneInformation.Biasの値を秒数にして加算
//協定世界時と日本標準時との差は-9時間なのでLTimeZoneInfo.Biasの値は-540
LUnixTime := DateTimeToUnix(LDateTime) + LTimeZoneInfo.Bias * 60;
Panel1.Caption := Format('%d', [LUnixTime]);
end;
//=============================================================================
// Unix時間をTDateTime型の値に変換
// TTimeZoneInformationを使用するコード
//
// Delphi 6 以降で使用可能なコード
// UnixToDateTimeの使用には,usesにDateUtilsが必要
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
LDateTime : TDateTime;
LUnixTime : Int64;
LTimeZoneInfo : TTimeZoneInformation;
begin
GetTimeZoneInformation(LTimeZoneInfo);
//TTimeZoneInformation.Biasの値を秒数にして減算
//協定世界時と日本標準時との差は-9時間なのでLTimeZoneInfo.Biasの値は-540
LUnixTime := StrToInt64(Panel1.Caption) - LTimeZoneInfo.Bias * 60;
LDateTime := UnixToDateTime(LUnixTime);
Panel2.Caption := DateTimeToStr(LDateTime);
end;
|
Delphi XE で実装された TTimeZone という抽象クラスには、協定世界時刻とローカル時刻の変換用のメソッドが用意されています。以下は、それを使用したサンプルです。
|
リスト2
日本標準時を Unix 時間に変換、および Unix 時間を日本標準時に変換
Delphi XE 以降用 |
implementation
uses
DateUtils;
{$R *.dfm}
//=============================================================================
// フォーム生成時の処理
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
Panel1.Caption := '0';
end;
//=============================================================================
// TDateTime型の値をUnix時間に変換
// TTimeZoneを使用するコード
//
// Delphi XE 以降で使用可能なコード
// DateTimeToUnix,TTimeZoneの使用には,usesにDateUtilsが必要
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
LDateTime : TDateTime;
LUnixTime : Int64;
begin
Panel2.Caption := '';
LDateTime := StrToDateTime('2016/01/03 08:09:10');
//ローカルな日時を協定世界時に変換してからUnix時間に変換
LUnixTime := DateTimeToUnix(TTimeZone.Local.ToUniversalTime(LDateTime));
Panel1.Caption := Format('%d', [LUnixTime]);
end;
//=============================================================================
// Unix時間をTDateTime型の値に変換
// TTimeZoneを使用するコード
//
// Delphi XE 以降で使用可能なコード
// UnixToDateTime,TTimeZoneの使用には,usesにDateUtilsが必要
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
LDateTime : TDateTime;
LUnixTime : Int64;
begin
LUnixTime := StrToInt64(Panel1.Caption);
//Unix時間をTDateTimeの値に変換したら,ローカルな日時に換算
LDateTime := TTimeZone.Local.ToLocalTime(UnixToDateTime(LUnixTime));
Panel2.Caption := DateTimeToStr(LDateTime);
end;
|
Delphi XE6 以降であれば、DateTimeToUnix, UnixToDateTime 関数の第 2 引数の値で、UTC として扱うか、ローカルな日時 (日本の場合は日本標準時) として扱うかを指定できます。次のコードはローカルな日時として扱う例です。
DateTimeToUnix, UnixToDateTime 関数の第 2 引数の値のデフォルト値は True です。True の場合は協定世界時 (世界標準時) の扱いとなります。
|
リスト3
日本標準時を Unix 時間に変換、および Unix 時間を日本標準時に変換
Delphi XE6 以降用 |
implementation
uses
DateUtils;
{$R *.dfm}
//=============================================================================
// フォーム生成時の処理
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
Panel1.Caption := '0';
end;
//=============================================================================
// TDateTime型の値をUnix時間に変換
// DateTimeToUnixの引数で、TDateTime型の値をUTCと解釈するかを指定できる
//
// Delphi XE6以降専用
// Delphi XE5以前のDateTimeToUnixには,第2引数はない
// DateTimeToUnixの使用には,usesにDateUtilsが必要
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
LDateTime : TDateTime;
begin
Panel2.Caption := '';
LDateTime := StrToDateTime('2016/01/03 08:09:10');
Panel1.Caption := DateTimeToUnix(LDateTime, False).ToString;
end;
//=============================================================================
// Unix時間をTDateTime型の値に変換
// UnixToDateTime(LUnixTimeの引数で、UTCで取得するかを指定できる
//
// Delphi XE5以前のUnixToDateTimeには,第2引数はない
// UnixToDateTimeの使用には,usesにDateUtilsが必要
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
LDateTime : TDateTime;
LUnixTime : Int64;
begin
LUnixTime := StrToInt64(Panel1.Caption);
LDateTime := UnixToDateTime(LUnixTime, False);
Panel2.Caption := DateTimeToStr(LDateTime);
end;
| [掲載 2018年09月09日] [更新 2018年09月12日] |
|
以下のサンプルプログラムに、DEKO 氏作の国民の祝日 (祭日) の検出用のコードを、関数のユニットとして添付しています。
|
|
サンプルプログラム集に添付の関数は、昭和23年7月20日 (1948年7月20日) に公布 (公布の日から施行) の「国民の祝日に関する法律」に基づく祝日を検出します。昭和23年1月1日 (1948年1月1日) 以降において、この法律施行前の、旧法 (昭和2年勅令第25号) における祝日には下表のものがあります。
|
| 元始祭 |
昭和23年01月03日 (1948年01月03日) |
| 新年宴会 |
昭和23年01月05日 (1948年01月05日) |
| 紀元節 |
昭和23年02月11日 (1948年02月11日) |
| 春季皇霊祭 |
昭和23年03月21日 (1948年03月21日) |
| 神武天皇祭 |
昭和23年04月03日 (1948年04月03日) |
| 天長節 |
昭和23年04月29日 (1948年04月29日) |
| [掲載 2019年05月04日] [更新 2019年05月04日] |
|
1 年を「元年」として、あるいは 1 月 1 日を「元日」の文字列で取得するには、例えば以下のようなコードで取得できます。
元年も元日も数値ではありませんから、文字列としての取得となります。
|

|
図3
元年の取得 |
 |
図4
元日の取得 |
リスト4
1 年を元年に、1 月 1 日を元日に変換する例 |
//=============================================================================
// フォーム表示開始時の処理
//=============================================================================
procedure TForm1.FormShow(Sender: TObject);
begin
plDateEdit1.DisplayError := False;
plDateEdit1.DateTime := Now;
end;
//=============================================================================
// 和暦の 1 年を元年で表示
// 1 月 1 日を元日で表示
//
// 「元年」の表記理由で言えば、年の最初の日である 1 月 1 日は「元日」である
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
LYear : string;
LMonthDay : string;
begin
Memo1.Lines.Clear;
if plDateEdit1.GengoYear = 1 then begin
LYear := plDateEdit1.GengoStr + ' 元年';
end else begin
LYear := plDateEdit1.GengoStr + ' ' + plDateEdit1.GengoYearStr + ' 年';
end;
if (plDateEdit1.Month = 1) and (plDateEdit1.Day = 1) then begin
LMonthDay := '元日'
end else begin
LMonthDay := plDateEdit1.MonthStr + ' 月 ' + plDateEdit1.DayStr + ' 日';
end;
Memo1.Lines.Add(LYear + ' ' + LMonthDay);
end;
//=============================================================================
// TplDateEdit の OnChange イベント
//=============================================================================
procedure TForm1.plDateEdit1Change(Sender: TObject);
begin
try
Button1Click(nil);
except
end;
end;
|