Beispiel #1
0
CFAbsoluteTime CFGregorianDateGetAbsoluteTime(CFGregorianDate gdate, CFTimeZoneRef tz) {
    CFAbsoluteTime at;
    CFTimeInterval offset0, offset1;

    at = 86400.0 * __CFAbsoluteFromYMD(gdate.year - 2001, gdate.month, gdate.day);
    at += 3600.0 * gdate.hour + 60.0 * gdate.minute + gdate.second;
    if (tz) {
        offset0 = CFTimeZoneGetSecondsFromGMT(tz, at);
        offset1 = CFTimeZoneGetSecondsFromGMT(tz, at - offset0);
        at -= offset1;
    }
    return at;
}
		/**
		 * MacDateTime::LocalTZA
		 * 
		 * Determines the Local Time Zone Adjustment, in seconds from GMT
		 */
		double MacDateTime::LocalTZA(double time)
		{
			CFTimeZoneRef tz = CFTimeZoneCopySystem();
			if (tz) 
			{			
				CFAbsoluteTime at = ECMADateToCFAbsoluteTime(time);
				// pass now as the reference. 
				// This will include any daylight savings offsets in the result.
				CFTimeInterval result = CFTimeZoneGetSecondsFromGMT(tz, at);
						
				CFRelease(tz);	

				result *= kMsecPerSecond;
		
				// Remove the effects of daylight saving time
				return ( result -= MacDateTime::DaylightSavingTA(time) );
			}

			MachineLocation location;
			ReadMachineLocation(&location);

			// Extract the GMT delta
			long gmtDelta = location.u.gmtDelta & 0xFFFFFF;
			if (gmtDelta & 0x800000) {
				gmtDelta |= 0xFF000000;
			}

			// Remove the effects of daylight saving time
			if (location.u.dlsDelta < 0) {
				gmtDelta -= 3600;
			}
 
			return (double)gmtDelta * kMsecPerSecond;
		}
