예제 #1
0
static timelib_sll do_years(timelib_sll year)
{
	timelib_sll i;
	timelib_sll res = 0;
	timelib_sll eras;

	eras = (year - 1970) / 40000;
	if (eras != 0) {
		year = year - (eras * 40000);
		res += (SECS_PER_ERA * eras * 100);
	}

	if (year >= 1970) {
		for (i = year - 1; i >= 1970; i--) {
			if (timelib_is_leap(i)) {
				res += (DAYS_PER_LYEAR * SECS_PER_DAY);
			} else {
				res += (DAYS_PER_YEAR * SECS_PER_DAY);
			}
		}
	} else {
		for (i = 1969; i >= year; i--) {
			if (timelib_is_leap(i)) {
				res -= (DAYS_PER_LYEAR * SECS_PER_DAY);
			} else {
				res -= (DAYS_PER_YEAR * SECS_PER_DAY);
			}
		}
	}
	return res;
}
예제 #2
0
static int do_range_limit_days_relative(timelib_sll *base_y, timelib_sll *base_m, timelib_sll *y, timelib_sll *m, timelib_sll *d)
{
	timelib_sll leapyear;
	timelib_sll days_this_month;
	timelib_sll next_month, next_year;
	timelib_sll days_next_month;

	do_range_limit(1, 13, 12, base_m, base_y);

	leapyear = timelib_is_leap(*base_y);
	days_this_month = leapyear ? days_in_month_leap[*base_m] : days_in_month[*base_m];
	next_month = (*base_m) + 1;

	if (next_month > 12) {
		next_month -= 12;
		next_year = (*base_y) + 1;
	} else {
		next_year = (*base_y);
	}
	leapyear = timelib_is_leap(next_year);
	days_next_month = leapyear ? days_in_month_leap[next_month] : days_in_month[next_month];

	if (*d < 0) {
		*d += days_this_month;
		(*m)--;
		return 1;
	}
	if (*d > days_next_month) {
		*d -= days_next_month;
		(*m)++;
		return 1;
	}
	return 0;
}
예제 #3
0
timelib_t timelib_make(struct timelib_tm * timeinfo)
{
	int i;
	timelib_t tstamp;

	// Compute the number of seconds since the year 1970 to the begining of
	// the given year on the structure, add to the output value
	tstamp = timeinfo->tm_year * (TIMELIB_SECS_PER_DAY * 365);
	// Add the seconds corresponding to leap years (add extra days)
	for (i = 0; i < timeinfo->tm_year; i++) {
		if (timelib_is_leap(i + 1970))
			tstamp += (timelib_t) TIMELIB_SECS_PER_DAY;
	}
	// Add seconds for the months elapsed
	for (i = 1; i < timeinfo->tm_mon; i++) {
		if (i == 2 && timelib_is_leap(timeinfo->tm_year + 1970))
			tstamp += (timelib_t) TIMELIB_SECS_PER_DAY * 29;
		else
			tstamp += (timelib_t) TIMELIB_SECS_PER_DAY * month_length[i - 1];
	}
	// Add seconds for past days
	tstamp += (timelib_t) (timeinfo->tm_mday - 1) * (timelib_t) TIMELIB_SECS_PER_DAY;
	// Add seconds on this day
	tstamp += (timelib_t) timeinfo->tm_hour * (timelib_t) TIMELIB_SECS_PER_HOUR;
	tstamp += (timelib_t) timeinfo->tm_min * (timelib_t) TIMELIB_SECS_PER_MINUTE;
	tstamp += (timelib_t) timeinfo->tm_sec;

	return tstamp;
}
예제 #4
0
void timelib_break(timelib_t timeinput, struct timelib_tm * timeinfo)
{
	uint8_t year;
	uint8_t month, monthLength;
	uint32_t time;
	unsigned long days;

	time = (uint32_t) timeinput;
	timeinfo->tm_sec = time % 60;

	time /= 60; // now it is minutes
	timeinfo->tm_min = time % 60;

	time /= 60; // now it is hours
	timeinfo->tm_hour = time % 24;

	time /= 24; // now it is days
	timeinfo->tm_wday = ((time + 4) % 7) + 1; // Sunday is day 1

	year = 0;
	days = 0;
	while ((unsigned) (days += (timelib_is_leap(1970 + year) ? 366 : 365)) <= time)
		year++;

	timeinfo->tm_year = year; // year is offset from 1970

	days -= timelib_is_leap(1970 + year) ? 366 : 365;
	time -= days; // now it is days in this year, starting at 0

	days = 0;
	month = 0;
	monthLength = 0;
	for (month = 0; month < 12; month++) {
		// Check
		if (month == 1) {
			if (timelib_is_leap(1970 + year)) {
				monthLength = 29;
			} else {
				monthLength = 28;
			}
		} else {
			monthLength = month_length[month];
		}

		if (time >= monthLength) {
			time -= monthLength;
		} else {
			break;
		}
	}
	timeinfo->tm_mon = month + 1; // jan is month 1
	timeinfo->tm_mday = time + 1; // day of month
}
예제 #5
0
파일: dow.c 프로젝트: vpj/PHP-Extension-API
void timelib_isoweek_from_date(timelib_sll y, timelib_sll m, timelib_sll d, timelib_sll *iw, timelib_sll *iy)
{
	int y_leap, prev_y_leap, doy, jan1weekday, weekday;

	y_leap = timelib_is_leap(y);
	prev_y_leap = timelib_is_leap(y-1);
	doy = timelib_day_of_year(y, m, d) + 1;
	if (y_leap && m > 2) {
		doy++;
	}
	jan1weekday = timelib_day_of_week(y, 1, 1);
	weekday = timelib_day_of_week(y, m, d);
	if (weekday == 0) weekday = 7;
	if (jan1weekday == 0) jan1weekday = 7;
	/* Find if Y M D falls in YearNumber Y-1, WeekNumber 52 or 53 */
	if (doy <= (8 - jan1weekday) && jan1weekday > 4) {
		*iy = y - 1;
		if (jan1weekday == 5 || (jan1weekday == 6 && prev_y_leap)) {
			*iw = 53;
		} else {
			*iw = 52;
		}
	} else {
		*iy = y;
	}
	/* 8. Find if Y M D falls in YearNumber Y+1, WeekNumber 1 */
	if (*iy == y) {
		int i;

		i = y_leap ? 366 : 365;
		if ((i - (doy - y_leap)) < (4 - weekday)) {
			*iy = y + 1;
			*iw = 1;
			return;
		}
	}
	/* 9. Find if Y M D falls in YearNumber Y, WeekNumber 1 through 53 */
	if (*iy == y) {
		int j;

		j = doy + (7 - weekday) + (jan1weekday - 1);
		*iw = j / 7;
		if (jan1weekday > 4) {
			*iw -= 1;
		}
	}
}
예제 #6
0
static timelib_sll do_months(timelib_ull month, timelib_ull year)
{
	if (timelib_is_leap(year)) {
		return ((month_tab_leap[month - 1] + 1) * SECS_PER_DAY);
	} else {
		return ((month_tab[month - 1]) * SECS_PER_DAY);
	}
}
예제 #7
0
static void do_range_limit_days_relative(timelib_sll *base_y, timelib_sll *base_m, timelib_sll *y, timelib_sll *m, timelib_sll *d, timelib_sll invert)
{
	timelib_sll leapyear;
	timelib_sll month, year;
	timelib_sll days;

	do_range_limit(1, 13, 12, base_m, base_y);

	year = *base_y;
	month = *base_m;

/*
	printf( "S: Y%d M%d   %d %d %d   %d\n", year, month, *y, *m, *d, days);
*/
	if (!invert) {
		while (*d < 0) {
			dec_month(&year, &month);
			leapyear = timelib_is_leap(year);
			days = leapyear ? days_in_month_leap[month] : days_in_month[month];

			/* printf( "I  Y%d M%d   %d %d %d   %d\n", year, month, *y, *m, *d, days); */

			*d += days;
			(*m)--;
		}
	} else {
		while (*d < 0) {
			leapyear = timelib_is_leap(year);
			days = leapyear ? days_in_month_leap[month] : days_in_month[month];

			/* printf( "I  Y%d M%d   %d %d %d   %d\n", year, month, *y, *m, *d, days); */

			*d += days;
			(*m)--;
			inc_month(&year, &month);
		}
	}
	/*
	printf( "E: Y%d M%d   %d %d %d   %d\n", year, month, *y, *m, *d, days);
	*/
}
예제 #8
0
static int do_range_limit_days(timelib_sll *y, timelib_sll *m, timelib_sll *d)
{
	timelib_sll leapyear;
	timelib_sll days_this_month;
	timelib_sll last_month, last_year;
	timelib_sll days_last_month;
	
	/* can jump an entire leap year period quickly */
	if (*d >= DAYS_PER_LYEAR_PERIOD || *d <= -DAYS_PER_LYEAR_PERIOD) {
		*y += YEARS_PER_LYEAR_PERIOD * (*d / DAYS_PER_LYEAR_PERIOD);
		*d -= DAYS_PER_LYEAR_PERIOD * (*d / DAYS_PER_LYEAR_PERIOD);
	}

	do_range_limit(1, 13, 12, m, y);

	leapyear = timelib_is_leap(*y);
	days_this_month = leapyear ? days_in_month_leap[*m] : days_in_month[*m];
	last_month = (*m) - 1;

	if (last_month < 1) {
		last_month += 12;
		last_year = (*y) - 1;
	} else {
		last_year = (*y);
	}
	leapyear = timelib_is_leap(last_year);
	days_last_month = leapyear ? days_in_month_leap[last_month] : days_in_month[last_month];

	if (*d <= 0) {
		*d += days_last_month;
		(*m)--;
		return 1;
	}
	if (*d > days_this_month) {
		*d -= days_this_month;
		(*m)++;
		return 1;
	}
	return 0;
}
예제 #9
0
파일: dow.c 프로젝트: 0x1111/php-src
static timelib_sll timelib_day_of_week_ex(timelib_sll y, timelib_sll m, timelib_sll d, int iso)
{
	timelib_sll c1, y1, m1, dow;

	/* Only valid for Gregorian calendar, commented out as we don't handle
	 * Julian calendar. We just return the 'wrong' day of week to be
	 * consistent. */
	c1 = century_value(y / 100);
	y1 = (y % 100);
	m1 = timelib_is_leap(y) ? m_table_leap[m] : m_table_common[m];
	dow = (c1 + y1 + m1 + (y1 / 4) + d) % 7;
	if (iso) {
		if (dow == 0) {
			dow = 7;
		}
	}
	return dow;
}
예제 #10
0
파일: dow.c 프로젝트: vpj/PHP-Extension-API
timelib_sll timelib_days_in_month(timelib_sll y, timelib_sll m)
{
	return timelib_is_leap(y) ? ml_table_leap[m] : ml_table_common[m];
}
예제 #11
0
파일: dow.c 프로젝트: vpj/PHP-Extension-API
timelib_sll timelib_day_of_year(timelib_sll y, timelib_sll m, timelib_sll d)
{
	return (timelib_is_leap(y) ? d_table_leap[m] : d_table_common[m]) + d - 1;
}