127 lines
3.9 KiB
Markdown
127 lines
3.9 KiB
Markdown
# PlanetaryTime
|
|
|
|
Python library for representing and working with time on other bodies in the Solar System — similar in spirit to the standard `datetime` module.
|
|
|
|
Time on a given body is expressed using a human-readable clock where **one hour is as close to one Earth hour as possible**. The number of hours per sol (day) is derived from the body's sidereal rotation period rounded to the nearest integer.
|
|
|
|
## Installation
|
|
|
|
```bash
|
|
pip install planetarytime
|
|
```
|
|
|
|
## Supported bodies
|
|
|
|
### Planets
|
|
|
|
| Body | Hours per sol | Sols per year |
|
|
|---------|--------------|---------------|
|
|
| Mercury | 1408 | 2 |
|
|
| Venus | 5833 | 1 |
|
|
| Mars | 25 | 670 |
|
|
| Jupiter | 10 | 10476 |
|
|
| Saturn | 11 | 24491 |
|
|
| Uranus | 17 | 42718 |
|
|
| Neptune | 16 | 89667 |
|
|
|
|
### Moons
|
|
|
|
Accessible via `Body.<PLANET>[index]`, ordered by distance from the planet.
|
|
|
|
| Planet | Index | Moon | Hours per sol | Tidally locked |
|
|
|---------|-------|-----------|--------------|----------------|
|
|
| Mars | 0 | Phobos | 8 | yes |
|
|
| Mars | 1 | Deimos | 30 | yes |
|
|
| Jupiter | 0 | Io | 42 | yes |
|
|
| Jupiter | 1 | Europa | 85 | yes |
|
|
| Jupiter | 2 | Ganymede | 172 | yes |
|
|
| Jupiter | 3 | Callisto | 401 | yes |
|
|
| Saturn | 0 | Titan | 383 | yes |
|
|
| Saturn | 1 | Enceladus | 33 | yes |
|
|
| Uranus | 0 | Miranda | 34 | yes |
|
|
| Uranus | 1 | Ariel | 60 | yes |
|
|
| Uranus | 2 | Umbriel | 99 | yes |
|
|
| Uranus | 3 | Titania | 209 | yes |
|
|
| Uranus | 4 | Oberon | 323 | yes |
|
|
| Neptune | 0 | Triton | 141 | yes |
|
|
|
|
For tidally locked moons, one sol equals one year (one orbit around the parent planet).
|
|
|
|
## Usage
|
|
|
|
### Planets
|
|
|
|
```python
|
|
from datetime import datetime, timezone
|
|
from planetarytime import Body, EpochType, PlanetaryTime
|
|
|
|
now = datetime.now(timezone.utc)
|
|
|
|
# Mars time since discovery (Galileo, 1610)
|
|
pt = PlanetaryTime.from_earth(now, Body.MARS, EpochType.DISCOVERY)
|
|
print(pt)
|
|
# Year 415, Sol 668, 14:22:07 (Mars / discovery epoch)
|
|
|
|
print(pt.year) # 415
|
|
print(pt.sol) # 668
|
|
print(pt.hour) # 14
|
|
print(pt.minute) # 22
|
|
print(pt.second) # 7
|
|
|
|
# Mars time since first contact (Viking 1, 1976)
|
|
pt = PlanetaryTime.from_earth(now, Body.MARS, EpochType.CONTACT)
|
|
print(pt)
|
|
# Year 25, Sol 23, 14:22:07 (Mars / contact epoch)
|
|
```
|
|
|
|
### Moons
|
|
|
|
```python
|
|
# Titan time since discovery (Huygens, 1655)
|
|
titan = Body.SATURN[0]
|
|
pt = PlanetaryTime.from_earth(now, titan, EpochType.DISCOVERY)
|
|
print(pt)
|
|
# Year 1, Sol 0, 08:11:45 (Titan / discovery epoch)
|
|
|
|
# Titan time since Huygens probe landing (2005)
|
|
pt = PlanetaryTime.from_earth(now, titan, EpochType.CONTACT)
|
|
print(pt)
|
|
|
|
# Check if a moon is tidally locked
|
|
print(titan.is_tidally_locked) # True
|
|
```
|
|
|
|
### Epochs
|
|
|
|
| EpochType | Meaning |
|
|
|--------------------|----------------------------------------------|
|
|
| `EpochType.DISCOVERY` | First recorded observation of the body |
|
|
| `EpochType.CONTACT` | First probe landing or crewed landing |
|
|
|
|
`EpochUnavailableError` is raised when `CONTACT` is requested for a body that has not been visited yet.
|
|
|
|
## Logging
|
|
|
|
This library uses [loguru](https://github.com/Delgan/loguru) for internal logging.
|
|
|
|
By default, loguru has a sink to `stderr` enabled. If your application also uses loguru, library logs appear in your configured sinks automatically.
|
|
|
|
### Suppress library logs
|
|
|
|
```python
|
|
from loguru import logger
|
|
logger.disable("planetarytime")
|
|
```
|
|
|
|
### Filter by level
|
|
|
|
```python
|
|
from loguru import logger
|
|
import sys
|
|
logger.add(sys.stderr, filter={"planetarytime": "WARNING"})
|
|
```
|
|
|
|
## License
|
|
|
|
MIT
|