2016-04-15 7 views
2

Скажем, мое приложение для Windows работает в восточном часовом поясе (NY).Как получить статус летнего времени другого часового пояса

Я конвертирую и сохраняю каждое событие datetime (в момент их появления) в UTC, так что любое клиентское приложение, которое подключается к серверу, считывает время UTC и преобразует его и отображает его в собственной TZ клиента.

Но вот сложная часть, некоторые события сообщают о своей временной отметке в другое состояние и не указывают явно информацию о летнем освещении (например, xx: xx: xx AM PT, что означает «Тихоокеанское время», но я не знаю, в летнее время).

Сервер может проверить, находится ли он в летнее время, но это будет для собственного TZ сервера (который является Восточным временем). Лучшее, что я мог придумать, это прочитать локальную информацию о летнем освещении сервера и использовать ее для PT, но я знаю, что это не на 100% точно. Особенно в коротком окне, когда ET только что начал (или остановился) с использованием летнего времени, и у PT есть еще часы для этого.

Теперь мой вопрос: есть ли способ (в Windows API) точно узнать о статусе летнего времени другого временного зонда, независимо от того, в каком часовом поясе находится приложение сервера?

Редактировать: ok, как его преобразовать в UTC «Sun, Mar 13, 2016 1:15 AM PT», с Windows-машины, работающей в восточное время? (обратите внимание, что эта дата/время, особенно выбранная, когда работающий компьютер (в ET) находится в DST в данный момент, а дата/время, которое нужно преобразовать, не только что осталось в DST. У меня есть конвертация UTC, но не удалось

+0

ли [этот предыдущий вопрос] (http://stackoverflow.com/questions/2532729/daylight-saving-time-and-time-zone-best-practices) Помогите? –

+0

Как вы определяете часовой пояс в своем приложении? Если аббревиатуры типа «ПТ» - все, что у вас есть, вы можете найти очень трудное или невозможное. Являются ли эти входы ограниченными некоторым набором фиксированных значений? Или они могут быть буквально кем угодно? –

+0

@MattJohnson они обычно являются стандартными строками даты/времени в HTTP (которые фактически содержат информацию DST, например xx: xx: xx AM PST или PDT, если DST активен), но некоторые серверы не так щедры, чтобы предоставить информацию DST и просто сказать что это PT (Pasific Time) и дает вам возможность выяснить, находится ли PT в DST или нет на дате/времени. Системе (Windows) следует это знать, поскольку она корректирует системные часы на 2-м и 1-м воскресеньях марта и ноября и может предоставить это пользователю с API. –

ответ

1

Я не уверен в Windows API, но в целом вы должны позвонить mktime, со значением TZ вашего удаленного времени, действующего на данный момент.. Под Unix можно буквально назвать setenv("TZ", whatever), чтобы сделать это. Не уверен, что Windows, но я думаю, что вы можете сделать то же рода вещи там тоже.

Было бы, конечно, неплохо, если бы, кроме mktime и timegm, был вариант, который позволяет указать зону для использования явно (вместо обработки переменной окружения TZ как глобальной переменной), но такой вариант не является стандартным.

При преобразовании местных времен, когда вы не знаете, действует ли DST или нет, не забудьте установить tm_isdst в -1, чтобы библиотека выяснила это для вас.

Вот пример:

#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 

int main() 
{ 
    struct tm tm = {0}; 
    time_t t; 
    tm.tm_hour = 12; tm.tm_min = 30, tm.tm_sec = 15;   /* 12:30:15 */ 
    tm.tm_year = 2005-1900; tm.tm_mon = 4-1; tm.tm_mday = 12; /* 2005-04-12 */ 
    tm.tm_isdst = -1; 
    setenv("TZ", "America/Los_Angeles", 1); 
    t = mktime(&tm); 
    setenv("TZ", "America/New_York", 1); 
    printf("%ld = %.24s\n", t, ctime(&t)); 
} 

Это говорит о том, что время 12:30:15 Лос-Анджелес соответствует Unix (UTC) Время 1113334215 и время Нью-Йорк 15:30:15.


Приложение: это не поможет для Windows, либо, но если вам не нравится, установив переменные окружения внутри каждый раз, когда вам нужно работать со временем в другом часовом поясе вашей программы, см если вы можете использовать функции BSD tzalloc, localtime_rz и mktime_z.

+0

Незначительная точка: лучше всего заполнить 'struct tm', например' struct tm tm = {0}; 'перед вызовом' mktime() '. Эта функция использует все поля, кроме 'tm_wday, tm_yday' и' struct tm' может иметь больше, чем обычно 9 полей. – chux

+0

@chux Хорошая точка, исправлена. –

+0

Вы действительно запускали этот код в Windows? По моему опыту, Windows не обращает внимания на переменную окружения TZ. Это POSIX. Предыдущее обращение к этой теме см. В разделе [Как программа Windows может временно изменить свой часовой пояс?] (Http://stackoverflow.com/q/2611017/33732) –

2

данных Time Zone Windows, на самом деле хранится в реестре:

HKLM 
    SOFTWARE 
    Microsoft 
     Windows NT 
     CurrentVersion 
      Time Zones 

"часовых поясов", по сути, два слова.

Каждого часовой пояс имеет свой собственный раздел, и каждый подключ имеет значение TZI, что является двоичным REG_TZI_FORMAT структуры:

typedef struct _REG_TZI_FORMAT 
{ 
    LONG Bias; 
    LONG StandardBias; 
    LONG DaylightBias; 
    SYSTEMTIME StandardDate; 
    SYSTEMTIME DaylightDate; 
} REG_TZI_FORMAT; 

Две соответствующих членов структур являются StandardDate и DaylightDate.

Обратитесь к MSDN для получения более подробной информации: TIME_ZONE_INFORMATION

+0

@Remy: Я добавил ссылку, чтобы избежать дублирования кода Microsoft, который, вероятно, защищен авторским правом и не имеет четко обозначенных принципов «справедливого использования». –

+0

Это не имеет никакого отношения к моему вопросу. Реестр - это просто место, где Windows хранит информацию о часовом поясе для пользователей, чтобы они могли устанавливать часовые пояса своих компьютеров. Мне нужно было выяснить, находится ли другое государство (или страна в этом отношении) в настоящее время в летнее время или нет. –

+0

Он дает вам информацию, необходимую для выяснения этого. У членов 'SYSTEMTIME' DaylightDate' есть то, что вам нужно. –