16
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

うるう年とは

  • 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")
  • 実行結果

    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")
  • 見やすいように前半250年のみ切り出した実行結果

    loss_day_simpleleap.png

  • 今度は100-150年あたりで1日今度はカレンダーが遅れる

新たに生じる微妙なずれも修正したい

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")
  • 見やすさのために前半500年部分のみ切り出した実行結果

    loss_day_100notleap.png

  • 今度は300-500年あたりで1日カレンダーが進む

このずれを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")
  • 誤差を見るために前半5000年まで切り出した実行結果

    loss_day_400leap.png

  • 2000年くらいまではほぼ誤差ないが3200年くらいでカレンダーが1日遅れる

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")
  • 200000年分切り出した実行結果

    loss_day_4000notleap.png

しばらくは安泰そう

1000000年までプロットしてみる

loss_day_3200notleap.png

  • 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")
  • 実行結果

    loss_day_12800leap.png

5000万年後くらいまではこの調整で通りそう

16
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?