示例#1
0
/*----------------------------------------------------------------------------------------------
	Core routine to map between local and Utc. This assumes that DST doesn't kick in
	near a year boundary so that when the switch happens, the DST and STD times are in the
	same year.
----------------------------------------------------------------------------------------------*/
int64 TimeMapper::MapMsec(int64 msecSrc, bool fToUtc)
{
	int64 msecT;
	int msecDay;
	int day;
	int dayMin;
	int dyear;
	int yday;
	int yt;
	int ymin;

	// First determines the year type and minute within the year.

	// Mod to 400 year period.
	msecT = ModPos(msecSrc, kmsecPerPeriod);

	// Find the day within the 400 year period.
	day = (int)(msecT / kmsecPerDay);
	Assert(0 <= day && day < kdayPerPeriod);

	// Get the time within the day.
	msecDay = (int)(msecT - day * (int64)kmsecPerDay);
	Assert(0 <= msecDay && msecDay < kmsecPerDay);

	// Find the year within the 400 year period (dyear) and the day within that year (yday).
	Assert(0 <= day && day < 146097);
	dyear = YearFromDayInPeriod(day, &yday);
	Assert(0 <= dyear && dyear < 400);
	Assert(0 <= yday && (yday < 365 || yday == 365 && SilTime::IsLeapYear(dyear + kyearBase)));

	// Calculate the day number (within the 400 year period) of the first day of
	// the year (dayMin).
	dayMin = day - yday;
	Assert(dayMin == DayFromYearInPeriod(dyear));

	// Get the year type. kdayMonday is used because T0 is a Monday.
	yt = ModPos(dayMin + kwdayMonday, kdayPerWeek);
	if (SilTime::IsLeapYear(dyear + kyearBase))
		yt += kdayPerWeek;

	// Calculate the minute within the year.
	ymin = yday * kminPerDay + msecDay / kmsecPerMin;

	if (!fToUtc)
	{
		// Mapping from utc to local.
		if (m_rgyminMin[yt] <= ymin && ymin < m_rgyminLim[yt])
			return msecSrc + Mul(m_dminTz2, kmsecPerMin);
		return msecSrc + Mul(m_dminTz1, kmsecPerMin);
	}

	// The overlap is always ambiguous and there's nothing we can do about it.
	ymin -= m_dminTz2;
	if (m_rgyminMin[yt] <= ymin && ymin < m_rgyminLim[yt])
		return msecSrc - Mul(m_dminTz2, kmsecPerMin);
	return msecSrc - Mul(m_dminTz1, kmsecPerMin);
}
示例#2
0
/*----------------------------------------------------------------------------------------------
	Fill in the SilTimeInfo structure from this time.
----------------------------------------------------------------------------------------------*/
void SilTime::GetTimeInfo(SilTimeInfo * psti, bool fUtc) const
{
    AssertPtr(psti);

    int dyear;
    int day;
    int msecDay;
    int yday;
    int64 msec = m_msec;

    if (!fUtc)
        msec = g_tmm.ToLcl(msec);

    // Decompose m_msec into which 400 year period it is in (relative to T0) and
    // the millisecond within the 400 year period.
    psti->year = (int)FloorDiv(msec, kmsecPerPeriod) * kyearPerPeriod + kyearBase;
    msec = ModPos(msec, kmsecPerPeriod);
    Assert(0 <= 0 && msec < kmsecPerPeriod);

    // Find the day within the 400 year period.
    day = (int)(msec / kmsecPerDay);
    Assert(0 <= day && day < kdayPerPeriod);

    // Get the time within the day.
    msecDay = (int)(msec - day * (int64)kmsecPerDay);
    Assert(0 <= msecDay && msecDay < kmsecPerDay);

    // Find the year within the 400 year period (dyear) and the day within that year (yday).
    Assert(0 <= day && day < 146097);
    dyear = YearFromDayInPeriod(day, &yday);
    Assert(0 <= dyear && dyear < 400);
    Assert(0 <= yday && (yday < 365 || yday == 365 && SilTime::IsLeapYear(dyear + kyearBase)));

    // Add dyear into the year.
    psti->year += dyear;

    // Find the month and day in the month.
    const int * prgday = g_rgyday[IsLeapYear(psti->year)];
    for (psti->ymon = 1; yday >= prgday[psti->ymon]; psti->ymon++)
        ;
    psti->mday = yday - prgday[psti->ymon - 1] + 1;

    // Calculate the week day.
    // kdayMonday is used because T0 is a Monday. Note that kdayPerPeriod is divisible by 7
    // so we don't have to adjust the day of the week.
    psti->wday = ModPos(day + kwdayMonday, kdayPerWeek);

    // Fill in the time.
    psti->hour = msecDay / kmsecPerHour;
    psti->min = (msecDay % kmsecPerHour) / kmsecPerMin;
    psti->sec = (msecDay % kmsecPerMin) / kmsecPerSec;
    psti->msec = msecDay % kmsecPerSec;
}