Уведомления

Группа в Telegram: @pythonsu

#1 Фев. 27, 2011 21:29:44

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

Питон, дата и время

Собственно, вот статья: http://asvetlov.blogspot.com/2011/02/date-and-time.html

Ругайте, если где ошибся



Офлайн

#2 Март 1, 2011 23:03:18

poltergeist
От:
Зарегистрирован: 2007-02-28
Сообщения: 522
Репутация: +  0  -
Профиль   Отправить e-mail  

Питон, дата и время

>>> from datetime import *
>>> dt = datetime.now()
Так писать зачастую правильно, главное чтобы все машины были синхронизированы на UTC с помощью протокола NTP (это уже другая история). Отсутствие tzinfo означает, что время указано в UTC - можно взять за правило (неписанное?). Это если питон работает на сервере. Про клиентов будет чуть ниже.

UTC это формально не “по Гринвичу”. По Гринвичу - это GMT. Лучше чтобы люди знали чем они отличаются, и не путали друг с другом.

Когда пишешь программу, на локальное время клиента вообще опасно ссылаться, т.к. не факт что время настроено правильно. Типичные два случая: либо пользователь указал правильную временную зону и своё локальное время, либо пользователь оставил временную зону как есть (по дефолту UTC везде стоит) и подстроил её под своё время. Во втором случае мы получим сдвиг по времени и знать об этом мы не можем. Поэтому питон тут не причём. Всегда надо хранить и передавать данные в UTC, локальное время годится только для отображения пользователю, который должен в настройках указать свою временную зону.

“При обработке сразу же добавляйте временную зону UTC в явном виде.” - мне кажется это лишнее усложнение. Зачем в расчётах использовать локальное время? Что это даст? Я считаю, что и хранить и рассчитывать можно с datetime объектами без tzinfo (подразумевая UTC), а для отображения пользователю применять преобразование в локальное время.

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



Отредактировано (Март 1, 2011 23:12:06)

Офлайн

#3 Март 2, 2011 00:09:45

zheromo
От:
Зарегистрирован: 2010-10-02
Сообщения: 356
Репутация: +  2  -
Профиль   Отправить e-mail  

Питон, дата и время

Статья правильная
Тоже хотелось бы услышать про

poltergeist
горький опыт на производстве
, если таковой имеется конечно

Я сам всегда использую datetime.utcnow(), ну и нормальная база данных обычно поступает также, при выводе пользователю использую что-то типа date|datetimeformat который знает о локали и временной зоне пользователя с учетом которых дата и форматируется.



Офлайн

#4 Март 2, 2011 20:00:46

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

Питон, дата и время

poltergeist, вы рекомендуете на всех серверах принудительно ставить UTC? Не думаю, что это практично.
Формально UTC - не GMT. А на деле тонкостями астрономии не заморачиваются. В компьютерном деле используют GMT и UTC как синонимы.

Зачастую требуется ссылаться именно на локальное время, установленное на компьютере клиента - другого ведь нет :) Сервер далеко, каждый раз спрашивать у него время в UTC - попахивает маразмом.
Приходилось как-то при старте клиентской программы проверять правильность синхронизации времени (нужно было чтобы оно отличалось от серверного не больше чем на 30 сек) - или отказываться работать. Это довольно медленная процедура, кстати. Таким образом можно защитится от кривых рук пользователя.

poltergeist, вот вы призываете использовать относительное время, считая что оно было в UTC. При этом datetime.now() даст локальное - да и вообще слишком много способов ошибится. Можно довольно нескоро увидеть, что времена-то не совпадают!
Абсолютные времена этой проблемы лишены, а потому - безопасны. В них всегда время прописано однозначно, будь то зона UTC или EET/EEST. Просто убираем возможность наступить на грабли. Программисты - они не всегда внимательные и разбирающиеся, особенно в большом проекте. Так что строгость - не лишняя.

Опыт на производстве - да сколько угодно!
Нью-Йоркская фирма, клиенты исключительно с восточного побережья. Счастливо жили пару лет с локальным временем - пока не появился клиент из Чикаго, кажется. Ну невозможно было этомим парням из Иллинойса показывать локальные времена - так и жили все в Нью-Йоркском часовом поясе.

Другой случай, другая работа. Было строгое предупреждение - использовать только относительное время в UTC. Совсем как вы предлагаете.
В отдельной подсистеме программист по глупости и недосмотру забыл про utcnow, использовал только now. И все отлично работало, потому что в интерфейсе отображались только временные разницы. Ну, там, “5 минут назад” или “через полчаса”. Беда была в том, что в базу писались логи. В относительном локальном времени. И когда для выяснения одного инцидента пришлось в эти логи смотреть - там была каша.

