3

http://www.lfd.uci.edu/%7Egohlke/pythonlibs/によって配布されたプリコンパイル済みバージョンのおかげで、天文計算のEphemパッケージを Windows7 64 ビット マシンと Python 3.3.1 に最終的にインストールできました。

それを使用することを学ぶ中で、私は説明を見つけることができない次の奇妙な点に出くわしました:

Python 3.3.1 (v3.3.1:d9893d13c628、2013 年 4 月 6 日、20:30:21) [MSC v.1600 64 ビット (AMD64)] win32情報。

>>>エフェムをインポート

>>> ephem.localtime( ephem.Date( '1970' ) )

datetime.datetime(1970, 1, 1, 1, 0, 0, 3)

>>> ephem.localtime( ephem.Date( '1969' ) )

トレースバック (最新の呼び出しが最後):

ファイル ""、1 行目、ephem.localtime( ephem.Date( '1969' ) ) 内

ファイル「C:\Python33\lib\site-packages\ephem__init__.py」、479 行目、localtime timetuple = time.localtime(calendar.timegm(date.tuple()))

OSError: [Errno 22] 引数が無効です

>>>

1970より小さいすべての引数は、この同じエラーを引き起こします。ephem.Date ()が原因ではないようですので、

>>> ephem.Date('1969')

25202.5

>>>

奇妙な動作はephem.localtime()に属しているとしか結論付けられません。私の使い方が間違っているのでしょうか、それともコードにバグがありますか?

4

2 に答える 2

2

私は Ephem パッケージに直接精通しているわけではありませんが、あなたが目にしている振る舞いは、あなたが見ているものがエポックの問題であることを強く示唆しています。Unix エポックが 1970-01-01 00:00:00 UTC である場合、それより前の日付を Unix 時間値 (符号なし 32 ビットまたは 64 ビット int) に変換しようとすると、未定義の結果になります。

Ephem's methodのドキュメントからdate判断すると、これは起こっていないはずです。エポックが1899-12-31 12:00:00である別の内部時間表現を使用しているように見えますが、どのタイムゾーンであるかはよくわかりません. localtimeただし、Ephemメソッドは Pythondatetimeオブジェクトを返します。Python 独自の datetime モジュールのドキュメントでは、 1 ~ 9999 の範囲の年をサポートしていると説明さdatetimeれているため、表示されている動作は、Ephem の内部日付表現と Python の の間のどこかでdatetime、Unix タイムスタンプに変換しようとしているように思われます。あなたの質問のトレースバックを見ると、次の非常に示唆に富んだ行があります。

File "C:\Python33\lib\site-packages\ephem__init__.py", line 479, in localtime \
timetuple = time.localtime(calendar.timegm(date.tuple()))

そして、calendar モジュールの Python ドキュメントを確認すると、次のことがわかります。

calendar.timegm(タプル)

time モジュールの gmtime() 関数によって返されるような時間タプルを取り、対応する Unix タイムスタンプ値を返す、無関係ですが便利な関数です。エポックは 1970で、POSIX エンコーディングを想定しています。実際、 time.gmtime() と timegm() は互いに逆です。

問題があります: Ephemlocaltime()は引数を Unix タイムスタンプ形式で渡そうとしていますが、Unix エポックより前の日付は負のタイムスタンプ値で表す必要があり、Unix タイムスタンプは符号なし整数であるため、これは機能しません。

さて、これを修正する方法については、Ephem も Python も使用したことがないので、あまり役に立たないかもしれません。localtime()一般に、引数を Unix タイムスタンプとして表そうとしないようにEphem を変更することをお勧めします。おそらく、使用できるより広範囲の時間表現がいくつかあるかもしれません。またはlocaltime()、datetime モジュールによって提供される時間変換関数の観点から操作するように作り直すことができるかもしれません。

また、これをバグとして Ephem 開発者に報告したいと思うかもしれません。彼らのパッケージが 1899 年までさかのぼり、おそらくそれ以前の日付で動作することを意図している場合、パッケージ内の関数の少なくとも 1 つが 1970 年より前のものを処理できないことを知りたいと思うでしょう。のこの制限について説明しlocaltime()ます。調べたときには何も見つかりませんでしたが、私のレビューはすべてを網羅しているとは言えませんでした。)

于 2013-05-05T18:17:53.107 に答える
1

私のマシン(Ubuntu、Python 3.3.0、ephem 3.7.5.1)で動作します:

>>> import ephem
>>> ephem.Date('1969')
25202.5
>>> d = ephem.Date('1969')
>>> d.datetime() # utc
datetime.datetime(1969, 1, 1, 0, 0)
>>> ephem.localtime(d) # local timezone
datetime.datetime(1969, 1, 1, 6, 0, 0, 2)
于 2013-05-05T21:40:46.120 に答える