UnixTime⇔グレゴリオ暦の計算をAPIを使わずにやってみる[※未解決※]
※できてません。助けて!
そもそもUnixTimeって?
UNIX時間またはUNIX時刻(UNIX time or POSIX time)とはコンピューターシステム上で日時を表す単位。UTCでの1970年1月1日真夜中(0時0分0秒)からの経過秒数(閏秒を加味しない)で表される。
UNIX時間 - Wikipedia
1970年1月1日からの累計秒ですね!なるほど!
うるう年とかも考慮しつつ…むむむ。
先人たちの知恵を借りる。
フェアフィールドの公式
1年1月1日(0年13月1日) 〜 y 年 m 月 d の日数を求める
ツェラーの公式 - Wikipedia
よーし!これをプログラミングしたらいいんだよね!
近代の先人たちの知恵をさらに借りる
参考:
すでにプログラミングっぽく成立してる!
よーしやるぞー!と思ってそのまま実装。ほとんど式がまんまなのでコピペですね。
手近にあったrubyでやってみました。
# グレゴリオ暦元年から現在までの経過日数を計算 sum_day = (365.0 * year + (year / 4.0).floor - (year / 100.0).floor + (year / 400.0).floor + ((306.0 * (month + 1)) / 10.0).floor + day - 428) - epoc_time # floorをかまさなかったらなんだか値が大幅にずれた。 #sum_day = (365 * year + (year / 4) - (year / 100) + (year / 400) + (306 * ((month + 1) / 10)) - 428 + day) - epoc_time # 経過日数を秒変換し、時分秒を加算 sum_time = sum_day * 86400.0 + (hour * 3600.0) + (minute * 60.0) + second p "----------------------------------------" p "a_経過日数(1970から):" + sum_day.to_s p "a_経過秒(1970から):" + sum_time.to_s p Time.at(sum_time).utc; p Time.utc(year , month , day ,hour , minute , second).to_i p (Time.utc(year , month , day ,hour , minute , second).to_i - sum_time) / 3600 p "----------------------------------------" #=> #"----------------------------------------" #"a_経過日数(1970から):12841.0" #"a_経過秒(1970から):1109502671.0" #Sun Feb 27 11:11:11 UTC 2005 #1109589071 #24.0 #"----------------------------------------"
なんかずれる…。
場合によっては一致したり、1日2日のずれが発生します。
これはだめだ…orz
逆変換は月日の扱いに弱い…
# グレゴリオ暦元年から現在までの経過秒から年月日時分秒を取得 h = (( sum_time % 86400 ) / 3600.0).floor mm = ((( sum_time % 86400 ) - h * 3600.0 ) / 60.0).floor s = (( sum_time % 86400 ) - h * 3600 ) - mm * 60 times = (h * 3600) + (mm * 60) + s # 割り切れない値をそれぞれ分配 p h.to_s + ":" + mm.to_s + ":" + s.to_s days = (sum_time - times) / 86400.0 # 1970/1/1以降の累積日数を追加する。 days = days + epoc_time y = (days / 365.0).floor # 1年で割り切れない値を月と日のために算出(当年以外のうるう日は除く) uruu = (((y-1) / 4.0).floor - ((y-1) / 100.0).floor + ((y-1) / 400.0).floor) samedays = ((days + 365 - uruu)% 365).floor # 当年がうるう年の場合に備える jan = (y % 4 == 0 || y % 100 != 0 && y % 400 == 0) ? 29 : 28 # 計算式が思いつかないので、地道に足していきます months = [31,jan,31,30,31,30,31,31,30,31,30,31] m = 0 d = 0 for i in 0...12 if m + months[i] > samedays d = samedays - m m = i + 1 break end m = m + months[i] end p y.to_s + "/" + m.to_s + "/" + d.to_s
うーん、一日二日ずれる…計算どっかで違うのかなー