Display ICU UDate formatted for different timezones

若如初见. 提交于 2019-12-08 00:35:04

问题


In the following example, I would like to format EPOCH (1/1/1970) in different time zones. For example, I may wish to format EPOCH using the Los Angeles time zone and/or format EPOCH using the New York timezone.

UErrorCode uErrorCode = U_ZERO_ERROR;
UnicodeString unicodeString;
UDate uDate;

icu::Locale locale = icu::Locale("en");
TimeZone* timeZone = TimeZone::createTimeZone("America/Los_Angeles");
Calendar* calendar = Calendar::createInstance(timeZone, uErrorCode);

// setting calendar to EPOCH, e.g. zero MS from 1/1/1970
calendar->setTime(0, uErrorCode);

// get calendar time as milliseconds (UDate)
uDate = calendar->getTime(uErrorCode);

DateFormat* dateFormat = DateFormat::createDateTimeInstance(
    icu::DateFormat::MEDIUM,    // date style
    icu::DateFormat::SHORT,     // time style
    locale);

unicodeString = dateFormat->format(uDate, unicodeString, uErrorCode);

std::string str;
unicodeString.toUTF8String(str);
std::cout << "Date: " << str;

// Use getOffset to get the stdOffset and dstOffset for the given time
int32_t stdOffset, dstOffset;
timeZone->getOffset(uDate, true, stdOffset, dstOffset, uErrorCode);
std::cout << " | ";
std::cout << "Time zone STD offset: " << stdOffset / (1000 * 60 * 60) << " | ";
std::cout << "Time zone DST offset: " << dstOffset / (1000 * 60 * 60) << std::endl;

The problem that I have is that the output is not formatted respective to the time zone.

Here is the output when using the Los Angeles time zone:

Date: Dec 31, 1969, 6:00 PM | Time zone STD offset: -8 | Time zone DST offset: 0

Here is the output when using the New York time zone:

Date: Dec 31, 1969, 6:00 PM | Time zone STD offset: -5 | Time zone DST offset: 0

Please notice that the date is not EPOCH and secondly notice that the dates and times for both outputs are identical. The offsets are correct, but the date/time display is not.

UPDATE

It is important to note that the displayed date/time is 6 hours behind since I'm currently (-6 UTC) meaning that you ADD 6 hours to Dec. 31, 1969 at 6:00PM which would then equal EPOCH Jan. 1, 1970 12:00AM.

ICU is using my PC's timezone automatically since I have found no way to specify timezone when formatting date/time using DateFormat::Format(...). If format() accepted a timezone argument to override my PC's local timezone, I would not be having this issue.


回答1:


You should call dateFormat->setTimeZone(*timeZone) to specify time zone.




回答2:


@earts had it right, because you are formatting based on the scalar time value and not the calendar.

Alternatively, you can format the Calendar object itself, which will use the timezone and time from that calendar:

unicodeString = dateFormat -> format(*calendar,
                                     unicodeString,
                                     (FieldPositionIterator*) nullptr, // ignored
                                     uErrorCode);

Note, though, that using the above function, the calendar type had better match that of the dateformat. An easy way to do that is to make sure you pass in the locale parameter when creating the calendar:

// above:
Calendar* calendar = Calendar::createInstance(timeZone, locale, uErrorCode);


来源:https://stackoverflow.com/questions/57560291/display-icu-udate-formatted-for-different-timezones

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!