number_t sub_number(number_t a, number_t b)
{
    number_t result;
    int borrow, dif, i;

    if (a.sign != b.sign) {
        b.sign *= -1;
        return add_number(a, b);
    }

    if (a.sign < 0 && b.sign < 0) {
        a.sign = b.sign = 1;
        return sub_number(b, a);
    }

    if (compare_number(a, b) < 0) {
        result = sub_number(b, a);
        if (! (result.digit_len == 2 && result.digit[0] == 0 && result.digit[1] == 0))
            result.sign = -1;
        return result;
    }

    result.sign = 1;
    result.int_len = max(a.int_len, b.int_len);
    result.digit_len = result.int_len + max(a.digit_len - a.int_len, b.digit_len - b.int_len);

    borrow = 0;
    for (i = result.digit_len - 1; i >= 0; i--) {
        dif = -borrow + digit_at(a, result.int_len - i - 1) - digit_at(b, result.int_len - i - 1);

        if (dif < 0) {
            borrow = 1;
            dif += 10;
        } else
            borrow = 0;

        result.digit[i] = dif % 10;
    }
    return remove_zeros(result);
}
number_t add_number(number_t a, number_t b)
{
    number_t result;
    int sum, carry, i;

    if (a.sign != b.sign) {
        b.sign *= -1;
        return sub_number(a, b);
    }

    result.sign = a.sign;
    result.int_len = max(a.int_len, b.int_len) + 1;
    result.digit_len = result.int_len + max(a.digit_len - a.int_len, b.digit_len - b.int_len);

    carry = 0;
    for (i = result.digit_len - 1; i >= 0; i--) {
        sum = carry + digit_at(a, result.int_len - i - 1) + digit_at(b,	result.int_len - i - 1);
        result.digit[i] = sum % 10;
        carry = sum / 10;
    }
    return remove_zeros(result);
}
/**
 * time_from_isodate:
 * @str: Date/time value in ISO 8601 format.
 *
 * Converts an ISO 8601 UTC time string into a time_t value.
 *
 * Return value: Time_t corresponding to the specified ISO string.
 * Note that we only allow UTC times at present.
 **/
time_t
time_from_isodate (const char *str)
{
	struct icaltimetype tt = icaltime_null_time ();
	icaltimezone *utc_zone;
	int len, i;

	g_return_val_if_fail (str != NULL, -1);

	/* yyyymmdd[Thhmmss[Z]] */

	len = strlen (str);

	if (!(len == 8 || len == 15 || len == 16))
		return -1;

	for (i = 0; i < len; i++)
		if (!((i != 8 && i != 15 && isdigit (str[i]))
		      || (i == 8 && str[i] == 'T')
		      || (i == 15 && str[i] == 'Z')))
			return -1;

#define digit_at(x,y) (x[y] - '0')

	tt.year = digit_at (str, 0) * 1000
		+ digit_at (str, 1) * 100
		+ digit_at (str, 2) * 10
		+ digit_at (str, 3);

	tt.month = digit_at (str, 4) * 10
		 + digit_at (str, 5);

	tt.day = digit_at (str, 6) * 10
	       + digit_at (str, 7);

	if (len > 8) {
		tt.hour = digit_at (str, 9) * 10
			+ digit_at (str, 10);
		tt.minute  = digit_at (str, 11) * 10
			   + digit_at (str, 12);
		tt.second  = digit_at (str, 13) * 10
			   + digit_at (str, 14);
	}

	utc_zone = icaltimezone_get_utc_timezone ();

	return icaltime_as_timet_with_zone (tt, utc_zone);
}
Exemple #4
0
time_t
time_from_isodate (char *str)
{
	struct tm my_tm;
	time_t t;

	if (strlen (str) < 14)
		return -1;
	
	my_tm.tm_year = (digit_at (str, 0) * 1000 + digit_at (str, 1) * 100 +
		digit_at (str, 2) * 10 + digit_at (str, 3)) - 1900;

	my_tm.tm_mon  = digit_at (str, 4) * 10 + digit_at (str, 5) - 1;
	my_tm.tm_mday = digit_at (str, 6) * 10 + digit_at (str, 7);
	my_tm.tm_hour = digit_at (str, 9) * 10 + digit_at (str, 10);
	my_tm.tm_min  = digit_at (str, 11) * 10 + digit_at (str, 12);
	my_tm.tm_sec  = digit_at (str, 13) * 10 + digit_at (str, 14);
	my_tm.tm_isdst = -1;
	
	t = mktime (&my_tm);

	if (str [15] == 'Z')
#if defined(HAVE_TM_GMTOFF)
		t -= my_tm.tm_gmtoff
#elsif defined(HAVE_TIMEZONE)
		t -= timezone
#endif
		;
	    
	return t;
}