root/ext/date/lib/timelib.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. timelib_time_ctor
  2. timelib_rel_time_ctor
  3. timelib_time_clone
  4. timelib_time_compare
  5. timelib_rel_time_clone
  6. timelib_time_tz_abbr_update
  7. timelib_time_dtor
  8. timelib_rel_time_dtor
  9. timelib_time_offset_ctor
  10. timelib_time_offset_dtor
  11. timelib_tzinfo_ctor
  12. timelib_tzinfo_clone
  13. timelib_tzinfo_dtor
  14. timelib_get_tz_abbr_ptr
  15. timelib_error_container_dtor
  16. timelib_date_to_int
  17. timelib_decimal_hour_to_hms
  18. timelib_dump_date
  19. timelib_dump_rel_time
  20. timelib_parse_tz_cor

   1 /*
   2  * The MIT License (MIT)
   3  *
   4  * Copyright (c) 2015 Derick Rethans
   5  *
   6  * Permission is hereby granted, free of charge, to any person obtaining a copy
   7  * of this software and associated documentation files (the "Software"), to deal
   8  * in the Software without restriction, including without limitation the rights
   9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10  * copies of the Software, and to permit persons to whom the Software is
  11  * furnished to do so, subject to the following conditions:
  12  *
  13  * The above copyright notice and this permission notice shall be included in
  14  * all copies or substantial portions of the Software.
  15  *
  16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22  * THE SOFTWARE.
  23  */
  24 
  25 #include "timelib.h"
  26 #include <ctype.h>
  27 #include <math.h>
  28 
  29 #define TIMELIB_TIME_FREE(m)    \
  30         if (m) {                \
  31                 timelib_free(m);        \
  32                 m = NULL;       \
  33         }                       \
  34 
  35 #define TIMELIB_LLABS(y) (y < 0 ? (y * -1) : y)
  36 
  37 #define HOUR(a) (int)(a * 60)
  38 
  39 timelib_time* timelib_time_ctor(void)
  40 {
  41         timelib_time *t;
  42         t = timelib_calloc(1, sizeof(timelib_time));
  43 
  44         return t;
  45 }
  46 
  47 timelib_rel_time* timelib_rel_time_ctor(void)
  48 {
  49         timelib_rel_time *t;
  50         t = timelib_calloc(1, sizeof(timelib_rel_time));
  51 
  52         return t;
  53 }
  54 
  55 timelib_time* timelib_time_clone(timelib_time *orig)
  56 {
  57         timelib_time *tmp = timelib_time_ctor();
  58         memcpy(tmp, orig, sizeof(timelib_time));
  59         if (orig->tz_abbr) {
  60                 tmp->tz_abbr = timelib_strdup(orig->tz_abbr);
  61         }
  62         if (orig->tz_info) {
  63                 tmp->tz_info = orig->tz_info;
  64         }
  65         return tmp;
  66 }
  67 
  68 int timelib_time_compare(timelib_time *t1, timelib_time *t2)
  69 {
  70         if (t1->sse == t2->sse) {
  71                 if (t1->f == t2->f) {
  72                         return 0;
  73                 }
  74 
  75                 if (t1->sse < 0) {
  76                         return (t1->f < t2->f) ? 1 : -1;
  77                 } else {
  78                         return (t1->f < t2->f) ? -1 : 1;
  79                 }
  80         }
  81 
  82         return (t1->sse < t2->sse) ? -1 : 1;
  83 }
  84 
  85 timelib_rel_time* timelib_rel_time_clone(timelib_rel_time *rel)
  86 {
  87         timelib_rel_time *tmp = timelib_rel_time_ctor();
  88         memcpy(tmp, rel, sizeof(timelib_rel_time));
  89         return tmp;
  90 }
  91 
  92 void timelib_time_tz_abbr_update(timelib_time* tm, char* tz_abbr)
  93 {
  94         unsigned int i;
  95         size_t tz_abbr_len = strlen(tz_abbr);
  96 
  97         TIMELIB_TIME_FREE(tm->tz_abbr);
  98         tm->tz_abbr = timelib_strdup(tz_abbr);
  99         for (i = 0; i < tz_abbr_len; i++) {
 100                 tm->tz_abbr[i] = toupper(tz_abbr[i]);
 101         }
 102 }
 103 
 104 void timelib_time_dtor(timelib_time* t)
 105 {
 106         TIMELIB_TIME_FREE(t->tz_abbr);
 107         TIMELIB_TIME_FREE(t);
 108 }
 109 
 110 void timelib_rel_time_dtor(timelib_rel_time* t)
 111 {
 112         TIMELIB_TIME_FREE(t);
 113 }
 114 
 115 timelib_time_offset* timelib_time_offset_ctor(void)
 116 {
 117         timelib_time_offset *t;
 118         t = timelib_calloc(1, sizeof(timelib_time_offset));
 119 
 120         return t;
 121 }
 122 
 123 void timelib_time_offset_dtor(timelib_time_offset* t)
 124 {
 125         TIMELIB_TIME_FREE(t->abbr);
 126         TIMELIB_TIME_FREE(t);
 127 }
 128 
 129 timelib_tzinfo* timelib_tzinfo_ctor(char *name)
 130 {
 131         timelib_tzinfo *t;
 132         t = timelib_calloc(1, sizeof(timelib_tzinfo));
 133         t->name = timelib_strdup(name);
 134 
 135         return t;
 136 }
 137 
 138 timelib_tzinfo *timelib_tzinfo_clone(timelib_tzinfo *tz)
 139 {
 140         timelib_tzinfo *tmp = timelib_tzinfo_ctor(tz->name);
 141         tmp->bit32.ttisgmtcnt = tz->bit32.ttisgmtcnt;
 142         tmp->bit32.ttisstdcnt = tz->bit32.ttisstdcnt;
 143         tmp->bit32.leapcnt = tz->bit32.leapcnt;
 144         tmp->bit32.timecnt = tz->bit32.timecnt;
 145         tmp->bit32.typecnt = tz->bit32.typecnt;
 146         tmp->bit32.charcnt = tz->bit32.charcnt;
 147 
 148         tmp->trans = (int32_t *) timelib_malloc(tz->bit32.timecnt * sizeof(int32_t));
 149         tmp->trans_idx = (unsigned char*) timelib_malloc(tz->bit32.timecnt * sizeof(unsigned char));
 150         memcpy(tmp->trans, tz->trans, tz->bit32.timecnt * sizeof(int32_t));
 151         memcpy(tmp->trans_idx, tz->trans_idx, tz->bit32.timecnt * sizeof(unsigned char));
 152 
 153         tmp->type = (ttinfo*) timelib_malloc(tz->bit32.typecnt * sizeof(struct ttinfo));
 154         memcpy(tmp->type, tz->type, tz->bit32.typecnt * sizeof(struct ttinfo));
 155 
 156         tmp->timezone_abbr = (char*) timelib_malloc(tz->bit32.charcnt);
 157         memcpy(tmp->timezone_abbr, tz->timezone_abbr, tz->bit32.charcnt);
 158 
 159         tmp->leap_times = (tlinfo*) timelib_malloc(tz->bit32.leapcnt * sizeof(tlinfo));
 160         memcpy(tmp->leap_times, tz->leap_times, tz->bit32.leapcnt * sizeof(tlinfo));
 161 
 162         return tmp;
 163 }
 164 
 165 void timelib_tzinfo_dtor(timelib_tzinfo *tz)
 166 {
 167         TIMELIB_TIME_FREE(tz->name);
 168         TIMELIB_TIME_FREE(tz->trans);
 169         TIMELIB_TIME_FREE(tz->trans_idx);
 170         TIMELIB_TIME_FREE(tz->type);
 171         TIMELIB_TIME_FREE(tz->timezone_abbr);
 172         TIMELIB_TIME_FREE(tz->leap_times);
 173         TIMELIB_TIME_FREE(tz->location.comments);
 174         TIMELIB_TIME_FREE(tz);
 175         tz = NULL;
 176 }
 177 
 178 char *timelib_get_tz_abbr_ptr(timelib_time *t)
 179 {
 180         if (!t->sse_uptodate) {
 181                 timelib_update_ts(t, NULL);
 182         };
 183         return t->tz_abbr;
 184 }
 185 
 186 void timelib_error_container_dtor(timelib_error_container *errors)
 187 {
 188         int i;
 189 
 190         for (i = 0; i < errors->warning_count; i++) {
 191                 timelib_free(errors->warning_messages[i].message);
 192         }
 193         timelib_free(errors->warning_messages);
 194         for (i = 0; i < errors->error_count; i++) {
 195                 timelib_free(errors->error_messages[i].message);
 196         }
 197         timelib_free(errors->error_messages);
 198         timelib_free(errors);
 199 }
 200 
 201 timelib_long timelib_date_to_int(timelib_time *d, int *error)
 202 {
 203         timelib_sll ts;
 204 
 205         ts = d->sse;
 206 
 207         if (ts < TIMELIB_LONG_MIN || ts > TIMELIB_LONG_MAX) {
 208                 if (error) {
 209                         *error = 1;
 210                 }
 211                 return 0;
 212         }
 213         if (error) {
 214                 *error = 0;
 215         }
 216         return (timelib_long) d->sse;
 217 }
 218 
 219 void timelib_decimal_hour_to_hms(double h, int *hour, int *min, int *sec)
 220 {
 221         *hour = floor(h);
 222         *min =  floor((h - *hour) * 60);
 223         *sec =  (h - *hour - ((float) *min / 60)) * 3600;
 224 }
 225 
 226 void timelib_dump_date(timelib_time *d, int options)
 227 {
 228         if ((options & 2) == 2) {
 229                 printf("TYPE: %d ", d->zone_type);
 230         }
 231         printf("TS: %lld | %s%04lld-%02lld-%02lld %02lld:%02lld:%02lld",
 232                 d->sse, d->y < 0 ? "-" : "", TIMELIB_LLABS(d->y), d->m, d->d, d->h, d->i, d->s);
 233         if (d->f > +0.0) {
 234                 printf(" %.5f", d->f);
 235         }
 236 
 237         if (d->is_localtime) {
 238                 switch (d->zone_type) {
 239                         case TIMELIB_ZONETYPE_OFFSET: /* Only offset */
 240                                 printf(" GMT %05d%s", d->z, d->dst == 1 ? " (DST)" : "");
 241                                 break;
 242                         case TIMELIB_ZONETYPE_ID: /* Timezone struct */
 243                                 /* Show abbreviation if wanted */
 244                                 if (d->tz_abbr) {
 245                                         printf(" %s", d->tz_abbr);
 246                                 }
 247                                 /* Do we have a TimeZone struct? */
 248                                 if (d->tz_info) {
 249                                         printf(" %s", d->tz_info->name);
 250                                 }
 251                                 break;
 252                         case TIMELIB_ZONETYPE_ABBR:
 253                                 printf(" %s", d->tz_abbr);
 254                                 printf(" %05d%s", d->z, d->dst == 1 ? " (DST)" : "");
 255                                 break;
 256                 }
 257         }
 258 
 259         if ((options & 1) == 1) {
 260                 if (d->have_relative) {
 261                         printf("%3lldY %3lldM %3lldD / %3lldH %3lldM %3lldS",
 262                                 d->relative.y, d->relative.m, d->relative.d, d->relative.h, d->relative.i, d->relative.s);
 263                         if (d->relative.first_last_day_of != 0) {
 264                                 switch (d->relative.first_last_day_of) {
 265                                         case 1:
 266                                                 printf(" / first day of");
 267                                                 break;
 268                                         case 2:
 269                                                 printf(" / last day of");
 270                                                 break;
 271                                 }
 272                         }
 273                         if (d->relative.have_weekday_relative) {
 274                                 printf(" / %d.%d", d->relative.weekday, d->relative.weekday_behavior);
 275                         }
 276                         if (d->relative.have_special_relative) {
 277                                 switch (d->relative.special.type) {
 278                                         case TIMELIB_SPECIAL_WEEKDAY:
 279                                                 printf(" / %lld weekday", d->relative.special.amount);
 280                                                 break;
 281                                         case TIMELIB_SPECIAL_DAY_OF_WEEK_IN_MONTH:
 282                                                 printf(" / x y of z month");
 283                                                 break;
 284                                         case TIMELIB_SPECIAL_LAST_DAY_OF_WEEK_IN_MONTH:
 285                                                 printf(" / last y of z month");
 286                                                 break;
 287                                 }
 288                         }
 289                 }
 290         }
 291         printf("\n");
 292 }
 293 
 294 void timelib_dump_rel_time(timelib_rel_time *d)
 295 {
 296         printf("%3lldY %3lldM %3lldD / %3lldH %3lldM %3lldS (days: %lld)%s",
 297                 d->y, d->m, d->d, d->h, d->i, d->s, d->days, d->invert ? " inverted" : "");
 298         if (d->first_last_day_of != 0) {
 299                 switch (d->first_last_day_of) {
 300                         case 1:
 301                                 printf(" / first day of");
 302                                 break;
 303                         case 2:
 304                                 printf(" / last day of");
 305                                 break;
 306                 }
 307         }
 308         printf("\n");
 309 }
 310 
 311 timelib_long timelib_parse_tz_cor(char **ptr)
 312 {
 313         char *begin = *ptr, *end;
 314         timelib_long  tmp;
 315 
 316         while (isdigit(**ptr) || **ptr == ':') {
 317                 ++*ptr;
 318         }
 319         end = *ptr;
 320         switch (end - begin) {
 321                 case 1:
 322                 case 2:
 323                         return HOUR(strtol(begin, NULL, 10));
 324                         break;
 325                 case 3:
 326                 case 4:
 327                         if (begin[1] == ':') {
 328                                 tmp = HOUR(strtol(begin, NULL, 10)) + strtol(begin + 2, NULL, 10);
 329                                 return tmp;
 330                         } else if (begin[2] == ':') {
 331                                 tmp = HOUR(strtol(begin, NULL, 10)) + strtol(begin + 3, NULL, 10);
 332                                 return tmp;
 333                         } else {
 334                                 tmp = strtol(begin, NULL, 10);
 335                                 return HOUR(tmp / 100) + tmp % 100;
 336                         }
 337                 case 5:
 338                         tmp = HOUR(strtol(begin, NULL, 10)) + strtol(begin + 3, NULL, 10);
 339                         return tmp;
 340         }
 341         return 0;
 342 }

/* [<][>][^][v][top][bottom][index][help] */