PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LTP GCOV extension - code coverage report
Current view: directory - date/lib - tm2unixtime.c
Test: PHP Code Coverage
Date: 2009-11-19 Instrumented lines: 165
Code covered: 80.6 % Executed lines: 133
Legend: not executed executed

       1                 : /*
       2                 :    +----------------------------------------------------------------------+
       3                 :    | PHP Version 5                                                        |
       4                 :    +----------------------------------------------------------------------+
       5                 :    | Copyright (c) 1997-2009 The PHP Group                                |
       6                 :    +----------------------------------------------------------------------+
       7                 :    | This source file is subject to version 3.01 of the PHP license,      |
       8                 :    | that is bundled with this package in the file LICENSE, and is        |
       9                 :    | available through the world-wide-web at the following url:           |
      10                 :    | http://www.php.net/license/3_01.txt                                  |
      11                 :    | If you did not receive a copy of the PHP license and are unable to   |
      12                 :    | obtain it through the world-wide-web, please send a note to          |
      13                 :    | license@php.net so we can mail you a copy immediately.               |
      14                 :    +----------------------------------------------------------------------+
      15                 :    | Authors: Derick Rethans <derick@derickrethans.nl>                    |
      16                 :    +----------------------------------------------------------------------+
      17                 :  */
      18                 : 
      19                 : /* $Id: tm2unixtime.c 279800 2009-05-03 18:22:59Z derick $ */
      20                 : 
      21                 : #include "timelib.h"
      22                 : 
      23                 : /*                                    jan  feb  mrt  apr  may  jun  jul  aug  sep  oct  nov  dec */
      24                 : static int month_tab_leap[12]     = {  -1,  30,  59,  90, 120, 151, 181, 212, 243, 273, 304, 334 };
      25                 : static int month_tab[12]          = {   0,  31,  59,  90, 120, 151, 181, 212, 243, 273, 304, 334 };
      26                 : 
      27                 : /*                                    dec  jan  feb  mrt  apr  may  jun  jul  aug  sep  oct  nov  dec */
      28                 : static int days_in_month_leap[13] = {  31,  31,  29,  31,  30,  31,  30,  31,  31,  30,  31,  30,  31 };
      29                 : static int days_in_month[13]      = {  31,  31,  28,  31,  30,  31,  30,  31,  31,  30,  31,  30,  31 };
      30                 : 
      31                 : static int do_range_limit(timelib_sll start, timelib_sll end, timelib_sll adj, timelib_sll *a, timelib_sll *b)
      32          258132 : {
      33          258132 :         if (*a < start) {
      34            4396 :                 *b -= (start - *a - 1) / adj + 1;
      35            4396 :                 *a += adj * ((start - *a - 1) / adj + 1);
      36                 :         }
      37          258132 :         if (*a >= end) {
      38            9538 :                 *b += *a / adj;
      39            9538 :                 *a -= adj * (*a / adj);
      40                 :         }
      41          258132 :         return 0;
      42                 : }
      43                 : 
      44                 : static int do_range_limit_days(timelib_sll *y, timelib_sll *m, timelib_sll *d)
      45          175077 : {
      46                 :         timelib_sll leapyear;
      47                 :         timelib_sll days_this_month;
      48                 :         timelib_sll last_month, last_year;
      49                 :         timelib_sll days_last_month;
      50                 :         
      51                 :         /* can jump an entire leap year period quickly */
      52          175077 :         if (*d >= DAYS_PER_LYEAR_PERIOD || *d <= -DAYS_PER_LYEAR_PERIOD) {
      53              16 :                 *y += YEARS_PER_LYEAR_PERIOD * (*d / DAYS_PER_LYEAR_PERIOD);
      54              16 :                 *d -= DAYS_PER_LYEAR_PERIOD * (*d / DAYS_PER_LYEAR_PERIOD);
      55                 :         }
      56                 : 
      57          175077 :         do_range_limit(1, 13, 12, m, y);
      58                 : 
      59          175077 :         leapyear = timelib_is_leap(*y);
      60          175077 :         days_this_month = leapyear ? days_in_month_leap[*m] : days_in_month[*m];
      61          175077 :         last_month = (*m) - 1;
      62                 : 
      63          175077 :         if (last_month < 1) {
      64           18976 :                 last_month += 12;
      65           18976 :                 last_year = (*y) - 1;
      66                 :         } else {
      67          156101 :                 last_year = (*y);
      68                 :         }
      69          175077 :         leapyear = timelib_is_leap(last_year);
      70          175077 :         days_last_month = leapyear ? days_in_month_leap[last_month] : days_in_month[last_month];
      71                 : 
      72          175077 :         if (*d <= 0) {
      73           50981 :                 *d += days_last_month;
      74           50981 :                 (*m)--;
      75           50981 :                 return 1;
      76                 :         }
      77          124096 :         if (*d > days_this_month) {
      78          107485 :                 *d -= days_this_month;
      79          107485 :                 (*m)++;
      80          107485 :                 return 1;
      81                 :         }
      82           16611 :         return 0;
      83                 : }
      84                 : 
      85                 : static void do_adjust_for_weekday(timelib_time* time)
      86             162 : {
      87                 :         timelib_sll current_dow, difference;
      88                 : 
      89             162 :         current_dow = timelib_day_of_week(time->y, time->m, time->d);
      90             162 :         difference = time->relative.weekday - current_dow;
      91             162 :         if ((time->relative.d < 0 && difference < 0) || (time->relative.d >= 0 && difference <= -time->relative.weekday_behavior)) {
      92             104 :                 difference += 7;
      93                 :         }
      94             162 :         if (time->relative.weekday >= 0) {
      95             162 :                 time->d += difference;
      96                 :         } else {
      97               0 :                 time->d -= (7 - (abs(time->relative.weekday) - current_dow));
      98                 :         }
      99             162 :         time->have_weekday_relative = 0;
     100             162 : }
     101                 : 
     102                 : static void do_normalize(timelib_time* time)
     103           16611 : {
     104           16611 :         do {} while (do_range_limit(0, 60, 60, &time->s, &time->i));
     105           16611 :         do {} while (do_range_limit(0, 60, 60, &time->i, &time->h));
     106           16611 :         do {} while (do_range_limit(0, 24, 24, &time->h, &time->d));
     107           16611 :         do {} while (do_range_limit(1, 13, 12, &time->m, &time->y));
     108                 : 
     109          175077 :         do {} while (do_range_limit_days(&time->y, &time->m, &time->d));
     110           16611 :         do {} while (do_range_limit(1, 13, 12, &time->m, &time->y));
     111           16611 : }
     112                 : 
     113                 : static void do_adjust_relative(timelib_time* time)
     114            5537 : {
     115            5537 :         if (time->have_weekday_relative) {
     116             162 :                 do_adjust_for_weekday(time);
     117                 :         }
     118            5537 :         do_normalize(time);
     119                 : 
     120            5537 :         if (time->have_relative) {
     121             664 :                 time->s += time->relative.s;
     122             664 :                 time->i += time->relative.i;
     123             664 :                 time->h += time->relative.h;
     124                 : 
     125             664 :                 time->d += time->relative.d;
     126             664 :                 time->m += time->relative.m;
     127             664 :                 time->y += time->relative.y;
     128                 :         }
     129            5537 :         do_normalize(time);
     130                 : 
     131            5537 :         memset(&(time->relative), 0, sizeof(time->relative));
     132            5537 :         time->have_relative = 0;
     133            5537 : }
     134                 : 
     135                 : static void do_adjust_special_weekday(timelib_time* time)
     136               0 : {
     137                 :         timelib_sll current_dow, count;
     138                 : 
     139               0 :         count = time->special.amount;
     140                 : 
     141               0 :         current_dow = timelib_day_of_week(time->y, time->m, time->d);
     142               0 :         if (count == 0) {
     143                 :                 /* skip over saturday and sunday */
     144               0 :                 if (current_dow == 6) {
     145               0 :                         time->d += 2;
     146                 :                 }
     147                 :                 /* skip over sunday */
     148               0 :                 if (current_dow == 0) {
     149               0 :                         time->d += 1;
     150                 :                 }
     151               0 :         } else if (count > 0) {
     152                 :                 /* skip over saturday and sunday */
     153               0 :                 if (current_dow == 5) {
     154               0 :                         time->d += 2;
     155                 :                 }
     156                 :                 /* skip over sunday */
     157               0 :                 if (current_dow == 6) {
     158               0 :                         time->d += 1;
     159                 :                 }
     160                 :                 /* add increments of 5 weekdays as a week */
     161               0 :                 time->d += (count / 5) * 7;
     162                 :                 /* if current DOW plus the remainder > 5, add two days */
     163               0 :                 current_dow = timelib_day_of_week(time->y, time->m, time->d);
     164               0 :                 time->d += (count % 5);
     165               0 :                 if ((count % 5) + current_dow > 5) {
     166               0 :                         time->d += 2;
     167                 :                 }
     168               0 :         } else if (count < 0) {
     169                 :                 /* skip over sunday and saturday */
     170               0 :                 if (current_dow == 1) {
     171               0 :                         time->d -= 2;
     172                 :                 }
     173                 :                 /* skip over satruday */
     174               0 :                 if (current_dow == 0 ) {
     175               0 :                         time->d -= 1;
     176                 :                 }
     177                 :                 /* subtract increments of 5 weekdays as a week */
     178               0 :                 time->d += (count / 5) * 7;
     179                 :                 /* if current DOW minus the remainder < 0, subtract two days */
     180               0 :                 current_dow = timelib_day_of_week(time->y, time->m, time->d);
     181               0 :                 time->d += (count % 5);
     182               0 :                 if ((count % 5) + current_dow < 1) {
     183               0 :                         time->d -= 2;
     184                 :                 }
     185                 :         }
     186               0 : }
     187                 : 
     188                 : static void do_adjust_special(timelib_time* time)
     189            5537 : {
     190            5537 :         if (time->have_special_relative) {
     191               0 :                 switch (time->special.type) {
     192                 :                         case TIMELIB_SPECIAL_WEEKDAY:
     193               0 :                                 do_adjust_special_weekday(time);
     194                 :                                 break;
     195                 :                 }
     196                 :         }
     197            5537 :         do_normalize(time);
     198            5537 :         memset(&(time->special), 0, sizeof(time->special));
     199            5537 :         time->have_relative = 0;
     200            5537 : }
     201                 : 
     202                 : static timelib_sll do_years(timelib_sll year)
     203            5537 : {
     204                 :         timelib_sll i;
     205            5537 :         timelib_sll res = 0;
     206                 :         timelib_sll eras;
     207                 : 
     208            5537 :         eras = (year - 1970) / 40000;
     209            5537 :         if (eras != 0) {
     210              18 :                 year = year - (eras * 40000);
     211              18 :                 res += (SECS_PER_ERA * eras * 100);
     212                 :         }
     213                 : 
     214            5537 :         if (year >= 1970) {
     215          381047 :                 for (i = year - 1; i >= 1970; i--) {
     216          467404 :                         if (timelib_is_leap(i)) {
     217           91611 :                                 res += (DAYS_PER_LYEAR * SECS_PER_DAY);
     218                 :                         } else {
     219          284182 :                                 res += (DAYS_PER_YEAR * SECS_PER_DAY);
     220                 :                         }
     221                 :                 }
     222                 :         } else {
     223          576785 :                 for (i = 1969; i >= year; i--) {
     224          716338 :                         if (timelib_is_leap(i)) {
     225          139836 :                                 res -= (DAYS_PER_LYEAR * SECS_PER_DAY);
     226                 :                         } else {
     227          436666 :                                 res -= (DAYS_PER_YEAR * SECS_PER_DAY);
     228                 :                         }
     229                 :                 }
     230                 :         }
     231            5537 :         return res;
     232                 : }
     233                 : 
     234                 : static timelib_sll do_months(timelib_ull month, timelib_ull year)
     235            5537 : {
     236            5537 :         if (timelib_is_leap(year)) {
     237            1823 :                 return ((month_tab_leap[month - 1] + 1) * SECS_PER_DAY);
     238                 :         } else {
     239            3714 :                 return ((month_tab[month - 1]) * SECS_PER_DAY);
     240                 :         }
     241                 : }
     242                 : 
     243                 : static timelib_sll do_days(timelib_ull day)
     244            5537 : {
     245            5537 :         return ((day - 1) * SECS_PER_DAY);
     246                 : }
     247                 : 
     248                 : static timelib_sll do_time(timelib_ull hour, timelib_ull minute, timelib_ull second)
     249            5537 : {
     250            5537 :         timelib_sll res = 0;
     251                 : 
     252            5537 :         res += hour * 3600;
     253            5537 :         res += minute * 60;
     254            5537 :         res += second;
     255            5537 :         return res;
     256                 : }
     257                 : 
     258                 : static timelib_sll do_adjust_timezone(timelib_time *tz, timelib_tzinfo *tzi)
     259            5537 : {
     260            5537 :         switch (tz->zone_type) {
     261                 :                 case TIMELIB_ZONETYPE_OFFSET:
     262                 : 
     263             100 :                         tz->is_localtime = 1;
     264             100 :                         return tz->z * 60;
     265                 :                         break;
     266                 : 
     267                 :                 case TIMELIB_ZONETYPE_ABBR: {
     268                 :                         timelib_sll tmp;
     269                 : 
     270              55 :                         tz->is_localtime = 1;
     271              55 :                         tmp = tz->z;
     272              55 :                         tmp -= tz->dst * 60;
     273              55 :                         tmp *= 60;
     274              55 :                         return tmp;
     275                 :                         }
     276                 :                         break;
     277                 : 
     278                 :                 case TIMELIB_ZONETYPE_ID:
     279            4495 :                         tzi = tz->tz_info;
     280                 :                         /* Break intentionally missing */
     281                 : 
     282                 :                 default:
     283                 :                         /* No timezone in struct, fallback to reference if possible */
     284            5382 :                         if (tzi) {
     285                 :                                 timelib_time_offset *before, *after;
     286                 :                                 timelib_sll          tmp;
     287                 :                                 int                  in_transistion;
     288                 :                                 
     289            4495 :                                 tz->is_localtime = 1;
     290            4495 :                                 before = timelib_get_time_zone_info(tz->sse, tzi);
     291            4495 :                                 after = timelib_get_time_zone_info(tz->sse - before->offset, tzi);
     292            4495 :                                 timelib_set_timezone(tz, tzi);
     293                 : 
     294            4495 :                                 in_transistion = (
     295                 :                                         ((tz->sse - after->offset) >= (after->transistion_time + (before->offset - after->offset))) &&
     296                 :                                         ((tz->sse - after->offset) < after->transistion_time)
     297                 :                                 );
     298                 :                                 
     299            4521 :                                 if ((before->offset != after->offset) && !in_transistion) {
     300              26 :                                         tmp = -after->offset;
     301                 :                                 } else {
     302            4469 :                                         tmp = -tz->z;
     303                 :                                 }
     304            4495 :                                 timelib_time_offset_dtor(before);
     305            4495 :                                 timelib_time_offset_dtor(after);
     306                 :                                 
     307            4495 :                                 return tmp;
     308                 :                         }
     309                 :         }
     310             887 :         return 0;
     311                 : }
     312                 : 
     313                 : void timelib_update_ts(timelib_time* time, timelib_tzinfo* tzi)
     314            5537 : {
     315            5537 :         timelib_sll res = 0;
     316                 : 
     317            5537 :         do_adjust_relative(time);
     318            5537 :         do_adjust_special(time);
     319            5537 :         res += do_years(time->y);
     320            5537 :         res += do_months(time->m, time->y);
     321            5537 :         res += do_days(time->d);
     322            5537 :         res += do_time(time->h, time->i, time->s);
     323            5537 :         time->sse = res;
     324                 : 
     325            5537 :         res += do_adjust_timezone(time, tzi);
     326            5537 :         time->sse = res;
     327                 : 
     328            5537 :         time->sse_uptodate = 1;
     329            5537 : }
     330                 : 
     331                 : #if 0
     332                 : int main(void)
     333                 : {
     334                 :         timelib_sll res;
     335                 :         timelib_time time;
     336                 : 
     337                 :         time = timelib_strtotime("10 Feb 2005 06:07:03 PM CET"); /* 1108055223 */
     338                 :         printf ("%04d-%02d-%02d %02d:%02d:%02d.%-5d %+04d %1d",
     339                 :                 time.y, time.m, time.d, time.h, time.i, time.s, time.f, time.z, time.dst);
     340                 :         if (time.have_relative) {
     341                 :                 printf ("%3dY %3dM %3dD / %3dH %3dM %3dS", 
     342                 :                         time.relative.y, time.relative.m, time.relative.d, time.relative.h, time.relative.i, time.relative.s);
     343                 :         }
     344                 :         if (time.have_weekday_relative) {
     345                 :                 printf (" / %d", time.relative.weekday);
     346                 :         }
     347                 :         res = time2unixtime(&time);
     348                 :         printf("%Ld\n", res);
     349                 : 
     350                 :         return 0;
     351                 : }
     352                 : #endif

Generated by: LTP GCOV extension version 1.5

Generated at Thu, 19 Nov 2009 08:20:05 +0000 (5 days ago)

Copyright © 2005-2009 The PHP Group
All rights reserved.