Новый ответ на старый вопрос.
Обоснование нового ответа: теперь есть современная бесплатная библиотека с открытым исходным кодом, библиотека C ++ 11/14/17 для выполненияthis. 1 Требуется немного установка .Но он переносим через Linux / macOS / Windows.И у него есть полная документация , и даже видео введение .
Вот пример программы для получения информации о конкретном часовом поясе.Я использую свой собственный часовой пояс только в качестве примера.Эта библиотека поддерживает полную базу данных часовых поясов IANA :
#include "tz.h"
#include <iostream>
int
main()
{
auto zone = date::locate_zone("America/New_York");
std::cout << *zone << '\n';
std::cout << zone->get_info(std::chrono::system_clock::now()) << '\n';
}
Первая строка ищет базу данных по ее имени IANA.
auto zone = date::locate_zone("America/New_York");
Тип возвращаемого значения:date::time_zone const*
.Эта функция никогда не сможет вернуть nullptr
, хотя она выдаст, если не сможет найти часовой пояс (с отличным what()
).
Во второй строке выводится определение часового пояса:
std::cout << *zone << '\n';
Вывод этой строки обычно бесполезен для клиентов этой библиотеки.Это в основном полезно для отладки библиотеки:
America/New_York -04:56:02 LMT 1883 Nov/18 12:03:58 1883-11-18 17:00:00 UTC 1883-11-18 12:03:58 STD 1883-11-18 12:03:58 00:00 {nullptr, -32768} {nullptr, 32767}
-05:00:00 US E%sT 1920 Jan/01 00:00:00 1920-01-01 05:00:00 UTC 1920-01-01 00:00:00 STD 1920-01-01 00:00:00 00:00 S {US 1918 1919 Mar/Sun[last] 02:00:00 01:00 D, 1918} {US 1918 1919 Oct/Sun[last] 02:00:00 00:00 S, 1919}
-05:00:00 NYC E%sT 1942 Jan/01 00:00:00 1942-01-01 05:00:00 UTC 1942-01-01 00:00:00 STD 1942-01-01 00:00:00 00:00 S {NYC 1920 1920 Mar/28 02:00:00 01:00 D, 1920} {NYC 1921 1954 Sep/Sun[last] 02:00:00 00:00 S, 1941}
-05:00:00 US E%sT 1946 Jan/01 00:00:00 1946-01-01 05:00:00 UTC 1946-01-01 00:00:00 STD 1946-01-01 00:00:00 00:00 S {US 1942 1942 Feb/09 02:00:00 01:00 W, 1942} {US 1945 1945 Sep/30 02:00:00 00:00 S, 1945}
-05:00:00 NYC E%sT 1967 Jan/01 00:00:00 1967-01-01 05:00:00 UTC 1967-01-01 00:00:00 STD 1967-01-01 00:00:00 00:00 S {NYC 1921 1954 Apr/Sun[last] 02:00:00 01:00 D, 1946} {NYC 1955 1966 Oct/Sun[last] 02:00:00 00:00 S, 1966}
-05:00:00 US E%sT 32767 Dec/31 00:00:00UTC 32767-12-31 00:00:00 UTC 32767-12-30 19:00:00 STD 32767-12-30 19:00:00 00:00 S {US 1967 1973 Apr/Sun[last] 02:00:00 01:00 D, 1967} {US 2007 32767 Nov/Sun[1] 02:00:00 00:00 S, 32767}
Но одна из причин, по которой я показываю эту строку, состоит в том, чтобы проиллюстрировать этот запрос информации о часовом поясе без указания времени.точка , вряд ли даст вам информацию, которую вы ищете.Информация о часовом поясе сама является функцией времени, включая смещения, детали перехода на летнее время, сокращения и т. Д.
Последняя строка:
std::cout << zone->get_info(std::chrono::system_clock::now()) << '\n';
, вероятно, будет наиболее полезной.Это возвращает совокупность sys_info
, которая выглядит следующим образом:
struct sys_info
{
sys_seconds begin;
sys_seconds end;
std::chrono::seconds offset;
std::chrono::minutes save;
std::string abbrev;
};
Это просто вывод для меня:
2016-11-06 06:00:00
2017-03-12 07:00:00
-05:00:00
00:00
EST
Что означает:
- Эта информациядействует с 2016-11-06 06:00:00 UTC до (но не включая) 2017-03-12 07:00:00 UTC.
- Смещение UTC для этого периода составляет -5 часов.
- Это не считается переходом на летнее время (сохранить == 00:00).
- Сокращение этого периода - EST.
Конечно, выможет получить доступ к полям этого агрегата в вашей программе, а не просто распечатывать их.
Если вы хотите увидеть, как этот результат может выглядеть через 6 месяцев:
std::cout << zone->get_info(std::chrono::system_clock::now() + date::months{6}) << '\n';
, которыйв настоящее время выводит:
2017-03-12 07:00:00
2017-11-05 06:00:00
-04:00:00
01:00
EDT
Это все считается низкоуровневым доступом в этой библиотеке.Существует высокоуровневый API, поэтому вам не нужно иметь дело с низкоуровневыми понятиями, такими как текущее смещение UTC.Низкоуровневые вещи есть, если они вам нужны (не скрыты), но не обязательны для общих случаев использования, таких как получение текущего времени в любом конкретном часовом поясе:
using namespace date;
using namespace std::chrono;
std::cout << make_zoned("America/New_York", system_clock::now()) << '\n';
, которые просто выводят для меня:
2017-03-07 19:26:53.711662 EST
В C ++ 17 из-за шаблонных руководств по выводу приведенная выше строка больше не будет нуждаться в "фабричных функциях" для целей вывода:
std::cout << zoned_time{"America/New_York", system_clock::now()} << '\n';
zoned_time
это шаблон класса, основанный на продолжительности и выводимый chrono::duration
из chrono::time_point
(второй аргумент - в моем случае microseconds
).
Это полнофункциональная дата / время/ библиотека часовых поясов с низкоуровневым доступом и высокоуровневыми абстракциями (соответствует философии C ++).Корректность и безопасность типов высоко ценятся в этой библиотеке.Это расширение , а не замена библиотеки <chrono>
, представленной в C ++ 11.
1 Отказ от ответственности: Я являюсь главнымАвтор этой библиотеки, хотя есть много авторов (за что я благодарен).