C ++: Как я могу использовать ICU для получения текущего времени по заданному смещению часового пояса? - PullRequest
1 голос
/ 17 марта 2019

Я хотел бы использовать библиотеку ICU для получения текущего времени по заданному смещению часового пояса (также необходимо рассчитать переход на летнее время), я пробовал нижеприведенные коды, но функция snext возвращает NULL,версия библиотеки ICU 6.1, CentOS 7.6 64 бит + gcc 6.4.1.

timezoneOffset = 1; //(UTC + 1)

UErrorCode success = U_ZERO_ERROR;
U_ICU_NAMESPACE::UnicodeString dateReturned, curTZNameEn, curTZNameFr;

int32_t stdOffset = 0;
int32_t dstOffset = 0;
//  
// Create a Calendar to get current date
U_ICU_NAMESPACE::Calendar* calendar = U_ICU_NAMESPACE::Calendar::createInstance(success);
if (!calendar)
{
    return;
}

success = U_ZERO_ERROR;

UErrorCode ec;
std::string errorName;

int32_t rawOffset = timezoneOffset * 3600 * 1000;
U_ICU_NAMESPACE::StringEnumeration* se = U_ICU_NAMESPACE::TimeZone::createEnumeration(rawOffset); // Obtain timezones by GMT timezone offset
if (se)
{
    auto next = se->snext(ec);
    if (next && ec == U_ZERO_ERROR)
    {
        U_ICU_NAMESPACE::TimeZone *tzWest = U_ICU_NAMESPACE::TimeZone::createTimeZone(*next);
        if (tzWest)
        {
            UDate curDate = calendar->getNow();
            tzWest->getOffset(curDate, false, stdOffset, dstOffset, success);
            if (U_SUCCESS(success))
            {
                timezoneOffset = (stdOffset / (1000 * 60 * 60) + dstOffset / (1000 * 60 * 60));
            }
        }
    }
    else
    {
        errorName = u_errorName(ec); // The error name is "bogus error"
    }

    delete se;
}

delete calendar;

1 Ответ

2 голосов
/ 17 марта 2019

Из документации ICU :

Может быть несколько раз зон с одинаковым смещением по Гринвичу, которые различаются по способу работы с летним временем.Например, штат Аризона не соблюдает летнее время.Если вы запросите идентификаторы часовых поясов, соответствующие GMT-7: 00, вы получите перечисление по двум идентификаторам часовых поясов: «Америка / Денвер», что соответствует стандартному горному времени зимой и горному летнему времени влето и "Америка / Феникс", что соответствует горному стандартному времени круглый год, даже летом.

Другими словами, вы не можете рассчитать переход на летнее времявремя правильно, если все, что у вас есть для ввода, это смещение.Множество разных зон могут использовать это смещение, некоторые могут использовать его в стандартное время, некоторые могут использовать его в дневное время, а некоторые могут использовать его в течение всего года.

Также понимают, что разные части мира используют DST по-разному,Некоторые начинают раньше или позже, чем в США, а некоторые не используют его вообще.Те, кто использует его в Южном полушарии, обычно в зимнее время, в то время как в северном полушарии летнее, и наоборот.Один часовой пояс переключается только на 30 минут вместо обычных 60. В мире нет единой реализации DST.

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

Лучшее, что вы могли бы сделать, это получить текущее время для смещения, которое у вас есть, и вам действительно не нужен ICU для выполнениячто.

...