| 743 | } |
| 744 | |
| 745 | bool TimeZoneUtil::decodeTimeStamp(const ISC_TIMESTAMP_TZ& timeStampTz, bool gmtFallback, SLONG gmtOffset, |
| 746 | struct tm* times, int* fractions) |
| 747 | { |
| 748 | bool icuFail = false; |
| 749 | int displacement; |
| 750 | |
| 751 | if (timeStampTz.time_zone == GMT_ZONE) |
| 752 | displacement = 0; |
| 753 | else if (isOffset(timeStampTz.time_zone)) |
| 754 | displacement = offsetZoneToDisplacement(timeStampTz.time_zone); |
| 755 | else |
| 756 | { |
| 757 | UErrorCode icuErrorCode = U_ZERO_ERROR; |
| 758 | |
| 759 | try |
| 760 | { |
| 761 | #ifdef DEV_BUILD |
| 762 | if (gmtFallback && getenv("MISSING_ICU_EMULATION")) |
| 763 | (Arg::Gds(isc_random) << "Emulating missing ICU").raise(); |
| 764 | #endif |
| 765 | Jrd::UnicodeUtil::ConversionICU& icuLib = Jrd::UnicodeUtil::getConversionICU(); |
| 766 | |
| 767 | auto icuCalendar = getDesc(timeStampTz.time_zone)->getCalendar(icuLib, &icuErrorCode); |
| 768 | |
| 769 | if (!icuCalendar) |
| 770 | status_exception::raise(Arg::Gds(isc_random) << "Error calling ICU's ucal_open."); |
| 771 | |
| 772 | icuLib.ucalSetMillis(icuCalendar, timeStampToIcuDate(timeStampTz.utc_timestamp), &icuErrorCode); |
| 773 | |
| 774 | if (U_FAILURE(icuErrorCode)) |
| 775 | status_exception::raise(Arg::Gds(isc_random) << "Error calling ICU's ucal_setMillis."); |
| 776 | |
| 777 | displacement = (icuLib.ucalGet(icuCalendar, UCAL_ZONE_OFFSET, &icuErrorCode) + |
| 778 | icuLib.ucalGet(icuCalendar, UCAL_DST_OFFSET, &icuErrorCode)) / U_MILLIS_PER_MINUTE; |
| 779 | |
| 780 | if (U_FAILURE(icuErrorCode)) |
| 781 | status_exception::raise(Arg::Gds(isc_random) << "Error calling ICU's ucal_get."); |
| 782 | } |
| 783 | catch (const Exception&) |
| 784 | { |
| 785 | if (!gmtFallback) |
| 786 | throw; |
| 787 | |
| 788 | icuFail = true; |
| 789 | displacement = gmtOffset == NO_OFFSET ? 0 : gmtOffset; |
| 790 | } |
| 791 | } |
| 792 | |
| 793 | const auto ticks = TimeStamp::timeStampToTicks(timeStampTz.utc_timestamp) + |
| 794 | (displacement * 60 * ISC_TIME_SECONDS_PRECISION); |
| 795 | |
| 796 | TimeStamp::decode_timestamp(TimeStamp::ticksToTimeStamp(ticks), times, fractions); |
| 797 | |
| 798 | return !icuFail; |
| 799 | } |
| 800 | |
| 801 | ISC_TIMESTAMP_TZ TimeZoneUtil::getCurrentSystemTimeStamp() |
| 802 | { |
nothing calls this directly
no test coverage detected