Esempio n. 1
0
File: date.c Progetto: Brian1176/git
/* Gr. strptime is crap for this; it doesn't have a way to require RFC2822
   (i.e. English) day/month names, and it doesn't work correctly with %z. */
int parse_date_basic(const char *date, unsigned long *timestamp, int *offset)
{
	struct tm tm;
	int tm_gmt;
	unsigned long dummy_timestamp;
	int dummy_offset;

	if (!timestamp)
		timestamp = &dummy_timestamp;
	if (!offset)
		offset = &dummy_offset;

	memset(&tm, 0, sizeof(tm));
	tm.tm_year = -1;
	tm.tm_mon = -1;
	tm.tm_mday = -1;
	tm.tm_isdst = -1;
	tm.tm_hour = -1;
	tm.tm_min = -1;
	tm.tm_sec = -1;
	*offset = -1;
	tm_gmt = 0;

	if (*date == '@' &&
	    !match_object_header_date(date + 1, timestamp, offset))
		return 0; /* success */
	for (;;) {
		int match = 0;
		unsigned char c = *date;

		/* Stop at end of string or newline */
		if (!c || c == '\n')
			break;

		if (isalpha(c))
			match = match_alpha(date, &tm, offset);
		else if (isdigit(c))
			match = match_digit(date, &tm, offset, &tm_gmt);
		else if ((c == '-' || c == '+') && isdigit(date[1]))
			match = match_tz(date, offset);

		if (!match) {
			/* BAD CRAP */
			match = 1;
		}

		date += match;
	}

	/* mktime uses local timezone */
	*timestamp = tm_to_time_t(&tm);
	if (*offset == -1) {
		time_t temp_time = mktime(&tm);
		if ((time_t)*timestamp > temp_time) {
			*offset = ((time_t)*timestamp - temp_time) / 60;
		} else {
			*offset = -(int)((temp_time - (time_t)*timestamp) / 60);
		}
	}

	if (*timestamp == -1)
		return -1;

	if (!tm_gmt)
		*timestamp -= *offset * 60;
	return 0; /* success */
}
Esempio n. 2
0
/* Gr. strptime is crap for this; it doesn't have a way to require RFC2822
   (i.e. English) day/month names, and it doesn't work correctly with %z. */
int parse_date_basic(const char *date, struct timeval *tv, int *offset)
{
	struct atm tm;
	int tm_gmt;
	int dummy_offset;

	if (!offset)
		offset = &dummy_offset;

	tm.tm_year = -1;
	tm.tm_mon = -1;
	tm.tm_mday = -1;
	tm.tm_isdst = -1;
	tm.tm_hour = -1;
	tm.tm_min = -1;
	tm.tm_sec = -1;
	tm.tm_usec = 0;
	*offset = -1;
	tm_gmt = 0;

	if (*date == '@' &&
	    !match_object_header_date(date + 1, tv, offset))
		return 0; /* success */
	for (;;) {
		int match = 0;
		unsigned char c = *date;

		/* Stop at end of string or newline */
		if (!c || c == '\n')
			break;

		if (isalpha(c))
			match = match_alpha(date, &tm, offset);
		else if (isdigit(c))
			match = match_digit(date, &tm, offset, &tm_gmt);
		else if ((c == '-' || c == '+') && isdigit(date[1]))
			match = match_tz(date, offset);

		if (!match) {
			/* BAD CRAP */
			match = 1;
		}

		date += match;
	}

	// mktime() is larger than struct atm, so it can clobber usec
	tv->tv_usec = tm.tm_usec;

	/* mktime uses local timezone */
	tv->tv_sec = tm_to_time_t(&tm);
	if (*offset == -1)
		*offset = (((time_t)tv->tv_sec) - mktime((struct tm*)&tm)) / 60;

	if (tv->tv_sec == -1)
		return -1;

	if (!tm_gmt)
		tv->tv_sec -= *offset * 60;

	return 0; /* success */
}