Delphi Tips 
-----------------------------

キーワード:日時

>> Index

03/04 春分、秋分、夏至、冬至の求め方
06/27 ファイルの更新日時を得る
09/09 文字列を TDateTime に変換する
09/09 経過日数を取得する
09/09 1時間後を取得する
02/11 和暦を西暦に直したい
02/08 time_t を TDateTime に変換する

最終更新: 7329 日前

0221  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/08/26 西坂良幸 rev 1.2
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 2004/03/04 osamu 編集
春分、秋分、夏至、冬至の求め方


水野さんが明快なアイデアをだしています。[Delphi-ML:38594]
  
春分、秋分、夏至、冬至の求め方は、単純に1997年の春分、夏至、秋分、冬至の日時に、地球が太陽の周りを回る周期(365.2422日)を足したり引いたりするだけのものです。
ただ、ここ20〜30年くらいの春分、秋分の日は、上の式で求めたものと同じだそうです。
実際は、計算して人間(政府)が決めるらしいですね。
カレンダーなどの作成に大変便利です。

下記のコードは、時刻部を省略し、日付のみに変えてあります。

type
  TSeason = (seVernalEquinox, seSummerSolstice, seAutummnalEquinox, seWinterSolstice);

function JapanHoliday4(myYear: Integer; mySeason: TSeason): TDateTime;
var
  myDate: TDateTime;
begin
  case Integer(mySeason) of
    0: myDate:= StrToDateTime('97/03/20 22:55') + 365.2422 * (myYear - 1997); //春分
    1: myDate:= StrToDateTime('97/06/22 03:55') + 365.2422 * (myYear - 1997); //夏至
    2: myDate:= StrToDateTime('97/09/23 08:56') + 365.2422 * (myYear - 1997); //秋分
    3: myDate:= StrToDateTime('97/12/21 18:49') + 365.2422 * (myYear - 1997); //冬至
  end;
  Result:= Int(myDate);
end;

またコンポーネントでは、
Delphian World < http://www.delphianworld.com/ >;
に「祝祭日カレンダー」というのがあります。
秋分・春分計算もしてくれる様です。
参照: [Delphi-ML:38539] [Delphi-ML:38594] <PASCAL>

0173  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/03/08 osamu rev 1.2
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 2003/06/27 osamu 編集
ファイルの更新日時を得る

Windows 的な方法としては、FindFirst/FindClose を使って、得られた TSerchRec を読みます。

別解として、PASCAL の FileAge 関数を使った方法を、ひきさんが以下のホームページで解説してくださっています。

[Delphi壁の穴]-[その二:システムを覗く]
http://hp.vector.co.jp/authors/VA009712/take/delphi/kabesys.htm#datetimefile1
http://hp.vector.co.jp/authors/VA009712/take/delphi/kabesys.htm#datetimefile2
参照: <ファイル> <PASCAL>

0250  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/09/09 osamu rev 1.2
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 1999/09/09 osamu 編集
文字列を TDateTime に変換する

文字通り StrToDateTime という関数もあるんですが、これは yyyy/mm/dd などの形式にしか対応していません。ちょっとひねって VarToDateTime を使えば、ほぼどんな形式でもうまく変換できます。string -> Variant は自動で変換されるので、そのまま文字列を渡すだけで使えます。

MyDateTime := VarToDateTime('平成1年1月1日午後1時1分1秒');

全角数字もOKですが、さすがに '平成九年九月九日' は無理でした。

VarToDateTime('1999/1/2') = VarToDateTime('1/2/1999');

の結果は、True になりました。

注意点として、VerToDateTime は StrToDateTime と違い、ShortDateFormat グローバル変数を見ていないようです。

    ShortDateFormat:='DD/MM/YY';
    ShowMessage(FloatToStr(VarToDateTime('2/1/1999')-VarToDateTime('平成11年2月1日')));

の結果は 0 になります。
参照: <文字列> <PASCAL>

0251  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/09/09 osamu rev 1.1
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 1999/09/09 osamu 編集
経過日数を取得する

> 1998年12月3日 − 1998年11月29日 = 4日
> という答えが欲しいのですが、年・月をまたがっても、
> 日数が帰って来るようにするにはどうしたらよいでしょう?

TDateTime 型は日数を単位とする double 値 (1899/12/30 0:0:0 からの経過日数) なので、Trunc して引き算すれば望みの結果が得られます。

Days := Trunc(Now) - VarToDateTime('昭和20年8月15日');

あるいは、D3 以前ならば、

Days := Trunc(Now) - EncodeDate(1945,8,15);
参照: [Delphi-ML:33577] <PASCAL>

0249  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/09/09 osamu rev 1.1
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 1999/09/09 osamu 編集
1時間後を取得する

TDateTime 型は日数を単位とする double 値 (1899/12/30 0:0:0 からの経過日数) なので、一時間後の時刻を得るには 1/24 を足してやれば良いです。1時間20分後などを得るには

a := Now + StrToTime('1:20:00');    // 現時刻の1時間20分後
b := Now + EncodeTime(1, 20, 0, 0); // これも1時間20分後

EncodeDate、DecodeDate、EncodeTime、DecodeTimeを使うと環境に依存しないので、a より b がおすすめです。
参照: [Delphi-ML:33577] <PASCAL>

0151  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/02/11 osamu rev 1.1
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 1999/02/11 osamu 編集
和暦を西暦に直したい

こんなのはどうでしょう?

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
  if Key<>#13 then
    Exit;
  Key:= #0;
  with Edit1 do
  try
    Text:= FormatDateTime('yyyy/m/d',VarToDateTime(Text));
    SelectAll;
  except
    on EVariantError do begin
      SelectAll;
      raise Exception.Create('入力が不正です');
    end;
  end;
end;

98/8/21 h10/8/21 s24-10-2 m1/1/1 8/21 8/21/98 98/5 1996-8/21
等 ほとんど何でもありです。半角、全角関係なしです。
参照: [Delphi-ML:25313] [Delphi-ML:25315] <文字列> <計算> <PASCAL>

0088  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/02/08 osamu rev 1.1
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 1999/02/08 osamu 編集
time_t を TDateTime に変換する

time_t は、 int (4バイト)で、GMT の 1970年1月1日0時0分0秒からの経過時間を秒単位で表したもので、どうやら2038年1月19日3時14分07秒で破綻するようです。

function time_tToDateTime(vtime_t : Integer) : TDateTime;
const
  cDeltaDate  : Integer = 25569; // 1970/01/01 の TDateTime値
  cSecPerMint : Integer = 60;
  cSecPerHour : Integer = (60*60);
  cSecPerDay  : Integer = (60*60*24);
var
  hh, mm, ss : Word;
  n : Integer;
begin
  vtime_t := vtime_t - cSecPerHour * 9;  // JST=+9
  n  := vtime_t mod cSecPerDay;
  hh := n div cSecPerHour;
  n  := n mod cSecPerHour;
  mm := n div cSecPerMint;
  ss := n mod cSecPerMint;
  Result := (vtime_t div cSecPerDay) +
        cDeltaDate + EncodeTime(hh, mm, ss, 0);
end;
参照: [Delphi-ML:18520] <計算> <PASCAL>

[新規作成] [最新の情報に更新]

How To
Lounge
KeyWords

Tips
Delphi
Home
Osamu Takeuchi osamu@big.or.jp