2016-06-29 10 views
3

У меня проблема с использованием функции std :: localtime. Когда я преобразовываю std :: time_t в локальную структуру tm, он всегда использует американское летнее время, тогда как я хочу использовать европейский (Франция).C++ std :: localtime летнее время (dst) european vs american

UTC: 03/19/16 16:56 преобразован Местность: 03/19/16 18:56.

В этот день, как правило, местный - 17:56 (UTC + 1). DST происходит на 27-м во Франции. После нескольких тестов кажется, что используемый DST основан на американском правиле: DST происходит во второе воскресенье в марше.

Я также изменил переменную environement TZ, но она также терпит неудачу.


`

if(putenv("TZ=CET-1CEST-2,M3.5.0/2,M10.5.0/3") != 0) { 
    std::cout << "Unable to set TZ" << std::endl; 
} else { 
    tz = getenv("TZ"); 
    if (tz) std::cout << tz << std::endl; 
    else std::cout << "TZ not defined" << std::endl; tzset(); 
} 

struct std::tm t; 
t.tm_sec = 0; 
t.tm_min = 56; 
t.tm_hour = 18; 
t.tm_mday = 19; 
t.tm_mon = 3-1; 
t.tm_year = 2016-1900; 
t.tm_isdst = -1; 
std::time_t tt = std::mktime(&t); 
std::cout << "UTC: " << std::put_time(std::gmtime(&tt), "%c %Z") << '\n'; // UTC : 03/19/16 16:56 
std::cout << "local: " << std::put_time(std::localtime(&tt), "%c %Z") << '\n'; // Local : 03/19/16 18:56 (not waited result) 

`

В точности, я использую bcc32c компилятор (Причал C++ лязг компьютер на базе).

Надеюсь, я достаточно ясен, и вы сможете мне помочь.

Заранее спасибо

+0

Это, вероятно, окружающая среда вещь тоже, что ваша операционная система? – Neil

+0

Есть ли у вашей среды ''? –

+0

Я использую ОС Win 7 32 бит.Я использовал

ответ

1

Если у вас есть C++ 11 (или более поздней версии) доступны, которая включает в себя <chrono>, и если вы готовы работать с системой <chrono>. И если вы готовы использовать этот free, open-source timezone library. Тогда это очень простой вопрос:

#include "tz.h" 
#include <iostream> 

int 
main() 
{ 
    using namespace date; 
    using namespace std::chrono_literals; 
    auto zt = make_zoned("Europe/Paris", sys_days{2016_y/mar/19} + 18h + 56min); 
    std::cout << format("%m/%d/%y %H:%M %Z", zt.get_sys_time()) << '\n'; 
    std::cout << format("%m/%d/%y %H:%M %Z", zt) << '\n'; 
} 

Выход:

03/19/16 18:56 UTC 
03/19/16 19:56 CET 

Короче говоря, вы формируете один zoned_time путем сопряжения часового пояса вашего выбора («Европа/Париж»), с sys_time (УНИВЕРСАЛЬНОЕ ГЛОБАЛЬНОЕ ВРЕМЯ). Затем вы можете отформатировать этот zoned_time как путем извлечения из него sys_time, так и путем форматирования самого zoned_time, который будет использовать zoned_time.

Я попытался использовать форматирование, соответствующее вашим комментариям. Вы могли бы, конечно, выбрать любой формат. Вы также можете включить любые std::locale, которые ваша система поддерживает в качестве первого аргумента в звонках format (что воспользуется %c).

Вы также можете извлекать отдельные поля как из sys_time, так и из local_time, если вам нужно или делать другие вычисления даты и времени. Это больше, чем просто библиотека форматирования.

Если вы начинаете с time_t, есть статическая функция член std::chrono::system_clock для преобразования time_t в system_clock::time_point. Затем вы можете использовать это time_point вместо sys_days{2016_y/mar/19} + 18h + 56min в этом примере:

auto zt = make_zoned("Europe/Paris", system_clock::from_time_t(t)); 
+0

Хорошо, спасибо. Я попробую это. На самом деле, у меня есть time_point –

+0

@MathiasVantieghem: Если у вас есть какие-либо проблемы или вопросы, вы можете общаться на gitter (связанный с README в github). Запустите github. Пинг меня здесь. Или напишите мне прямо (просто найдите мой адрес электронной почты, его легко найти). –