LTP GCOV extension - code coverage report
Current view: directory - ext/date/lib - tm2unixtime.c
Test: PHP Code Coverage
Date: 2007-04-10 Instrumented lines: 158
Code covered: 57.6 % Executed lines: 91
Legend: not executed executed

       1                 : /*
       2                 :    +----------------------------------------------------------------------+
       3                 :    | PHP Version 5                                                        |
       4                 :    +----------------------------------------------------------------------+
       5                 :    | Copyright (c) 1997-2007 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,v 1.13.2.3.2.2 2007/01/01 09:35:59 sebastian Exp $ */
      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              18 : {
      33              18 :         if (*a < start) {
      34               0 :                 *a += adj;
      35               0 :                 (*b)--;
      36               0 :                 return 1;
      37                 :         }
      38              18 :         if (*a >= end) {
      39               0 :                 if (start == 0) {
      40               0 :                         (*b) += (*a / end);
      41               0 :                         (*a) -= (end * (*a / end));
      42               0 :                         return 0;
      43                 :                 }
      44                 : 
      45               0 :                 *a -= adj;
      46               0 :                 (*b)++;
      47               0 :                 return 1;
      48                 :         }
      49              18 :         return 0;
      50                 : }
      51                 : 
      52                 : static int do_range_limit_days(timelib_sll *y, timelib_sll *m, timelib_sll *d)
      53               3 : {
      54                 :         timelib_sll leapyear;
      55                 :         timelib_sll days_this_month;
      56                 :         timelib_sll last_month, last_year;
      57                 :         timelib_sll days_last_month;
      58                 : 
      59               3 :         do_range_limit(1, 13, 12, m, y);
      60                 : 
      61               3 :         leapyear = timelib_is_leap(*y);
      62               3 :         days_this_month = leapyear ? days_in_month_leap[*m] : days_in_month[*m];
      63               3 :         last_month = (*m) - 1;
      64                 : 
      65               3 :         if (last_month < 1) {
      66               0 :                 last_month += 12;
      67               0 :                 last_year = (*y) - 1;
      68                 :         } else {
      69               3 :                 last_year = (*y);
      70                 :         }
      71               3 :         leapyear = timelib_is_leap(last_year);
      72               3 :         days_last_month = leapyear ? days_in_month_leap[last_month] : days_in_month[last_month];
      73                 : 
      74               3 :         if (*d <= 0) {
      75               0 :                 *d += days_last_month;
      76               0 :                 (*m)--;
      77               0 :                 return 1;
      78                 :         }
      79               3 :         if (*d > days_this_month) {
      80               0 :                 *d -= days_this_month;
      81               0 :                 (*m)++;
      82               0 :                 return 1;
      83                 :         }
      84               3 :         return 0;
      85                 : }
      86                 : 
      87                 : static void do_adjust_for_weekday(timelib_time* time)
      88               1 : {
      89                 :         timelib_sll current_dow, difference;
      90                 : 
      91               1 :         current_dow = timelib_day_of_week(time->y, time->m, time->d);
      92               1 :         difference = time->relative.weekday - current_dow;
      93               1 :         if ((time->relative.d < 0 && difference < 0) || (time->relative.d >= 0 && difference <= -time->relative.weekday_behavior)) {
      94               0 :                 difference += 7;
      95                 :         }
      96               1 :         if (time->relative.weekday >= 0) {
      97               1 :                 time->d += difference;
      98                 :         } else {
      99               0 :                 time->d -= (7 - (abs(time->relative.weekday) - current_dow));
     100                 :         }
     101               1 : }
     102                 : 
     103                 : static void do_normalize(timelib_time* time)
     104               3 : {
     105               3 :         do {} while (do_range_limit(0, 60, 60, &time->s, &time->i));
     106               3 :         do {} while (do_range_limit(0, 60, 60, &time->i, &time->h));
     107               3 :         do {} while (do_range_limit(0, 24, 24, &time->h, &time->d));
     108               3 :         do {} while (do_range_limit(1, 13, 12, &time->m, &time->y));
     109                 : 
     110               3 :         do {} while (do_range_limit_days(&time->y, &time->m, &time->d));
     111               3 :         do {} while (do_range_limit(1, 13, 12, &time->m, &time->y));
     112               3 : }
     113                 : 
     114                 : static void do_adjust_relative(timelib_time* time)
     115               1 : {
     116               1 :         if (time->have_weekday_relative) {
     117               1 :                 do_adjust_for_weekday(time);
     118                 :         }
     119               1 :         do_normalize(time);
     120                 : 
     121               1 :         if (time->have_relative) {
     122               1 :                 time->s += time->relative.s;
     123               1 :                 time->i += time->relative.i;
     124               1 :                 time->h += time->relative.h;
     125                 : 
     126               1 :                 time->d += time->relative.d;
     127               1 :                 time->m += time->relative.m;
     128               1 :                 time->y += time->relative.y;
     129                 :         }
     130               1 :         do_normalize(time);
     131                 : 
     132               1 :         memset(&(time->relative), 0, sizeof(time->relative));
     133               1 : }
     134                 : 
     135                 : static void do_adjust_special_weekday(timelib_time* time)
     136               0 : {
     137               0 :         timelib_sll current_dow, this_weekday = 0, count;
     138                 : 
     139               0 :         current_dow = timelib_day_of_week(time->y, time->m, time->d);
     140               0 :         count = time->special.amount;
     141               0 :         if (count == 0) {
     142               0 :                 if (current_dow == 6) {
     143               0 :                         this_weekday = 2;
     144                 :                 }
     145               0 :                 if (current_dow == 0) {
     146               0 :                         this_weekday = 1;
     147                 :                 }
     148               0 :                 time->d += this_weekday;
     149               0 :                 return;
     150               0 :         } else if (count > 0) {
     151               0 :                 if (current_dow == 5) {
     152               0 :                         this_weekday = 2;
     153                 :                 }
     154               0 :                 if (current_dow == 6) {
     155               0 :                         this_weekday = 1;
     156                 :                 }
     157               0 :         } else if (count < 0) {
     158               0 :                 if (current_dow == 0) {
     159               0 :                         this_weekday = -1;
     160                 :                 }
     161               0 :                 if (current_dow == 1) {
     162               0 :                         this_weekday = -2;
     163                 :                 }
     164                 :         }
     165               0 :         time->d += this_weekday + ((count / 5) * 7) + (count % 5);
     166                 : }
     167                 : 
     168                 : static void do_adjust_special(timelib_time* time)
     169               1 : {
     170               1 :         if (time->have_special_relative) {
     171               0 :                 switch (time->special.type) {
     172                 :                         case TIMELIB_SPECIAL_WEEKDAY:
     173               0 :                                 do_adjust_special_weekday(time);
     174                 :                                 break;
     175                 :                 }
     176                 :         }
     177               1 :         do_normalize(time);
     178               1 :         memset(&(time->special), 0, sizeof(time->special));
     179               1 : }
     180                 : 
     181                 : static timelib_sll do_years(timelib_sll year)
     182               1 : {
     183                 :         timelib_sll i;
     184               1 :         timelib_sll res = 0;
     185                 :         timelib_sll eras;
     186                 : 
     187               1 :         eras = (year - 1970) / 400;
     188               1 :         if (eras != 0) {
     189               0 :                 year = year - (eras * 400);
     190               0 :                 res += (SECS_PER_ERA * eras);
     191                 :         }
     192                 : 
     193               1 :         if (year >= 1970) {
     194              38 :                 for (i = year - 1; i >= 1970; i--) {
     195              46 :                         if (timelib_is_leap(i)) {
     196               9 :                                 res += (DAYS_PER_LYEAR * SECS_PER_DAY);
     197                 :                         } else {
     198              28 :                                 res += (DAYS_PER_YEAR * SECS_PER_DAY);
     199                 :                         }
     200                 :                 }
     201                 :         } else {
     202               0 :                 for (i = 1969; i >= year; i--) {
     203               0 :                         if (timelib_is_leap(i)) {
     204               0 :                                 res -= (DAYS_PER_LYEAR * SECS_PER_DAY);
     205                 :                         } else {
     206               0 :                                 res -= (DAYS_PER_YEAR * SECS_PER_DAY);
     207                 :                         }
     208                 :                 }
     209                 :         }
     210               1 :         return res;
     211                 : }
     212                 : 
     213                 : static timelib_sll do_months(timelib_ull month, timelib_ull year)
     214               1 : {
     215               1 :         if (timelib_is_leap(year)) {
     216               0 :                 return ((month_tab_leap[month - 1] + 1) * SECS_PER_DAY);
     217                 :         } else {
     218               1 :                 return ((month_tab[month - 1]) * SECS_PER_DAY);
     219                 :         }
     220                 : }
     221                 : 
     222                 : static timelib_sll do_days(timelib_ull day)
     223               1 : {
     224               1 :         return ((day - 1) * SECS_PER_DAY);
     225                 : }
     226                 : 
     227                 : static timelib_sll do_time(timelib_ull hour, timelib_ull minute, timelib_ull second)
     228               1 : {
     229               1 :         timelib_sll res = 0;
     230                 : 
     231               1 :         res += hour * 3600;
     232               1 :         res += minute * 60;
     233               1 :         res += second;
     234               1 :         return res;
     235                 : }
     236                 : 
     237                 : static timelib_sll do_adjust_timezone(timelib_time *tz, timelib_tzinfo *tzi)
     238               1 : {
     239               1 :         switch (tz->zone_type) {
     240                 :                 case TIMELIB_ZONETYPE_OFFSET:
     241                 : 
     242               0 :                         tz->is_localtime = 1;
     243               0 :                         return tz->z * 60;
     244                 :                         break;
     245                 : 
     246                 :                 case TIMELIB_ZONETYPE_ABBR: {
     247                 :                         timelib_sll tmp;
     248                 : 
     249               1 :                         tz->is_localtime = 1;
     250               1 :                         tmp = tz->z;
     251               1 :                         tmp -= tz->dst * 60;
     252               1 :                         tmp *= 60;
     253               1 :                         return tmp;
     254                 :                         }
     255                 :                         break;
     256                 : 
     257                 :                 case TIMELIB_ZONETYPE_ID:
     258               0 :                         tzi = tz->tz_info;
     259                 :                         /* Break intentionally missing */
     260                 : 
     261                 :                 default:
     262                 :                         /* No timezone in struct, fallback to reference if possible */
     263               0 :                         if (tzi) {
     264                 :                                 timelib_time_offset *before, *after;
     265                 :                                 timelib_sll          tmp;
     266                 :                                 int                  in_transistion;
     267                 :                                 
     268               0 :                                 tz->is_localtime = 1;
     269               0 :                                 before = timelib_get_time_zone_info(tz->sse, tzi);
     270               0 :                                 after = timelib_get_time_zone_info(tz->sse - before->offset, tzi);
     271               0 :                                 timelib_set_timezone(tz, tzi);
     272                 : 
     273               0 :                                 in_transistion = (
     274                 :                                         ((tz->sse - after->offset) >= (after->transistion_time + (before->offset - after->offset))) &&
     275                 :                                         ((tz->sse - after->offset) < after->transistion_time)
     276                 :                                 );
     277                 :                                 
     278               0 :                                 if ((before->offset != after->offset) && !in_transistion) {
     279               0 :                                         tmp = -after->offset;
     280                 :                                 } else {
     281               0 :                                         tmp = -tz->z;
     282                 :                                 }
     283               0 :                                 timelib_time_offset_dtor(before);
     284               0 :                                 timelib_time_offset_dtor(after);
     285                 :                                 
     286               0 :                                 return tmp;
     287                 :                         }
     288                 :         }
     289               0 :         return 0;
     290                 : }
     291                 : 
     292                 : void timelib_update_ts(timelib_time* time, timelib_tzinfo* tzi)
     293               1 : {
     294               1 :         timelib_sll res = 0;
     295                 : 
     296               1 :         do_adjust_relative(time);
     297               1 :         do_adjust_special(time);
     298               1 :         res += do_years(time->y);
     299               1 :         res += do_months(time->m, time->y);
     300               1 :         res += do_days(time->d);
     301               1 :         res += do_time(time->h, time->i, time->s);
     302               1 :         time->sse = res;
     303                 : 
     304               1 :         res += do_adjust_timezone(time, tzi);
     305               1 :         time->sse = res;
     306                 : 
     307               1 :         time->sse_uptodate = 1;
     308               1 : }
     309                 : 
     310                 : #if 0
     311                 : int main(void)
     312                 : {
     313                 :         timelib_sll res;
     314                 :         timelib_time time;
     315                 : 
     316                 :         time = timelib_strtotime("10 Feb 2005 06:07:03 PM CET"); /* 1108055223 */
     317                 :         printf ("%04d-%02d-%02d %02d:%02d:%02d.%-5d %+04d %1d",
     318                 :                 time.y, time.m, time.d, time.h, time.i, time.s, time.f, time.z, time.dst);
     319                 :         if (time.have_relative) {
     320                 :                 printf ("%3dY %3dM %3dD / %3dH %3dM %3dS", 
     321                 :                         time.relative.y, time.relative.m, time.relative.d, time.relative.h, time.relative.i, time.relative.s);
     322                 :         }
     323                 :         if (time.have_weekday_relative) {
     324                 :                 printf (" / %d", time.relative.weekday);
     325                 :         }
     326                 :         res = time2unixtime(&time);
     327                 :         printf("%Ld\n", res);
     328                 : 
     329                 :         return 0;
     330                 : }
     331                 : #endif

Generated by: LTP GCOV extension version 1.5