【マイレース開発記録(4)】Swiss Ephemeris導入で詰まる
「理論」はできた。次は“本物の天体計算”
ロジック設計がある程度まとまり、
いよいよ「実際の天体位置を取得する」段階に入りました。
ここで選んだのが、
Swiss Ephemeris(pyswisseph)
天体の高精度計算ライブラリです。
占星術アプリを作るなら、
ここは避けて通れないと考えました。
なぜ Swiss Ephemeris を選んだのか
選定理由はシンプルです。
- 精度が高い
- 実務レベルで使われている
- Pythonから扱える
一方で、
- 導入が少し重い
- ephemerisファイルの扱いが独特
- 時刻計算の前提知識が必要
というクセもあります。
私は「とりあえず入れてみる」ことにしました。
ここから、迷走が始まります。
インストールはできた。でも動かない
まずはインストール。
Bash
pip install pyswisseph
これは問題なく成功しました。
ところが、実際に swe.calc_ut() を呼び出すと、
- 計算値が異常
- 想定外の値が返る
- そもそもエラーになる
最初は「使い方が間違っている」と思いました。
しかし原因は、
ephemerisファイルのパス設定でした。
Swiss Ephemerisは、
- 天体の位置データファイル
- それを読み込むパス指定
が必要になる場合があります。
私は最初、
Python
swe.set_ephe_path()
を明示的に設定しようとして、逆に壊しました。
結果的に、pyswisseph同梱のデフォルトパスを使う方が正解でした。
ここで学んだのは、
ライブラリの仕様を“想像で補完しない”
ということでした。
もっと大きな壁:時刻の扱い
しかし本当の壁はここからでした。
Swiss Ephemerisは
UTC基準のユリウス日で計算します。
私は日本時間(JST)で入力を受け取っています。
つまり、
- JST → UTC変換
- datetime → ユリウス日変換
- その結果を
calc_ut()に渡す
という流れが必要でした。
最初、私はこれを軽く見ていました。
「タイムゾーンつければいいだけでしょ?」
そう思っていました。
違いました。
ユリウス日という概念
Python
swe.julday(year, month, day, hour)
でユリウス日を作ります。
しかしここで必要なのは、
UTCの時刻を“浮動小数点時間”で渡すこと
つまり、
- 時間
- 分
- 秒
を 24時間形式の小数に変換しなければなりません。
さらに、
JSTで入力された時間をUTCに変換する必要があります。
私は最初、
- JSTのままユリウス日を生成
- そのままcalc_utに渡す
というミスをしていました。
結果、
天体位置が約9時間ずれる。
当然、計算結果が不自然になります。
なぜ気づけたのか
最初は原因が分かりませんでした。
- ロジックが間違っている?
- フラグ指定が悪い?
- 精度設定?
AIと対話しながら一つずつ確認していきました。
- タイムゾーンは?
- UTCに変換している?
- juldayのhourはUTC?
そこでようやく、
Python
utc = dt.astimezone(timezone.utc)
の重要性に気づきました。
そして、
Python
hour = utc.hour + utc.minute / 60 + utc.second / 3600
と小数時間を作り、
Python
return swe.julday(utc.year, utc.month, utc.day, hour)
と修正。
やっと正常値が出ました。
精度より先に「前提条件」
この経験で強く感じたのは、
高精度ライブラリほど、前提条件が厳密
だということです。
- 単位は何か
- 時刻基準は何か
- タイムゾーンは何か
- 入力形式は何か
ロジック以前に、
前提の整合性を取らなければならない。
これは実務でも非常に重要な視点だと思います。
発達特性と環境構築
私は以前、
- 環境構築でつまずくとパニックになる
- どこが悪いか分からず混乱する
- 途中で投げたくなる
という傾向がありました。
しかし今回は違いました。
AIとの対話を使い、
- 仮説を一つずつ検証
- 前提を言語化
- ロジックを分解
していくことで、
冷静に原因を特定できました。
つまり今回は、
詰まったけれど、逃げなかった。
これが以前との大きな違いでした。

次回予告
Swiss Ephemeris導入は、
単なるライブラリ追加ではありませんでした。
それは、
- 時間とは何か
- 計算基準とは何か
- データの前提とは何か
を考えるプロセスでした。
そして私は次に、
「ユリウス日そのもの」と本格的に格闘することになります。
次の記事では、
を書いていきます。



