Search code examples
icu

Display ICU UDate formatted for different timezones


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.


Solution

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