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;
}