zheromo
Про базу данных - вот не надо! Посмотрите еще раз, там абсолютные времена или относительные? А ваша библиотека для работы с БД какие возвращает?

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

Да, файлы и сокеты работают с байтами. Да, я могу написать программу, которой этот юникод никогда в жизни не понадобится - и без него все работает.
И я прекрасно разбираюсь в кодировках.
Но если я работаю с байтами - каждый раз приходится задумываться, какая кодировка имелась в виду? При том что явно она к строке байт не прилагается.
Если у меня юникодные строки - я работаю с ними без опасений. Вспоминаю о кодировке только тогда, когда эту строку нужно создать (получить каким-либо вводом) или наоборот выпихнуть наружу. Использование юникода гораздо безопасней.



Офлайн

#5 Март 2, 2011 23:12:42

zheromo
От:
Зарегистрирован: 2010-10-02
Сообщения: 356
Репутация: +  2  -
Профиль   Отправить e-mail  

Питон, дата и время

Андрей Светлов
А ваша библиотека для работы с БД какие возвращает?
В общем, получается вот что, за меня уже подумали - и даже если захотеть, ошибиться не получится
Кусок кода, библиотека, так сказать, уже импортирована
dn, du = datetime.now(), datetime.utcnow()
print dn
print du
print dn == du
Ожидали увидеть разные даты и False в конце, не тут то было :)

2011-03-02 21:06:44.625000
2011-03-02 21:06:44.625000
True
Андрей Светлов
Посмотрите еще раз, там абсолютные времена или относительные?
Времена все относительные и считается что кроме UTC у нас ничего нет (т.е. все даты даны в UTC)



Отредактировано (Март 2, 2011 23:19:48)

Офлайн

#6 Март 2, 2011 23:37:17

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

Питон, дата и время

zheromo, вы случайно не в Лондоне живете?
На моем ноуте, с которого вам пишу:

>>> from datetime import datetime
>>> dl = datetime.now()
>>> du = datetime.utcnow()
>>> dl == du
False
>>> dl
datetime.datetime(2011, 3, 2, 23, 24, 50, 923726)
>>> du
datetime.datetime(2011, 3, 2, 21, 24, 59, 994903)
>>> import time
>>> time.tzname
('EET', 'EEST')
>>> time.timezone
-7200
Время настроено как Киевское. Когда еду в Москву - ставлю Московское.
Если лечу в Штаты - опять таки выставляю местное. В Нью-Йорке - одно, а в Калифорнии - совсем иное.
И timezone в каждом случае - разная.

Принудительно использовать UTC в настройках локали - это как заявлять, что у автомобиля может быть любой цвет, если этот цвет - черный.
Или, иными словами, пользователь может использовать любую кодировку при условии, что она называется ascii.
Это очень удобные для разработчика правила, но люди их не приветствуют.

Вот вы мне в cp1251 пишете, потому что форум этого хочет. Не ascii и даже не универсальный utf-8. И все - работает.



Офлайн

#7 Март 3, 2011 00:35:35

zheromo
От:
Зарегистрирован: 2010-10-02
Сообщения: 356
Репутация: +  2  -
Профиль   Отправить e-mail  

Питон, дата и время

Андрей Светлов
zheromo, вы случайно не в Лондоне живете?
В том то и дело что был изрядно удивлен этим фактом
Как я написал
zheromo
библиотека, так сказать, уже импортирована
В консоли выдает вполне ожидаемый результат
>>> from datetime import datetime
>>> dl = datetime.now()
>>> du = datetime.utcnow()
>>> dl == du
False
>>> dl
datetime.datetime(2011, 3, 3, 4, 33, 16, 593000)
>>> du
datetime.datetime(2011, 3, 2, 22, 33, 24, 625000)



Офлайн

#8 Март 3, 2011 00:37:43

zheromo
От:
Зарегистрирован: 2010-10-02
Сообщения: 356
Репутация: +  2  -
Профиль   Отправить e-mail  

Питон, дата и время

Андрей Светлов
Это очень удобные для разработчика правила, но люди их не приветствуют.
Согласен, но код не мой, я просто разместил объяву :)

Естественно, как и ожидалось, после импорта либы получаем
import time
print time.tzname

('UTC', '')



Отредактировано (Март 3, 2011 00:41:31)

Офлайн

#9 Март 3, 2011 00:55:55

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

Питон, дата и время

О какой “импортированной библиотеке” идет речь?



Офлайн

#10 Март 3, 2011 01:00:01

zheromo
От:
Зарегистрирован: 2010-10-02
Сообщения: 356
Репутация: +  2  -
Профиль   Отправить e-mail  

Питон, дата и время

Андрей Светлов
О какой “импортированной библиотеке” идет речь?
Ну это фигурально выражаясь - библиотека - appengine



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version