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"
39 #ifdef ICAL_NO_LIBICAL
40 #define icalerror_set_errno(x)
41 #define icalerror_check_arg_rv(x,y)
42 #define icalerror_check_arg_re(x,y,z)
44 #include "icalerror.h"
45 #include "icalmemory.h"
51 /* From Seth Alves, <alves@hungry.com> */
52 struct icaldurationtype icaldurationtype_from_int(int t)
54 struct icaldurationtype dur;
57 dur = icaldurationtype_null_duration();
64 dur.weeks = (t - used) / (60 * 60 * 24 * 7);
65 used += dur.weeks * (60 * 60 * 24 * 7);
66 dur.days = (t - used) / (60 * 60 * 24);
67 used += dur.days * (60 * 60 * 24);
68 dur.hours = (t - used) / (60 * 60);
69 used += dur.hours * (60 * 60);
70 dur.minutes = (t - used) / (60);
71 used += dur.minutes * (60);
72 dur.seconds = (t - used);
77 #ifndef ICAL_NO_LIBICAL
78 #include "icalvalue.h"
79 struct icaldurationtype icaldurationtype_from_string(const char* str)
89 int size = strlen(str);
91 struct icaldurationtype d;
93 memset(&d, 0, sizeof(struct icaldurationtype));
95 for(i=0;i != size;i++){
101 if(i != 0 || begin_flag == 1) goto error;
108 if (i != 0 && i !=1 ) goto error;
130 /* HACK. Skip any more digits if the l;ast one
131 read has not been assigned */
136 if (begin_flag == 0) goto error;
137 /* Get all of the digits, not one at a time */
138 scan_size = sscanf((char*)(str+i),"%d",&digits);
139 if(scan_size == 0) goto error;
144 if (time_flag == 0||week_flag == 1||d.hours !=0||digits ==-1)
146 d.hours = digits; digits = -1;
150 if (time_flag == 0||week_flag==1||d.minutes != 0||digits ==-1)
152 d.minutes = digits; digits = -1;
156 if (time_flag == 0||week_flag==1||d.seconds!=0||digits ==-1)
158 d.seconds = digits; digits = -1;
162 if (time_flag==1||date_flag==1||d.weeks!=0||digits ==-1)
165 d.weeks = digits; digits = -1;
169 if (time_flag==1||week_flag==1||d.days!=0||digits ==-1)
172 d.days = digits; digits = -1;
186 icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR);
187 memset(&d, 0, sizeof(struct icaldurationtype));
192 #define TMP_BUF_SIZE 1024
193 void append_duration_segment(char** buf, char** buf_ptr, size_t* buf_size,
194 char* sep, unsigned int value) {
196 char temp[TMP_BUF_SIZE];
198 sprintf(temp,"%d",value);
200 icalmemory_append_string(buf, buf_ptr, buf_size, temp);
201 icalmemory_append_string(buf, buf_ptr, buf_size, sep);
205 char* icaldurationtype_as_ical_string(struct icaldurationtype d)
208 char *buf, *output_line;
209 size_t buf_size = 256;
213 buf = (char*)icalmemory_new_buffer(buf_size);
217 seconds = icaldurationtype_as_int(d);
222 icalmemory_append_char(&buf, &buf_ptr, &buf_size, '-');
225 icalmemory_append_char(&buf, &buf_ptr, &buf_size, 'P');
228 append_duration_segment(&buf, &buf_ptr, &buf_size, "W", d.weeks);
232 append_duration_segment(&buf, &buf_ptr, &buf_size, "D", d.days);
235 if (d.hours != 0 || d.minutes != 0 || d.seconds != 0) {
237 icalmemory_append_string(&buf, &buf_ptr, &buf_size, "T");
240 append_duration_segment(&buf, &buf_ptr, &buf_size, "H", d.hours);
242 if (d.minutes != 0 ) {
243 append_duration_segment(&buf, &buf_ptr, &buf_size, "M",
246 if (d.seconds != 0 ) {
247 append_duration_segment(&buf, &buf_ptr, &buf_size, "S",
253 icalmemory_append_string(&buf, &buf_ptr, &buf_size, "PTS0");
256 output_line = icalmemory_tmp_copy(buf);
257 icalmemory_free_buffer(buf);
266 /* From Russel Steinthal */
267 int icaldurationtype_as_int(struct icaldurationtype dur)
269 return (int)( (dur.seconds +
271 (60 * 60 * dur.hours) +
272 (60 * 60 * 24 * dur.days) +
273 (60 * 60 * 24 * 7 * dur.weeks))
274 * (dur.is_neg==1? -1 : 1) ) ;
277 struct icaldurationtype icaldurationtype_null_duration()
279 struct icaldurationtype d;
281 memset(&d,0,sizeof(struct icaldurationtype));
286 int icaldurationtype_is_null_duration(struct icaldurationtype d)
288 if(icaldurationtype_as_int(d) == 0){
297 struct icaltimetype icaltime_add(struct icaltimetype t,
298 struct icaldurationtype d)
300 int dt = icaldurationtype_as_int(d);
304 t = icaltime_normalize(t);
309 struct icaldurationtype icaltime_subtract(struct icaltimetype t1,
310 struct icaltimetype t2)
313 time_t t1t = icaltime_as_timet(t1);
314 time_t t2t = icaltime_as_timet(t2);
316 return icaldurationtype_from_int(t1t-t2t);