Очень странно: другой вывод tzlocal.get_localzone() на основе псевдонимов Python3?

Я только что заметил это и совершенно озадачен тем, почему это происходит и как я могу это предотвратить.

На компьютере, на котором я работаю, установлена ​​Windows 10, и он установлен в городе Копенгаген. Моя платформа такова:

$ for ix in "uname -s" "python3 --version"; do echo "$ix: " $($ix); done
uname -s:  MINGW64_NT-10.0-19045
python3 --version:  Python 3.11.9

Поскольку я использую терминал bash под MINGW64, у меня также есть псевдоним для python3 в .bashrc:

alias python3 = "winpty python3"

ХОРОШО; поэтому теперь я хочу напечатать tzlocal.get_localzone(), вызвав команду python3 в терминале bash:

$ python3 -c 'import tzlocal; print(tzlocal.get_localzone())'
Europe/Copenhagen

Отлично, я получил именно тот часовой пояс, как и ожидал. Однако напомним, что python3 здесь на самом деле winpty python3; чтобы проверить просто python3, давайте добавим к команде обратную косую черту, чтобы избежать псевдонима bash:

$ \python3 -c 'import tzlocal; print(tzlocal.get_localzone())'
Europe/Paris

Удивительно – я никогда бы этого не ожидал; с какой стати у меня здесь Париж, а не Копенгаген (на это настроена сама Windows 10 на этой машине)?

Я имею в виду, что это не так уж и далеко, что касается часовых поясов - но зачем соглашаться на меньшее, когда очевидно, что есть условия, которые заставляют его выводить правильный часовой пояс?

Итак, почему это происходит и как мне \python3 запустить tzlocal.get_localzone() и вернуть Европу/Копенгаген?


Обновлено: напечатав os.environ в обоих случаях, можно увидеть, что среда winpty python определяет переменную среды «TZ»: «Europe/Copenhagen» - тогда как в прямой среде Python такой переменной нет.

См. также: github.com/orgs/pyinstaller/discussions/8414

sdbbs 17.04.2024 19:13
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
1
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Немного предыстории: Windows и IANA не используют одни и те же идентификаторы часовых поясов в своих базах данных часовых поясов. tzlocal дает вам идентификаторы IANA. Итак, когда вы работаете в Windows, вам нужно сопоставление между этими двумя системами БД часовых поясов. Это чревато ошибками, поскольку между IANA и MS нет соглашения о том, что это должно быть однозначно (см. также тег тег часового пояса , раздел «Базы данных часовых поясов»). tzlocal полагается в этом на усилия сообщества.

В Windows, если я устанавливаю tz на Копенгаген, Windows использует внутреннее «Романтское стандартное время» (на данный момент; 18 апреля 2024 г.). Вы можете проверить это, запустив tzutil /g в терминале. Если вы проверите XML-файл, ссылку на который я дал выше, первое сопоставление будет... «Европа/Париж». «Европа/Копенгаген» также указано внизу. Эти два часовых пояса следуют одним и тем же правилам AFAIK, поэтому отображение «ОК» (правильно с точки зрения смещения UTC), но не идеально.

Что касается того, почему вы получаете разные результаты; Я думаю, вы предоставили объяснение в разделе «печать os.environ в обоих случаях. Вы можете видеть, что среда winpty python определяет переменную среды «TZ»: «Европа/Копенгаген»». tzlocalищет переменную среды TZ. Если для него установлен идентификатор базы данных IANA, он вернет его, поскольку на самом деле это более надежно, чем описанное выше сопоставление Windows tz.

Отлично, огромное спасибо за этот ответ, действительно здорово знать предысторию таких проблем, с которыми я не сталкиваюсь ежедневно, но в любом случае меня удивляют...

sdbbs 18.04.2024 15:17

Кстати, о: «нет соглашения между IANA и MS» — я нашел stackoverflow.com/q/74970414 «Не существует стандартного способа сделать это до C++20, и даже тогда реализована только последняя версия MSVC на сегодняшний день (gcc приближается). В C++20 есть тип std::chrono::time_zone, который имеет функцию-член name(), которая возвращает строку, например "America/Los_Angeles"." - Я попробовал скомпилировать программу с помощью MSVC и получил «Европу/Копенгаген», так что, возможно, есть надежда на взаимодействие IANA и MS.

sdbbs 18.04.2024 16:34

@sdbbs Мой опыт работы с C++ очень ограничен, но на первый взгляд кажется, что хроно поставляется с базой данных IANA. Это обычное дело для библиотек часовых поясов: быть независимыми от платформы и контролировать версию базы данных. Крейт Chronic-tz в Rust делает то же самое, а также пакет времени в Go. Проблемы всегда начинаются тогда, когда вы хотите получить текущее состояние системы, т. е. когда вам нужно вызвать какой-то API ОС.

FObersteiner 18.04.2024 16:56

Другие вопросы по теме