|
16番会議室「玉石混淆みんなで作るSample蔵」に寄せられたサンプル
"グレゴリオ暦<->MJD暦 相互変換"
もう使うことはないだろうと思ってたDOSの時代に作った日付データを
読み込むことになったなったので関数を作ってみました。
もうちょっとスッキリしたコードになりそうなんですが...
const
// 月の日数(1月〜12月)
mdays: array[0..11] of Smallint = (31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31);
// 3/1 からの通し日(3月〜翌2月)
ydays: array[0..11] of Smallint = ( 0, 31, 61, 92, 122, 153,
184, 214, 245, 275, 306, 337);
implementation
// 閏年の2月の日数設定
procedure leapyear(y: SmallInt);
begin
if (y mod 400) = 0 then
mdays[ 1] := 29
else if (y mod 100) = 0 then
mdays[ 1] := 28
else if (y mod 4) = 0 then
mdays[ 1] := 29
else
mdays[ 1] := 28;
end;
// Greg -> MJD
function greg2mjd(y, m, d: Integer): Integer;
begin
leapyear(y);
if (m < 1) or (m > 12) or (d < 1) or (d > mdays[m - 1]) then begin
Result := -1;
Exit;
end else if m >= 3 then
m := m - 3
else begin
m := m + 9;
Dec(y);
end;
Result := 365 * y + y div 4 - y div 100 + y div 400 + ydays[m] + d - 678882;
end;
// MJD -> Greg
procedure mjd2greg(mjd: Integer; var jy, jm, jd, jw: Integer);
function day_week(mjd: Integer): Integer;
begin
Result := (mjd - 4) mod 7; // 曜日の取得 : 日〜土 -> 0〜6
if Result < 0 then
Result := Result + 7;
end;
var
mjd1, mjd2, y, i, d: Integer;
tf: Boolean;
begin
mjd1 := mjd + 678882;
y := mjd1 div 365 - 2;
tf := True;
while tf = True do begin
mjd2 := y * 365 + y div 4 - y div 100 + y div 400 + 306;
if mjd2 < mjd1 then tf := False;
Dec(y);
end;
y := y + 2;
leapyear(y);
d := mjd - greg2mjd(y, 1, 1) + 1;
for i := 0 to 11 do begin
d := d - mdays[i];
if d <= 0 then begin
d := d + mdays[i];
Break;
end;
end;
jy := y; // 年
jm := i + 1; // 月
jd := d; // 日
jw := day_week(mjd); // 曜日
end;
Original document by テレ坊 氏 ID:(QWT05010)
ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum の16番会議室「玉石混淆みんなで作るSample蔵」に投稿されたサンプルです。これらのサンプルはボーランド株式会社がサポートする公式のものではありません。また、必ずしも動作が検証されているものではありません。これらのサンプルを使用したことに起因するいかなる損害も投稿者、およびフォーラムスタッフはその責めを負いません。使用者のリスクの範疇でご使用下さい。
Copyright 1996-2002 Delphi Users' Forum
|