static CFIndex __CFCalendarGetOrdinalityOfUnit3()

in CoreFoundation/Locale.subproj/CFCalendar.c [1798:2526]


static CFIndex __CFCalendarGetOrdinalityOfUnit3(CFCalendarRef calendar, CFCalendarUnit smallerUnit, CFCalendarUnit biggerUnit, CFAbsoluteTime at) {
    if (!calendar->_cal) {
        __CFCalendarSetupCal(calendar);
        if (!calendar->_cal) {
            return kCFNotFound;
        }
    }
    switch (biggerUnit) {
    case kCFCalendarUnitEra:
#pragma GCC diagnostic push // See 10693376
#pragma GCC diagnostic ignored "-Wswitch-enum"
        switch (smallerUnit) {
        case kCFCalendarUnitYear: {
            UErrorCode status = U_ZERO_ERROR;
            __cficu_ucal_clear(calendar->_cal);
            UDate udate = (floor(at) + kCFAbsoluteTimeIntervalSince1970) * 1000.0;
            __cficu_ucal_setMillis(calendar->_cal, udate, &status);
            CFIndex year = __cficu_ucal_get(calendar->_cal, UCAL_YEAR, &status);
            return year;
        }
        case kCFCalendarUnitYearForWeekOfYear: {
            UErrorCode status = U_ZERO_ERROR;
            __cficu_ucal_clear(calendar->_cal);
            UDate udate = (floor(at) + kCFAbsoluteTimeIntervalSince1970) * 1000.0;
            __cficu_ucal_setMillis(calendar->_cal, udate, &status);
            CFIndex year = __cficu_ucal_get(calendar->_cal, UCAL_YEAR_WOY, &status);
            return year;
        }
        case kCFCalendarUnitQuarter: {
            CFIndex year = __CFCalendarGetOrdinalityOfUnit3(calendar, kCFCalendarUnitYear, kCFCalendarUnitEra, at);
            if (kCFNotFound == year) return kCFNotFound;
            CFIndex q = __CFCalendarGetOrdinalityOfUnit3(calendar, kCFCalendarUnitQuarter, kCFCalendarUnitYear, at);
            if (kCFNotFound == q) return kCFNotFound;
            CFIndex quarter = 4 * (year - 1) + q;
            return quarter;
        }
        case kCFCalendarUnitMonth: { // do not use this combo for recursion
            CFAbsoluteTime start = 0.0;
            Boolean b = CFCalendarGetTimeRangeOfUnit(calendar, kCFCalendarUnitEra, at, &start, NULL);
            if (!b) return kCFNotFound;

            UErrorCode status = U_ZERO_ERROR;
            UDate at_udate = (floor(at) + kCFAbsoluteTimeIntervalSince1970) * 1000.0;
            UDate start_udate = (floor(start) + kCFAbsoluteTimeIntervalSince1970) * 1000.0;
            UDate test_udate;

            CFIndex month = 0;
            CFRange r = CFCalendarGetMaximumRangeOfUnit(calendar, kCFCalendarUnitDay);
            if (r.location != kCFNotFound && r.length != kCFNotFound) {
                month = (CFIndex)floor(((at - start) / 86400.0 / (r.length - r.location + 1)) * 0.96875); // low-ball the estimate
                month = (10 < month) ? month - 10 : 0; // low-ball estimate further
            }
            do {
                month++;
                status = U_ZERO_ERROR;
                __cficu_ucal_clear(calendar->_cal);
                __cficu_ucal_setMillis(calendar->_cal, start_udate, &status);
                test_udate = __CFCalendarAdd(calendar, UCAL_MONTH, month, 0, &status);
            } while (test_udate <= at_udate);
            return month;
        }
        case kCFCalendarUnitWeekOfYear: // do not use this combo for recursion
        case kCFCalendarUnitWeekOfMonth: // do not use this combo for recursion
        case kCFCalendarUnitWeek_Deprecated: { // do not use this combo for recursion
            CFAbsoluteTime start = 0.0;
            Boolean b = CFCalendarGetTimeRangeOfUnit(calendar, kCFCalendarUnitEra, at, &start, NULL);
            if (!b) return kCFNotFound;

            UErrorCode status = U_ZERO_ERROR;
            UDate at_udate = (floor(at) + kCFAbsoluteTimeIntervalSince1970) * 1000.0;
            UDate start_udate = (floor(start) + kCFAbsoluteTimeIntervalSince1970) * 1000.0;
            UDate test_udate;
            __cficu_ucal_clear(calendar->_cal);
            __cficu_ucal_setMillis(calendar->_cal, start_udate, &status);
            // move start forward to first day of week if not already there
            CFIndex days_added = 0;
            while (__cficu_ucal_get(calendar->_cal, UCAL_DAY_OF_WEEK, &status) != calendar->_firstWeekday) {
                __CFCalendarAdd(calendar, UCAL_DAY_OF_MONTH, 1, 0, &status);
                days_added++;
            }
            start_udate += days_added * 86400.0 * 1000.0;
            if (calendar->_minDaysInFirstWeek <= days_added) {
                start_udate -= 7 * 86400.0 * 1000.0; // previous week chunk was big enough, count it
            }

            CFIndex week = (CFIndex)floor((at - start) / 86400.0 / 7.0);
            week = (10 < week) ? week - 10 : 0; // low-ball estimate
            do {
                week++;
                status = U_ZERO_ERROR;
                __cficu_ucal_clear(calendar->_cal);
                __cficu_ucal_setMillis(calendar->_cal, start_udate, &status);
                test_udate = __CFCalendarAdd(calendar, UCAL_WEEK_OF_YEAR, week, 0, &status);
            } while (test_udate <= at_udate);
            return week;
        }
        case kCFCalendarUnitWeekdayOrdinal:
        case kCFCalendarUnitWeekday: { // do not use this combo for recursion
            CFAbsoluteTime start = 0.0;
            Boolean b = CFCalendarGetTimeRangeOfUnit(calendar, kCFCalendarUnitEra, at, &start, NULL);
            if (!b) return kCFNotFound;

            UErrorCode status = U_ZERO_ERROR;
            UDate at_udate = (floor(at) + kCFAbsoluteTimeIntervalSince1970) * 1000.0;
            UDate start_udate = (floor(start) + kCFAbsoluteTimeIntervalSince1970) * 1000.0;
            UDate test_udate;
            __cficu_ucal_clear(calendar->_cal);
            __cficu_ucal_setMillis(calendar->_cal, at_udate, &status);
            CFIndex target_dow = __cficu_ucal_get(calendar->_cal, UCAL_DAY_OF_WEEK, &status);
            __cficu_ucal_clear(calendar->_cal);
            __cficu_ucal_setMillis(calendar->_cal, start_udate, &status);
            // move start forward to target day of week if not already there
            while (__cficu_ucal_get(calendar->_cal, UCAL_DAY_OF_WEEK, &status) != target_dow) {
                __CFCalendarAdd(calendar, UCAL_DAY_OF_MONTH, 1, 0, &status);
                start_udate += 86400.0 * 1000.0;
            }

            CFIndex nth_weekday = (CFIndex)floor((at - start) / 86400.0 / 7.0);
            nth_weekday = (10 < nth_weekday) ? nth_weekday - 10 : 0; // low-ball estimate
            do {
                nth_weekday++;
                status = U_ZERO_ERROR;
                __cficu_ucal_clear(calendar->_cal);
                __cficu_ucal_setMillis(calendar->_cal, start_udate, &status);
                test_udate = __CFCalendarAdd(calendar, UCAL_WEEK_OF_YEAR, nth_weekday, 0, &status);
            } while (test_udate <= at_udate);
            return nth_weekday;
        }
        case kCFCalendarUnitDay: {
            CFAbsoluteTime start = 0.0;
            Boolean b = CFCalendarGetTimeRangeOfUnit(calendar, kCFCalendarUnitEra, at, &start, NULL);
            // must do this to make sure things are set up for recursive calls to __CFCalendarGetOrdinalityOfUnit3
            UErrorCode status = U_ZERO_ERROR;
            __cficu_ucal_clear(calendar->_cal);
            UDate udate = (floor(at) + kCFAbsoluteTimeIntervalSince1970) * 1000.0;
            __cficu_ucal_setMillis(calendar->_cal, udate, &status);
            if (!b) return kCFNotFound;
            CFIndex day = (CFIndex)floor((at - start) / 86400.0) + 1;
            return day;
        }
        case kCFCalendarUnitHour: {
            UErrorCode status = U_ZERO_ERROR;
            CFIndex day = __CFCalendarGetOrdinalityOfUnit3(calendar, kCFCalendarUnitDay, kCFCalendarUnitEra, at);
            if (kCFNotFound == day) return kCFNotFound;
            if ((LONG_MAX - 24) / 24 < (day - 1)) return kCFNotFound;
            CFIndex hour = (day - 1) * 24 + __cficu_ucal_get(calendar->_cal, UCAL_HOUR_OF_DAY, &status) + 1;
            return hour;
        }
        case kCFCalendarUnitMinute: {
            UErrorCode status = U_ZERO_ERROR;
            CFIndex hour = __CFCalendarGetOrdinalityOfUnit3(calendar, kCFCalendarUnitHour, kCFCalendarUnitEra, at);
            if (kCFNotFound == hour) return kCFNotFound;
            if ((LONG_MAX - 60) / 60 < (hour - 1)) return kCFNotFound;
            CFIndex minute = (hour - 1) * 60 + __cficu_ucal_get(calendar->_cal, UCAL_MINUTE, &status) + 1;
            return minute;
        }
        case kCFCalendarUnitSecond: {
            UErrorCode status = U_ZERO_ERROR;
            CFIndex minute = __CFCalendarGetOrdinalityOfUnit3(calendar, kCFCalendarUnitMinute, kCFCalendarUnitEra, at);
            if (kCFNotFound == minute) return kCFNotFound;
            if ((LONG_MAX - 60) / 60 < (minute - 1)) return kCFNotFound;
            CFIndex second = (minute - 1) * 60 + __cficu_ucal_get(calendar->_cal, UCAL_SECOND, &status) + 1;
            return second;
        }
        }
#pragma GCC diagnostic pop // See 10693376
         break;
    case kCFCalendarUnitYear:
#pragma GCC diagnostic push // See 10693376
#pragma GCC diagnostic ignored "-Wswitch-enum"
        switch (smallerUnit) {
        case kCFCalendarUnitQuarter: {
            UErrorCode status = U_ZERO_ERROR;
            __cficu_ucal_clear(calendar->_cal);
            UDate udate = (floor(at) + kCFAbsoluteTimeIntervalSince1970) * 1000.0;
            __cficu_ucal_setMillis(calendar->_cal, udate, &status);
            CFIndex quarter = __cficu_ucal_get(calendar->_cal, UCAL_MONTH, &status);
            CFStringRef ident = CFCalendarGetIdentifier(calendar);
            if (kCFCalendarIdentifierHebrew == ident) {
                CFIndex mquarter[] = {3, 3, 3, 4, 4, 4, 4, 1, 1, 1, 2, 2, 2};
                quarter = mquarter[quarter];
            } else {
                CFIndex mquarter[] = {1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4};
                quarter = mquarter[quarter];
            }
            return quarter;
        }
        case kCFCalendarUnitMonth: {
            UErrorCode status = U_ZERO_ERROR;
            __cficu_ucal_clear(calendar->_cal);
            UDate udate = (floor(at) + kCFAbsoluteTimeIntervalSince1970) * 1000.0;
            __cficu_ucal_setMillis(calendar->_cal, udate, &status);
            CFIndex month = __cficu_ucal_get(calendar->_cal, UCAL_MONTH, &status) + 1;
            return month;
        }
        case kCFCalendarUnitWeekOfMonth:
            return kCFNotFound;
        case kCFCalendarUnitWeekOfYear:
        case kCFCalendarUnitWeek_Deprecated: {
            UErrorCode status = U_ZERO_ERROR;
            __cficu_ucal_clear(calendar->_cal);
            UDate udate = (floor(at) + kCFAbsoluteTimeIntervalSince1970) * 1000.0;
            __cficu_ucal_setMillis(calendar->_cal, udate, &status);
            CFIndex doy = __cficu_ucal_get(calendar->_cal, UCAL_DAY_OF_YEAR, &status);
            __cficu_ucal_set(calendar->_cal, UCAL_DAY_OF_YEAR, 1);
            CFIndex fd_dow = __cficu_ucal_get(calendar->_cal, UCAL_DAY_OF_WEEK, &status);
            CFIndex week = (doy + 7 - calendar->_minDaysInFirstWeek + (fd_dow + calendar->_minDaysInFirstWeek - calendar->_firstWeekday + 6) % 7) / 7;
            status = U_ZERO_ERROR;
            __cficu_ucal_clear(calendar->_cal);
            __cficu_ucal_setMillis(calendar->_cal, udate, &status);
            return week;
        }
        case kCFCalendarUnitWeekdayOrdinal:
        case kCFCalendarUnitWeekday: { // do not use this combo for recursion
            CFAbsoluteTime start = 0.0;
            Boolean b = CFCalendarGetTimeRangeOfUnit(calendar, kCFCalendarUnitYear, at, &start, NULL);
            if (!b) return kCFNotFound;

            UErrorCode status = U_ZERO_ERROR;
            CFIndex at_week = __CFCalendarGetOrdinalityOfUnit3(calendar, kCFCalendarUnitWeek_Deprecated, kCFCalendarUnitYear, at);
            CFIndex target_dow = __cficu_ucal_get(calendar->_cal, UCAL_DAY_OF_WEEK, &status);
            if (kCFNotFound == at_week) return kCFNotFound;

            status = U_ZERO_ERROR;
            __cficu_ucal_clear(calendar->_cal);
            UDate udate = (floor(start) + kCFAbsoluteTimeIntervalSince1970) * 1000.0;
            __cficu_ucal_setMillis(calendar->_cal, udate, &status);
            // move start forward to target day of week if not already there
            while (__cficu_ucal_get(calendar->_cal, UCAL_DAY_OF_WEEK, &status) != target_dow) {
                udate = __CFCalendarAdd(calendar, UCAL_DAY_OF_MONTH, 1, 0, &status);
            }
            start = udate / 1000.0 - kCFAbsoluteTimeIntervalSince1970;

            CFIndex start_week = __CFCalendarGetOrdinalityOfUnit3(calendar, kCFCalendarUnitWeek_Deprecated, kCFCalendarUnitYear, start);
            if (kCFNotFound == start_week) return kCFNotFound;
            CFIndex nth_weekday = at_week - start_week + 1;
            return nth_weekday;
        }
        case kCFCalendarUnitDay: {
            UErrorCode status = U_ZERO_ERROR;
            __cficu_ucal_clear(calendar->_cal);
            UDate udate = (floor(at) + kCFAbsoluteTimeIntervalSince1970) * 1000.0;
            __cficu_ucal_setMillis(calendar->_cal, udate, &status);
            CFIndex day = __cficu_ucal_get(calendar->_cal, UCAL_DAY_OF_YEAR, &status);
            return day;
        }
        case kCFCalendarUnitHour: {
            UErrorCode status = U_ZERO_ERROR;
            CFIndex day = __CFCalendarGetOrdinalityOfUnit3(calendar, kCFCalendarUnitDay, kCFCalendarUnitYear, at);
            if (kCFNotFound == day) return kCFNotFound;
            CFIndex hour = (day - 1) * 24 + __cficu_ucal_get(calendar->_cal, UCAL_HOUR_OF_DAY, &status) + 1;
            return hour;
        }
        case kCFCalendarUnitMinute: {
            UErrorCode status = U_ZERO_ERROR;
            CFIndex hour = __CFCalendarGetOrdinalityOfUnit3(calendar, kCFCalendarUnitHour, kCFCalendarUnitYear, at);
            if (kCFNotFound == hour) return kCFNotFound;
            CFIndex minute = (hour - 1) * 60 + __cficu_ucal_get(calendar->_cal, UCAL_MINUTE, &status) + 1;
            return minute;
        }
        case kCFCalendarUnitSecond: {
            UErrorCode status = U_ZERO_ERROR;
            CFIndex minute = __CFCalendarGetOrdinalityOfUnit3(calendar, kCFCalendarUnitMinute, kCFCalendarUnitYear, at);
            if (kCFNotFound == minute) return kCFNotFound;
            CFIndex second = (minute - 1) * 60 + __cficu_ucal_get(calendar->_cal, UCAL_SECOND, &status) + 1;
            return second;
        }
#if _CF_CALENDAR_NANOSECONDS_AVAILABLE
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wswitch-enum"
        case kCFCalendarUnitNanosecond: {
            CFIndex second = __CFCalendarGetOrdinalityOfUnit3(calendar, kCFCalendarUnitSecond, kCFCalendarUnitYear, at);
            if (kCFNotFound == second) return kCFNotFound;
            double dseconds = (double)(second - 1) + (at - floor(at));
            return (CFIndex)(dseconds * 1.0e+9) + 1;
        }
#pragma GCC diagnostic pop
#endif
        }
#pragma GCC diagnostic pop // See 10693376
         break;
    case kCFCalendarUnitYearForWeekOfYear:
#pragma GCC diagnostic push // See 10693376
#pragma GCC diagnostic ignored "-Wswitch-enum"
        switch (smallerUnit) {
        case kCFCalendarUnitQuarter:
            return kCFNotFound;
        case kCFCalendarUnitMonth:
            return kCFNotFound;
        case kCFCalendarUnitWeekOfMonth:
        case kCFCalendarUnitWeek_Deprecated:
            return kCFNotFound;
        case kCFCalendarUnitWeekOfYear: {
            UErrorCode status = U_ZERO_ERROR;
            __cficu_ucal_clear(calendar->_cal);
            UDate udate = (floor(at) + kCFAbsoluteTimeIntervalSince1970) * 1000.0;
            __cficu_ucal_setMillis(calendar->_cal, udate, &status);
            CFIndex week = __cficu_ucal_get(calendar->_cal, UCAL_WEEK_OF_YEAR, &status);
            return U_SUCCESS(status) ? week : kCFNotFound;
        }
        case kCFCalendarUnitWeekdayOrdinal:
        case kCFCalendarUnitWeekday: { // do not use this combo for recursion
            CFAbsoluteTime start = 0.0;
            Boolean b = CFCalendarGetTimeRangeOfUnit(calendar, kCFCalendarUnitYearForWeekOfYear, at, &start, NULL);
            if (!b) return kCFNotFound;

            UErrorCode status = U_ZERO_ERROR;
            CFIndex at_week = __CFCalendarGetOrdinalityOfUnit3(calendar, kCFCalendarUnitWeekOfYear, kCFCalendarUnitYearForWeekOfYear, at);
            CFIndex target_dow = __cficu_ucal_get(calendar->_cal, UCAL_DAY_OF_WEEK, &status);
            if (kCFNotFound == at_week) return kCFNotFound;

            status = U_ZERO_ERROR;
            __cficu_ucal_clear(calendar->_cal);
            UDate udate = (floor(start) + kCFAbsoluteTimeIntervalSince1970) * 1000.0;
            __cficu_ucal_setMillis(calendar->_cal, udate, &status);
            // move start forward to target day of week if not already there
            while (__cficu_ucal_get(calendar->_cal, UCAL_DAY_OF_WEEK, &status) != target_dow) {
                udate = __CFCalendarAdd(calendar, UCAL_DAY_OF_MONTH, 1, 0, &status);
            }
            start = udate / 1000.0 - kCFAbsoluteTimeIntervalSince1970;

            CFIndex start_week = __CFCalendarGetOrdinalityOfUnit3(calendar, kCFCalendarUnitWeekOfYear, kCFCalendarUnitYearForWeekOfYear, start);
            if (kCFNotFound == start_week) return kCFNotFound;
            CFIndex nth_weekday = at_week - start_week + 1;
            return nth_weekday;
        }
        case kCFCalendarUnitDay: {
            CFAbsoluteTime start = 0.0;
            Boolean b = CFCalendarGetTimeRangeOfUnit(calendar, kCFCalendarUnitYearForWeekOfYear, at, &start, NULL);
            if (!b) return kCFNotFound;
            CFIndex day = (CFIndex)floor((at - start) / 86400.0) + 1;
            return day;
        }
        case kCFCalendarUnitHour: {
            UErrorCode status = U_ZERO_ERROR;
            CFIndex day = __CFCalendarGetOrdinalityOfUnit3(calendar, kCFCalendarUnitDay, kCFCalendarUnitYearForWeekOfYear, at);
            if (kCFNotFound == day) return kCFNotFound;
            CFIndex hour = (day - 1) * 24 + __cficu_ucal_get(calendar->_cal, UCAL_HOUR_OF_DAY, &status) + 1;
            return hour;
        }
        case kCFCalendarUnitMinute: {
            UErrorCode status = U_ZERO_ERROR;
            CFIndex hour = __CFCalendarGetOrdinalityOfUnit3(calendar, kCFCalendarUnitHour, kCFCalendarUnitYearForWeekOfYear, at);
            if (kCFNotFound == hour) return kCFNotFound;
            CFIndex minute = (hour - 1) * 60 + __cficu_ucal_get(calendar->_cal, UCAL_MINUTE, &status) + 1;
            return minute;
        }
        case kCFCalendarUnitSecond: {
            UErrorCode status = U_ZERO_ERROR;
            CFIndex minute = __CFCalendarGetOrdinalityOfUnit3(calendar, kCFCalendarUnitMinute, kCFCalendarUnitYearForWeekOfYear, at);
            if (kCFNotFound == minute) return kCFNotFound;
            CFIndex second = (minute - 1) * 60 + __cficu_ucal_get(calendar->_cal, UCAL_SECOND, &status) + 1;
            return second;
        }
#if _CF_CALENDAR_NANOSECONDS_AVAILABLE
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wswitch-enum"
        case kCFCalendarUnitNanosecond: {
            CFIndex second = __CFCalendarGetOrdinalityOfUnit3(calendar, kCFCalendarUnitSecond, kCFCalendarUnitYearForWeekOfYear, at);
            if (kCFNotFound == second) return kCFNotFound;
            double dseconds = (double)(second - 1) + (at - floor(at));
            return (CFIndex)(dseconds * 1.0e+9) + 1;
        }
#pragma GCC diagnostic pop
#endif
        }
#pragma GCC diagnostic pop // See 10693376
         break;
    case kCFCalendarUnitQuarter:
#pragma GCC diagnostic push // See 10693376
#pragma GCC diagnostic ignored "-Wswitch-enum"
        switch (smallerUnit) {
        case kCFCalendarUnitMonth: {
            UErrorCode status = U_ZERO_ERROR;
            __cficu_ucal_clear(calendar->_cal);
            UDate udate = (floor(at) + kCFAbsoluteTimeIntervalSince1970) * 1000.0;
            __cficu_ucal_setMillis(calendar->_cal, udate, &status);
            CFIndex month = __cficu_ucal_get(calendar->_cal, UCAL_MONTH, &status);
            CFStringRef ident = CFCalendarGetIdentifier(calendar);
            if (kCFCalendarIdentifierHebrew == ident) {
                CFIndex mcount[] = {1, 2, 3, 1, 2, 3, 4, 1, 2, 3, 1, 2, 3};
                month = mcount[month];
            } else {
                CFIndex mcount[] = {1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 4};
                month = mcount[month];
            }
            return month;
        }
        case kCFCalendarUnitWeekOfYear:
        case kCFCalendarUnitWeekOfMonth:
        case kCFCalendarUnitWeek_Deprecated: { // do not use this combo for recursion
            CFAbsoluteTime start = 0.0;
            Boolean b = CFCalendarGetTimeRangeOfUnit(calendar, kCFCalendarUnitQuarter, at, &start, NULL);
            if (!b) return kCFNotFound;

            UErrorCode status = U_ZERO_ERROR;
            __cficu_ucal_clear(calendar->_cal);
            UDate udate = (floor(start) + kCFAbsoluteTimeIntervalSince1970) * 1000.0;
            __cficu_ucal_setMillis(calendar->_cal, udate, &status);
            // move start forward to first day of week if not already there
            CFIndex days_added = 0;
            while (__cficu_ucal_get(calendar->_cal, UCAL_DAY_OF_WEEK, &status) != calendar->_firstWeekday) {
                udate = __CFCalendarAdd(calendar, UCAL_DAY_OF_MONTH, 1, 0, &status);
                days_added++;
            }
            start = udate / 1000.0 - kCFAbsoluteTimeIntervalSince1970;

            CFIndex start_week = __CFCalendarGetOrdinalityOfUnit3(calendar, kCFCalendarUnitWeek_Deprecated, kCFCalendarUnitYear, start);
            if (kCFNotFound == start_week) return kCFNotFound;
            if (calendar->_minDaysInFirstWeek <= days_added) {
                start_week--; // previous week chunk was big enough, back up
            }

            CFIndex at_week = __CFCalendarGetOrdinalityOfUnit3(calendar, kCFCalendarUnitWeek_Deprecated, kCFCalendarUnitYear, at);
            if (kCFNotFound == at_week) return kCFNotFound;
            CFIndex week = at_week - start_week + 1;
            return week;
        }
        case kCFCalendarUnitWeekdayOrdinal:
        case kCFCalendarUnitWeekday: { // do not use this combo for recursion
            CFAbsoluteTime start = 0.0;
            Boolean b = CFCalendarGetTimeRangeOfUnit(calendar, kCFCalendarUnitQuarter, at, &start, NULL);
            if (!b) return kCFNotFound;

            UErrorCode status = U_ZERO_ERROR;
            CFIndex at_week = __CFCalendarGetOrdinalityOfUnit3(calendar, kCFCalendarUnitWeek_Deprecated, kCFCalendarUnitYear, at);
            CFIndex target_dow = __cficu_ucal_get(calendar->_cal, UCAL_DAY_OF_WEEK, &status);
            if (kCFNotFound == at_week) return kCFNotFound;

            status = U_ZERO_ERROR;
            __cficu_ucal_clear(calendar->_cal);
            UDate udate = (floor(start) + kCFAbsoluteTimeIntervalSince1970) * 1000.0;
            __cficu_ucal_setMillis(calendar->_cal, udate, &status);
            // move start forward to target day of week if not already there
            while (__cficu_ucal_get(calendar->_cal, UCAL_DAY_OF_WEEK, &status) != target_dow) {
                udate = __CFCalendarAdd(calendar, UCAL_DAY_OF_MONTH, 1, 0, &status);
            }
            start = udate / 1000.0 - kCFAbsoluteTimeIntervalSince1970;

            CFIndex start_week = __CFCalendarGetOrdinalityOfUnit3(calendar, kCFCalendarUnitWeek_Deprecated, kCFCalendarUnitYear, start);
            if (kCFNotFound == start_week) return kCFNotFound;
            CFIndex nth_weekday = at_week - start_week + 1;
            return nth_weekday;
        }
        case kCFCalendarUnitDay: {
            CFAbsoluteTime start = 0.0;
            Boolean b = CFCalendarGetTimeRangeOfUnit(calendar, kCFCalendarUnitQuarter, at, &start, NULL);
            // must do this to make sure things are set up for recursive calls to __CFCalendarGetOrdinalityOfUnit3
            UErrorCode status = U_ZERO_ERROR;
            __cficu_ucal_clear(calendar->_cal);
            UDate udate = (floor(at) + kCFAbsoluteTimeIntervalSince1970) * 1000.0;
            __cficu_ucal_setMillis(calendar->_cal, udate, &status);
            if (!b) return kCFNotFound;
            CFIndex day = (CFIndex)floor((at - start) / 86400.0) + 1;
            return day;
        }
        case kCFCalendarUnitHour: {
            UErrorCode status = U_ZERO_ERROR;
            CFIndex day = __CFCalendarGetOrdinalityOfUnit3(calendar, kCFCalendarUnitDay, kCFCalendarUnitQuarter, at);
            if (kCFNotFound == day) return kCFNotFound;
            CFIndex hour = (day - 1) * 24 + __cficu_ucal_get(calendar->_cal, UCAL_HOUR_OF_DAY, &status) + 1;
            return hour;
        }
        case kCFCalendarUnitMinute: {
            UErrorCode status = U_ZERO_ERROR;
            CFIndex hour = __CFCalendarGetOrdinalityOfUnit3(calendar, kCFCalendarUnitHour, kCFCalendarUnitQuarter, at);
            if (kCFNotFound == hour) return kCFNotFound;
            CFIndex minute = (hour - 1) * 60 + __cficu_ucal_get(calendar->_cal, UCAL_MINUTE, &status) + 1;
            return minute;
        }
        case kCFCalendarUnitSecond: {
            UErrorCode status = U_ZERO_ERROR;
            CFIndex minute = __CFCalendarGetOrdinalityOfUnit3(calendar, kCFCalendarUnitMinute, kCFCalendarUnitQuarter, at);
            if (kCFNotFound == minute) return kCFNotFound;
            CFIndex second = (minute - 1) * 60 + __cficu_ucal_get(calendar->_cal, UCAL_SECOND, &status) + 1;
            return second;
        }
#if _CF_CALENDAR_NANOSECONDS_AVAILABLE
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wswitch-enum"
        case kCFCalendarUnitNanosecond: {
            CFIndex second = __CFCalendarGetOrdinalityOfUnit3(calendar, kCFCalendarUnitSecond, kCFCalendarUnitQuarter, at);
            if (kCFNotFound == second) return kCFNotFound;
            double dseconds = (double)(second - 1) + (at - floor(at));
            return (CFIndex)(dseconds * 1.0e+9) + 1;
        }
#pragma GCC diagnostic pop
#endif
        }
#pragma GCC diagnostic pop // See 10693376
         break;
    case kCFCalendarUnitMonth:
#pragma GCC diagnostic push // See 10693376
#pragma GCC diagnostic ignored "-Wswitch-enum"
        switch (smallerUnit) {
        case kCFCalendarUnitWeekOfYear:
            return kCFNotFound;
        case kCFCalendarUnitWeekOfMonth:
        case kCFCalendarUnitWeek_Deprecated: {
            UErrorCode status = U_ZERO_ERROR;
            __cficu_ucal_clear(calendar->_cal);
            UDate udate = (floor(at) + kCFAbsoluteTimeIntervalSince1970) * 1000.0;
            __cficu_ucal_setMillis(calendar->_cal, udate, &status);
            CFIndex week = __cficu_ucal_get(calendar->_cal, UCAL_WEEK_OF_MONTH, &status);
            return week;
        }
        case kCFCalendarUnitDay: {
            UErrorCode status = U_ZERO_ERROR;
            __cficu_ucal_clear(calendar->_cal);
            UDate udate = (floor(at) + kCFAbsoluteTimeIntervalSince1970) * 1000.0;
            __cficu_ucal_setMillis(calendar->_cal, udate, &status);
            CFIndex day = __cficu_ucal_get(calendar->_cal, UCAL_DAY_OF_MONTH, &status);
            return day;
        }
        case kCFCalendarUnitWeekdayOrdinal:
        case kCFCalendarUnitWeekday: {
            CFIndex day = __CFCalendarGetOrdinalityOfUnit3(calendar, kCFCalendarUnitDay, kCFCalendarUnitMonth, at);
            if (kCFNotFound == day) return kCFNotFound;
            CFIndex nth_weekday = (day + 6) / 7;
            return nth_weekday;
        }
        case kCFCalendarUnitHour: {
            UErrorCode status = U_ZERO_ERROR;
            CFIndex day = __CFCalendarGetOrdinalityOfUnit3(calendar, kCFCalendarUnitDay, kCFCalendarUnitMonth, at);
            if (kCFNotFound == day) return kCFNotFound;
            CFIndex hour = (day - 1) * 24 + __cficu_ucal_get(calendar->_cal, UCAL_HOUR_OF_DAY, &status) + 1;
            return hour;
        }
        case kCFCalendarUnitMinute: {
            UErrorCode status = U_ZERO_ERROR;
            CFIndex hour = __CFCalendarGetOrdinalityOfUnit3(calendar, kCFCalendarUnitHour, kCFCalendarUnitMonth, at);
            if (kCFNotFound == hour) return kCFNotFound;
            CFIndex minute = (hour - 1) * 60 + __cficu_ucal_get(calendar->_cal, UCAL_MINUTE, &status) + 1;
            return minute;
        }
        case kCFCalendarUnitSecond: {
            UErrorCode status = U_ZERO_ERROR;
            CFIndex minute = __CFCalendarGetOrdinalityOfUnit3(calendar, kCFCalendarUnitMinute, kCFCalendarUnitMonth, at);
            if (kCFNotFound == minute) return kCFNotFound;
            CFIndex second = (minute - 1) * 60 + __cficu_ucal_get(calendar->_cal, UCAL_SECOND, &status) + 1;
            return second;
        }
#if _CF_CALENDAR_NANOSECONDS_AVAILABLE
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wswitch-enum"
        case kCFCalendarUnitNanosecond: {
            CFIndex second = __CFCalendarGetOrdinalityOfUnit3(calendar, kCFCalendarUnitSecond, kCFCalendarUnitMonth, at);
            if (kCFNotFound == second) return kCFNotFound;
            double dseconds = (double)(second - 1) + (at - floor(at));
            return (CFIndex)(dseconds * 1.0e+9) + 1;
        }
#pragma GCC diagnostic pop
#endif
        }
#pragma GCC diagnostic pop // See 10693376
         break;
    case kCFCalendarUnitWeekOfYear:
    case kCFCalendarUnitWeekOfMonth:
    case kCFCalendarUnitWeek_Deprecated:
#pragma GCC diagnostic push // See 10693376
#pragma GCC diagnostic ignored "-Wswitch-enum"
        switch (smallerUnit) {
        case kCFCalendarUnitDay:
        case kCFCalendarUnitWeekday: {
            UErrorCode status = U_ZERO_ERROR;
            __cficu_ucal_clear(calendar->_cal);
            UDate udate = (floor(at) + kCFAbsoluteTimeIntervalSince1970) * 1000.0;
            __cficu_ucal_setMillis(calendar->_cal, udate, &status);
            CFIndex day = __cficu_ucal_get(calendar->_cal, UCAL_DAY_OF_WEEK, &status) + 1 - calendar->_firstWeekday;
            if (day <= 0) day += 7;
            return day;
        }
        case kCFCalendarUnitHour: {
            UErrorCode status = U_ZERO_ERROR;
            CFIndex day = __CFCalendarGetOrdinalityOfUnit3(calendar, kCFCalendarUnitDay, kCFCalendarUnitWeek_Deprecated, at);
            if (kCFNotFound == day) return kCFNotFound;
            CFIndex hour = (day - 1) * 24 + __cficu_ucal_get(calendar->_cal, UCAL_HOUR_OF_DAY, &status) + 1;
            return hour;
        }
        case kCFCalendarUnitMinute: {
            UErrorCode status = U_ZERO_ERROR;
            CFIndex hour = __CFCalendarGetOrdinalityOfUnit3(calendar, kCFCalendarUnitHour, kCFCalendarUnitWeek_Deprecated, at);
            if (kCFNotFound == hour) return kCFNotFound;
            CFIndex minute = (hour - 1) * 60 + __cficu_ucal_get(calendar->_cal, UCAL_MINUTE, &status) + 1;
            return minute;
        }
        case kCFCalendarUnitSecond: {
            UErrorCode status = U_ZERO_ERROR;
            CFIndex minute = __CFCalendarGetOrdinalityOfUnit3(calendar, kCFCalendarUnitMinute, kCFCalendarUnitWeek_Deprecated, at);
            if (kCFNotFound == minute) return kCFNotFound;
            CFIndex second = (minute - 1) * 60 + __cficu_ucal_get(calendar->_cal, UCAL_SECOND, &status) + 1;
            return second;
        }
#if _CF_CALENDAR_NANOSECONDS_AVAILABLE
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wswitch-enum"
        case kCFCalendarUnitNanosecond: {
            CFIndex second = __CFCalendarGetOrdinalityOfUnit3(calendar, kCFCalendarUnitSecond, kCFCalendarUnitWeek_Deprecated, at);
            if (kCFNotFound == second) return kCFNotFound;
            double dseconds = (double)(second - 1) + (at - floor(at));
            return (CFIndex)(dseconds * 1.0e+9) + 1;
        }
#pragma GCC diagnostic pop
#endif
        }
#pragma GCC diagnostic pop // See 10693376
         break;
    case kCFCalendarUnitWeekday:
    case kCFCalendarUnitDay:
#pragma GCC diagnostic push // See 10693376
#pragma GCC diagnostic ignored "-Wswitch-enum"
        switch (smallerUnit) {
        case kCFCalendarUnitHour: {
            UErrorCode status = U_ZERO_ERROR;
            __cficu_ucal_clear(calendar->_cal);
            UDate udate = (floor(at) + kCFAbsoluteTimeIntervalSince1970) * 1000.0;
            __cficu_ucal_setMillis(calendar->_cal, udate, &status);
            CFIndex hour = __cficu_ucal_get(calendar->_cal, UCAL_HOUR_OF_DAY, &status) + 1;
            return hour;
        }
        case kCFCalendarUnitMinute: {
            UErrorCode status = U_ZERO_ERROR;
            CFIndex hour = __CFCalendarGetOrdinalityOfUnit3(calendar, kCFCalendarUnitHour, kCFCalendarUnitDay, at);
            if (kCFNotFound == hour) return kCFNotFound;
            CFIndex minute = (hour - 1) * 60 + __cficu_ucal_get(calendar->_cal, UCAL_MINUTE, &status) + 1;
            return minute;
        }
        case kCFCalendarUnitSecond: {
            UErrorCode status = U_ZERO_ERROR;
            CFIndex minute = __CFCalendarGetOrdinalityOfUnit3(calendar, kCFCalendarUnitMinute, kCFCalendarUnitDay, at);
            if (kCFNotFound == minute) return kCFNotFound;
            CFIndex second = (minute - 1) * 60 + __cficu_ucal_get(calendar->_cal, UCAL_SECOND, &status) + 1;
            return second;
        }
#if _CF_CALENDAR_NANOSECONDS_AVAILABLE
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wswitch-enum"
        case kCFCalendarUnitNanosecond: {
            CFIndex second = __CFCalendarGetOrdinalityOfUnit3(calendar, kCFCalendarUnitSecond, kCFCalendarUnitDay, at);
            if (kCFNotFound == second) return kCFNotFound;
            double dseconds = (double)(second - 1) + (at - floor(at));
            return (CFIndex)(dseconds * 1.0e+9) + 1;
        }
#pragma GCC diagnostic pop
#endif
        }
#pragma GCC diagnostic pop // See 10693376
        break;
    case kCFCalendarUnitHour:
#pragma GCC diagnostic push // See 10693376
#pragma GCC diagnostic ignored "-Wswitch-enum"
        switch (smallerUnit) {
        case kCFCalendarUnitMinute: {
            UErrorCode status = U_ZERO_ERROR;
            __cficu_ucal_clear(calendar->_cal);
            UDate udate = (floor(at) + kCFAbsoluteTimeIntervalSince1970) * 1000.0;
            __cficu_ucal_setMillis(calendar->_cal, udate, &status);
            CFIndex minute = __cficu_ucal_get(calendar->_cal, UCAL_MINUTE, &status) + 1;
            return minute;
        }
        case kCFCalendarUnitSecond: {
            UErrorCode status = U_ZERO_ERROR;
            CFIndex minute = __CFCalendarGetOrdinalityOfUnit3(calendar, kCFCalendarUnitMinute, kCFCalendarUnitHour, at);
            if (kCFNotFound == minute) return kCFNotFound;
            CFIndex second = (minute - 1) * 60 + __cficu_ucal_get(calendar->_cal, UCAL_SECOND, &status) + 1;
            return second;
        }
#if _CF_CALENDAR_NANOSECONDS_AVAILABLE
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wswitch-enum"
        case kCFCalendarUnitNanosecond: {
            CFIndex second = __CFCalendarGetOrdinalityOfUnit3(calendar, kCFCalendarUnitSecond, kCFCalendarUnitHour, at);
            if (kCFNotFound == second) return kCFNotFound;
            double dseconds = (double)(second - 1) + (at - floor(at));
            return (CFIndex)(dseconds * 1.0e+9) + 1;
        }
#pragma GCC diagnostic pop
#endif
        }
#pragma GCC diagnostic pop // See 10693376
        break;
    case kCFCalendarUnitMinute:
#pragma GCC diagnostic push // See 10693376
#pragma GCC diagnostic ignored "-Wswitch-enum"
        switch (smallerUnit) {
        case kCFCalendarUnitSecond: {
            UErrorCode status = U_ZERO_ERROR;
            __cficu_ucal_clear(calendar->_cal);
            UDate udate = (floor(at) + kCFAbsoluteTimeIntervalSince1970) * 1000.0;
            __cficu_ucal_setMillis(calendar->_cal, udate, &status);
            CFIndex second = __cficu_ucal_get(calendar->_cal, UCAL_SECOND, &status) + 1;
            return second;
        }
#if _CF_CALENDAR_NANOSECONDS_AVAILABLE
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wswitch-enum"
        case kCFCalendarUnitNanosecond: {
            CFIndex second = __CFCalendarGetOrdinalityOfUnit3(calendar, kCFCalendarUnitSecond, kCFCalendarUnitMinute, at);
            if (kCFNotFound == second) return kCFNotFound;
            double dseconds = (double)(second - 1) + (at - floor(at));
            return (CFIndex)(dseconds * 1.0e+9) + 1;
        }
#pragma GCC diagnostic pop
#endif
        }
#pragma GCC diagnostic pop // See 10693376
        break;
    case kCFCalendarUnitSecond:
#pragma GCC diagnostic push // See 10693376
#pragma GCC diagnostic ignored "-Wswitch-enum"
        switch (smallerUnit) {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wswitch-enum"
        case kCFCalendarUnitNanosecond:
#pragma GCC diagnostic pop
            return (CFIndex)((at - floor(at)) * 1.0e+9) + 1;
        }
#pragma GCC diagnostic pop // See 10693376
        break;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wswitch-enum"
    case kCFCalendarUnitNanosecond:
        break;
#pragma GCC diagnostic pop
    case kCFCalendarUnitWeekdayOrdinal:
        break;
    }
    return kCFNotFound;
}