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) {
109 if (tm->tm_year == 138 &&
112 (tm->tm_mday == 19 &&
116 (tm->tm_min == 14 && tm->tm_sec > 7))))))) {
122 if (tm->tm_year >= 8100) {
133 tim = (icaltime_t)((tm->tm_year - 70) * 365 + ((tm->tm_year - 1) / 4) - 17);
137 febs = (tm->tm_year - 100) - ((tm->tm_mon <= 1) ? 1 : 0);
143 tim += days[tm->tm_mon];
147 if ((tm->tm_year & 3) == 0 && tm->tm_mon > 1) {
157 tim = tim * 24 + tm->tm_hour;
161 tim = tim * 60 + tm->tm_min;
169 tim = tim * 60 + tm->tm_sec;
183static icaltime_t icaltime_timegm(
const struct tm *tm)
192 if (!make_time(tm, 0, NULL)) {
197 year = 1900 + tm->tm_year;
198 int idays = (365 * (year - 1970) + icaltime_leap_days(1970, year));
199 days = (icaltime_t)idays;
200 days += days_in_year_passed_month[0][tm->tm_mon];
206 days += tm->tm_mday - 1;
207 hours = days * 24 + tm->tm_hour;
208 minutes = hours * 60 + tm->tm_min;
209 seconds = minutes * 60 + tm->tm_sec;
224 memset(&t, 0,
sizeof(
struct tm));
225 if (!icalgmtime_r(&tm, &t)) {
229 tt.
year = t.tm_year + 1900;
230 tt.
month = t.tm_mon + 1;
237 tt.
zone = (zone == NULL) ? NULL : utc_zone;
267 icaltime_t t = (icaltime_t)-1;
275 memset(&stm, 0,
sizeof(
struct tm));
278 stm.tm_sec = stm.tm_min = stm.tm_hour = 0;
282 stm.tm_hour = tt.
hour;
285 stm.tm_mday = tt.
day;
286 stm.tm_mon = tt.
month - 1;
287 stm.tm_year = tt.
year - 1900;
290 if (!make_time(&stm, 0, &t)) {
291 t = ((icaltime_t)-1);
317 if (tt.
zone != utc_zone) {
322 memset(&stm, 0,
sizeof(
struct tm));
324 stm.tm_sec = local_tt.
second;
325 stm.tm_min = local_tt.
minute;
326 stm.tm_hour = local_tt.
hour;
327 stm.tm_mday = local_tt.
day;
328 stm.tm_mon = local_tt.
month - 1;
329 stm.tm_year = local_tt.
year - 1900;
332 t = icaltime_timegm(&stm);
352 snprintf(buf, size,
"%04d%02d%02d", tt.
year, tt.
month, tt.
day);
354#pragma GCC diagnostic push
355#pragma GCC diagnostic ignored "-Wformat-nonliteral"
359 fmt =
"%04d%02d%02dT%02d%02d%02dZ";
361 fmt =
"%04d%02d%02dT%02d%02d%02d";
364#pragma GCC diagnostic pop
388 if ((size == 15) || (size == 19)) {
390 }
else if ((size == 16) || (size == 20)) {
391 if ((
str[size - 1] !=
'Z')) {
397 }
else if ((size == 8) || (size == 10)) {
407 if (sscanf(
str,
"%04d%c%02d%c%02d",
412 if ((dsep1 !=
'-') || (dsep2 !=
'-')) {
415 }
else if (sscanf(
str,
"%04d%02d%02d", &tt.
year, &tt.
month, &tt.
day) < 3) {
420 char dsep1, dsep2, tsep, tsep1, tsep2;
422 if (sscanf(
str,
"%04d%c%02d%c%02d%c%02d%c%02d%c%02d",
429 (dsep1 !=
'-') || (dsep2 !=
'-') ||
430 (tsep1 !=
':') || (tsep2 !=
':')) {
437 if (sscanf(
str,
"%04d%02d%02d%c%02d%02d%02d",
459 return (
year % 4 == 0);
461 return ((
year % 4 == 0) && (
year % 100 != 0)) || (
year % 400 == 0);
474static const int _days_in_month[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
492 days = _days_in_month[
month];
506 memset(&jt, 0,
sizeof(UTinstantInt));
514 return jt.weekday + 1;
522 memset(&jt, 0,
sizeof(UTinstantInt));
531 delta = jt.weekday - (fdow - 1);
535 return jt.day_of_year - delta;
546 return days_in_year_passed_month[is_leap][t.
month - 1] + t.
day;
552 unsigned int is_leap;
563 doy += days_in_year_passed_month[is_leap][12];
564 }
else if (doy > days_in_year_passed_month[is_leap][12]) {
567 doy -= days_in_year_passed_month[is_leap][12];
574 if (doy > days_in_year_passed_month[is_leap][
month]) {
576 tt.
day = doy - days_in_year_passed_month[is_leap][
month];
617 t.
day < 0 || t.
day > 31 ||
651 if (a_is_valid && !b_is_valid) {
680 }
else if (a.
day > b.
day) {
682 }
else if (a.
day < b.
day) {
719 if (a_in.
zone != NULL) {
721 }
else if (b_in.
zone != NULL) {
753 }
else if (a.
day < b.
day) {
761 const int days,
const int hours,
762 const int minutes,
const int seconds)
765 int minutes_overflow, hours_overflow, days_overflow = 0, years_overflow;
780 minutes_overflow =
second / 60;
789 hours_overflow =
minute / 60;
796 hour = tt->
hour + hours + hours_overflow;
798 days_overflow =
hour / 24;
808 if (tt->
month >= 13) {
809 years_overflow = (tt->
month - 1) / 12;
810 tt->
year += years_overflow;
811 tt->
month -= years_overflow * 12;
812 }
else if (tt->
month <= 0) {
814 years_overflow = (tt->
month / 12) - 1;
815 tt->
year += years_overflow;
816 tt->
month -= years_overflow * 12;
820 day = tt->
day + days + days_overflow;
824 if (
day <= days_in_month) {
829 if (tt->
month >= 13) {
834 day -= days_in_month;
838 if (tt->
month == 1) {
860 if (tt.zone ==
zone) {
865 if (tt.zone != NULL) {
881 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