Esempio n. 1
0
echs_instant_t
echs_instant_add(echs_instant_t bas, echs_idiff_t add)
{
	echs_instant_t res;
	int dd = add.dd;
	int msd = add.msd;
	int df_y;
	int df_m;

	res.y = bas.y + dd / 365;
	if ((df_y = res.y - bas.y)) {
		dd -= df_y * 365 + (df_y - 1) / 4;
	}

	res.m = bas.m + dd / 31;
	if ((df_m = res.m - bas.m)) {
		dd -= doy[bas.m + df_m] - doy[bas.m + 1];
	}

	res.d = bas.d + dd;

	if (echs_instant_all_day_p(bas)) {
		res.H = ECHS_ALL_DAY;
		res.M = 0U;
		res.S = 0U;
		res.ms = 0U;
		goto out;
	} else if (msd < 0) {
		res.d--;
		msd += 86400000;
	}

	if (echs_instant_all_sec_p(bas)) {
		res.ms = ECHS_ALL_SEC;
		msd /= 1000;
	} else {
		int carry = (bas.ms + msd) / 1000;
		res.ms = (bas.ms + msd) % 1000;
		msd /= 1000;
		msd += carry;
	}
	{
		int carry = (bas.S + msd) / 60;
		res.S = (bas.S + msd) % 60;
		msd /= 60;
		msd += carry;
	}
	res.M = bas.M + msd % 60;
	msd /= 60;
	res.H = bas.H + msd % 24;
	msd /= 24;

	res.d += msd;
out:
	return echs_instant_fixup(res);
}
Esempio n. 2
0
echs_instant_t
echs_instant_add(echs_instant_t bas, echs_idiff_t add)
{
	echs_instant_t res = bas;
	int dd = add.d / (int)MSECS_PER_DAY;
	int msd = add.d % (int)MSECS_PER_DAY;
	int car, cdr;

	if (UNLIKELY(echs_instant_all_day_p(bas))) {
		/* just fix up the day, dom and year portion */
		goto fixup_d;
	} else if (UNLIKELY(echs_instant_all_sec_p(bas))) {
		/* just fix up the sec, min, ... portions */
		msd /= (int)MSECS_PER_SEC;
		goto fixup_S;
	}

	car = (res.ms + msd) / (int)MSECS_PER_SEC;
	if ((cdr = (res.ms + msd) % (int)MSECS_PER_SEC) >= 0) {
		res.ms = cdr;
	} else {
		res.ms = cdr + MSECS_PER_SEC;
		car--;
	}
	msd = car;
fixup_S:
	car = (res.S + msd) / (int)SECS_PER_MIN;
	if ((cdr = (res.S + msd) % (int)SECS_PER_MIN) >= 0) {
		res.S = cdr;
	} else {
		res.S = cdr + SECS_PER_MIN;
		car--;
	}
	msd = car;

	car = ((int)res.M + msd) / (int)MINS_PER_HOUR;
	if ((cdr = ((int)res.M + msd) % (int)MINS_PER_HOUR) >= 0) {
		res.M = cdr;
	} else {
		res.M = cdr + MINS_PER_HOUR;
		car--;
	}
	msd = car;

	car = (res.H + msd) / (int)HOURS_PER_DAY;
	if ((cdr = (res.H + msd) % (int)HOURS_PER_DAY) >= 0) {
		res.H = cdr;
	} else {
		res.H = cdr + HOURS_PER_DAY;
		car--;
	}
	msd = car;

	/* get ready to adjust the day */
	if (UNLIKELY(msd)) {
		dd += msd;
	}
	if (dd) {
		int y;
		int m;
		int d;

	fixup_d:
		y = bas.y;
		m = bas.m;
		d = bas.d + dd;

		if (LIKELY(d >= 1 && d <= 28)) {
			/* all months in our design range have 28 days */
			;
		} else if (d < 1) {
			int mdays;

			do {
				if (UNLIKELY(--m < 1)) {
					--y;
					m = 12;
				}
				mdays = __get_mdays(y, m);
				d += mdays;
			} while (d < 1);

		} else {
			int mdays;

			while (d > (mdays = __get_mdays(y, m))) {
				d -= mdays;
				if (UNLIKELY(++m > 12)) {
					++y;
					m = 1;
				}
			}
		}

		res.d = d;
		res.m = m;
		res.y = y;
	}
	return res;
}
Esempio n. 3
0
echs_instant_t
echs_instant_fixup(echs_instant_t e)
{
/* this is basically __ymd_fixup_d of dateutils
 * we only care about additive cockups though because instants are
 * chronologically ascending */
	unsigned int md;

	if (UNLIKELY(echs_instant_all_day_p(e))) {
		/* just fix up the day, dom and year portion */
		goto fixup_d;
	} else if (UNLIKELY(echs_instant_all_sec_p(e))) {
		/* just fix up the sec, min, ... portions */
		goto fixup_S;
	}

	if (UNLIKELY(e.ms >= MSECS_PER_SEC)) {
		unsigned int dS = e.ms / MSECS_PER_SEC;
		unsigned int ms = e.ms % MSECS_PER_SEC;

		e.ms = ms;
		e.S += dS;
	}

fixup_S:
	if (UNLIKELY(e.S >= SECS_PER_MIN)) {
		/* leap seconds? */
		unsigned int dM = e.S / SECS_PER_MIN;
		unsigned int S = e.S % SECS_PER_MIN;

		e.S = S;
		e.M += dM;
	}
	if (UNLIKELY(e.M >= MINS_PER_HOUR)) {
		unsigned int dH = e.M / MINS_PER_HOUR;
		unsigned int M = e.M % MINS_PER_HOUR;

		e.M = M;
		e.H += dH;
	}
	if (UNLIKELY(e.H >= HOURS_PER_DAY)) {
		unsigned int dd = e.H / HOURS_PER_DAY;
		unsigned int H = e.H % HOURS_PER_DAY;

		e.H = H;
		e.d += dd;
	}

fixup_d:
refix_ym:
	if (UNLIKELY(e.m > 12U)) {
		unsigned int dy = (e.m - 1) / 12U;
		unsigned int m = (e.m - 1) % 12U + 1U;

		e.m = m;
		e.y += dy;
	}

	if (UNLIKELY(e.d > (md = __get_mdays(e.y, e.m)))) {
		e.d -= md;
		e.m++;
		goto refix_ym;
	}
	return e;
}
Esempio n. 4
0
echs_instant_t
echs_instant_fixup(echs_instant_t e)
{
/* this is basically __ymd_fixup_d of dateutils
 * we only care about additive cockups though because instants are
 * chronologically ascending */
	static const unsigned int mdays[] = {
		0U, 31U, 28U, 31U, 30U, 31U, 30U, 31U, 31U, 30U, 31U, 30U, 31U,
	};
	unsigned int md;

	if (UNLIKELY(echs_instant_all_day_p(e))) {
		/* just fix up the day, dom and year portion */
		goto fixup_d;
	}

	if (UNLIKELY(e.S >= 60U)) {
		/* leap seconds? */
		unsigned int dM = e.S / 60U;
		unsigned int S = e.S % 60U;

		e.S = S;
		e.M += dM;
	}
	if (UNLIKELY(e.M >= 60U)) {
		unsigned int dH = e.M / 60U;
		unsigned int M = e.M % 60U;

		e.M = M;
		e.H += dH;
	}
	if (UNLIKELY(e.H >= 24U)) {
		unsigned int dd = e.H / 24U;
		unsigned int H = e.H % 24U;

		e.H = H;
		e.d += dd;
	}

fixup_d:
	if (UNLIKELY((int32_t)e.d <= 0)) {
		e.m--;
	}
refix_ym:
	if (UNLIKELY((int32_t)e.m <= 0)) {
		unsigned int m = (e.m + 11) % 12U + 1U;

		e.m = m;
		e.y--;
	} else if (UNLIKELY(e.m > 12U)) {
		unsigned int dy = (e.m - 1) / 12U;
		unsigned int m = (e.m - 1) % 12U + 1U;

		e.m = m;
		e.y += dy;
	}

	if (UNLIKELY((int32_t)e.d <= 0)) {
		/* at least e.m should be fixed up now */
		e.d += mdays[e.m];
		/* leap year handling */
		if (UNLIKELY(e.m == 2U && (e.y % 4U) == 0U)) {
			e.d++;
		}
	} else if (UNLIKELY(e.d > (md = mdays[e.m]))) {
		/* leap year handling */
		if (UNLIKELY(e.m == 2U && (e.y % 4U) == 0U)) {
			md++;
		}
		if (LIKELY((e.d -= md) > 0)) {
			e.m++;
			goto refix_ym;
		}
	}
	return e;
}