2 ======================================================================
4 CREATOR: eric 02 June 2000
9 (C) COPYRIGHT 2000, Eric Busboom, http://www.softwarestudio.org
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of either:
14 The LGPL as published by the Free Software Foundation, version
15 2.1, available at: http://www.fsf.org/copyleft/lesser.html
19 The Mozilla Public License Version 1.0. You may obtain a copy of
20 the License at http://www.mozilla.org/MPL/
22 The Original Code is eric. The Initial Developer of the Original
26 ======================================================================*/
32 #include "icalduration.h"
41 #ifdef ICAL_NO_LIBICAL
42 #define icalerror_set_errno(x)
43 #define icalerror_check_arg_rv(x,y)
44 #define icalerror_check_arg_re(x,y,z)
46 #include "icalerror.h"
47 #include "icalmemory.h"
53 /* From Seth Alves, <alves@hungry.com> */
54 struct icaldurationtype icaldurationtype_from_int(int t)
56 struct icaldurationtype dur;
59 dur = icaldurationtype_null_duration();
66 dur.weeks = (t - used) / (60 * 60 * 24 * 7);
67 used += dur.weeks * (60 * 60 * 24 * 7);
68 dur.days = (t - used) / (60 * 60 * 24);
69 used += dur.days * (60 * 60 * 24);
70 dur.hours = (t - used) / (60 * 60);
71 used += dur.hours * (60 * 60);
72 dur.minutes = (t - used) / (60);
73 used += dur.minutes * (60);
74 dur.seconds = (t - used);
79 #ifndef ICAL_NO_LIBICAL
80 #include "icalvalue.h"
81 struct icaldurationtype icaldurationtype_from_string(const char* str)
91 int size = strlen(str);
93 struct icaldurationtype d;
95 memset(&d, 0, sizeof(struct icaldurationtype));
97 for(i=0;i != size;i++){
103 if(i != 0 || begin_flag == 1) goto error;
110 if (i != 0 && i !=1 ) goto error;
132 /* HACK. Skip any more digits if the l;ast one
133 read has not been assigned */
138 if (begin_flag == 0) goto error;
139 /* Get all of the digits, not one at a time */
140 scan_size = sscanf((char*)(str+i),"%d",&digits);
141 if(scan_size == 0) goto error;
146 if (time_flag == 0||week_flag == 1||d.hours !=0||digits ==-1)
148 d.hours = digits; digits = -1;
152 if (time_flag == 0||week_flag==1||d.minutes != 0||digits ==-1)
154 d.minutes = digits; digits = -1;
158 if (time_flag == 0||week_flag==1||d.seconds!=0||digits ==-1)
160 d.seconds = digits; digits = -1;
164 if (time_flag==1||date_flag==1||d.weeks!=0||digits ==-1)
167 d.weeks = digits; digits = -1;
171 if (time_flag==1||week_flag==1||d.days!=0||digits ==-1)
174 d.days = digits; digits = -1;
188 icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR);
189 memset(&d, 0, sizeof(struct icaldurationtype));
194 #define TMP_BUF_SIZE 1024
195 void append_duration_segment(char** buf, char** buf_ptr, size_t* buf_size,
196 char* sep, unsigned int value) {
198 char temp[TMP_BUF_SIZE];
200 sprintf(temp,"%d",value);
202 icalmemory_append_string(buf, buf_ptr, buf_size, temp);
203 icalmemory_append_string(buf, buf_ptr, buf_size, sep);
207 char* icaldurationtype_as_ical_string(struct icaldurationtype d)
210 char *buf, *output_line;
211 size_t buf_size = 256;
215 buf = (char*)icalmemory_new_buffer(buf_size);
219 seconds = icaldurationtype_as_int(d);
224 icalmemory_append_char(&buf, &buf_ptr, &buf_size, '-');
227 icalmemory_append_char(&buf, &buf_ptr, &buf_size, 'P');
230 append_duration_segment(&buf, &buf_ptr, &buf_size, "W", d.weeks);
234 append_duration_segment(&buf, &buf_ptr, &buf_size, "D", d.days);
237 if (d.hours != 0 || d.minutes != 0 || d.seconds != 0) {
239 icalmemory_append_string(&buf, &buf_ptr, &buf_size, "T");
242 append_duration_segment(&buf, &buf_ptr, &buf_size, "H", d.hours);
244 if (d.minutes != 0 ) {
245 append_duration_segment(&buf, &buf_ptr, &buf_size, "M",
248 if (d.seconds != 0 ) {
249 append_duration_segment(&buf, &buf_ptr, &buf_size, "S",
255 icalmemory_append_string(&buf, &buf_ptr, &buf_size, "PTS0");
258 output_line = icalmemory_tmp_copy(buf);
259 icalmemory_free_buffer(buf);
268 /* From Russel Steinthal */
269 int icaldurationtype_as_int(struct icaldurationtype dur)
271 return (int)( (dur.seconds +
273 (60 * 60 * dur.hours) +
274 (60 * 60 * 24 * dur.days) +
275 (60 * 60 * 24 * 7 * dur.weeks))
276 * (dur.is_neg==1? -1 : 1) ) ;
279 struct icaldurationtype icaldurationtype_null_duration()
281 struct icaldurationtype d;
283 memset(&d,0,sizeof(struct icaldurationtype));
288 int icaldurationtype_is_null_duration(struct icaldurationtype d)
290 if(icaldurationtype_as_int(d) == 0){
299 struct icaltimetype icaltime_add(struct icaltimetype t,
300 struct icaldurationtype d)
302 int dt = icaldurationtype_as_int(d);
309 zone = g_time_zone_new_utc();
311 zone = g_time_zone_new_local();
313 dtm = g_date_time_new(
322 GDateTime *d2 = g_date_time_add_seconds(dtm, dt);
324 t.year = g_date_time_get_year(d2);
325 t.month = g_date_time_get_month(d2);
326 t.day = g_date_time_get_day_of_month(d2);
327 t.hour = g_date_time_get_hour(d2);
328 t.minute = g_date_time_get_minute(d2);
329 t.second = g_date_time_get_second(d2);
331 g_date_time_unref(dtm);
332 g_date_time_unref(d2);
333 g_time_zone_unref(zone);
337 t = icaltime_normalize(t);
343 struct icaldurationtype icaltime_subtract(struct icaltimetype t1,
344 struct icaltimetype t2)
347 time_t t1t = icaltime_as_timet(t1);
348 time_t t2t = icaltime_as_timet(t2);
350 return icaldurationtype_from_int(t1t-t2t);