Delphi Programming / Object Pascal
サイトのトップページへ リンクのページへ ロゴマーク
[掲載 2012年08月01日] [更新 各項目を参照] 元号選択式日付時刻入力コンポーネント
元号選択式日付時刻入力コンポーネント
ヒント・検討事項・バグ等
動作確認等 -







このページの内容


このページは,主に,コンポーネントを利用された方からの情報等を掲載しています.
掲載記事は順不同です.更新日のもっとも古いのは,このページの作成日となっています.各項目の記事は予告なしに変更,削除する場合があります.




日付入力の空白チェック動作の不正


[掲載 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日)






1 年を元年に,1 月 1 日を元日に変換


[掲載 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;