Quantcast
Channel: 円周率近似値の日に生まれて理系じゃないわけないだろ! - knifeのblog
Viewing all articles
Browse latest Browse all 5376

ユリウス日

$
0
0

ユリウス暦やグレゴリオ暦の年月日からユリウス日(ユリウス通日)を求める、その逆のユリウス日から年月日を求めることを考える。

まずはそれぞれの暦の年月日からユリウス日を求めてみる。

ユリウス暦にしてもグレゴリオ暦にしても、1月と2月は前年の13月と14月ということで計算します。
また、紀元前1年は0年、紀元前2年以前は負数として計算する。

以下、JavaScriptの書き方で数式を書きますね。
ここでは、JDは整数として、時刻に使われる端数はないものとします。

ユリウス暦(jy年jm月jd日)→ユリウス日(JD)

if ( jm < 3 ) jy--, jm+=12;
JD = Math.floor(365.25*jy)+Math.floor(30.59*(jm-2))+jd+1721087;


グレゴリオ暦(gy年gm月gd日)→ユリウス日(JD)

if ( gm < 3 ) gy--, gm+=12;
JD = Math.floor(365.25*gy)+Math.floor(gy/400)-Math.floor(gy/100)+Math.floor(30.59*(gm-2))+gd+1721089;


式は長ったらしいが、それほど難しいことをやっているわけではない。
長ったらしく感じるのは、Math.floor関数を使って整数化しているからだろう。

まず、ユリウス暦の1721087や、グレゴリオ暦の1721089は、定数であるからユリウス日なんだろうということは解る。

1721087は、ユリウス暦の紀元前1年1月30日
1721089は、グレゴリオ歴の紀元前1年1月30日

であり、紀元前1年1月30日を起点にして、経過日数を立式しているということである。

次に気になるのが、共通して登場する Math.floor(30.59*(m-2)) の部分であろう。

月から2を引いたものに、30.59を掛け、整数化している。

m30.59*(m-2)
330.59
461.18
591.77
6122.36
7152.95
8183.54
9214.13
10244.72
11275.31
12305.90
13336.49
14367.08

Math.floorを外した整数化前の状態の値をみると、上手いこと経過日数を計算していることが解る。

30.58でも、30.60でも、上手く行かないので、絶妙な値であるとも言える。

あとは、閏年か平年かで2月29日分をどうするかって計算をしている。

つまり、ユリウス日からユリウス歴やグレゴリオ歴を求めるのは、それほど難しいというわけではない。

しかし、その逆算が難しいというか面倒なのである。

ネットには、様々なプログラムコードや式があるにはあるのだが、どこからこんな値が出てきたのが不明確で、その式を使う気になれない。

であれば、数学屋の私としては、何とかしたいと考えるのである。

では、どういう取っ掛かりで考えるかというと、ユリウス日の連続性であり、ユリウス暦やグレゴリオ暦の周期性である。


連続性、周期性とはどういうことなのか、手始めに西向く士を考えてみる。

ユリウス歴やグレゴリオ暦からユリウス日を求める際に、3月1日を起点として、平年であろうが閏年であろうが、2月という厄介者を一番最後に持ってくるようにする。



1年


135×2+31=337日



153日153日153日
2345678910111212


日数??
3130313031313031303131
??




西向く士も、一見すると不規則に並んでいるかのようですが、3月から開始し、5ヶ月毎に分けると、153日周期で、2月を除くと337日周期とみることができる。

しかし、ユリウス日からいきなり年、月を求めずして日を求めることは難しい。

一番簡単な年を求め、月、日の順番でいくのが妥当だろう。


ユリウス日(JD)→ユリウス暦(jy年jm月jd日)


1461日
306日365日365日365日29日
n年(n+1)年(n+2)年(n+3)年(n+4)年
020312010203120102031201020312010202
290131012801310128013101280131012829
月'110009101100091011000910110009101111


n'年(n'+1)年(n'+2)年(n'+3)年


365日365日365日365日

この表をみれば解ると思うが、4年に1回の閏年で、3月1日を起点とし、2月29日を終点とする。
この4年が1461日周期で、365日周期が4回と2月29日の1日分である。

では、起点とする3月1日を何年にするか。

紀元前4713年3月1日、JD=60としてみる。

jy = Math.floor((JD-60+0.5)/1461*4);

で適当なものを入れて確認してみると、求めたいjyと4712の差がありました。
jyが負になると、日の計算で厄介になるかもしれないので、とりあえずこのままにしておく。

続いて、月を考える。

m0 = (JD-60)%1461;

これが起点からの経過日数であり、m0=1460が2月29日になります。

これを更に365日で剰余を取り、年ごとの3月1日からの経過日数を求める。

m1 = m0%365;

これで、m1=0が、3月1日、最後は2月29日になります。

最後の2月29日に365を加えたいので、

m2 = 365*Math.floor((m0+1)/1461);

これらから、3月1日を起点とした経過日数は、

m3 = m1+m2;

となる。

これをユリウス日計算に使われる30.59で割って、月を求める。

m4 = Math.floor((m3+0.4)/30.59);

下駄を0.4としましたが、0.36から0.48の間ならよい。

jm = m4+3;

解説のため、数式を分けましたが、実際はここまで分ける必要はありません。

年、月が求まったので、これを使えば、JDとの差分から日が求まる。

jd = JD-Math.floor(jy*365.25)-Math.floor(30.59*(jm-2))-29;

最後に人前に出せる数値にするため、

jy -= 4712;
if ( jm>12 ) jy++, jm-=12;

紀元前を表示するするときは、-jy+1で問題なしでしょう。



ユリウス日(JD)→グレゴリオ暦(gy年gm月gd日)

ユリウス歴の1461日周期を25周と-1日で100年分、それを4周と1日で400年分である。

36524×4+1=146097日
100×4+1=400年
1461×25-1=36524日36524日02

29
4×25-1=100年100年
1461日1461日1460日1461日1461日1460日
4年4年4年-14年4年4年-1

では、グレゴリオ暦の起点とする3月1日を何年にするか。

紀元前4401年3月1日、JD=114053としてみる。

まずは、年と月を考えます。

a = (JD-114053)%146097;
b = a%36524;
c = b%1461;

y0 = 400*Math.floor((JD-114053+0.5)/146097);
y1 = 100*Math.floor(a/36524)-Math.floor((a+1)/146097);
y2 = 4*Math.floor(b/1461);
y3 = Math.floor(c/365)-Math.floor((c+1)/1461);

gy = y0+y1+y2+y3;

この状態で、gyは4400の下駄を履いているが、400年周期であるから、月や日の計算には支障がないというか、下駄を履かせたままでないと、日に支障が出る。

m0 = c%365+365*(Math.floor((a+1)/146097)+Math.floor((c+1)/1461));

これがすべての年の3月1日からの経過日数。

gm = Math.floor((m0+0.4)/30.59)+3;

gd = JD-(Math.floor(365.25*gy)+Math.floor(gy/400)-Math.floor(gy/100)+Math.floor(30.59*(gm-2)))-114053+31

最後に、

gy -= 4400;
if ( gm>12 ) gy++, gm-=12;


こんな感じで、プログラムを組んでみるかな。



Viewing all articles
Browse latest Browse all 5376

Trending Articles