Przeglądaj źródła

feat(timezone): add support for the tz database

tags/v1.0.0rc1
Jérôme Deuchnord 2 miesięcy temu
committed by Deuchnord
rodzic
commit
3a87cfad10
9 zmienionych plików z 166 dodań i 78 usunięć
  1. +33
    -8
      kosmorro/__main__.py
  2. +2
    -0
      kosmorro/environment.py
  3. +32
    -19
      kosmorro/locales/messages.pot
  4. +11
    -0
      kosmorro/utils.py
  5. +1
    -1
      manpage/kosmorro.1.md
  6. +13
    -1
      poetry.lock
  7. +1
    -0
      pyproject.toml
  8. +10
    -6
      tests/general.py
  9. +63
    -43
      tests/timezone.py

+ 33
- 8
kosmorro/__main__.py Wyświetl plik

@@ -17,14 +17,18 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.

import argparse
import datetime
import sys
import os.path

import pytz
from babel.dates import format_date
from kosmorrolib import Position, get_ephemerides, get_events, get_moon_phase
from kosmorrolib.exceptions import OutOfRangeDateError
from datetime import date

from pytz import timezone

from . import dumper, environment, debug
from .date import parse_date
from .geolocation import get_position
@@ -34,6 +38,7 @@ from .utils import (
colored,
set_colors_activated,
print_stderr,
get_timezone,
)
from .exceptions import (
InvalidOutputFormatError,
@@ -88,12 +93,31 @@ def run():
)
)

timezone = args.timezone
timezone = 0

if timezone is None and env_vars.timezone is not None:
timezone = int(env_vars.timezone)
elif timezone is None:
timezone = 0
try:
if args.timezone is not None:
timezone = get_timezone(args.timezone)
elif env_vars.tz is not None:
timezone = get_timezone(env_vars.tz)
elif env_vars.timezone is not None:
print_stderr(
colored(
_(
"Environment variable KOSMORRO_TIMEZONE is deprecated. Use TZ instead, which is more standard."
),
"yellow",
)
)
timezone = get_timezone(env_vars.timezone)
except pytz.UnknownTimeZoneError as error:
print_stderr(
colored(
_("Unknown timezone: {timezone}").format(timezone=error.args[0]),
color="red",
)
)
return -1

