うるう年とは
- 1年が366日ある年
- 西暦が4の倍数であり,100の倍数ではない年がうるう年
- ただし,400の倍数である年はうるう年
- 4, 8, 12, ..., 96, 104, ..., 196, 204, ..., 296, 304, ..., 396年はうるう年
- 100, 200, 300年はうるう年ではない
- 400年はうるう年
ややこしすぎる...!
うるう年の原理
- 地球の公転と1年の日数とのずれ
- 地球の公転:365.24218944日(Wikipedia - 年,閲覧時の最新更新日時:2024/05/16(木)22:27 )
- 1年の日数:365日
上記のずれが蓄積して,うるう年が発生する
うるう年がなかった場合のずれを計算する
- 日数のずれをプロットするコードを示す
import matplotlib.pyplot as plt
revolution = 365.24218944
y = 365
loss = [(revolution-y)*i for i in range(2024)]
m3 = [365/4 for i in range(2024)]
m6 = [365*2/4 for i in range(2024)]
m9 = [365*3/4 for i in range(2024)]
m12 = [365 for i in range(2024)]
t = [i for i in range(2024)]
plt.plot(t, loss)
plt.plot(t, m3, color='red')
plt.plot(t, m6, color='red')
plt.plot(t, m9, color='red')
plt.plot(t, m12, color='red')
plt.savefig("loss_day.png")
四季が存在するとした場合に,計算上で実際よりも季節が1つ,2つ,3つ,4つ進んでしまうところを赤い直線で示した
- 300-400年あたりで季節1つ分ずれている
- 750-800年あたりで季節2つ分ずれている
- カレンダー上で夏でも実際は冬なので,夏なのに最高気温10℃といった現象が起きる
- 1500-1600年あたりでついに1年分ずれている
1年単位では小さな誤差でも,数百年たつと季節が変わるまでの誤差になる
うるう年の調整を実装
- 計算上で実際よりも1年で$0.24218944 \risingdotseq \frac{1}{4}$日進む
- 4年で1日分進む
- 4年に1度だけ,1日分カレンダーを遅らせればよい
import matplotlib.pyplot as plt
revolution = 365.24218944
y = 365
loss = [0]
for i in range(1,2024):
if i % 4 == 0:
loss.append(loss[-1]+revolution-y-1)
else:
loss.append(loss[-1]+revolution-y)
t = [i for i in range(2024)]
m1 = [-1 for i in range(2024)]
plt.plot(t[:250], loss[:250])
plt.plot(t[:250], m1[:250], 'red')
plt.savefig("loss_day_simpleleap.png")
新たに生じる微妙なずれも修正したい
100年に1回はうるう年とはしない調整を実装
import matplotlib.pyplot as plt
revolution = 365.24218944
y = 365
loss = [0]
for i in range(1,2024):
if i % 4 == 0 and i % 100 != 0:
loss.append(loss[-1]+revolution-y-1)
else:
loss.append(loss[-1]+revolution-y)
t = [i for i in range(2024)]
m1 = [1 for i in range(2024)]
plt.plot(t[:500], loss[:500])
plt.plot(t[:500], m1[:500], 'red')
plt.savefig("loss_day_100notleap.png")
このずれを400年に一度うるう年をいれることで調整
400年に1回はうるう年とする調整を実装
import matplotlib.pyplot as plt
revolution = 365.24218944
y = 365
now = 10000
loss = [0]
for i in range(1,now):
if i % 4 == 0 and (i % 100 != 0 or i % 400 == 0):
loss.append(loss[-1]+revolution-y-1)
else:
loss.append(loss[-1]+revolution-y)
t = [i for i in range(now)]
m1 = [-1 for i in range(now)]
plt.plot(t, loss)
plt.plot(t, m1, 'red')
plt.savefig("loss_day_400leap.png")
3200年に1回はうるう年でない年をつくる
import matplotlib.pyplot as plt
revolution = 365.24218944
y = 365
now = 200000
loss = [0]
for i in range(1,now):
if i % 3200 == 0:
loss.append(loss[-1]+revolution-y)
elif i % 400 == 0:
loss.append(loss[-1]+revolution-y-1)
elif i % 100 == 0:
loss.append(loss[-1]+revolution-y)
elif i % 4 == 0:
loss.append(loss[-1]+revolution-y-1)
else:
loss.append(loss[-1]+revolution-y)
t = [i for i in range(now)]
m1 = [0 for i in range(now)]
plt.plot(t, loss)
plt.plot(t, m1, 'red')
plt.savefig("loss_day_3200notleap.png")
しばらくは安泰そう
1000000年までプロットしてみる
- 500000 - 600000年あたりで1日ずれている
- 今まで,$2^m \times 10^n$年ごとに調整してきた
- よって,範囲内で該当する$512000 = 2^9 \times 10^3$年で調整すればうまくいきそう
512000年に1回はうるう年を入れる
import matplotlib.pyplot as plt
revolution = 365.24218944
y = 365
now = 50000000
loss = [0]
for i in range(1,now):
if i % 512000 == 0:
loss.append(loss[-1]+revolution-y-1)
elif i % 3200 == 0:
loss.append(loss[-1]+revolution-y)
elif i % 400 == 0:
loss.append(loss[-1]+revolution-y-1)
elif i % 100 == 0:
loss.append(loss[-1]+revolution-y)
elif i % 4 == 0:
loss.append(loss[-1]+revolution-y-1)
else:
loss.append(loss[-1]+revolution-y)
t = [i for i in range(now)]
m1 = [0 for i in range(now)]
plt.plot(t, loss)
plt.plot(t, m1, 'red')
plt.savefig("loss_day_512000leap.png")
5000万年後くらいまではこの調整で通りそう