RSExport RSGregorianDate RSAbsoluteTimeGetGregorianDate(RSAbsoluteTime at, RSTimeZoneRef tz) { RSGregorianDate gdate; int64_t absolute, year; int8_t month, day; RSAbsoluteTime fixedat; #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX // if (nil != tz) { // __RSGenericValidateType(tz, RSTimeZoneGetTypeID()); // } fixedat = at + (nil != tz ? RSTimeZoneGetSecondsFromGMT(tz, 0) : 0.0); #else fixedat = at; #endif absolute = (int64_t)floor(fixedat / 86400.0); __RSYMDFromAbsolute(absolute, &year, &month, &day); if (INT32_MAX - 2001 < year) year = INT32_MAX - 2001; gdate.year = (RSBit8)year + 2001; gdate.month = month; gdate.day = day; gdate.hour = __RSDoubleModToInt(floor(fixedat / 3600.0), 24); gdate.minute = __RSDoubleModToInt(floor(fixedat / 60.0), 60); gdate.second = __RSDoubleMod(fixedat, 60); if (0.0 == gdate.second) gdate.second = 0.0; // stomp out possible -0.0 return gdate; }
RSExport RSAbsoluteTime RSGregorianDateGetAbsoluteTime(RSGregorianDate gdate, RSTimeZoneRef tz) { RSAbsoluteTime at; at = 86400.0 * __RSAbsoluteFromYMD(gdate.year - 2001, gdate.month, gdate.day); at += 3600.0 * gdate.hour + 60.0 * gdate.minute + gdate.second; #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX // if (nil != tz) { // __RSGenericValidateType(tz, RSTimeZoneGetTypeID()); // } RSTimeInterval offset0, offset1; if (nil != tz) { offset0 = RSTimeZoneGetSecondsFromGMT(tz, at); offset1 = RSTimeZoneGetSecondsFromGMT(tz, at - offset0); at -= offset1; } #endif return at; }
RSExport RSBitU32 RSAbsoluteTimeGetDayOfWeek(RSAbsoluteTime at, RSTimeZoneRef tz) { int64_t absolute; RSAbsoluteTime fixedat; #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX if (tz) { if (RSTimeZoneGetTypeID() != RSGetTypeID(tz)) HALTWithError(RSInvalidArgumentException, "timezone is not kind of RSTimeZone"); } fixedat = at + (nil != tz ? RSTimeZoneGetSecondsFromGMT(tz, at) : 0.0); #else fixedat = at; #endif absolute = (int64_t)floor(fixedat / 86400.0); return (absolute < 0) ? ((absolute + 1) % 7 + 7) : (absolute % 7 + 1); /* Monday = 1, etc. */ }
RSExport RSBitU32 RSAbsoluteTimeGetDayOfYear(RSAbsoluteTime at, RSTimeZoneRef tz) { RSAbsoluteTime fixedat; int64_t absolute, year; int8_t month, day; #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX if (tz) { if (RSTimeZoneGetTypeID() != RSGetTypeID(tz)) HALTWithError(RSInvalidArgumentException, "timezone is not kind of RSTimeZone"); } fixedat = at + (nil != tz ? RSTimeZoneGetSecondsFromGMT(tz, at) : 0.0); #else fixedat = at; #endif absolute = (int64_t)floor(fixedat / 86400.0); __RSYMDFromAbsolute(absolute, &year, &month, &day); return __RSDaysBeforeMonth(month, year, isleap(year)) + day; }
RSExport RSBitU32 RSAbsoluteTimeGetWeekOfYear(RSAbsoluteTime at, RSTimeZoneRef tz) { int64_t absolute, year; int8_t month, day; RSAbsoluteTime fixedat; #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX if (tz) { if (RSTimeZoneGetTypeID() != RSGetTypeID(tz)) HALTWithError(RSInvalidArgumentException, "timezone is not kind of RSTimeZone"); } fixedat = at + (nil != tz ? RSTimeZoneGetSecondsFromGMT(tz, at) : 0.0); #else fixedat = at; #endif absolute = (int64_t)floor(fixedat / 86400.0); __RSYMDFromAbsolute(absolute, &year, &month, &day); double absolute0101 = __RSAbsoluteFromYMD(year, 1, 1); int64_t dow0101 = __RSDoubleModToInt(absolute0101, 7) + 1; /* First three and last three days of a year can end up in a week of a different year */ if (1 == month && day < 4) { if ((day < 4 && 5 == dow0101) || (day < 3 && 6 == dow0101) || (day < 2 && 7 == dow0101)) { return 53; } } if (12 == month && 28 < day) { double absolute20101 = __RSAbsoluteFromYMD(year + 1, 1, 1); int64_t dow20101 = __RSDoubleModToInt(absolute20101, 7) + 1; if ((28 < day && 4 == dow20101) || (29 < day && 3 == dow20101) || (30 < day && 2 == dow20101)) { return 1; } } /* Days into year, plus a week-shifting correction, divided by 7. First week is 1. */ return (__RSDaysBeforeMonth(month, year, isleap(year)) + day + (dow0101 - 11) % 7 + 2) / 7 + 1; }
static RSStringRef __RSTimeZoneClassDescription(RSTypeRef obj) { RSTimeZoneRef tz = (RSTimeZoneRef)obj; RSStringRef description = RSStringCreateWithFormat(RSAllocatorSystemDefault, RSSTR("%R - GMT : %5.0f"), __RSTimeZoneGetName(tz), RSTimeZoneGetSecondsFromGMT(tz, 0)); return description; }