c ++ 11 — C ++ std :: localtime летнее время правило (dst) европейский против американского

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

UTC: 19.03.16 16:56 преобразован в Локальный: 19.03.16 18:56.

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

Я также изменил переменную окружения 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 (компьютер на основе Clang Embarcadero C ++).

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

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

3

Решение

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

#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 сам, который будет использовать local_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));
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]