try:
use_colors = not environment.NO_COLOR and args.colors
@@ -290,11 +314,12 @@ def get_args(output_formats: [str]):
parser.add_argument(
"--timezone",
"-t",
type=int,
type=str,
default=None,
help=_(
"The timezone to display the hours in (e.g. 2 for UTC+2 or -3 for UTC-3). "
"Can also be set in the KOSMORRO_TIMEZONE environment variable."
"The timezone to use to display the hours. It can be either a number (e.g. 1 for UTC+1) or a timezone name (e.g. Europe/Paris). "
"See https://en.wikipedia.org/wiki/List_of_tz_database_time_zones to find your timezone. "
"Can also be set in the TZ environment variable."
),
)
parser.add_argument(


+ 2
- 0
kosmorro/environment.py Wyświetl plik

@@ -44,6 +44,8 @@ class Environment:
def get_env_vars() -> Environment:
environment = Environment()

environment.tz = os.getenv("TZ")

for var in os.environ:
if not re.search("^KOSMORRO_", var):
continue


+ 32
- 19
kosmorro/locales/messages.pot Wyświetl plik

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2025-04-21 15:35+0200\n"
"POT-Creation-Date: 2025-09-22 17:24+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -17,89 +17,102 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.17.0\n"

#: kosmorro/__main__.py:84
#: kosmorro/__main__.py:89
msgid ""
"Output file will not contain the ephemerides, because you didn't provide "
"the observation coordinates."
msgstr ""

#: kosmorro/__main__.py:135
#: kosmorro/__main__.py:107
msgid ""
"Environment variable KOSMORRO_TIMEZONE is deprecated. Use TZ instead, "
"which is more standard."
msgstr ""

#: kosmorro/__main__.py:116
#, python-brace-format
msgid "Unknown timezone: {timezone}"
msgstr ""

#: kosmorro/__main__.py:159
#, python-brace-format
msgid "The file could not be saved in \"{path}\": {error}"
msgstr ""

#: kosmorro/__main__.py:149
#: kosmorro/__main__.py:173
msgid "Please provide a file path to export in this format (--output)."
msgstr ""

#: kosmorro/__main__.py:181
#: kosmorro/__main__.py:205
#, python-brace-format
msgid "Moon phase can only be computed between {min_date} and {max_date}"
msgstr ""

#: kosmorro/__main__.py:228
#: kosmorro/__main__.py:252
#, python-brace-format
msgid "Running on Python {python_version} with Kosmorrolib v{kosmorrolib_version}"
msgstr ""

#: kosmorro/__main__.py:241
#: kosmorro/__main__.py:265
msgid ""
"Compute the ephemerides and the events for a given date and a given "
"position on Earth."
msgstr ""

#: kosmorro/__main__.py:244
#: kosmorro/__main__.py:268
msgid ""
"By default, only the events will be computed for today.\n"
"To compute also the ephemerides, latitude and longitude arguments are "
"needed."
msgstr ""

#: kosmorro/__main__.py:256
#: kosmorro/__main__.py:280
msgid "Show the program version"
msgstr ""

#: kosmorro/__main__.py:265
#: kosmorro/__main__.py:289
msgid ""
"The format to output the information to. If not provided, the output "
"format will be inferred from the file extension of the output file."
msgstr ""

#: kosmorro/__main__.py:275
#: kosmorro/__main__.py:299
#, python-brace-format
msgid ""
"The observer's position on Earth, in the \"{latitude},{longitude}\" "
"format. Can also be set in the KOSMORRO_POSITION environment variable."
msgstr ""

#: kosmorro/__main__.py:285
#: kosmorro/__main__.py:309
msgid ""
"The date for which the ephemerides must be calculated. Can be in the "
"YYYY-MM-DD format or an interval in the \"[+-]YyMmDd\" format (with Y, M,"
" and D numbers). Defaults to current date."
msgstr ""

#: kosmorro/__main__.py:296
#: kosmorro/__main__.py:320
msgid ""
"The timezone to display the hours in (e.g. 2 for UTC+2 or -3 for UTC-3). "
"Can also be set in the KOSMORRO_TIMEZONE environment variable."
"The timezone to use to display the hours. It can be either a number (e.g."
" 1 for UTC+1) or a timezone name (e.g. Europe/Paris). See "
"https://en.wikipedia.org/wiki/List_of_tz_database_time_zones to find your"
" timezone. Can also be set in the TZ environment variable."
msgstr ""

#: kosmorro/__main__.py:304
#: kosmorro/__main__.py:329
msgid "Disable the colors in the console."
msgstr ""

#: kosmorro/__main__.py:312
#: kosmorro/__main__.py:337
msgid "A file to export the output to. If not given, the standard output is used."
msgstr ""

#: kosmorro/__main__.py:320
#: kosmorro/__main__.py:345
msgid ""
"Do not generate a graph to represent the rise and set times in the LaTeX "
"file."
msgstr ""

#: kosmorro/__main__.py:327
#: kosmorro/__main__.py:352
msgid "Show debugging messages"
msgstr ""



+ 11
- 0
kosmorro/utils.py Wyświetl plik

@@ -1,5 +1,7 @@
#!/usr/bin/env python3
from datetime import datetime

import pytz
from termcolor import colored as do_color
from sys import stderr

@@ -27,3 +29,12 @@ def colored(text, color=None, on_color=None, attrs=None):

def print_stderr(*values: object):
print(*values, file=stderr)


def get_timezone(value: int | str) -> float:
try:
timezone = float(value)
except ValueError:
timezone = pytz.timezone(value).utcoffset(datetime.now()).total_seconds() / 3600

return timezone

+ 1
- 1
manpage/kosmorro.1.md Wyświetl plik

@@ -23,7 +23,7 @@
The date for which the ephemerides must be computed, either in the YYYY-MM-DD format or as an interval in the "[+-]YyMmDd" format (with Y, M, and D numbers); defaults to the current date

`--timezone=`_TIMEZONE_, `-t` _TIMEZONE_
the timezone to display the hours in; e.g. 2 for UTC+2 or -3 for UTC-3
the timezone to use to display the hours; it can be either a number (e.g. 1 for UTC+1) or a timezone name (e.g. Europe/Paris)

`--no-colors`
disable the colors in the console


+ 13
- 1
poetry.lock Wyświetl plik

@@ -391,6 +391,18 @@ files = [
[package.dependencies]
six = ">=1.5"

[[package]]
name = "pytz"
version = "2025.2"
description = "World timezone definitions, modern and historical"
optional = false
python-versions = "*"
groups = ["main"]
files = [
{file = "pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00"},
{file = "pytz-2025.2.tar.gz", hash = "sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3"},
]

[[package]]
name = "sgp4"
version = "2.25"
@@ -529,4 +541,4 @@ tests = ["pytest", "pytest-cov"]
[metadata]
lock-version = "2.1"
python-versions = "^3.12"
content-hash = "edfb347df82f9895ce51f3af9005b1d924129c24aa7e38b5e2f7bd858e33ec25"
content-hash = "12bf9cdda9cfaf9616bf3d899450e105991f788267601a41a79fed1b5cbd73a9"

+ 1
- 0
pyproject.toml Wyświetl plik

@@ -22,6 +22,7 @@ kosmorrolib = "^1.0"
python-dateutil = "^2.8"
Babel = "^2.9"
openlocationcode = "^1.0"
pytz = "^2025.2"

[tool.poetry.group.dev.dependencies]
black = "^24.4"


+ 10
- 6
tests/general.py Wyświetl plik

@@ -62,9 +62,11 @@ options:
"[+-]YyMmDd" format (with Y, M, and D numbers).
Defaults to current date.
--timezone TIMEZONE, -t TIMEZONE
The timezone to display the hours in (e.g. 2 for UTC+2
or -3 for UTC-3). Can also be set in the
KOSMORRO_TIMEZONE environment variable.
The timezone to use to display the hours. It can be
either a number (e.g. 1 for UTC+1) or a timezone name
(e.g. Europe/Paris). See https://en.wikipedia.org/wiki
/List_of_tz_database_time_zones to find your timezone.
Can also be set in the TZ environment variable.
--no-colors Disable the colors in the console.
--output OUTPUT, -o OUTPUT
A file to export the output to. If not given, the
@@ -103,9 +105,11 @@ options:
"[+-]YyMmDd" format (with Y, M, and D numbers).
Defaults to current date.
--timezone, -t TIMEZONE
The timezone to display the hours in (e.g. 2 for UTC+2
or -3 for UTC-3). Can also be set in the
KOSMORRO_TIMEZONE environment variable.
The timezone to use to display the hours. It can be
either a number (e.g. 1 for UTC+1) or a timezone name
(e.g. Europe/Paris). See https://en.wikipedia.org/wiki
/List_of_tz_database_time_zones to find your timezone.
Can also be set in the TZ environment variable.
--no-colors Disable the colors in the console.
--output, -o OUTPUT A file to export the output to. If not given, the
standard output is used.


+ 63
- 43
tests/timezone.py Wyświetl plik

@@ -6,68 +6,88 @@ from .utils import (
)


def check_command_return_t_plus_one(result):
def test_timezone_with_command_line_arg():
result = execute(KOSMORRO + ["--timezone=1", "-d2020-01-27"])
assert result.successful
assert (
result.stdout
== """Monday, January 27, 2020
assert "Note: All the hours are given in the UTC+1.0 timezone." in result.stdout

New Moon
First Quarter on Sunday, February 2, 2020 at 2:41 AM
result = execute(KOSMORRO + ["--timezone=Europe/Paris", "-d2020-01-27"])
assert result.successful
assert "Note: All the hours are given in the UTC+1.0 timezone." not in result.stdout

Expected events:
9:00 PM Venus and Neptune are in conjunction
result = execute(KOSMORRO + ["--timezone=-5", "-d2020-01-27"])
assert result.successful
assert "Note: All the hours are given in the UTC-5.0 timezone." in result.stdout

Note: All the hours are given in the UTC+1 timezone.
"""
)
result = execute(KOSMORRO + ["--timezone=America/Chicago", "-d2020-01-27"])
assert result.successful
assert "Note: All the hours are given in the UTC-5.0 timezone." in result.stdout


def check_command_return_t_minus_one(result):
def test_timezone_with_env_var():
result = execute(KOSMORRO + ["-d2020-01-27"], environment={"TZ": "1"})
assert result.successful
assert (
result.stdout
== """Monday, January 27, 2020
assert "Note: All the hours are given in the UTC+1.0 timezone." in result.stdout

New Moon
First Quarter on Sunday, February 2, 2020 at 12:41 AM
result = execute(KOSMORRO + ["-d2020-01-27"], environment={"TZ": "Europe/Paris"})
assert result.successful
assert "Note: All the hours are given in the UTC+1.0 timezone." not in result.stdout

result = execute(KOSMORRO + ["-d2020-01-27"], environment={"TZ": "-5"})
assert result.successful
assert "Note: All the hours are given in the UTC-5.0 timezone." in result.stdout

result = execute(KOSMORRO + ["-d2020-01-27"], environment={"TZ": "America/Chicago"})
assert result.successful
assert "Note: All the hours are given in the UTC-5.0 timezone." in result.stdout

Expected events:
7:00 PM Venus and Neptune are in conjunction

Note: All the hours are given in the UTC-1 timezone.
"""
def test_timezone_with_env_var_and_command_line_arg():
result = execute(
KOSMORRO + ["--timezone=3", "-d2020-01-27"], environment={"TZ": "Europe/Paris"}
)
assert result.successful
assert "Note: All the hours are given in the UTC+3.0 timezone." in result.stdout


def test_timezone():
check_command_return_t_plus_one(
execute(KOSMORRO + ["--timezone=1", "-d2020-01-27"])
def test_timezone_with_deprecated_env_var():
result = execute(
KOSMORRO + ["-d2020-01-27"], environment={"KOSMORRO_TIMEZONE": "1"}
)
check_command_return_t_minus_one(
execute(KOSMORRO + ["--timezone=-1", "-d2020-01-27"])
assert result.successful
assert (
"Environment variable KOSMORRO_TIMEZONE is deprecated. Use TZ instead, which is more standard."
in result.stderr
)
assert "Note: All the hours are given in the UTC+1.0 timezone." in result.stdout


def test_timezone_with_env_var():
check_command_return_t_plus_one(
execute(KOSMORRO + ["-d2020-01-27"], environment={"KOSMORRO_TIMEZONE": "1"})
result = execute(
KOSMORRO + ["-d2020-01-27"], environment={"KOSMORRO_TIMEZONE": "Europe/Paris"}
)
check_command_return_t_minus_one(
execute(KOSMORRO + ["-d2020-01-27"], environment={"KOSMORRO_TIMEZONE": "-1"})
assert result.successful
assert (
"Environment variable KOSMORRO_TIMEZONE is deprecated. Use TZ instead, which is more standard."
in result.stderr
)
assert "Note: All the hours are given in the UTC+1.0 timezone." not in result.stdout

# If both environment variable and argument are set, use argument:
result = execute(
KOSMORRO + ["-d2020-01-27"], environment={"KOSMORRO_TIMEZONE": "-5"}
)
assert result.successful
assert (
"Environment variable KOSMORRO_TIMEZONE is deprecated. Use TZ instead, which is more standard."
in result.stderr
)
assert "Note: All the hours are given in the UTC-5.0 timezone." in result.stdout

check_command_return_t_plus_one(
execute(
KOSMORRO + ["--timezone=1", "-d2020-01-27"],
environment={"KOSMORRO_TIMEZONE": "-1"},
)
result = execute(
KOSMORRO + ["-d2020-01-27"],
environment={"KOSMORRO_TIMEZONE": "America/Chicago"},
)
check_command_return_t_minus_one(
execute(
KOSMORRO + ["--timezone=-1", "-d2020-01-27"],
environment={"KOSMORRO_TIMEZONE": "1"},
)
assert result.successful
assert (
"Environment variable KOSMORRO_TIMEZONE is deprecated. Use TZ instead, which is more standard."
in result.stderr
)
assert "Note: All the hours are given in the UTC-5.0 timezone." in result.stdout

Ładowanie…
Anuluj
Zapisz