Beispiel #3
0
/* "the first week of a year is the one which includes the first Thursday" (ISO 8601) */
SInt32 CFAbsoluteTimeGetWeekOfYear(CFAbsoluteTime at, CFTimeZoneRef tz) {
    int64_t absolute, year;
    int8_t month, day;
    CFAbsoluteTime fixedat;

    fixedat = at + (tz ? CFTimeZoneGetSecondsFromGMT(tz, at) : 0.0);
    absolute = (int64_t)floor(fixedat / 86400.0);
    __CFYMDFromAbsolute(absolute, &year, &month, &day);
    double absolute0101 = __CFAbsoluteFromYMD(year, 1, 1);
    int64_t dow0101 = __CFDoubleModToInt(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 = __CFAbsoluteFromYMD(year + 1, 1, 1);
        int64_t dow20101 = __CFDoubleModToInt(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 (__CFDaysBeforeMonth(month, year) + day + (dow0101 - 11) % 7 + 2) / 7 + 1;
}
void MacLongDateTimeToTimeString(const sint64 &inMacDate,
                                        uint32 inLength, void *outData)
{
	// @@@ this code is close, but on the fringe case of a daylight savings time it will be off for a little while
	CFAbsoluteTime absTime = inMacDate - kCFAbsoluteTimeIntervalSince1904;

	// Remove local timezone component from absTime
	CFTimeZoneRef timeZone = CFTimeZoneCopyDefault();
	absTime -= CFTimeZoneGetSecondsFromGMT(timeZone, absTime);
	CFRelease(timeZone);

	timeZone = CFTimeZoneCreateWithTimeIntervalFromGMT(NULL, 0);
	CFGregorianDate date = CFAbsoluteTimeGetGregorianDate(absTime, timeZone);
	CFRelease(timeZone);

    if (inLength == 16)
    {
        sprintf((char *)(outData), "%04d%02d%02d%02d%02d%02dZ",
                int(date.year % 10000), date.month, date.day,
                date.hour, date.minute, int(date.second));
    }
    else if (inLength == 14)
    {
 		/* UTC - 2 year digits - code which parses this assumes that
		 * (2-digit) years between 0 and 49 are in century 21 */
        sprintf((char *)(outData), "%02d%02d%02d%02d%02d%02dZ",
                int(date.year % 100), date.month, date.day,
                date.hour, date.minute, int(date.second));
    }
    else
        MacOSError::throwMe(paramErr);
}
Beispiel #5
0
SInt32 CFAbsoluteTimeGetDayOfWeek(CFAbsoluteTime at, CFTimeZoneRef tz) {
    int64_t absolute;
    CFAbsoluteTime fixedat;

    fixedat = at + (tz ? CFTimeZoneGetSecondsFromGMT(tz, at) : 0.0);
    absolute = (int64_t)floor(fixedat / 86400.0);
    return (absolute < 0) ? ((absolute + 1) % 7 + 7) : (absolute % 7 + 1); /* Monday = 1, etc. */
}
void
GetCurrentMacLongDateTime(sint64 &outMacDate)
{
	CFTimeZoneRef timeZone = CFTimeZoneCopyDefault();
	CFAbsoluteTime absTime = CFAbsoluteTimeGetCurrent();
	absTime += CFTimeZoneGetSecondsFromGMT(timeZone, absTime);
	CFRelease(timeZone);
	outMacDate = sint64(double(absTime + kCFAbsoluteTimeIntervalSince1904));
}
Beispiel #7
0
SInt32 CFAbsoluteTimeGetDayOfYear(CFAbsoluteTime at, CFTimeZoneRef tz) {
    CFAbsoluteTime fixedat;
    int64_t absolute, year;
    int8_t month, day;

    fixedat = at + (tz ? CFTimeZoneGetSecondsFromGMT(tz, at) : 0.0);
    absolute = (int64_t)floor(fixedat / 86400.0);
    __CFYMDFromAbsolute(absolute, &year, &month, &day);
    return __CFDaysBeforeMonth(month, year) + day;
}
Beispiel #8
0
CFGregorianDate CFAbsoluteTimeGetGregorianDate(CFAbsoluteTime at, CFTimeZoneRef tz) {
    CFGregorianDate gdate;
    int64_t absolute, year;
    int8_t month, day;
    CFAbsoluteTime fixedat;

    fixedat = at + (tz ? CFTimeZoneGetSecondsFromGMT(tz, at) : 0.0);
    absolute = (int64_t)floor(fixedat / 86400.0);
    __CFYMDFromAbsolute(absolute, &year, &month, &day);
    if (INT32_MAX - 2001 < year) {
        year = INT32_MAX - 2001;
    }
    gdate.year = (SInt32)(year + 2001);
    gdate.month = month;
    gdate.day = day;
    gdate.hour = __CFDoubleModToInt(floor(fixedat / 3600.0), 24);
    gdate.minute = __CFDoubleModToInt(floor(fixedat / 60.0), 60);
    gdate.second = __CFDoubleMod(fixedat, 60);
    if (0.0 == gdate.second) {
        gdate.second = 0.0; // stomp out possible -0.0
    }
    return gdate;
}
Beispiel #9
0
dng_time_zone LocalTimeZone (const dng_date_time &dt)
	{
	
	dng_time_zone result;
	
	if (dt.IsValid ())
		{
		
		#if qMacOS
		
		CFTimeZoneRef zoneRef = CFTimeZoneCopyDefault ();
		
		if (zoneRef)
			{
			
			CFGregorianDate gregDate;

			gregDate.year   = dt.fYear;
			gregDate.month  = dt.fMonth;
			gregDate.day    = dt.fDay;
			gregDate.hour   = dt.fHour;
			gregDate.minute = dt.fMinute;
			gregDate.second = dt.fSecond;
			
			CFAbsoluteTime absTime = CFGregorianDateGetAbsoluteTime (gregDate, zoneRef);
			
			CFTimeInterval secondsDelta = CFTimeZoneGetSecondsFromGMT (zoneRef, absTime);
		
			CFRelease (zoneRef);
			
			result.SetOffsetSeconds (secondsDelta);
			
			if (result.IsValid ())
				{
				return result;
				}
			
			}
		
		#endif
		
		#if qWinOS
		
		if (GetTimeZoneInformation          != NULL &&
			SystemTimeToTzSpecificLocalTime != NULL &&
		    SystemTimeToFileTime            != NULL)
			{
			
			TIME_ZONE_INFORMATION tzInfo;
			
			DWORD x = GetTimeZoneInformation (&tzInfo);
			
			SYSTEMTIME localST;
			
			memset (&localST, 0, sizeof (localST));

			localST.wYear   = (WORD) dt.fYear;
			localST.wMonth  = (WORD) dt.fMonth;
			localST.wDay    = (WORD) dt.fDay;
			localST.wHour   = (WORD) dt.fHour;
			localST.wMinute = (WORD) dt.fMinute;
			localST.wSecond = (WORD) dt.fSecond;
			
			SYSTEMTIME utcST;

			if (TzSpecificLocalTimeToSystemTime (&tzInfo, &localST, &utcST))
				{
				
				FILETIME localFT;
				FILETIME utcFT;
				
				(void) SystemTimeToFileTime (&localST, &localFT);
				(void) SystemTimeToFileTime (&utcST  , &utcFT  );
				
				uint64 time1 = (((uint64) localFT.dwHighDateTime) << 32) + localFT.dwLowDateTime;
				uint64 time2 = (((uint64) utcFT  .dwHighDateTime) << 32) + utcFT  .dwLowDateTime;
				
				// FILETIMEs are in units to 100 ns.  Convert to seconds.
				
				int64 time1Sec = time1 / 10000000;
				int64 time2Sec = time2 / 10000000;
			
				int32 delta = (int32) (time1Sec - time2Sec);

				result.SetOffsetSeconds (delta);
					
				if (result.IsValid ())
					{
					return result;
					}
			
				}
			
			}
		
		#endif
		
		}
	
	// Figure out local time zone.
	
	dng_date_time_info current_info;
	
	CurrentDateTimeAndZone (current_info);
	
	result = current_info.TimeZone ();
		
	return result;
			
	}
Beispiel #10
0
/*
 * Parse a GeneralizedTime string into a CFAbsoluteTime. Returns NULL on parse error.
 * Fractional parts of a second are discarded.
 */
CFAbsoluteTime genTimeToCFAbsTime(
	const CSSM_DATA *strData)
{
	if((strData == NULL) || (strData->Data == NULL) || (strData->Length == 0)) {
    	return NULL_TIME;
  	}

	uint8 *timeStr = strData->Data;
	size_t timeStrLen = strData->Length;

  	/* tolerate NULL terminated or not */
  	if(timeStr[timeStrLen - 1] == '\0') {
  		timeStrLen--;
  	}

	/* start with a fresh editable copy */
	uint8 *str = (uint8 *)malloc(timeStrLen);
	uint32 strLen = 0;

	/*
	 * If there is a decimal point, strip it and all trailing digits off
	 */
	const uint8 *inCp = timeStr;
	uint8 *outCp = str;
	int foundDecimal = 0;
	int minutesOffset = 0;
	int hoursOffset = 0;
	bool minusOffset = false;
	bool isGMT = false;
	size_t toGo = timeStrLen;

	do {
		if(*inCp == '.') {
			if(foundDecimal) {
				/* only legal once */ {
					free(str);
					return NULL_TIME;
				}
			}
			foundDecimal++;

			/* skip the decimal point... */
			inCp++;
			toGo--;
			if(toGo == 0) {
				/* all done */
				break;
			}
			/* then all subsequent contiguous digits */
			while(isdigit(*inCp) && (toGo != 0)) {
				inCp++;
				toGo--;
			}
		}	/* decimal point processing */
		else if((*inCp == '+') || (*inCp == '-')) {
			/* Time zone offset - handle 2 or 4 chars */
			if((toGo != 2) & (toGo != 4)) {
				free(str);
				return NULL_TIME;
			}
			if(*inCp == '-') {
				minusOffset = true;
			}
			inCp++;
			hoursOffset = (10 * (inCp[0] - '0')) + (inCp[1] - '0');
			toGo -= 2;
			if(toGo) {
				minutesOffset = (10 * (inCp[0] - '0')) + (inCp[1] - '0');
				toGo -= 2;
			}
		}
		else {
			*outCp++ = *inCp++;
			strLen++;
			toGo--;
		}
	} while(toGo != 0);

	if(str[strLen - 1] == 'Z') {
		isGMT = true;
		strLen--;
	}

	CFAbsoluteTime absTime;
	absTime = parseGenTime(str, strLen);
	free(str);
	if(absTime == NULL_TIME) {
		return NULL_TIME;
	}

	/* post processing needed? */
	if(isGMT) {
		/* Nope, string was in GMT */
		return absTime;
	}
	if((minutesOffset != 0) || (hoursOffset != 0)) {
		/* string contained explicit offset from GMT */
		if(minusOffset) {
			absTime -= (minutesOffset * 60);
			absTime -= (hoursOffset * 3600);
		}
		else {
			absTime += (minutesOffset * 60);
			absTime += (hoursOffset * 3600);
		}
	}
	else {
		/* implciit offset = local */
		CFTimeInterval tzDelta;
		CFTimeZoneRef localZone = CFTimeZoneCopySystem();
		tzDelta = CFTimeZoneGetSecondsFromGMT (localZone, CFAbsoluteTimeGetCurrent());
		CFRelease(localZone);
		absTime += tzDelta;
	}
	return absTime;
}
/*
 * Given a CSSM_DATA containing either a UTC-style or "generalized time"
 * time string, convert to 32-bit Mac time in seconds.
 * Returns nonzero on error. 
 */
void
TimeStringToMacLongDateTime (const CSSM_DATA &inUTCTime, sint64 &outMacDate)
{
	char 		szTemp[5];
	unsigned 	len;
	int 		isUtc;
	sint32 		x;
	sint32 		i;
	char 		*cp;

	CFGregorianDate date;
	::memset( &date, 0, sizeof(date) );

	if ((inUTCTime.Data == NULL) || (inUTCTime.Length == 0))
    {
    	MacOSError::throwMe(paramErr);
  	}

  	/* tolerate NULL terminated or not */
  	len = inUTCTime.Length;
  	if (inUTCTime.Data[len - 1] == '\0')
  		len--;

  	switch(len)
    {
  		case UTC_TIME_STRLEN:			// 2-digit year, not Y2K compliant
  			isUtc = 1;
  			break;
  		case GENERALIZED_TIME_STRLEN:	// 4-digit year
  			isUtc = 0;
  			break;
  		default:						// unknown format 
            MacOSError::throwMe(paramErr);
  	}

  	cp = (char *)inUTCTime.Data;
  	
	/* check that all characters except last are digits */
    for(i=0; i<(sint32)(len - 1); i++) {
		if ( !(isdigit(cp[i])) ) {
            MacOSError::throwMe(paramErr);
		}
	}

  	/* check last character is a 'Z' */
  	if(cp[len - 1] != 'Z' )	{
        MacOSError::throwMe(paramErr);
  	}

  	/* YEAR */
	szTemp[0] = *cp++;
	szTemp[1] = *cp++;
	if(!isUtc) {
		/* two more digits */
		szTemp[2] = *cp++;
		szTemp[3] = *cp++;
		szTemp[4] = '\0';
	}
	else { 
		szTemp[2] = '\0';
	}
	x = atoi( szTemp );
	if(isUtc) {
		/* 
		 * 2-digit year. 
		 *   0  <= year <= 50 : assume century 21
		 *   50 <  year <  70 : illegal per PKIX
		 *   70 <  year <= 99 : assume century 20
		 */
		if(x <= 50) {
			x += 100;
		}
		else if(x < 70) {
            MacOSError::throwMe(paramErr);
		}
		/* else century 20, OK */

		/* bug fix... we need to end up with a 4-digit year! */
		x += 1900;
	}
  	/* by definition - tm_year is year - 1900 */
  	//tmp->tm_year = x - 1900;
  	date.year = x;

  	/* MONTH */
	szTemp[0] = *cp++;
	szTemp[1] = *cp++;
	szTemp[2] = '\0';
	x = atoi( szTemp );
	/* in the string, months are from 1 to 12 */
	if((x > 12) || (x <= 0)) {
        MacOSError::throwMe(paramErr);
	}
	/* in a tm, 0 to 11 */
  	//tmp->tm_mon = x - 1;
  	date.month = x;

 	/* DAY */
	szTemp[0] = *cp++;
	szTemp[1] = *cp++;
	szTemp[2] = '\0';
	x = atoi( szTemp );
	/* 1..31 in both formats */
	if((x > 31) || (x <= 0)) {
        MacOSError::throwMe(paramErr);
	}
  	//tmp->tm_mday = x;
  	date.day = x;

	/* HOUR */
	szTemp[0] = *cp++;
	szTemp[1] = *cp++;
	szTemp[2] = '\0';
	x = atoi( szTemp );
	if((x > 23) || (x < 0)) {
        MacOSError::throwMe(paramErr);
	}
	//tmp->tm_hour = x;
	date.hour = x;

  	/* MINUTE */
	szTemp[0] = *cp++;
	szTemp[1] = *cp++;
	szTemp[2] = '\0';
	x = atoi( szTemp );
	if((x > 59) || (x < 0)) {
        MacOSError::throwMe(paramErr);
	}
  	//tmp->tm_min = x;
  	date.minute = x;

  	/* SECOND */
	szTemp[0] = *cp++;
	szTemp[1] = *cp++;
	szTemp[2] = '\0';
  	x = atoi( szTemp );
	if((x > 59) || (x < 0)) {
        MacOSError::throwMe(paramErr);
	}
  	//tmp->tm_sec = x;
  	date.second = x;

	CFTimeZoneRef timeZone = CFTimeZoneCreateWithTimeIntervalFromGMT(NULL, 0);
	CFAbsoluteTime absTime = CFGregorianDateGetAbsoluteTime(date, timeZone);
	CFRelease(timeZone);

	// Adjust abstime to local timezone
	timeZone = CFTimeZoneCopyDefault();
	absTime += CFTimeZoneGetSecondsFromGMT(timeZone, absTime);
	CFRelease(timeZone);

	outMacDate = sint64(double(absTime + kCFAbsoluteTimeIntervalSince1904));
}