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); }
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; }