50#include "icaldate_p.h"
51#include "icalerror_p.h"
60static const int days_in_year_passed_month[2][13] = {
62 {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365},
63 {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366}};
65static int icaltime_leap_days(
int y1,
int y2)
69 return (y2 / 4 - y1 / 4) - (y2 / 100 - y1 / 100) + (y2 / 400 - y1 / 400);
83static bool make_time(
const struct tm *tm,
int tzm, icaltime_t *out_time_t)
88 static const int days[] = {-1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364};
92 if (tm->tm_mon < 0 || tm->tm_mon > 11) {
96 if (tm->tm_year < 2) {
100#if (SIZEOF_ICALTIME_T == 4)
103 if (tm->tm_year > 138) {
108 if (tm->tm_year == 138) {
109 if (tm->tm_mon > 0) {
111 }
else if (tm->tm_mday > 17) {
117 if (tm->tm_year >= 8100) {
128 tim = (icaltime_t)((tm->tm_year - 70) * 365 + ((tm->tm_year - 1) / 4) - 17);
132 febs = (tm->tm_year - 100) - ((tm->tm_mon <= 1) ? 1 : 0);
138 tim += days[tm->tm_mon];
142 if ((tm->tm_year & 3) == 0 && tm->tm_mon > 1) {
152 tim = tim * 24 + tm->tm_hour;
156 tim = tim * 60 + tm->tm_min;
164 tim = tim * 60 + tm->tm_sec;
178static icaltime_t icaltime_timegm(
const struct tm *tm)
187 if (!make_time(tm, 0, NULL)) {
192 year = 1900 + tm->tm_year;
193 int idays = (365 * (year - 1970) + icaltime_leap_days(1970, year));
194 days = (icaltime_t)idays;
195 days += days_in_year_passed_month[0][tm->tm_mon];
201 days += tm->tm_mday - 1;
202 hours = days * 24 + tm->tm_hour;
203 minutes = hours * 60 + tm->tm_min;
204 seconds = minutes * 60 + tm->tm_sec;
219 memset(&t, 0,
sizeof(
struct tm));
220 if (!icalgmtime_r(&tm, &t)) {
224 tt.
year = t.tm_year + 1900;
225 tt.
month = t.tm_mon + 1;
232 tt.
zone = (zone == NULL) ? NULL : utc_zone;
262 icaltime_t t = (icaltime_t)-1;
270 memset(&stm, 0,
sizeof(
struct tm));
273 stm.tm_sec = stm.tm_min = stm.tm_hour = 0;
277 stm.tm_hour = tt.
hour;
280 stm.tm_mday = tt.
day;
281 stm.tm_mon = tt.
month - 1;
282 stm.tm_year = tt.
year - 1900;
285 if (!make_time(&stm, 0, &t)) {
286 t = ((icaltime_t)-1);
312 if (tt.
zone != utc_zone) {
317 memset(&stm, 0,
sizeof(
struct tm));
319 stm.tm_sec = local_tt.
second;
320 stm.tm_min = local_tt.
minute;
321 stm.tm_hour = local_tt.
hour;
322 stm.tm_mday = local_tt.
day;
323 stm.tm_mon = local_tt.
month - 1;
324 stm.tm_year = local_tt.
year - 1900;
327 t = icaltime_timegm(&stm);
347 snprintf(buf, size,
"%04d%02d%02d", tt.
year, tt.
month, tt.
day);
349#pragma GCC diagnostic push
350#pragma GCC diagnostic ignored "-Wformat-nonliteral"
354 fmt =
"%04d%02d%02dT%02d%02d%02dZ";
356 fmt =
"%04d%02d%02dT%02d%02d%02d";
359#pragma GCC diagnostic pop
383 if ((size == 15) || (size == 19)) {
385 }
else if ((size == 16) || (size == 20)) {
386 if ((str[size - 1] !=
'Z')) {
392 }
else if ((size == 8) || (size == 10)) {
402 if (sscanf(str,
"%04d%c%02d%c%02d",
407 if ((dsep1 !=
'-') || (dsep2 !=
'-')) {
410 }
else if (sscanf(str,
"%04d%02d%02d", &tt.
year, &tt.
month, &tt.
day) < 3) {
415 char dsep1, dsep2, tsep, tsep1, tsep2;
417 if (sscanf(str,
"%04d%c%02d%c%02d%c%02d%c%02d%c%02d",
424 (dsep1 !=
'-') || (dsep2 !=
'-') ||
425 (tsep1 !=
':') || (tsep2 !=
':')) {
432 if (sscanf(str,
"%04d%02d%02d%c%02d%02d%02d",
454 return (
year % 4 == 0);
456 return ((
year % 4 == 0) && (
year % 100 != 0)) || (
year % 400 == 0);
469static const int _days_in_month[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
487 days = _days_in_month[
month];
501 memset(&jt, 0,
sizeof(UTinstantInt));
509 return jt.weekday + 1;
517 memset(&jt, 0,
sizeof(UTinstantInt));
526 delta = jt.weekday - (fdow - 1);
530 return jt.day_of_year - delta;
537 return days_in_year_passed_month[is_leap][t.
month - 1] + t.
day;
543 unsigned int is_leap;
554 doy += days_in_year_passed_month[is_leap][12];
555 }
else if (doy > days_in_year_passed_month[is_leap][12]) {
558 doy -= days_in_year_passed_month[is_leap][12];
565 if (doy > days_in_year_passed_month[is_leap][
month]) {
567 tt.
day = doy - days_in_year_passed_month[is_leap][
month];
608 t.
day < 0 || t.
day > 31 ||
642 if (a_is_valid && !b_is_valid) {
671 }
else if (a.
day > b.
day) {
673 }
else if (a.
day < b.
day) {
727 }
else if (a.
day < b.
day) {
757 }
else if (a.
day < b.
day) {
765 const int days,
const int hours,
766 const int minutes,
const int seconds)
769 int minutes_overflow, hours_overflow, days_overflow = 0, years_overflow;
784 minutes_overflow =
second / 60;
793 hours_overflow =
minute / 60;
800 hour = tt->
hour + hours + hours_overflow;
802 days_overflow =
hour / 24;
812 if (tt->
month >= 13) {
813 years_overflow = (tt->
month - 1) / 12;
814 tt->
year += years_overflow;
815 tt->
month -= years_overflow * 12;
816 }
else if (tt->
month <= 0) {
818 years_overflow = (tt->
month / 12) - 1;
819 tt->
year += years_overflow;
820 tt->
month -= years_overflow * 12;
824 day = tt->
day + days + days_overflow;
828 if (
day <= days_in_month) {
833 if (tt->
month >= 13) {
838 day -= days_in_month;
842 if (tt->
month == 1) {
864 if (tt.zone ==
zone) {
869 if (tt.zone != NULL) {
885 if (t.
zone != NULL) {
void icalerror_set_errno(icalerrorenum x)
Sets the icalerrno to a given error.
Error handling for libical.
@ ICAL_MALFORMEDDATA_ERROR
void * icalmemory_new_buffer(size_t size)
Creates new buffer with the specified size.
void icalmemory_add_tmp_buffer(void *buf)
Adds an externally allocated buffer to the ring.
Common memory management routines.
struct icaltimetype icaltime_from_timet_with_zone(const icaltime_t tm, const bool is_date, const icaltimezone *zone)
Constructor.
bool icaltime_is_date(const struct icaltimetype t)
struct icaltimetype icaltime_from_string(const char *str)
const char * icaltime_get_tzid(const struct icaltimetype t)
struct icaltimetype icaltime_current_time_with_zone(const icaltimezone *zone)
int icaltime_day_of_year(const struct icaltimetype t)
int icaltime_start_doy_week(const struct icaltimetype t, int fdow)
bool icaltime_is_leap_year(const int year)
const icaltimezone * icaltime_get_timezone(const struct icaltimetype t)
int icaltime_day_of_week(const struct icaltimetype t)
struct icaltimetype icaltime_from_day_of_year(const int _doy, const int _year)
struct icaltimetype icaltime_today(void)
Convenience constructor.
struct icaltimetype icaltime_null_date(void)
bool icaltime_is_valid_time(const struct icaltimetype t)
const char * icaltime_as_ical_string(const struct icaltimetype tt)
int icaltime_days_in_month(const int month, const int year)
bool icaltime_is_utc(const struct icaltimetype t)
struct icaltimetype icaltime_convert_to_zone(const struct icaltimetype tt, icaltimezone *zone)
int icaltime_compare_date_only(const struct icaltimetype a_in, const struct icaltimetype b_in)
int icaltime_days_in_year(const int year)
bool icaltime_is_null_time(const struct icaltimetype t)
icaltime_t icaltime_as_timet_with_zone(const struct icaltimetype tt, const icaltimezone *zone)
struct icaltimetype icaltime_normalize(const struct icaltimetype tt)
icaltime_t icaltime_as_timet(const struct icaltimetype tt)
int icaltime_compare(const struct icaltimetype a_in, const struct icaltimetype b_in)
struct icaltimetype icaltime_set_timezone(struct icaltimetype *t, const icaltimezone *zone)
void icaltime_adjust(struct icaltimetype *tt, const int days, const int hours, const int minutes, const int seconds)
struct icaltimetype icaltime_null_time(void)
int icaltime_compare_date_only_tz(const struct icaltimetype a_in, const struct icaltimetype b_in, icaltimezone *tz)
char * icaltime_as_ical_string_r(const struct icaltimetype tt)
Defines the data structure for representing date-times.
struct icaltimetype icaltime_from_timet_with_zone(const icaltime_t tm, const bool is_date, const icaltimezone *zone)
Constructor.
bool icaltime_is_leap_year(const int year)
struct icaltimetype icaltime_null_date(void)
void icaltime_adjust(struct icaltimetype *tt, const int days, const int hours, const int minutes, const int seconds)
const char * icaltimezone_get_tzid(icaltimezone *zone)
icaltimezone * icaltimezone_get_utc_timezone(void)
void icaltimezone_convert_time(struct icaltimetype *tt, icaltimezone *from_zone, icaltimezone *to_zone)
Timezone handling routines.
struct _icaltimezone icaltimezone
const icaltimezone * zone