久々すぎる更新なのにしれ~っと。
とある筋から「decimal years」なんてのを初めて知る。2017-7-26 なら 2016.56557 という具合だ。…なんてヘンな含み持たせてもしょうがないか…。えとな。緯度経度と現在日時から、Magnetic Declination Estimated Value (磁偏差) を取得出来る NOAA のサービスがあって、これのインターフェイスが decimal years なのでした。
decimal years てのは単に「12進数とか60進数なんかクソくらえ」ってだけの日付時刻表現てことね。
wikipedia みてもこの基礎以外はあんましわからない。decimal years の計算方法は英語でわんさか出て来る。
これだけ:
1 # -*- coding: utf-8 -*-
2 from datetime import datetime
3
4 def datetime_to_decimal_year(date):
5 """
6 Calculates the decimal representation of a date, e.g., 2013.12.
7
8 The code uses Python's datetime package to determine the fractional
9 year. Thus, leap years are taken into account. There may still be
10 issues with time zones or daylight saving times etc..
11
12 Parameters
13 ----------
14 date : python date instance
15 The input date (and time).
16
17 Returns
18 -------
19 Decimal year : float
20 Decimal representation of the date.
21
22 Examples
23 --------
24 >>> from datetime import datetime
25 >>> from decimal_year import datetime_to_decimal_year
26 >>> "%.5f" % datetime_to_decimal_year(datetime(2016, 7, 26))
27 '2016.56557'
28 """
29 st = datetime(date.year, 1, 1)
30 dur = (datetime(date.year + 1, 1, 1) - st).total_seconds()
31 return date.year + ((date - st).total_seconds()) / float(dur)
32
33
34 if __name__ == '__main__':
35 import doctest
36 doctest.testmod()
「単に10進表記にするだけデショ」て思ってるとそんな簡単な話でもなくて、「一年て何日デスカ」問題があってだな、そこの定義について wikipedia みてもよくわからんのですよ。けど色々徘徊してコードスニペットみてると皆上のコードと同じことしてた。つまり「今年は366日ある」で計算してる。
ちなみにこれを調べてたら天文学関係をまとめたと思しき PyAstronomy なんてのを見つけたんだけど、これの decimal years 関係は decimalYear.py。ここのコメントにある通り、元にしたのは stackoverflow てことで、PyAstronomy の作者はいわゆる専門家ではなさそうだ。(上に貼り付けたコードはもともとは decimalYear.py だったもの。)
追記:
PyAstronomy や StackOverflow の実装が time.mktime を使ってる意図を読み取れてなかったワタシは total_seconds() でなく days を使っていた。これだと時分秒を含んでいない。アホでした。今上で貼り付けられてるコードは total_seconds() に直してあるので、時分秒も考慮されまする。