C ++:我如何使用ICU通过给定的时区偏移来获取当前时间?

问题描述 投票:1回答:1

我想使用ICU library来获取当前时间给定的时区偏移量(也需要计算夏令时),我试过下面的代码,但是snext函数返回NULL,ICU库版本是6.1,CentOS 7.6 64 bit + 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;
c++ timezone icu
1个回答
2
投票

来自the ICU documentation

可能存在多个具有相同GMT偏移的区域,这些区域处理夏令时的方式不同。例如,亚利桑那州没有观察夏令时。如果您要求对应于GMT-7:00的时区ID,您将获得两个时区ID的枚举:“America / Denver”,对应于冬季的山地标准时间和山区的夏令时时间夏天,和“美国/凤凰”,即使在夏天,也全年对应山地标准时间。

换句话说,如果您输入的所有内容都是偏移量,则无法正确计算夏令时。许多不同的区域可能共享此偏移,有些可能在标准时间使用它,有些可能在白天使用它,有些可能全年使用它。

还要了解世界不同地区使用DST的方式不同。有些人比美国早或晚开始,有些人根本不使用它。那些在南半球使用它的人通常在冬季,而北半球在夏季时,反之亦然。一个时区仅切换30分钟而不是通常的60分钟。全球范围内没有单一的DST实施。

在您的代码中,您将创建在标准时间(或全年)内使用给定偏移的区域枚举,但您只检查枚举的第一项。无法保证第一项是正确使用的项目。

你能做的最好的事情就是获得你所拥有的偏移的当前时间,而你真的不需要ICU来做到这一点。

© www.soinside.com 2019 - 2024. All rights reserved.