LINUX.ORG.RU

Local time to UTC и обратно


0

1

Люди! Очень нужен сабж. Думал, вопрос простой и всё оставлял на потом, а оказалось не так и просто. Нужно «перевести» _заданную_ дату/время, считая, что она задана в UTC, и получить на выходе эту же дату в заданном для системы часовом поясе. Ну и наоборот.

Как ни странно, гугление дает или что-то совсем феерическое, или на каких-нибудь малопонятных языках типа Питона (не в обиду). А мне бы на чем-нибудь попроще, чтобы ясно было видно, какие библиотечные функции дёргать (например, на C).

Ну и, разумеется, всякие смежные задачи не интересуют (типа конвертации между различными форматами хранения, или получение _текущего_ времени в UTC или в локальном часовом поясе, или перевод даты из любого пояса в любой со всеми подвывертами с использованием каких-то странных баз данных часовых поясов).

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

KRoN73, плюсую! еще setenv(3) ;)

и всё в шоколаде! :)

сначала сетенвом ставишь переменную окружения TZ=нужная_зона потом вызываешь strtotime со временем в зоне, из которой переводишь. результат получаешь в той зоне, которую указал в TZ.

Вот тут в седьмом коментарии подобное на похапэ, но на сях будет так же. :)

aol ★★★★★ ()
Ответ на: комментарий от shamus24

нет, всё о чем я говорил - сишные функции.
man 3 setenv
man 3 strftime

(это если тебе не понятна запись типа setenv(3) - что эквивалентно)

aol ★★★★★ ()
Ответ на: комментарий от maloi

Опять куда-то в сторону. Впрочем, это так везде :-(

Объясню ещё раз: мне, в идеале, нужна пара функций вида:

time_t UtcTimeToSystemLocalTime(const time_t SystemTime)

time_t SystemLocalTimeToUtcTime(const time_t UtcTime)

Вместо time_t можно какой-нибудь другой тип для времени, тот же struct tm, например, с конвертацией я как-нибудь управлюсь. Где функция возьмет текущую системную таймзону не так важно - главное, чтобы способ был общепринятый. Например, из переменной TZ или из /etc/localtime, только желательно, чтобы я при использовании этой функции об этих тонкостях задумывался как можно меньше.

И мне не нужно выводить это на экран, преобразовывать в строку, засовывать в XML, etc... Нужно просто перевести время из часового пояса в UTC.

shamus24 ()
Ответ на: комментарий от shamus24

друк, не грусти. это не в сторону. это, можно сказать, не в бровь, а в глаз.

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

aol@vaio ~ $ date -d «Jul 24 13:00:00 MSD 2010»
Sat Jul 24 13:00:00 MSD 2010

aol@vaio ~ $ TZ=UTC date -d «Jul 24 13:00:00 MSD 2010»
Sat Jul 24 09:00:00 UTC 2010

aol@vaio ~ $ TZ=Europe/Moscow date -d «Jul 24 9:00:00 UTC 2010»
Sat Jul 24 13:00:00 MSD 2010


идея ясна?

так же и на сях: сначала выставляешь переменную TZ в нужную таймзону с помощью setenv(3), а потом делаешь strftime(3)

Удачи.

aol ★★★★★ ()
Ответ на: комментарий от shamus24

Я не совсем понял «const time_t UtcTime» и «const time_t SystemTime». Системное время оно же и так в UTC. Одно и тоже «time_t Time» представляется в различное разделённое время (broken-down time) для разных поясов. То есть можно преобразовывать «struct tm» <-> «time_t», но как функция по одному time_t должна вычислять другое я не понимаю.

mky ★★★★★ ()
Ответ на: комментарий от mky

> То есть можно преобразовывать «struct tm» <-> «time_t», но как функция по одному time_t должна вычислять другое я не понимаю.

Например: у нас есть time_t Time со значением, эквивалентным «26-jul-2010 00:24:50». Мы знаем, что это локальное время в таймзоне GMT+3 (именно такая у нас установлена в настройках системы). Вызываем SystemLocalTimeToUtcTime(Time) и на выходе получаем time_t со значением, эквивалентным «25-jul-2010 21:24:50», т.е. этот же самый момент времени, но уже в UTC. И по возможности избегая форматирования этого значения сначала в строку символов, а потом преобразования этой строки обратно в time_t, ибо как-то коряво. Конечно, если без этого никак, то пусть, но, блин жеж, неужели никому это никогда не было нужно?

shamus24 ()
Ответ на: комментарий от shamus24

В правильных системах time_t всегда в UTC.

То есть:

$ date -d '26-jul-2010 03:24:50 YEKST' '+%s'
1280093090

$ date -d '26-jul-2010 00:24:50 MSK' '+%s'
1280093090

$ date -d '25-jul-2010 21:24:50 UTC' '+%s'
1280093090

1280093090 --- это и есть time_t в половину первого ночи 26 июля в Москве. Поэтому не понятно, что во что вы хотите преобразовать.

mky ★★★★★ ()
Ответ на: комментарий от mky

Т.е. разговоры о часовых поясах и летнем времени применимы только к строковому представлению дат? Это всегда и везде так?

legolegs ★★★★★ ()
Ответ на: комментарий от legolegs

Если я правильно понимаю, то в POSIX-совместимых системах time_t используется для хранения POSIX времени, которое в секундах с 1 янв 1970 UTC. То есть, в принципе можно сказать, что если есть time_t, то это UTC, и разница только в строковм представлении.

Но были и есть не POSIX системы, там может быть другое.

А так, я просто пытался понять, чего хочет топикстартер, может в его системе есть время в секундах, с 1 янв 1970 MSK...

mky ★★★★★ ()
Ответ на: комментарий от x905

Ковырял я это. В ужосе сбежал на strptime/strftime. Недоделка, как парсер вообще бесполезна.

legolegs ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.