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 - php_date.c
Test: PHP Code Coverage
Date: 2009-11-19 Instrumented lines: 1052
Code covered: 90.3 % Executed lines: 950
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: php_date.c 289991 2009-10-27 16:21:03Z felipe $ */
      20                 : 
      21                 : #include "php.h"
      22                 : #include "php_streams.h"
      23                 : #include "php_main.h"
      24                 : #include "php_globals.h"
      25                 : #include "php_ini.h"
      26                 : #include "ext/standard/info.h"
      27                 : #include "ext/standard/php_versioning.h"
      28                 : #include "ext/standard/php_math.h"
      29                 : #include "php_date.h"
      30                 : #include "lib/timelib.h"
      31                 : #include <time.h>
      32                 : 
      33                 : #ifdef PHP_WIN32
      34                 : static __inline __int64 llabs( __int64 i ) { return i >= 0? i: -i; }
      35                 : #endif
      36                 : 
      37                 : #if defined(__GNUC__) && __GNUC__ < 3
      38                 : static __inline __int64_t llabs( __int64_t i ) { return i >= 0 ? i : -i; }
      39                 : #endif
      40                 : 
      41                 : #if defined(NETWARE) && defined(__MWERKS__)
      42                 : static __inline long long llabs( long long i ) { return i >= 0 ? i : -i; }
      43                 : #endif
      44                 : 
      45                 : /* {{{ arginfo */
      46                 : static
      47                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_date, 0, 0, 1)
      48                 :         ZEND_ARG_INFO(0, format)
      49                 :         ZEND_ARG_INFO(0, timestamp)
      50                 : ZEND_END_ARG_INFO()
      51                 : 
      52                 : static
      53                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_gmdate, 0, 0, 1)
      54                 :         ZEND_ARG_INFO(0, format)
      55                 :         ZEND_ARG_INFO(0, timestamp)
      56                 : ZEND_END_ARG_INFO()
      57                 : 
      58                 : static
      59                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_idate, 0, 0, 1)
      60                 :         ZEND_ARG_INFO(0, format)
      61                 :         ZEND_ARG_INFO(0, timestamp)
      62                 : ZEND_END_ARG_INFO()
      63                 : 
      64                 : static
      65                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_strtotime, 0, 0, 1)
      66                 :         ZEND_ARG_INFO(0, time)
      67                 :         ZEND_ARG_INFO(0, now)
      68                 : ZEND_END_ARG_INFO()
      69                 : 
      70                 : static
      71                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_mktime, 0, 0, 0)
      72                 :         ZEND_ARG_INFO(0, hour)
      73                 :         ZEND_ARG_INFO(0, min)
      74                 :         ZEND_ARG_INFO(0, sec)
      75                 :         ZEND_ARG_INFO(0, mon)
      76                 :         ZEND_ARG_INFO(0, day)
      77                 :         ZEND_ARG_INFO(0, year)
      78                 : ZEND_END_ARG_INFO()
      79                 : 
      80                 : static
      81                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_gmmktime, 0, 0, 0)
      82                 :         ZEND_ARG_INFO(0, hour)
      83                 :         ZEND_ARG_INFO(0, min)
      84                 :         ZEND_ARG_INFO(0, sec)
      85                 :         ZEND_ARG_INFO(0, mon)
      86                 :         ZEND_ARG_INFO(0, day)
      87                 :         ZEND_ARG_INFO(0, year)
      88                 : ZEND_END_ARG_INFO()
      89                 : 
      90                 : static
      91                 : ZEND_BEGIN_ARG_INFO(arginfo_checkdate, 0)
      92                 :         ZEND_ARG_INFO(0, month)
      93                 :         ZEND_ARG_INFO(0, day)
      94                 :         ZEND_ARG_INFO(0, year)
      95                 : ZEND_END_ARG_INFO()
      96                 : 
      97                 : static
      98                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_strftime, 0, 0, 1)
      99                 :         ZEND_ARG_INFO(0, format)
     100                 :         ZEND_ARG_INFO(0, timestamp)
     101                 : ZEND_END_ARG_INFO()
     102                 : 
     103                 : static
     104                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_gmstrftime, 0, 0, 1)
     105                 :         ZEND_ARG_INFO(0, format)
     106                 :         ZEND_ARG_INFO(0, timestamp)
     107                 : ZEND_END_ARG_INFO()
     108                 : 
     109                 : static
     110                 : ZEND_BEGIN_ARG_INFO(arginfo_time, 0)
     111                 : ZEND_END_ARG_INFO()
     112                 : 
     113                 : static
     114                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_localtime, 0, 0, 0)
     115                 :         ZEND_ARG_INFO(0, timestamp)
     116                 :         ZEND_ARG_INFO(0, associative_array)
     117                 : ZEND_END_ARG_INFO()
     118                 : 
     119                 : static
     120                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_getdate, 0, 0, 0)
     121                 :         ZEND_ARG_INFO(0, timestamp)
     122                 : ZEND_END_ARG_INFO()
     123                 : 
     124                 : static
     125                 : ZEND_BEGIN_ARG_INFO(arginfo_date_default_timezone_set, 0)
     126                 :         ZEND_ARG_INFO(0, timezone_identifier)
     127                 : ZEND_END_ARG_INFO()
     128                 : 
     129                 : static
     130                 : ZEND_BEGIN_ARG_INFO(arginfo_date_default_timezone_get, 0)
     131                 : ZEND_END_ARG_INFO()
     132                 : 
     133                 : static
     134                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_date_sunrise, 0, 0, 1)
     135                 :         ZEND_ARG_INFO(0, time)
     136                 :         ZEND_ARG_INFO(0, format)
     137                 :         ZEND_ARG_INFO(0, latitude)
     138                 :         ZEND_ARG_INFO(0, longitude)
     139                 :         ZEND_ARG_INFO(0, zenith)
     140                 :         ZEND_ARG_INFO(0, gmt_offset)
     141                 : ZEND_END_ARG_INFO()
     142                 : 
     143                 : static
     144                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_date_sunset, 0, 0, 1)
     145                 :         ZEND_ARG_INFO(0, time)
     146                 :         ZEND_ARG_INFO(0, format)
     147                 :         ZEND_ARG_INFO(0, latitude)
     148                 :         ZEND_ARG_INFO(0, longitude)
     149                 :         ZEND_ARG_INFO(0, zenith)
     150                 :         ZEND_ARG_INFO(0, gmt_offset)
     151                 : ZEND_END_ARG_INFO()
     152                 : 
     153                 : static
     154                 : ZEND_BEGIN_ARG_INFO(arginfo_date_sun_info, 0)
     155                 :         ZEND_ARG_INFO(0, time)
     156                 :         ZEND_ARG_INFO(0, latitude)
     157                 :         ZEND_ARG_INFO(0, longitude)
     158                 : ZEND_END_ARG_INFO()
     159                 : 
     160                 : /* }}} */
     161                 : 
     162                 : /* {{{ Function table */
     163                 : zend_function_entry date_functions[] = {
     164                 :         PHP_FE(strtotime, arginfo_strtotime)
     165                 :         PHP_FE(date, arginfo_date)
     166                 :         PHP_FE(idate, arginfo_idate)
     167                 :         PHP_FE(gmdate, arginfo_gmdate)
     168                 :         PHP_FE(mktime, arginfo_mktime)
     169                 :         PHP_FE(gmmktime, arginfo_gmmktime)
     170                 :         PHP_FE(checkdate, arginfo_checkdate)
     171                 : 
     172                 : #ifdef HAVE_STRFTIME
     173                 :         PHP_FE(strftime, arginfo_strftime)
     174                 :         PHP_FE(gmstrftime, arginfo_gmstrftime)
     175                 : #endif
     176                 : 
     177                 :         PHP_FE(time, arginfo_time)
     178                 :         PHP_FE(localtime, arginfo_localtime)
     179                 :         PHP_FE(getdate, arginfo_getdate)
     180                 : 
     181                 :         /* Advanced Interface */
     182                 :         PHP_FE(date_create, NULL)
     183                 :         PHP_FE(date_parse, NULL)
     184                 :         PHP_FE(date_format, NULL)
     185                 :         PHP_FE(date_modify, NULL)
     186                 :         PHP_FE(date_timezone_get, NULL)
     187                 :         PHP_FE(date_timezone_set, NULL)
     188                 :         PHP_FE(date_offset_get, NULL)
     189                 : 
     190                 :         PHP_FE(date_time_set, NULL)
     191                 :         PHP_FE(date_date_set, NULL)
     192                 :         PHP_FE(date_isodate_set, NULL)
     193                 : 
     194                 :         PHP_FE(timezone_open, NULL)
     195                 :         PHP_FE(timezone_name_get, NULL)
     196                 :         PHP_FE(timezone_name_from_abbr, NULL)
     197                 :         PHP_FE(timezone_offset_get, NULL)
     198                 :         PHP_FE(timezone_transitions_get, NULL)
     199                 :         PHP_FE(timezone_identifiers_list, NULL)
     200                 :         PHP_FE(timezone_abbreviations_list, NULL)
     201                 : 
     202                 :         /* Options and Configuration */
     203                 :         PHP_FE(date_default_timezone_set, arginfo_date_default_timezone_set)
     204                 :         PHP_FE(date_default_timezone_get, arginfo_date_default_timezone_get)
     205                 : 
     206                 :         /* Astronomical functions */
     207                 :         PHP_FE(date_sunrise, arginfo_date_sunrise)
     208                 :         PHP_FE(date_sunset, arginfo_date_sunset)
     209                 :         PHP_FE(date_sun_info, arginfo_date_sun_info)
     210                 :         {NULL, NULL, NULL}
     211                 : };
     212                 : 
     213                 : zend_function_entry date_funcs_date[] = {
     214                 :         PHP_ME(DateTime,                        __construct,            NULL, ZEND_ACC_CTOR|ZEND_ACC_PUBLIC)
     215                 :         PHP_ME_MAPPING(format,          date_format,            NULL, 0)
     216                 :         PHP_ME_MAPPING(modify,          date_modify,            NULL, 0)
     217                 :         PHP_ME_MAPPING(getTimezone, date_timezone_get,  NULL, 0)
     218                 :         PHP_ME_MAPPING(setTimezone, date_timezone_set,  NULL, 0)
     219                 :         PHP_ME_MAPPING(getOffset,       date_offset_get,        NULL, 0)
     220                 :         PHP_ME_MAPPING(setTime,         date_time_set,          NULL, 0)
     221                 :         PHP_ME_MAPPING(setDate,         date_date_set,          NULL, 0)
     222                 :         PHP_ME_MAPPING(setISODate,      date_isodate_set,       NULL, 0)
     223                 :         {NULL, NULL, NULL}
     224                 : };
     225                 : 
     226                 : zend_function_entry date_funcs_timezone[] = {
     227                 :         PHP_ME(DateTimeZone,                            __construct,                            NULL, ZEND_ACC_CTOR|ZEND_ACC_PUBLIC)
     228                 :         PHP_ME_MAPPING(getName,                         timezone_name_get,                      NULL, 0)
     229                 :         PHP_ME_MAPPING(getOffset,                       timezone_offset_get,            NULL, 0)
     230                 :         PHP_ME_MAPPING(getTransitions,          timezone_transitions_get,       NULL, 0)
     231                 :         PHP_ME_MAPPING(listAbbreviations,       timezone_abbreviations_list, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
     232                 :         PHP_ME_MAPPING(listIdentifiers,         timezone_identifiers_list,      NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
     233                 :         {NULL, NULL, NULL}
     234                 : };
     235                 : 
     236                 : static void date_register_classes(TSRMLS_D);
     237                 : static char* guess_timezone(const timelib_tzdb *tzdb TSRMLS_DC);
     238                 : /* }}} */
     239                 : 
     240                 : ZEND_DECLARE_MODULE_GLOBALS(date)
     241                 : static PHP_GINIT_FUNCTION(date);
     242                 : 
     243                 : /* True global */
     244                 : timelib_tzdb *php_date_global_timezone_db;
     245                 : int php_date_global_timezone_db_enabled;
     246                 : 
     247                 : #define DATE_DEFAULT_LATITUDE "31.7667"
     248                 : #define DATE_DEFAULT_LONGITUDE "35.2333"
     249                 : 
     250                 : /* on 90'35; common sunset declaration (start of sun body appear) */
     251                 : #define DATE_SUNSET_ZENITH "90.583333"
     252                 : 
     253                 : /* on 90'35; common sunrise declaration (sun body disappeared) */
     254                 : #define DATE_SUNRISE_ZENITH "90.583333"
     255                 : 
     256                 : /* {{{ INI Settings */
     257                 : PHP_INI_BEGIN()
     258                 :         STD_PHP_INI_ENTRY("date.timezone", "", PHP_INI_ALL, OnUpdateString, default_timezone, zend_date_globals, date_globals)
     259                 :         PHP_INI_ENTRY("date.default_latitude",           DATE_DEFAULT_LATITUDE,        PHP_INI_ALL, NULL)
     260                 :         PHP_INI_ENTRY("date.default_longitude",          DATE_DEFAULT_LONGITUDE,       PHP_INI_ALL, NULL)
     261                 :         PHP_INI_ENTRY("date.sunset_zenith",              DATE_SUNSET_ZENITH,           PHP_INI_ALL, NULL)
     262                 :         PHP_INI_ENTRY("date.sunrise_zenith",             DATE_SUNRISE_ZENITH,          PHP_INI_ALL, NULL)
     263                 : PHP_INI_END()
     264                 : /* }}} */
     265                 : 
     266                 : zend_class_entry *date_ce_date, *date_ce_timezone;
     267                 : 
     268                 : static zend_object_handlers date_object_handlers_date;
     269                 : static zend_object_handlers date_object_handlers_timezone;
     270                 : 
     271                 : typedef struct _php_date_obj php_date_obj;
     272                 : typedef struct _php_timezone_obj php_timezone_obj;
     273                 : 
     274                 : struct _php_date_obj {
     275                 :         zend_object   std;
     276                 :         timelib_time *time;
     277                 : };
     278                 : 
     279                 : struct _php_timezone_obj {
     280                 :         zend_object     std;
     281                 :         int             initialized;
     282                 :         int             type;
     283                 :         union {
     284                 :                 timelib_tzinfo *tz; /* TIMELIB_ZONETYPE_ID; */
     285                 :                 timelib_sll     utc_offset; /* TIMELIB_ZONETYPE_OFFSET */
     286                 :                 struct                      /* TIMELIB_ZONETYPE_ABBR */
     287                 :                 {
     288                 :                         timelib_sll  utc_offset;
     289                 :                         char        *abbr;
     290                 :                         int          dst;
     291                 :                 } z;
     292                 :         } tzi;
     293                 : };
     294                 : 
     295                 : #define DATE_SET_CONTEXT \
     296                 :         zval *object; \
     297                 :         object = getThis(); \
     298                 :    
     299                 : #define DATE_FETCH_OBJECT       \
     300                 :         php_date_obj *obj;      \
     301                 :         DATE_SET_CONTEXT; \
     302                 :         if (object) {   \
     303                 :                 if (ZEND_NUM_ARGS()) {  \
     304                 :                         WRONG_PARAM_COUNT;      \
     305                 :                 }       \
     306                 :         } else {        \
     307                 :                 if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, NULL, "O", &object, date_ce_date) == FAILURE) {       \
     308                 :                         RETURN_FALSE;   \
     309                 :                 }       \
     310                 :         }       \
     311                 :         obj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC);  \
     312                 : 
     313                 : #define DATE_CHECK_INITIALIZED(member, class_name) \
     314                 :         if (!(member)) { \
     315                 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "The " #class_name " object has not been correctly initialized by its constructor"); \
     316                 :                 RETURN_FALSE; \
     317                 :         }
     318                 : 
     319                 : static void date_object_free_storage_date(void *object TSRMLS_DC);
     320                 : static void date_object_free_storage_timezone(void *object TSRMLS_DC);
     321                 : static zend_object_value date_object_new_date(zend_class_entry *class_type TSRMLS_DC);
     322                 : static zend_object_value date_object_new_timezone(zend_class_entry *class_type TSRMLS_DC);
     323                 : static zend_object_value date_object_clone_date(zval *this_ptr TSRMLS_DC);
     324                 : static int date_object_compare_date(zval *d1, zval *d2 TSRMLS_DC);
     325                 : static zend_object_value date_object_clone_timezone(zval *this_ptr TSRMLS_DC);
     326                 : 
     327                 : /* {{{ Module struct */
     328                 : zend_module_entry date_module_entry = {
     329                 :         STANDARD_MODULE_HEADER_EX,
     330                 :         NULL,
     331                 :         NULL,
     332                 :         "date",                     /* extension name */
     333                 :         date_functions,             /* function list */
     334                 :         PHP_MINIT(date),            /* process startup */
     335                 :         PHP_MSHUTDOWN(date),        /* process shutdown */
     336                 :         PHP_RINIT(date),            /* request startup */
     337                 :         PHP_RSHUTDOWN(date),        /* request shutdown */
     338                 :         PHP_MINFO(date),            /* extension info */
     339                 :         PHP_VERSION,                /* extension version */
     340                 :         PHP_MODULE_GLOBALS(date),   /* globals descriptor */
     341                 :         PHP_GINIT(date),            /* globals ctor */
     342                 :         NULL,                       /* globals dtor */
     343                 :         NULL,                       /* post deactivate */
     344                 :         STANDARD_MODULE_PROPERTIES_EX
     345                 : };
     346                 : /* }}} */
     347                 : 
     348                 : 
     349                 : /* {{{ PHP_GINIT_FUNCTION */
     350                 : static PHP_GINIT_FUNCTION(date)
     351           13565 : {
     352           13565 :         date_globals->default_timezone = NULL;
     353           13565 :         date_globals->timezone = NULL;
     354           13565 :         date_globals->tzcache = NULL;
     355           13565 : }
     356                 : /* }}} */
     357                 : 
     358                 : 
     359                 : static void _php_date_tzinfo_dtor(void *tzinfo)
     360             468 : {
     361             468 :         timelib_tzinfo **tzi = (timelib_tzinfo **)tzinfo;
     362                 : 
     363             468 :         timelib_tzinfo_dtor(*tzi);
     364             468 : }
     365                 : 
     366                 : /* {{{ PHP_RINIT_FUNCTION */
     367                 : PHP_RINIT_FUNCTION(date)
     368           13551 : {
     369           13551 :         if (DATEG(timezone)) {
     370               0 :                 efree(DATEG(timezone));
     371                 :         }
     372           13551 :         DATEG(timezone) = NULL;
     373           13551 :         DATEG(tzcache) = NULL;
     374                 : 
     375           13551 :         return SUCCESS;
     376                 : }
     377                 : /* }}} */
     378                 : 
     379                 : /* {{{ PHP_RSHUTDOWN_FUNCTION */
     380                 : PHP_RSHUTDOWN_FUNCTION(date)
     381           13584 : {
     382           13584 :         if (DATEG(timezone)) {
     383             303 :                 efree(DATEG(timezone));
     384                 :         }
     385           13584 :         DATEG(timezone) = NULL;
     386           13584 :         if(DATEG(tzcache)) {
     387             326 :                 zend_hash_destroy(DATEG(tzcache));
     388             326 :                 FREE_HASHTABLE(DATEG(tzcache));
     389             326 :                 DATEG(tzcache) = NULL;
     390                 :         }
     391                 : 
     392           13584 :         return SUCCESS;
     393                 : }
     394                 : /* }}} */
     395                 : 
     396                 : #define DATE_TIMEZONEDB      php_date_global_timezone_db ? php_date_global_timezone_db : timelib_builtin_db()
     397                 : 
     398                 : /*
     399                 :  * RFC822, Section 5.1: http://www.ietf.org/rfc/rfc822.txt
     400                 :  *  date-time   =  [ day "," ] date time        ; dd mm yy hh:mm:ss zzz
     401                 :  *  day         =  "Mon"  / "Tue" /  "Wed"  / "Thu"  /  "Fri"  / "Sat" /  "Sun"
     402                 :  *  date        =  1*2DIGIT month 2DIGIT        ; day month year e.g. 20 Jun 82
     403                 :  *  month       =  "Jan"  /  "Feb" /  "Mar"  /  "Apr"  /  "May"  /  "Jun" /  "Jul"  /  "Aug"  /  "Sep"  /  "Oct" /  "Nov"  /  "Dec"
     404                 :  *  time        =  hour zone                    ; ANSI and Military
     405                 :  *  hour        =  2DIGIT ":" 2DIGIT [":" 2DIGIT] ; 00:00:00 - 23:59:59
     406                 :  *  zone        =  "UT"  / "GMT"  /  "EST" / "EDT"  /  "CST" / "CDT"  /  "MST" / "MDT"  /  "PST" / "PDT"  /  1ALPHA  / ( ("+" / "-") 4DIGIT )
     407                 :  */
     408                 : #define DATE_FORMAT_RFC822   "D, d M y H:i:s O"
     409                 : 
     410                 : /*
     411                 :  * RFC850, Section 2.1.4: http://www.ietf.org/rfc/rfc850.txt
     412                 :  *  Format must be acceptable both to the ARPANET and to the getdate routine.
     413                 :  *  One format that is acceptable to both is Weekday, DD-Mon-YY HH:MM:SS TIMEZONE
     414                 :  *  TIMEZONE can be any timezone name (3 or more letters)
     415                 :  */
     416                 : #define DATE_FORMAT_RFC850   "l, d-M-y H:i:s T"
     417                 : 
     418                 : /*
     419                 :  * RFC1036, Section 2.1.2: http://www.ietf.org/rfc/rfc1036.txt
     420                 :  *  Its format must be acceptable both in RFC-822 and to the getdate(3)
     421                 :  *  Wdy, DD Mon YY HH:MM:SS TIMEZONE
     422                 :  *  There is no hope of having a complete list of timezones.  Universal
     423                 :  *  Time (GMT), the North American timezones (PST, PDT, MST, MDT, CST,
     424                 :  *  CDT, EST, EDT) and the +/-hhmm offset specifed in RFC-822 should be supported.
     425                 :  */
     426                 : #define DATE_FORMAT_RFC1036  "D, d M y H:i:s O"
     427                 : 
     428                 : /*
     429                 :  * RFC1123, Section 5.2.14: http://www.ietf.org/rfc/rfc1123.txt
     430                 :  *  RFC-822 Date and Time Specification: RFC-822 Section 5
     431                 :  *  The syntax for the date is hereby changed to: date = 1*2DIGIT month 2*4DIGIT
     432                 :  */
     433                 : #define DATE_FORMAT_RFC1123  "D, d M Y H:i:s O"
     434                 : 
     435                 : /*
     436                 :  * RFC2822, Section 3.3: http://www.ietf.org/rfc/rfc2822.txt
     437                 :  *  FWS             =       ([*WSP CRLF] 1*WSP) /   ; Folding white space
     438                 :  *  CFWS            =       *([FWS] comment) (([FWS] comment) / FWS)
     439                 :  *  
     440                 :  *  date-time       =       [ day-of-week "," ] date FWS time [CFWS]
     441                 :  *  day-of-week     =       ([FWS] day-name)
     442                 :  *  day-name        =       "Mon" / "Tue" / "Wed" / "Thu" / "Fri" / "Sat" / "Sun"
     443                 :  *  date            =       day month year
     444                 :  *  year            =       4*DIGIT
     445                 :  *  month           =       (FWS month-name FWS)
     446                 :  *  month-name      =       "Jan" / "Feb" / "Mar" / "Apr" / "May" / "Jun" / "Jul" / "Aug" / "Sep" / "Oct" / "Nov" / "Dec"
     447                 :  *  day             =       ([FWS] 1*2DIGIT)
     448                 :  *  time            =       time-of-day FWS zone
     449                 :  *  time-of-day     =       hour ":" minute [ ":" second ]
     450                 :  *  hour            =       2DIGIT
     451                 :  *  minute          =       2DIGIT
     452                 :  *  second          =       2DIGIT
     453                 :  *  zone            =       (( "+" / "-" ) 4DIGIT)
     454                 :  */
     455                 : #define DATE_FORMAT_RFC2822  "D, d M Y H:i:s O"
     456                 : /*
     457                 :  * RFC3339, Section 5.6: http://www.ietf.org/rfc/rfc3339.txt
     458                 :  *  date-fullyear   = 4DIGIT
     459                 :  *  date-month      = 2DIGIT  ; 01-12
     460                 :  *  date-mday       = 2DIGIT  ; 01-28, 01-29, 01-30, 01-31 based on month/year
     461                 :  *  
     462                 :  *  time-hour       = 2DIGIT  ; 00-23
     463                 :  *  time-minute     = 2DIGIT  ; 00-59
     464                 :  *  time-second     = 2DIGIT  ; 00-58, 00-59, 00-60 based on leap second rules
     465                 :  *  
     466                 :  *  time-secfrac    = "." 1*DIGIT
     467                 :  *  time-numoffset  = ("+" / "-") time-hour ":" time-minute
     468                 :  *  time-offset     = "Z" / time-numoffset
     469                 :  *  
     470                 :  *  partial-time    = time-hour ":" time-minute ":" time-second [time-secfrac]
     471                 :  *  full-date       = date-fullyear "-" date-month "-" date-mday
     472                 :  *  full-time       = partial-time time-offset
     473                 :  *  
     474                 :  *  date-time       = full-date "T" full-time
     475                 :  */
     476                 : #define DATE_FORMAT_RFC3339  "Y-m-d\\TH:i:sP"
     477                 : 
     478                 : #define DATE_FORMAT_ISO8601  "Y-m-d\\TH:i:sO"
     479                 : 
     480                 : #define DATE_TZ_ERRMSG \
     481                 :         "It is not safe to rely on the system's timezone settings. Please use " \
     482                 :         "the date.timezone setting, the TZ environment variable or the " \
     483                 :         "date_default_timezone_set() function. In case you used any of those " \
     484                 :         "methods and you are still getting this warning, you most likely " \
     485                 :         "misspelled the timezone identifier. "
     486                 : 
     487                 : #define SUNFUNCS_RET_TIMESTAMP 0
     488                 : #define SUNFUNCS_RET_STRING    1
     489                 : #define SUNFUNCS_RET_DOUBLE    2
     490                 : 
     491                 : 
     492                 : /* {{{ PHP_MINIT_FUNCTION */
     493                 : PHP_MINIT_FUNCTION(date)
     494           13565 : {
     495           13565 :         REGISTER_INI_ENTRIES();
     496           13565 :         date_register_classes(TSRMLS_C);
     497                 : /*
     498                 :  * RFC4287, Section 3.3: http://www.ietf.org/rfc/rfc4287.txt
     499                 :  *   A Date construct is an element whose content MUST conform to the
     500                 :  *   "date-time" production in [RFC3339].  In addition, an uppercase "T"
     501                 :  *   character MUST be used to separate date and time, and an uppercase
     502                 :  *   "Z" character MUST be present in the absence of a numeric time zone offset.
     503                 :  */
     504           13565 :         REGISTER_STRING_CONSTANT("DATE_ATOM",    DATE_FORMAT_RFC3339, CONST_CS | CONST_PERSISTENT);
     505                 : /*
     506                 :  * Preliminary specification: http://wp.netscape.com/newsref/std/cookie_spec.html
     507                 :  *   "This is based on RFC 822, RFC 850,  RFC 1036, and  RFC 1123,
     508                 :  *   with the variations that the only legal time zone is GMT
     509                 :  *   and the separators between the elements of the date must be dashes."
     510                 :  */
     511           13565 :         REGISTER_STRING_CONSTANT("DATE_COOKIE",  DATE_FORMAT_RFC850,  CONST_CS | CONST_PERSISTENT);
     512           13565 :         REGISTER_STRING_CONSTANT("DATE_ISO8601", DATE_FORMAT_ISO8601, CONST_CS | CONST_PERSISTENT);
     513           13565 :         REGISTER_STRING_CONSTANT("DATE_RFC822",  DATE_FORMAT_RFC822,  CONST_CS | CONST_PERSISTENT);
     514           13565 :         REGISTER_STRING_CONSTANT("DATE_RFC850",  DATE_FORMAT_RFC850,  CONST_CS | CONST_PERSISTENT);
     515           13565 :         REGISTER_STRING_CONSTANT("DATE_RFC1036", DATE_FORMAT_RFC1036, CONST_CS | CONST_PERSISTENT);
     516           13565 :         REGISTER_STRING_CONSTANT("DATE_RFC1123", DATE_FORMAT_RFC1123, CONST_CS | CONST_PERSISTENT);
     517           13565 :         REGISTER_STRING_CONSTANT("DATE_RFC2822", DATE_FORMAT_RFC2822, CONST_CS | CONST_PERSISTENT);
     518           13565 :         REGISTER_STRING_CONSTANT("DATE_RFC3339", DATE_FORMAT_RFC3339, CONST_CS | CONST_PERSISTENT);
     519                 : /*
     520                 :  * RSS 2.0 Specification: http://blogs.law.harvard.edu/tech/rss
     521                 :  *   "All date-times in RSS conform to the Date and Time Specification of RFC 822,
     522                 :  *   with the exception that the year may be expressed with two characters or four characters (four preferred)"
     523                 :  */
     524           13565 :         REGISTER_STRING_CONSTANT("DATE_RSS",     DATE_FORMAT_RFC1123, CONST_CS | CONST_PERSISTENT);
     525           13565 :         REGISTER_STRING_CONSTANT("DATE_W3C",     DATE_FORMAT_RFC3339, CONST_CS | CONST_PERSISTENT);
     526                 : 
     527           13565 :         REGISTER_LONG_CONSTANT("SUNFUNCS_RET_TIMESTAMP", SUNFUNCS_RET_TIMESTAMP, CONST_CS | CONST_PERSISTENT);
     528           13565 :         REGISTER_LONG_CONSTANT("SUNFUNCS_RET_STRING", SUNFUNCS_RET_STRING, CONST_CS | CONST_PERSISTENT);
     529           13565 :         REGISTER_LONG_CONSTANT("SUNFUNCS_RET_DOUBLE", SUNFUNCS_RET_DOUBLE, CONST_CS | CONST_PERSISTENT);
     530                 : 
     531           13565 :         php_date_global_timezone_db = NULL;
     532           13565 :         php_date_global_timezone_db_enabled = 0;
     533                 :         
     534           13565 :         return SUCCESS;
     535                 : }
     536                 : /* }}} */
     537                 : 
     538                 : /* {{{ PHP_MSHUTDOWN_FUNCTION */
     539                 : PHP_MSHUTDOWN_FUNCTION(date)
     540           13597 : {
     541           13597 :         UNREGISTER_INI_ENTRIES();
     542                 : 
     543           13597 :         return SUCCESS;
     544                 : }
     545                 : /* }}} */
     546                 : 
     547                 : /* {{{ PHP_MINFO_FUNCTION */
     548                 : PHP_MINFO_FUNCTION(date)
     549               7 : {
     550               7 :         const timelib_tzdb *tzdb = DATE_TIMEZONEDB;
     551                 :         
     552               7 :         php_info_print_table_start();
     553               7 :         php_info_print_table_row(2, "date/time support", "enabled");
     554               7 :         php_info_print_table_row(2, "\"Olson\" Timezone Database Version", tzdb->version);
     555               7 :         php_info_print_table_row(2, "Timezone Database", php_date_global_timezone_db_enabled ? "external" : "internal");
     556               7 :         php_info_print_table_row(2, "Default timezone", guess_timezone(tzdb TSRMLS_CC));
     557               7 :         php_info_print_table_end();
     558                 : 
     559               7 :         DISPLAY_INI_ENTRIES();
     560               7 : }
     561                 : /* }}} */
     562                 : 
     563                 : /* {{{ Timezone Cache functions */
     564                 : static timelib_tzinfo *php_date_parse_tzfile(char *formal_tzname, const timelib_tzdb *tzdb TSRMLS_DC)
     565            7181 : {
     566                 :         timelib_tzinfo *tzi, **ptzi;
     567                 : 
     568            7181 :         if(!DATEG(tzcache)) {
     569             326 :                 ALLOC_HASHTABLE(DATEG(tzcache));
     570             326 :                 zend_hash_init(DATEG(tzcache), 4, NULL, _php_date_tzinfo_dtor, 0);
     571                 :         }
     572                 : 
     573            7181 :         if (zend_hash_find(DATEG(tzcache), formal_tzname, strlen(formal_tzname) + 1, (void **) &ptzi) == SUCCESS) {
     574            6668 :                 return *ptzi;
     575                 :         }
     576                 : 
     577             513 :         tzi = timelib_parse_tzfile(formal_tzname, tzdb);
     578             513 :         if (tzi) {
     579             468 :                 zend_hash_add(DATEG(tzcache), formal_tzname, strlen(formal_tzname) + 1, (void *) &tzi, sizeof(timelib_tzinfo*), NULL);
     580                 :         }
     581             513 :         return tzi;
     582                 : }
     583                 : /* }}} */
     584                 : 
     585                 : /* {{{ Helper functions */
     586                 : static char* guess_timezone(const timelib_tzdb *tzdb TSRMLS_DC)
     587            7082 : {
     588                 :         char *env;
     589                 : 
     590                 :         /* Checking configure timezone */
     591            7082 :         if (DATEG(timezone) && (strlen(DATEG(timezone)) > 0)) {
     592            5934 :                 return DATEG(timezone);
     593                 :         }
     594                 :         /* Check environment variable */
     595            1148 :         env = getenv("TZ");
     596            1148 :         if (env && *env && timelib_timezone_id_is_valid(env, tzdb)) {
     597             888 :                 return env;
     598                 :         }
     599                 :         /* Check config setting for default timezone */
     600             260 :         if (!DATEG(default_timezone)) {
     601                 :                 /* Special case: ext/date wasn't initialized yet */
     602                 :                 zval ztz;
     603                 :                 
     604               0 :                 if (SUCCESS == zend_get_configuration_directive("date.timezone", sizeof("date.timezone"), &ztz) &&
     605                 :                     Z_TYPE(ztz) == IS_STRING &&
     606                 :                     Z_STRLEN(ztz) > 0 &&
     607                 :                     timelib_timezone_id_is_valid(Z_STRVAL(ztz), tzdb)) {
     608               0 :                         return Z_STRVAL(ztz);
     609                 :                 }
     610             260 :         } else if (*DATEG(default_timezone) && timelib_timezone_id_is_valid(DATEG(default_timezone), tzdb)) {
     611             254 :                 return DATEG(default_timezone);
     612                 :         }
     613                 : #if HAVE_TM_ZONE
     614                 :         /* Try to guess timezone from system information */
     615                 :         {
     616                 :                 struct tm *ta, tmbuf;
     617                 :                 time_t     the_time;
     618               6 :                 char      *tzid = NULL;
     619                 :                 
     620               6 :                 the_time = time(NULL);
     621               6 :                 ta = php_localtime_r(&the_time, &tmbuf);
     622               6 :                 if (ta) {
     623               6 :                         tzid = timelib_timezone_id_from_abbr(ta->tm_zone, ta->tm_gmtoff, ta->tm_isdst);
     624                 :                 }
     625               6 :                 if (! tzid) {
     626               0 :                         tzid = "UTC";
     627                 :                 }
     628                 :                 
     629               6 :                 php_error_docref(NULL TSRMLS_CC, E_STRICT, DATE_TZ_ERRMSG "We selected '%s' for '%s/%.1f/%s' instead", tzid, ta ? ta->tm_zone : "Unknown", ta ? (float) (ta->tm_gmtoff / 3600) : 0, ta ? (ta->tm_isdst ? "DST" : "no DST") : "Unknown");
     630               6 :                 return tzid;
     631                 :         }
     632                 : #endif
     633                 : #ifdef PHP_WIN32
     634                 :         {
     635                 :                 char *tzid;
     636                 :                 TIME_ZONE_INFORMATION tzi;
     637                 : 
     638                 :                 switch (GetTimeZoneInformation(&tzi))
     639                 :                 {
     640                 :                         /* no DST or not in effect */
     641                 :                         case TIME_ZONE_ID_UNKNOWN:
     642                 :                         case TIME_ZONE_ID_STANDARD:
     643                 : php_win_std_time:
     644                 :                                 tzid = timelib_timezone_id_from_abbr("", (tzi.Bias + tzi.StandardBias) * -60, 0);
     645                 :                                 if (! tzid) {
     646                 :                                         tzid = "UTC";
     647                 :                                 }
     648                 :                                 php_error_docref(NULL TSRMLS_CC, E_STRICT, DATE_TZ_ERRMSG "We selected '%s' for '%.1f/no DST' instead", tzid, ((tzi.Bias + tzi.StandardBias) / -60.0));
     649                 :                                 break;
     650                 : 
     651                 :                         /* DST in effect */
     652                 :                         case TIME_ZONE_ID_DAYLIGHT:
     653                 :                                 /* If user has disabled DST in the control panel, Windows returns 0 here */
     654                 :                                 if (tzi.DaylightBias == 0) {
     655                 :                                         goto php_win_std_time;
     656                 :                                 }
     657                 :                                 
     658                 :                                 tzid = timelib_timezone_id_from_abbr("", (tzi.Bias + tzi.DaylightBias) * -60, 1);
     659                 :                                 if (! tzid) {
     660                 :                                         tzid = "UTC";
     661                 :                                 }
     662                 :                                 php_error_docref(NULL TSRMLS_CC, E_STRICT, DATE_TZ_ERRMSG "We selected '%s' for '%.1f/DST' instead", tzid, ((tzi.Bias + tzi.DaylightBias) / -60.0));
     663                 :                                 break;
     664                 :                 }
     665                 :                 return tzid;
     666                 :         }
     667                 : #elif defined(NETWARE)
     668                 :         /* Try to guess timezone from system information */
     669                 :         {
     670                 :                 char *tzid = timelib_timezone_id_from_abbr("", ((_timezone * -1) + (daylightOffset * daylightOnOff)), daylightOnOff);
     671                 :                 if (tzid) {
     672                 :                         return tzid;
     673                 :                 }
     674                 :         }
     675                 : #endif
     676                 :         /* Fallback to UTC */
     677                 :         php_error_docref(NULL TSRMLS_CC, E_WARNING, DATE_TZ_ERRMSG "We had to select 'UTC' because your platform doesn't provide functionality for the guessing algorithm");
     678                 :         return "UTC";
     679                 : }
     680                 : 
     681                 : PHPAPI timelib_tzinfo *get_timezone_info(TSRMLS_D)
     682            7075 : {
     683                 :         char *tz;
     684                 :         timelib_tzinfo *tzi;
     685                 : 
     686            7075 :         tz = guess_timezone(DATE_TIMEZONEDB TSRMLS_CC);
     687            7075 :         tzi = php_date_parse_tzfile(tz, DATE_TIMEZONEDB TSRMLS_CC);
     688            7075 :         if (! tzi) {
     689               0 :                 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Timezone database is corrupt - this should *never* happen!");
     690                 :         }
     691            7075 :         return tzi;
     692                 : }
     693                 : /* }}} */
     694                 : 
     695                 : 
     696                 : /* {{{ date() and gmdate() data */
     697                 : #include "ext/standard/php_smart_str.h"
     698                 : 
     699                 : static char *mon_full_names[] = {
     700                 :         "January", "February", "March", "April",
     701                 :         "May", "June", "July", "August",
     702                 :         "September", "October", "November", "December"
     703                 : };
     704                 : 
     705                 : static char *mon_short_names[] = {
     706                 :         "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
     707                 : };
     708                 : 
     709                 : static char *day_full_names[] = {
     710                 :         "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
     711                 : };
     712                 : 
     713                 : static char *day_short_names[] = {
     714                 :         "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
     715                 : };
     716                 : 
     717                 : static char *english_suffix(timelib_sll number)
     718              37 : {
     719              37 :         if (number >= 10 && number <= 19) {
     720              13 :                 return "th";
     721                 :         } else {
     722              24 :                 switch (number % 10) {
     723               4 :                         case 1: return "st";
     724               2 :                         case 2: return "nd";
     725               2 :                         case 3: return "rd";
     726                 :                 }
     727                 :         }
     728              16 :         return "th";
     729                 : }
     730                 : /* }}} */
     731                 : 
     732                 : /* {{{ day of week helpers */
     733                 : char *php_date_full_day_name(timelib_sll y, timelib_sll m, timelib_sll d)
     734             235 : {
     735             235 :         timelib_sll day_of_week = timelib_day_of_week(y, m, d);
     736             235 :         if (day_of_week < 0) {
     737               0 :                 return "Unknown";
     738                 :         } 
     739             235 :         return day_full_names[day_of_week];     
     740                 : }
     741                 : 
     742                 : char *php_date_short_day_name(timelib_sll y, timelib_sll m, timelib_sll d)
     743             239 : {
     744             239 :         timelib_sll day_of_week = timelib_day_of_week(y, m, d);
     745             239 :         if (day_of_week < 0) {
     746               0 :                 return "Unknown";
     747                 :         } 
     748             239 :         return day_short_names[day_of_week];    
     749                 : }
     750                 : /* }}} */
     751                 : 
     752                 : /* {{{ date_format - (gm)date helper */
     753                 : static char *date_format(char *format, int format_len, timelib_time *t, int localtime)
     754            3951 : {
     755            3951 :         smart_str            string = {0};
     756                 :         int                  i, length;
     757                 :         char                 buffer[33];
     758            3951 :         timelib_time_offset *offset = NULL;
     759                 :         timelib_sll          isoweek, isoyear;
     760                 :         int                  rfc_colon;
     761                 : 
     762            3951 :         if (!format_len) {
     763              41 :                 return estrdup("");
     764                 :         }
     765                 : 
     766            3910 :         if (localtime) {
     767            2997 :                 if (t->zone_type == TIMELIB_ZONETYPE_ABBR) {
     768              11 :                         offset = timelib_time_offset_ctor();
     769              11 :                         offset->offset = (t->z - (t->dst * 60)) * -60;
     770              11 :                         offset->leap_secs = 0;
     771              11 :                         offset->is_dst = t->dst;
     772              11 :                         offset->abbr = strdup(t->tz_abbr);
     773            2986 :                 } else if (t->zone_type == TIMELIB_ZONETYPE_OFFSET) {
     774              17 :                         offset = timelib_time_offset_ctor();
     775              17 :                         offset->offset = (t->z) * -60;
     776              17 :                         offset->leap_secs = 0;
     777              17 :                         offset->is_dst = 0;
     778              17 :                         offset->abbr = malloc(9); /* GMT±xxxx\0 */
     779              17 :                         snprintf(offset->abbr, 9, "GMT%c%02d%02d", 
     780                 :                                                   localtime ? ((offset->offset < 0) ? '-' : '+') : '+',
     781                 :                                                   localtime ? abs(offset->offset / 3600) : 0,
     782                 :                                                   localtime ? abs((offset->offset % 3600) / 60) : 0 );
     783                 :                 } else {
     784            2969 :                         offset = timelib_get_time_zone_info(t->sse, t->tz_info);
     785                 :                 }
     786                 :         }
     787            3910 :         timelib_isoweek_from_date(t->y, t->m, t->d, &isoweek, &isoyear);
     788                 : 
     789           26263 :         for (i = 0; i < format_len; i++) {
     790           22353 :                 rfc_colon = 0;
     791           22353 :                 switch (format[i]) {
     792                 :                         /* day */
     793            1462 :                         case 'd': length = slprintf(buffer, 32, "%02d", (int) t->d); break;
     794             204 :                         case 'D': length = slprintf(buffer, 32, "%s", php_date_short_day_name(t->y, t->m, t->d)); break;
     795              82 :                         case 'j': length = slprintf(buffer, 32, "%d", (int) t->d); break;
     796             198 :                         case 'l': length = slprintf(buffer, 32, "%s", php_date_full_day_name(t->y, t->m, t->d)); break;
     797              37 :                         case 'S': length = slprintf(buffer, 32, "%s", english_suffix(t->d)); break;
     798              12 :                         case 'w': length = slprintf(buffer, 32, "%d", (int) timelib_day_of_week(t->y, t->m, t->d)); break;
     799               4 :                         case 'N': length = slprintf(buffer, 32, "%d", (int) timelib_iso_day_of_week(t->y, t->m, t->d)); break;
     800               6 :                         case 'z': length = slprintf(buffer, 32, "%d", (int) timelib_day_of_year(t->y, t->m, t->d)); break;
     801                 : 
     802                 :                         /* week */
     803            1040 :                         case 'W': length = slprintf(buffer, 32, "%02d", (int) isoweek); break; /* iso weeknr */
     804            1026 :                         case 'o': length = slprintf(buffer, 32, "%d", (int) isoyear); break; /* iso year */
     805                 : 
     806                 :                         /* month */
     807              51 :                         case 'F': length = slprintf(buffer, 32, "%s", mon_full_names[t->m - 1]); break;
     808            1353 :                         case 'm': length = slprintf(buffer, 32, "%02d", (int) t->m); break;
     809             183 :                         case 'M': length = slprintf(buffer, 32, "%s", mon_short_names[t->m - 1]); break;
     810              18 :                         case 'n': length = slprintf(buffer, 32, "%d", (int) t->m); break;
     811              20 :                         case 't': length = slprintf(buffer, 32, "%d", (int) timelib_days_in_month(t->y, t->m)); break;
     812                 : 
     813                 :                         /* year */
     814              10 :                         case 'L': length = slprintf(buffer, 32, "%d", timelib_is_leap((int) t->y)); break;
     815              67 :                         case 'y': length = slprintf(buffer, 32, "%02d", (int) t->y % 100); break;
     816            1503 :                         case 'Y': length = slprintf(buffer, 32, "%s%04lld", t->y < 0 ? "-" : "", llabs(t->y)); break;
     817                 : 
     818                 :                         /* time */
     819              38 :                         case 'a': length = slprintf(buffer, 32, "%s", t->h >= 12 ? "pm" : "am"); break;
     820               7 :                         case 'A': length = slprintf(buffer, 32, "%s", t->h >= 12 ? "PM" : "AM"); break;
     821                 :                         case 'B': {
     822               6 :                                 int retval = (((((long)t->sse)-(((long)t->sse) - ((((long)t->sse) % 86400) + 3600))) * 10) / 864);                     
     823              12 :                                 while (retval < 0) {
     824               0 :                                         retval += 1000;
     825                 :                                 }
     826               6 :                                 retval = retval % 1000;
     827               6 :                                 length = slprintf(buffer, 32, "%03d", retval);
     828               6 :                                 break;
     829                 :                         }
     830              34 :                         case 'g': length = slprintf(buffer, 32, "%d", (t->h % 12) ? (int) t->h % 12 : 12); break;
     831              12 :                         case 'G': length = slprintf(buffer, 32, "%d", (int) t->h); break;
     832              23 :                         case 'h': length = slprintf(buffer, 32, "%02d", (t->h % 12) ? (int) t->h % 12 : 12); break;
     833            1465 :                         case 'H': length = slprintf(buffer, 32, "%02d", (int) t->h); break;
     834            1517 :                         case 'i': length = slprintf(buffer, 32, "%02d", (int) t->i); break;
     835            1509 :                         case 's': length = slprintf(buffer, 32, "%02d", (int) t->s); break;
     836               6 :                         case 'u': length = slprintf(buffer, 32, "%06d", (int) floor(t->f * 1000000)); break;
     837                 : 
     838                 :                         /* timezone */
     839             123 :                         case 'I': length = slprintf(buffer, 32, "%d", localtime ? offset->is_dst : 0); break;
     840              24 :                         case 'P': rfc_colon = 1; /* break intentionally missing */
     841            1055 :                         case 'O': length = slprintf(buffer, 32, "%c%02d%s%02d",
     842                 :                                                                                         localtime ? ((offset->offset < 0) ? '-' : '+') : '+',
     843                 :                                                                                         localtime ? abs(offset->offset / 3600) : 0,
     844                 :                                                                                         rfc_colon ? ":" : "",
     845                 :                                                                                         localtime ? abs((offset->offset % 3600) / 60) : 0
     846                 :                                                           );
     847            1055 :                                           break;
     848             251 :                         case 'T': length = slprintf(buffer, 32, "%s", localtime ? offset->abbr : "GMT"); break;
     849              19 :                         case 'e': if (!localtime) {
     850               4 :                                               length = slprintf(buffer, 32, "%s", "UTC");
     851                 :                                           } else {
     852              15 :                                                   switch (t->zone_type) {
     853                 :                                                           case TIMELIB_ZONETYPE_ID:
     854              11 :                                                                   length = slprintf(buffer, 32, "%s", t->tz_info->name);
     855              11 :                                                                   break;
     856                 :                                                           case TIMELIB_ZONETYPE_ABBR:
     857               0 :                                                                   length = slprintf(buffer, 32, "%s", offset->abbr);
     858               0 :                                                                   break;
     859                 :                                                           case TIMELIB_ZONETYPE_OFFSET:
     860               4 :                                                                   length = slprintf(buffer, 32, "%c%02d:%02d",
     861                 :                                                                                                 ((offset->offset < 0) ? '-' : '+'),
     862                 :                                                                                                 abs(offset->offset / 3600),
     863                 :                                                                                                 abs((offset->offset % 3600) / 60)
     864                 :                                                                                    );
     865                 :                                                                   break;
     866                 :                                                   }
     867                 :                                           }
     868              19 :                                           break;
     869               5 :                         case 'Z': length = slprintf(buffer, 32, "%d", localtime ? offset->offset : 0); break;
     870                 : 
     871                 :                         /* full date/time */
     872              10 :                         case 'c': length = slprintf(buffer, 32, "%04d-%02d-%02dT%02d:%02d:%02d%c%02d:%02d",
     873                 :                                                                         (int) t->y, (int) t->m, (int) t->d,
     874                 :                                                                                         (int) t->h, (int) t->i, (int) t->s,
     875                 :                                                                                         localtime ? ((offset->offset < 0) ? '-' : '+') : '+',
     876                 :                                                                                         localtime ? abs(offset->offset / 3600) : 0,
     877                 :                                                                                         localtime ? abs((offset->offset % 3600) / 60) : 0
     878                 :                                                           );
     879              10 :                                           break;
     880              35 :                         case 'r': length = slprintf(buffer, 32, "%3s, %02d %3s %04d %02d:%02d:%02d %c%02d%02d",
     881                 :                                                                         php_date_short_day_name(t->y, t->m, t->d),
     882                 :                                                                                         (int) t->d, mon_short_names[t->m - 1],
     883                 :                                                                                         (int) t->y, (int) t->h, (int) t->i, (int) t->s,
     884                 :                                                                                         localtime ? ((offset->offset < 0) ? '-' : '+') : '+',
     885                 :                                                                                         localtime ? abs(offset->offset / 3600) : 0,
     886                 :                                                                                         localtime ? abs((offset->offset % 3600) / 60) : 0
     887                 :                                                           );
     888              35 :                                           break;
     889              18 :                         case 'U': length = slprintf(buffer, 32, "%lld", (timelib_sll) t->sse); break;
     890                 : 
     891            1034 :                         case '\\': if (i < format_len) i++; /* break intentionally missing */
     892                 : 
     893            8944 :                         default: buffer[0] = format[i]; buffer[1] = '\0'; length = 1; break;
     894                 :                 }
     895           22353 :                 smart_str_appendl(&string, buffer, length);
     896                 :         }
     897                 : 
     898            3910 :         smart_str_0(&string);
     899                 : 
     900            3910 :         if (localtime) {
     901            2997 :                 timelib_time_offset_dtor(offset);
     902                 :         }
     903                 : 
     904            3910 :         return string.c;
     905                 : }
     906                 : 
     907                 : static void php_date(INTERNAL_FUNCTION_PARAMETERS, int localtime)
     908            3032 : {
     909                 :         char   *format;
     910                 :         int     format_len;
     911                 :         long    ts;
     912                 :         char   *string;
     913                 : 
     914            3032 :         if (ZEND_NUM_ARGS() == 1) {
     915              95 :                 ts = time(NULL);
     916                 :         }
     917            3032 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &format, &format_len, &ts) == FAILURE) {
     918              44 :                 RETURN_FALSE;
     919                 :         }
     920                 : 
     921            2988 :         string = php_format_date(format, format_len, ts, localtime TSRMLS_CC);
     922                 :         
     923            2988 :         RETVAL_STRING(string, 0);
     924                 : }
     925                 : /* }}} */
     926                 : 
     927                 : PHPAPI char *php_format_date(char *format, int format_len, time_t ts, int localtime TSRMLS_DC) /* {{{ */
     928            3720 : {
     929                 :         timelib_time   *t;
     930                 :         timelib_tzinfo *tzi;
     931                 :         char *string;
     932                 : 
     933            3720 :         t = timelib_time_ctor();
     934                 : 
     935            3720 :         if (localtime) {
     936            2791 :                 tzi = get_timezone_info(TSRMLS_C);
     937            2791 :                 t->tz_info = tzi;
     938            2791 :                 t->zone_type = TIMELIB_ZONETYPE_ID;
     939            2791 :                 timelib_unixtime2local(t, ts);
     940                 :         } else {
     941             929 :                 tzi = NULL;
     942             929 :                 timelib_unixtime2gmt(t, ts);
     943                 :         }
     944                 : 
     945            3720 :         string = date_format(format, format_len, t, localtime);
     946                 :         
     947            3720 :         timelib_time_dtor(t);
     948            3720 :         return string;
     949                 : }
     950                 : /* }}} */
     951                 : 
     952                 : /* {{{ php_idate
     953                 :  */
     954                 : PHPAPI int php_idate(char format, time_t ts, int localtime)
     955              83 : {
     956                 :         timelib_time   *t;
     957                 :         timelib_tzinfo *tzi;
     958              83 :         int retval = -1;
     959              83 :         timelib_time_offset *offset = NULL;
     960                 :         timelib_sll isoweek, isoyear;
     961                 : 
     962              83 :         t = timelib_time_ctor();
     963                 : 
     964              83 :         if (!localtime) {
     965                 :                 TSRMLS_FETCH();
     966              83 :                 tzi = get_timezone_info(TSRMLS_C);
     967              83 :                 t->tz_info = tzi;
     968              83 :                 t->zone_type = TIMELIB_ZONETYPE_ID;
     969              83 :                 timelib_unixtime2local(t, ts);
     970                 :         } else {
     971               0 :                 tzi = NULL;
     972               0 :                 timelib_unixtime2gmt(t, ts);
     973                 :         }
     974                 : 
     975              83 :         if (!localtime) {
     976              83 :                 if (t->zone_type == TIMELIB_ZONETYPE_ABBR) {
     977               0 :                         offset = timelib_time_offset_ctor();
     978               0 :                         offset->offset = (t->z - (t->dst * 60)) * -60;
     979               0 :                         offset->leap_secs = 0;
     980               0 :                         offset->is_dst = t->dst;
     981               0 :                         offset->abbr = strdup(t->tz_abbr);
     982              83 :                 } else if (t->zone_type == TIMELIB_ZONETYPE_OFFSET) {
     983               0 :                         offset = timelib_time_offset_ctor();
     984               0 :                         offset->offset = (t->z - (t->dst * 60)) * -60;
     985               0 :                         offset->leap_secs = 0;
     986               0 :                         offset->is_dst = t->dst;
     987               0 :                         offset->abbr = malloc(9); /* GMT±xxxx\0 */
     988               0 :                         snprintf(offset->abbr, 9, "GMT%c%02d%02d", 
     989                 :                                                   !localtime ? ((offset->offset < 0) ? '-' : '+') : '+',
     990                 :                                                   !localtime ? abs(offset->offset / 3600) : 0,
     991                 :                                                   !localtime ? abs((offset->offset % 3600) / 60) : 0 );
     992                 :                 } else {
     993              83 :                         offset = timelib_get_time_zone_info(t->sse, t->tz_info);
     994                 :                 }
     995                 :         }
     996                 : 
     997              83 :         timelib_isoweek_from_date(t->y, t->m, t->d, &isoweek, &isoyear);
     998                 : 
     999              83 :         switch (format) {
    1000                 :                 /* day */
    1001               4 :                 case 'd': case 'j': retval = (int) t->d; break;
    1002                 : 
    1003               3 :                 case 'w': retval = (int) timelib_day_of_week(t->y, t->m, t->d); break;
    1004               3 :                 case 'z': retval = (int) timelib_day_of_year(t->y, t->m, t->d); break;
    1005                 : 
    1006                 :                 /* week */
    1007               3 :                 case 'W': retval = (int) isoweek; break; /* iso weeknr */
    1008                 : 
    1009                 :                 /* month */
    1010               4 :                 case 'm': case 'n': retval = (int) t->m; break;
    1011               3 :                 case 't': retval = (int) timelib_days_in_month(t->y, t->m); break;
    1012                 : 
    1013                 :                 /* year */
    1014               3 :                 case 'L': retval = (int) timelib_is_leap((int) t->y); break;
    1015               5 :                 case 'y': retval = (int) (t->y % 100); break;
    1016              17 :                 case 'Y': retval = (int) t->y; break;
    1017                 : 
    1018                 :                 /* Swatch Beat a.k.a. Internet Time */
    1019                 :                 case 'B':
    1020               4 :                         retval = (((((long)t->sse)-(((long)t->sse) - ((((long)t->sse) % 86400) + 3600))) * 10) / 864);                 
    1021               8 :                         while (retval < 0) {
    1022               0 :                                 retval += 1000;
    1023                 :                         }
    1024               4 :                         retval = retval % 1000;
    1025               4 :                         break;
    1026                 : 
    1027                 :                 /* time */
    1028               4 :                 case 'g': case 'h': retval = (int) ((t->h % 12) ? (int) t->h % 12 : 12); break;
    1029               4 :                 case 'H': case 'G': retval = (int) t->h; break;
    1030               3 :                 case 'i': retval = (int) t->i; break;
    1031               3 :                 case 's': retval = (int) t->s; break;
    1032                 : 
    1033                 :                 /* timezone */
    1034               3 :                 case 'I': retval = (int) (!localtime ? offset->is_dst : 0); break;
    1035               2 :                 case 'Z': retval = (int) (!localtime ? offset->offset : 0); break;
    1036                 : 
    1037               3 :                 case 'U': retval = (int) t->sse; break;
    1038                 :         }
    1039                 : 
    1040              83 :         if (!localtime) {
    1041              83 :                 timelib_time_offset_dtor(offset);
    1042                 :         }
    1043              83 :         timelib_time_dtor(t);
    1044                 : 
    1045              83 :         return retval;
    1046                 : }
    1047                 : /* }}} */
    1048                 : 
    1049                 : /* {{{ proto string date(string format [, long timestamp])
    1050                 :    Format a local date/time */
    1051                 : PHP_FUNCTION(date)
    1052            2811 : {
    1053            2811 :         php_date(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
    1054            2811 : }
    1055                 : /* }}} */
    1056                 : 
    1057                 : /* {{{ proto string gmdate(string format [, long timestamp])
    1058                 :    Format a GMT date/time */
    1059                 : PHP_FUNCTION(gmdate)
    1060             221 : {
    1061             221 :         php_date(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
    1062             221 : }
    1063                 : /* }}} */
    1064                 : 
    1065                 : /* {{{ proto int idate(string format [, int timestamp])
    1066                 :    Format a local time/date as integer */
    1067                 : PHP_FUNCTION(idate)
    1068             142 : {
    1069                 :         char   *format;
    1070                 :         int     format_len;
    1071                 :         long    ts;
    1072                 :         int ret; 
    1073                 : 
    1074             142 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &format, &format_len, &ts) == FAILURE) {
    1075              26 :                 RETURN_FALSE;
    1076                 :         }
    1077                 : 
    1078             116 :         if (format_len != 1) {
    1079              33 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "idate format is one char");
    1080              33 :                 RETURN_FALSE;
    1081                 :         }
    1082                 : 
    1083              83 :         if (ZEND_NUM_ARGS() == 1) {
    1084              24 :                 ts = time(NULL);
    1085                 :         }
    1086                 : 
    1087              83 :         ret = php_idate(format[0], ts, 0);
    1088              83 :         if (ret == -1) {
    1089              12 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unrecognized date format token.");
    1090              12 :                 RETURN_FALSE;
    1091                 :         }
    1092              71 :         RETURN_LONG(ret);
    1093                 : }
    1094                 : /* }}} */
    1095                 : 
    1096                 : /* {{{ php_date_set_tzdb - NOT THREADSAFE */
    1097                 : PHPAPI void php_date_set_tzdb(timelib_tzdb *tzdb)
    1098               0 : {
    1099               0 :         const timelib_tzdb *builtin = timelib_builtin_db();
    1100                 :         
    1101               0 :         if (php_version_compare(tzdb->version, builtin->version) > 0) {
    1102               0 :                 php_date_global_timezone_db = tzdb;
    1103               0 :                 php_date_global_timezone_db_enabled = 1;
    1104                 :         }
    1105               0 : }
    1106                 : /* }}} */
    1107                 : 
    1108                 : /* {{{ php_parse_date: Backwards compability function */
    1109                 : PHPAPI signed long php_parse_date(char *string, signed long *now)
    1110              12 : {
    1111                 :         timelib_time *parsed_time;
    1112                 :         int           error2;
    1113                 :         signed long   retval;
    1114                 : 
    1115              12 :         parsed_time = timelib_strtotime(string, strlen(string), NULL, DATE_TIMEZONEDB);
    1116              12 :         timelib_update_ts(parsed_time, NULL);
    1117              12 :         retval = timelib_date_to_int(parsed_time, &error2);
    1118              12 :         timelib_time_dtor(parsed_time);
    1119              12 :         if (error2) {
    1120               2 :                 return -1;
    1121                 :         }
    1122              10 :         return retval;
    1123                 : }
    1124                 : /* }}} */
    1125                 : 
    1126                 : 
    1127                 : /* {{{ proto int strtotime(string time [, int now ])
    1128                 :    Convert string representation of date and time to a timestamp */
    1129                 : PHP_FUNCTION(strtotime)
    1130            2618 : {
    1131                 :         char *times, *initial_ts;
    1132                 :         int   time_len, error1, error2;
    1133                 :         struct timelib_error_container *error;
    1134                 :         long  preset_ts, ts;
    1135                 : 
    1136                 :         timelib_time *t, *now;
    1137                 :         timelib_tzinfo *tzi;
    1138                 : 
    1139            2618 :         tzi = get_timezone_info(TSRMLS_C);
    1140                 : 
    1141            2618 :         if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "sl", &times, &time_len, &preset_ts) != FAILURE) {
    1142                 :                 /* We have an initial timestamp */
    1143             189 :                 now = timelib_time_ctor();
    1144                 : 
    1145             189 :                 initial_ts = emalloc(25);
    1146             189 :                 snprintf(initial_ts, 24, "@%ld UTC", preset_ts);
    1147             189 :                 t = timelib_strtotime(initial_ts, strlen(initial_ts), NULL, DATE_TIMEZONEDB); /* we ignore the error here, as this should never fail */
    1148             189 :                 timelib_update_ts(t, tzi);
    1149             189 :                 now->tz_info = tzi;
    1150             189 :                 now->zone_type = TIMELIB_ZONETYPE_ID;
    1151             189 :                 timelib_unixtime2local(now, t->sse);
    1152             189 :                 timelib_time_dtor(t);
    1153             189 :                 efree(initial_ts);
    1154            2429 :         } else if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &times, &time_len, &preset_ts) != FAILURE) {
    1155                 :                 /* We have no initial timestamp */
    1156            2429 :                 now = timelib_time_ctor();
    1157            2429 :                 now->tz_info = tzi;
    1158            2429 :                 now->zone_type = TIMELIB_ZONETYPE_ID;
    1159            2429 :                 timelib_unixtime2local(now, (timelib_sll) time(NULL));
    1160                 :         } else {
    1161               0 :                 RETURN_FALSE;
    1162                 :         }
    1163                 : 
    1164            2618 :         if (!time_len) {
    1165               1 :                 timelib_time_dtor(now); 
    1166               1 :                 RETURN_FALSE;
    1167                 :         }
    1168                 :         
    1169            2617 :         t = timelib_strtotime(times, time_len, &error, DATE_TIMEZONEDB);
    1170            2617 :         error1 = error->error_count;
    1171            2617 :         timelib_error_container_dtor(error);
    1172            2617 :         timelib_fill_holes(t, now, TIMELIB_NO_CLONE);
    1173            2617 :         timelib_update_ts(t, tzi);
    1174            2617 :         ts = timelib_date_to_int(t, &error2);
    1175                 : 
    1176            2617 :         timelib_time_dtor(now);
    1177            2617 :         timelib_time_dtor(t);
    1178                 : 
    1179            2617 :         if (error1 || error2) {
    1180              12 :                 RETURN_FALSE;
    1181                 :         } else {
    1182            2605 :                 RETURN_LONG(ts);
    1183                 :         }
    1184                 : }
    1185                 : /* }}} */
    1186                 : 
    1187                 : 
    1188                 : /* {{{ php_mktime - (gm)mktime helper */
    1189                 : PHPAPI void php_mktime(INTERNAL_FUNCTION_PARAMETERS, int gmt)
    1190             755 : {
    1191             755 :         long hou, min, sec, mon, day, yea, dst = -1;
    1192                 :         timelib_time *now;
    1193             755 :         timelib_tzinfo *tzi = NULL;
    1194             755 :         long ts, adjust_seconds = 0;
    1195                 :         int error;
    1196                 : 
    1197             755 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|lllllll", &hou, &min, &sec, &mon, &day, &yea, &dst) == FAILURE) {
    1198             165 :                 RETURN_FALSE;
    1199                 :         }
    1200                 :         /* Initialize structure with current time */
    1201             590 :         now = timelib_time_ctor();
    1202             590 :         if (gmt) {
    1203             117 :                 timelib_unixtime2gmt(now, (timelib_sll) time(NULL));
    1204                 :         } else {
    1205             473 :                 tzi = get_timezone_info(TSRMLS_C);
    1206             473 :                 now->tz_info = tzi;
    1207             473 :                 now->zone_type = TIMELIB_ZONETYPE_ID;
    1208             473 :                 timelib_unixtime2local(now, (timelib_sll) time(NULL));
    1209                 :         }
    1210                 :         /* Fill in the new data */
    1211             590 :         switch (ZEND_NUM_ARGS()) {
    1212                 :                 case 7:
    1213                 :                         /* break intentionally missing */
    1214                 :                 case 6:
    1215             533 :                         if (yea >= 0 && yea < 70) {
    1216              25 :                                 yea += 2000;
    1217             483 :                         } else if (yea >= 70 && yea <= 100) {
    1218               8 :                                 yea += 1900;
    1219                 :                         }
    1220             508 :                         now->y = yea;
    1221                 :                         /* break intentionally missing again */
    1222                 :                 case 5:
    1223             524 :                         now->d = day;
    1224                 :                         /* break missing intentionally here too */
    1225                 :                 case 4:
    1226             540 :                         now->m = mon;
    1227                 :                         /* and here */
    1228                 :                 case 3:
    1229             556 :                         now->s = sec;
    1230                 :                         /* yup, this break isn't here on purpose too */
    1231                 :                 case 2:
    1232             572 :                         now->i = min;
    1233                 :                         /* last intentionally missing break */
    1234                 :                 case 1:
    1235             588 :                         now->h = hou;
    1236             588 :                         break;
    1237                 :                 default:
    1238               2 :                         php_error_docref(NULL TSRMLS_CC, E_STRICT, "You should be using the time() function instead");
    1239                 :         }
    1240                 :         /* Update the timestamp */
    1241             590 :         if (gmt) {
    1242             117 :                 timelib_update_ts(now, NULL);
    1243                 :         } else {
    1244             473 :                 timelib_update_ts(now, tzi);
    1245                 :         }
    1246                 :         /* Support for the deprecated is_dst parameter */
    1247             590 :         if (dst != -1) {
    1248              39 :                 php_error_docref(NULL TSRMLS_CC, E_STRICT, "The is_dst parameter is deprecated");
    1249              39 :                 if (gmt) {
    1250                 :                         /* GMT never uses DST */
    1251               1 :                         if (dst == 1) {
    1252               0 :                                 adjust_seconds = -3600;
    1253                 :                         }
    1254                 :                 } else {
    1255                 :                         /* Figure out is_dst for current TS */
    1256                 :                         timelib_time_offset *tmp_offset;
    1257              38 :                         tmp_offset = timelib_get_time_zone_info(now->sse, tzi);
    1258              38 :                         if (dst == 1 && tmp_offset->is_dst == 0) {
    1259               7 :                                 adjust_seconds = -3600;
    1260                 :                         }
    1261              38 :                         if (dst == 0 && tmp_offset->is_dst == 1) {
    1262              13 :                                 adjust_seconds = +3600;
    1263                 :                         }
    1264              38 :                         timelib_time_offset_dtor(tmp_offset);
    1265                 :                 }
    1266                 :         }
    1267                 :         /* Clean up and return */
    1268             590 :         ts = timelib_date_to_int(now, &error);
    1269             590 :         ts += adjust_seconds;
    1270             590 :         timelib_time_dtor(now);
    1271                 : 
    1272             590 :         if (error) {
    1273              22 :                 RETURN_FALSE;
    1274                 :         } else {
    1275             568 :                 RETURN_LONG(ts);
    1276                 :         }
    1277                 : }
    1278                 : /* }}} */
    1279                 : 
    1280                 : /* {{{ proto int mktime([int hour [, int min [, int sec [, int mon [, int day [, int year]]]]]])
    1281                 :    Get UNIX timestamp for a date */
    1282                 : PHP_FUNCTION(mktime)
    1283             565 : {
    1284             565 :         php_mktime(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
    1285             565 : }
    1286                 : /* }}} */
    1287                 : 
    1288                 : /* {{{ proto int gmmktime([int hour [, int min [, int sec [, int mon [, int day [, int year]]]]]])
    1289                 :    Get UNIX timestamp for a GMT date */
    1290                 : PHP_FUNCTION(gmmktime)
    1291             190 : {
    1292             190 :         php_mktime(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
    1293             190 : }
    1294                 : /* }}} */
    1295                 : 
    1296                 : 
    1297                 : /* {{{ proto bool checkdate(int month, int day, int year)
    1298                 :    Returns true(1) if it is a valid date in gregorian calendar */
    1299                 : PHP_FUNCTION(checkdate)
    1300             100 : {
    1301                 :         long m, d, y;
    1302                 : 
    1303             100 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lll", &m, &d, &y) == FAILURE) {
    1304              45 :                 RETURN_FALSE;
    1305                 :         }
    1306                 : 
    1307              55 :         if (y < 1 || y > 32767 || m < 1 || m > 12 || d < 1 || d > timelib_days_in_month(y, m)) {
    1308              36 :                 RETURN_FALSE;
    1309                 :         }
    1310              19 :         RETURN_TRUE;    /* True : This month, day, year arguments are valid */
    1311                 : }
    1312                 : /* }}} */
    1313                 : 
    1314                 : #ifdef HAVE_STRFTIME
    1315                 : /* {{{ php_strftime - (gm)strftime helper */
    1316                 : PHPAPI void php_strftime(INTERNAL_FUNCTION_PARAMETERS, int gmt)
    1317             383 : {
    1318                 :         char                *format, *buf;
    1319                 :         int                  format_len;
    1320                 :         long                 timestamp;
    1321                 :         struct tm            ta;
    1322             383 :         int                  max_reallocs = 5;
    1323             383 :         size_t               buf_len = 64, real_len;
    1324                 :         timelib_time        *ts;
    1325                 :         timelib_tzinfo      *tzi;
    1326             383 :         timelib_time_offset *offset = NULL;
    1327                 : 
    1328             383 :         timestamp = (long) time(NULL);
    1329                 : 
    1330             383 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &format, &format_len, &timestamp) == FAILURE) {
    1331              49 :                 RETURN_FALSE;
    1332                 :         }
    1333                 : 
    1334             334 :         if (format_len == 0) {
    1335              34 :                 RETURN_FALSE;
    1336                 :         }
    1337                 : 
    1338             300 :         ts = timelib_time_ctor();
    1339             300 :         if (gmt) {
    1340             112 :                 tzi = NULL;
    1341             112 :                 timelib_unixtime2gmt(ts, (timelib_sll) timestamp);
    1342                 :         } else {
    1343             188 :                 tzi = get_timezone_info(TSRMLS_C);
    1344             188 :                 ts->tz_info = tzi;
    1345             188 :                 ts->zone_type = TIMELIB_ZONETYPE_ID;
    1346             188 :                 timelib_unixtime2local(ts, (timelib_sll) timestamp);
    1347                 :         }
    1348             300 :         ta.tm_sec   = ts->s;
    1349             300 :         ta.tm_min   = ts->i;
    1350             300 :         ta.tm_hour  = ts->h;
    1351             300 :         ta.tm_mday  = ts->d;
    1352             300 :         ta.tm_mon   = ts->m - 1;
    1353             300 :         ta.tm_year  = ts->y - 1900;
    1354             300 :         ta.tm_wday  = timelib_day_of_week(ts->y, ts->m, ts->d);
    1355             300 :         ta.tm_yday  = timelib_day_of_year(ts->y, ts->m, ts->d);
    1356             300 :         if (gmt) {
    1357             112 :                 ta.tm_isdst = 0;
    1358                 : #if HAVE_TM_GMTOFF
    1359             112 :                 ta.tm_gmtoff = 0;
    1360                 : #endif
    1361                 : #if HAVE_TM_ZONE
    1362             112 :                 ta.tm_zone = "GMT";
    1363                 : #endif
    1364                 :         } else {
    1365             188 :                 offset = timelib_get_time_zone_info(timestamp, tzi);
    1366                 : 
    1367             188 :                 ta.tm_isdst = offset->is_dst;
    1368                 : #if HAVE_TM_GMTOFF
    1369             188 :                 ta.tm_gmtoff = offset->offset;
    1370                 : #endif
    1371                 : #if HAVE_TM_ZONE
    1372             188 :                 ta.tm_zone = offset->abbr;
    1373                 : #endif
    1374                 :         }
    1375                 : 
    1376             300 :         buf = (char *) emalloc(buf_len);
    1377             604 :         while ((real_len=strftime(buf, buf_len, format, &ta))==buf_len || real_len==0) {
    1378               4 :                 buf_len *= 2;
    1379               4 :                 buf = (char *) erealloc(buf, buf_len);
    1380               4 :                 if (!--max_reallocs) {
    1381               0 :                         break;
    1382                 :                 }
    1383                 :         }
    1384                 : 
    1385             300 :         timelib_time_dtor(ts);
    1386             300 :         if (!gmt) {
    1387             188 :                 timelib_time_offset_dtor(offset);
    1388                 :         }
    1389                 : 
    1390             300 :         if (real_len && real_len != buf_len) {
    1391             300 :                 buf = (char *) erealloc(buf, real_len + 1);
    1392             300 :                 RETURN_STRINGL(buf, real_len, 0);
    1393                 :         }
    1394               0 :         efree(buf);
    1395               0 :         RETURN_FALSE;
    1396                 : }
    1397                 : /* }}} */
    1398                 : 
    1399                 : /* {{{ proto string strftime(string format [, int timestamp])
    1400                 :    Format a local time/date according to locale settings */
    1401                 : PHP_FUNCTION(strftime)
    1402             229 : {
    1403             229 :         php_strftime(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
    1404             229 : }
    1405                 : /* }}} */
    1406                 : 
    1407                 : /* {{{ proto string gmstrftime(string format [, int timestamp])
    1408                 :    Format a GMT/UCT time/date according to locale settings */
    1409                 : PHP_FUNCTION(gmstrftime)
    1410             154 : {
    1411             154 :         php_strftime(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
    1412             154 : }
    1413                 : /* }}} */
    1414                 : #endif
    1415                 : 
    1416                 : /* {{{ proto int time(void)
    1417                 :    Return current UNIX timestamp */
    1418                 : PHP_FUNCTION(time)
    1419              21 : {
    1420              21 :         RETURN_LONG((long)time(NULL));
    1421                 : }
    1422                 : /* }}} */
    1423                 : 
    1424                 : /* {{{ proto array localtime([int timestamp [, bool associative_array]])
    1425                 :    Returns the results of the C system call localtime as an associative array if the associative_array argument is set to 1 other wise it is a regular array */
    1426                 : PHP_FUNCTION(localtime)
    1427             100 : {
    1428             100 :         long timestamp = (long)time(NULL);
    1429             100 :         zend_bool associative = 0;
    1430                 :         timelib_tzinfo *tzi;
    1431                 :         timelib_time   *ts;
    1432                 : 
    1433             100 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|lb", &timestamp, &associative) == FAILURE) {
    1434              32 :                 RETURN_FALSE;
    1435                 :         }
    1436                 : 
    1437              68 :         tzi = get_timezone_info(TSRMLS_C);
    1438              68 :         ts = timelib_time_ctor();
    1439              68 :         ts->tz_info = tzi;
    1440              68 :         ts->zone_type = TIMELIB_ZONETYPE_ID;
    1441              68 :         timelib_unixtime2local(ts, (timelib_sll) timestamp);
    1442                 : 
    1443              68 :         array_init(return_value);
    1444                 : 
    1445              68 :         if (associative) {
    1446              35 :                 add_assoc_long(return_value, "tm_sec",   ts->s);
    1447              35 :                 add_assoc_long(return_value, "tm_min",   ts->i);
    1448              35 :                 add_assoc_long(return_value, "tm_hour",  ts->h);
    1449              35 :                 add_assoc_long(return_value, "tm_mday",  ts->d);
    1450              35 :                 add_assoc_long(return_value, "tm_mon",   ts->m - 1);
    1451              35 :                 add_assoc_long(return_value, "tm_year",  ts->y - 1900);
    1452              35 :                 add_assoc_long(return_value, "tm_wday",  timelib_day_of_week(ts->y, ts->m, ts->d));
    1453              35 :                 add_assoc_long(return_value, "tm_yday",  timelib_day_of_year(ts->y, ts->m, ts->d));
    1454              35 :                 add_assoc_long(return_value, "tm_isdst", ts->dst);
    1455                 :         } else {
    1456              33 :                 add_next_index_long(return_value, ts->s);
    1457              33 :                 add_next_index_long(return_value, ts->i);
    1458              33 :                 add_next_index_long(return_value, ts->h);
    1459              33 :                 add_next_index_long(return_value, ts->d);
    1460              33 :                 add_next_index_long(return_value, ts->m - 1);
    1461              33 :                 add_next_index_long(return_value, ts->y- 1900);
    1462              33 :                 add_next_index_long(return_value, timelib_day_of_week(ts->y, ts->m, ts->d));
    1463              33 :                 add_next_index_long(return_value, timelib_day_of_year(ts->y, ts->m, ts->d));
    1464              33 :                 add_next_index_long(return_value, ts->dst);
    1465                 :         }
    1466                 : 
    1467              68 :         timelib_time_dtor(ts);
    1468                 : }
    1469                 : /* }}} */
    1470                 : 
    1471                 : /* {{{ proto array getdate([int timestamp])
    1472                 :    Get date/time information */
    1473                 : PHP_FUNCTION(getdate)
    1474              51 : {
    1475              51 :         long timestamp = (long)time(NULL);
    1476                 :         timelib_tzinfo *tzi;
    1477                 :         timelib_time   *ts;
    1478                 : 
    1479              51 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &timestamp) == FAILURE) {
    1480              14 :                 RETURN_FALSE;
    1481                 :         }
    1482                 : 
    1483              37 :         tzi = get_timezone_info(TSRMLS_C);
    1484              37 :         ts = timelib_time_ctor();
    1485              37 :         ts->tz_info = tzi;
    1486              37 :         ts->zone_type = TIMELIB_ZONETYPE_ID;
    1487              37 :         timelib_unixtime2local(ts, (timelib_sll) timestamp);
    1488                 : 
    1489              37 :         array_init(return_value);
    1490                 : 
    1491              37 :         add_assoc_long(return_value, "seconds", ts->s);
    1492              37 :         add_assoc_long(return_value, "minutes", ts->i);
    1493              37 :         add_assoc_long(return_value, "hours", ts->h);
    1494              37 :         add_assoc_long(return_value, "mday", ts->d);
    1495              37 :         add_assoc_long(return_value, "wday", timelib_day_of_week(ts->y, ts->m, ts->d));
    1496              37 :         add_assoc_long(return_value, "mon", ts->m);
    1497              37 :         add_assoc_long(return_value, "year", ts->y);
    1498              37 :         add_assoc_long(return_value, "yday", timelib_day_of_year(ts->y, ts->m, ts->d));
    1499              37 :         add_assoc_string(return_value, "weekday", php_date_full_day_name(ts->y, ts->m, ts->d), 1);
    1500              37 :         add_assoc_string(return_value, "month", mon_full_names[ts->m - 1], 1);
    1501              37 :         add_index_long(return_value, 0, timestamp);
    1502                 : 
    1503              37 :         timelib_time_dtor(ts);
    1504                 : }
    1505                 : /* }}} */
    1506                 : 
    1507                 : static void date_register_classes(TSRMLS_D)
    1508           13565 : {
    1509                 :         zend_class_entry ce_date, ce_timezone;
    1510                 : 
    1511           13565 :         INIT_CLASS_ENTRY(ce_date, "DateTime", date_funcs_date);
    1512           13565 :         ce_date.create_object = date_object_new_date;
    1513           13565 :         date_ce_date = zend_register_internal_class_ex(&ce_date, NULL, NULL TSRMLS_CC);
    1514           13565 :         memcpy(&date_object_handlers_date, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
    1515           13565 :         date_object_handlers_date.clone_obj = date_object_clone_date;
    1516           13565 :         date_object_handlers_date.compare_objects = date_object_compare_date;
    1517                 : 
    1518                 : #define REGISTER_DATE_CLASS_CONST_STRING(const_name, value) \
    1519                 :         zend_declare_class_constant_stringl(date_ce_date, const_name, sizeof(const_name)-1, value, sizeof(value)-1 TSRMLS_CC);
    1520                 : 
    1521           13565 :         REGISTER_DATE_CLASS_CONST_STRING("ATOM",    DATE_FORMAT_RFC3339);
    1522           13565 :         REGISTER_DATE_CLASS_CONST_STRING("COOKIE",  DATE_FORMAT_RFC850);
    1523           13565 :         REGISTER_DATE_CLASS_CONST_STRING("ISO8601", DATE_FORMAT_ISO8601);
    1524           13565 :         REGISTER_DATE_CLASS_CONST_STRING("RFC822",  DATE_FORMAT_RFC822);
    1525           13565 :         REGISTER_DATE_CLASS_CONST_STRING("RFC850",  DATE_FORMAT_RFC850);
    1526           13565 :         REGISTER_DATE_CLASS_CONST_STRING("RFC1036", DATE_FORMAT_RFC1036);
    1527           13565 :         REGISTER_DATE_CLASS_CONST_STRING("RFC1123", DATE_FORMAT_RFC1123);
    1528           13565 :         REGISTER_DATE_CLASS_CONST_STRING("RFC2822", DATE_FORMAT_RFC2822);
    1529           13565 :         REGISTER_DATE_CLASS_CONST_STRING("RFC3339", DATE_FORMAT_RFC3339);
    1530           13565 :         REGISTER_DATE_CLASS_CONST_STRING("RSS",     DATE_FORMAT_RFC1123);
    1531           13565 :         REGISTER_DATE_CLASS_CONST_STRING("W3C",     DATE_FORMAT_RFC3339);
    1532                 : 
    1533                 : 
    1534           13565 :         INIT_CLASS_ENTRY(ce_timezone, "DateTimeZone", date_funcs_timezone);
    1535           13565 :         ce_timezone.create_object = date_object_new_timezone;
    1536           13565 :         date_ce_timezone = zend_register_internal_class_ex(&ce_timezone, NULL, NULL TSRMLS_CC);
    1537           13565 :         memcpy(&date_object_handlers_timezone, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
    1538           13565 :         date_object_handlers_timezone.clone_obj = date_object_clone_timezone;
    1539           13565 : }
    1540                 : 
    1541                 : static inline zend_object_value date_object_new_date_ex(zend_class_entry *class_type, php_date_obj **ptr TSRMLS_DC)
    1542             327 : {
    1543                 :         php_date_obj *intern;
    1544                 :         zend_object_value retval;
    1545                 :         zval *tmp;
    1546                 : 
    1547             327 :         intern = emalloc(sizeof(php_date_obj));
    1548             327 :         memset(intern, 0, sizeof(php_date_obj));
    1549             327 :         if (ptr) {
    1550               7 :                 *ptr = intern;
    1551                 :         }
    1552                 :         
    1553             327 :         zend_object_std_init(&intern->std, class_type TSRMLS_CC);
    1554             327 :         zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
    1555                 :         
    1556             327 :         retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) date_object_free_storage_date, NULL TSRMLS_CC);
    1557             327 :         retval.handlers = &date_object_handlers_date;
    1558                 :         
    1559             327 :         return retval;
    1560                 : }
    1561                 : 
    1562                 : static zend_object_value date_object_new_date(zend_class_entry *class_type TSRMLS_DC)
    1563             320 : {
    1564             320 :         return date_object_new_date_ex(class_type, NULL TSRMLS_CC);
    1565                 : }
    1566                 : 
    1567                 : static zend_object_value date_object_clone_date(zval *this_ptr TSRMLS_DC)
    1568               7 : {
    1569               7 :         php_date_obj *new_obj = NULL;
    1570               7 :         php_date_obj *old_obj = (php_date_obj *) zend_object_store_get_object(this_ptr TSRMLS_CC);
    1571               7 :         zend_object_value new_ov = date_object_new_date_ex(old_obj->std.ce, &new_obj TSRMLS_CC);
    1572                 :         
    1573               7 :         zend_objects_clone_members(&new_obj->std, new_ov, &old_obj->std, Z_OBJ_HANDLE_P(this_ptr) TSRMLS_CC);
    1574                 :         
    1575                 :         /* this should probably moved to a new `timelib_time *timelime_time_clone(timelib_time *)` */
    1576               7 :         new_obj->time = timelib_time_ctor();
    1577               7 :         *new_obj->time = *old_obj->time;
    1578               7 :         if (old_obj->time->tz_abbr) {
    1579               7 :                 new_obj->time->tz_abbr = strdup(old_obj->time->tz_abbr);
    1580                 :         }
    1581               7 :         if (old_obj->time->tz_info) {
    1582               7 :                 new_obj->time->tz_info = old_obj->time->tz_info;
    1583                 :         }
    1584                 :         
    1585               7 :         return new_ov;
    1586                 : }
    1587                 : 
    1588                 : static int date_object_compare_date(zval *d1, zval *d2 TSRMLS_DC)
    1589              12 : {
    1590              12 :         if (Z_TYPE_P(d1) == IS_OBJECT && Z_TYPE_P(d2) == IS_OBJECT &&
    1591                 :                 instanceof_function(Z_OBJCE_P(d1), date_ce_date TSRMLS_CC) &&
    1592                 :                 instanceof_function(Z_OBJCE_P(d2), date_ce_date TSRMLS_CC)) {
    1593              12 :                 php_date_obj *o1 = zend_object_store_get_object(d1 TSRMLS_CC);
    1594              12 :                 php_date_obj *o2 = zend_object_store_get_object(d2 TSRMLS_CC);
    1595                 :                 
    1596              12 :                 if (!o1->time->sse_uptodate) {
    1597               0 :                         timelib_update_ts(o1->time, o1->time->tz_info);
    1598                 :                 }
    1599              12 :                 if (!o2->time->sse_uptodate) {
    1600               0 :                         timelib_update_ts(o2->time, o2->time->tz_info);
    1601                 :                 }
    1602                 :                 
    1603              12 :                 return (o1->time->sse == o2->time->sse) ? 0 : ((o1->time->sse < o2->time->sse) ? -1 : 1);
    1604                 :         }
    1605                 :         
    1606               0 :         return 1;
    1607                 : }
    1608                 : 
    1609                 : static inline zend_object_value date_object_new_timezone_ex(zend_class_entry *class_type, php_timezone_obj **ptr TSRMLS_DC)
    1610             132 : {
    1611                 :         php_timezone_obj *intern;
    1612                 :         zend_object_value retval;
    1613                 :         zval *tmp;
    1614                 : 
    1615             132 :         intern = emalloc(sizeof(php_timezone_obj));
    1616             132 :         memset(intern, 0, sizeof(php_timezone_obj));
    1617             132 :         if (ptr) {
    1618               7 :                 *ptr = intern;
    1619                 :         }
    1620                 : 
    1621             132 :         zend_object_std_init(&intern->std, class_type TSRMLS_CC);
    1622             132 :         zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
    1623                 :         
    1624             132 :         retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) date_object_free_storage_timezone, NULL TSRMLS_CC);
    1625             132 :         retval.handlers = &date_object_handlers_timezone;
    1626                 :         
    1627             132 :         return retval;
    1628                 : }
    1629                 : 
    1630                 : static zend_object_value date_object_new_timezone(zend_class_entry *class_type TSRMLS_DC)
    1631             125 : {
    1632             125 :         return date_object_new_timezone_ex(class_type, NULL TSRMLS_CC);
    1633                 : }
    1634                 : 
    1635                 : static zend_object_value date_object_clone_timezone(zval *this_ptr TSRMLS_DC)
    1636               7 : {
    1637               7 :         php_timezone_obj *new_obj = NULL;
    1638               7 :         php_timezone_obj *old_obj = (php_timezone_obj *) zend_object_store_get_object(this_ptr TSRMLS_CC);
    1639               7 :         zend_object_value new_ov = date_object_new_timezone_ex(old_obj->std.ce, &new_obj TSRMLS_CC);
    1640                 :         
    1641               7 :         zend_objects_clone_members(&new_obj->std, new_ov, &old_obj->std, Z_OBJ_HANDLE_P(this_ptr) TSRMLS_CC);
    1642               7 :         new_obj->type = old_obj->type;
    1643               7 :         new_obj->initialized = 1;
    1644               7 :         switch (new_obj->type) {
    1645                 :                 case TIMELIB_ZONETYPE_ID:
    1646               7 :                         new_obj->tzi.tz = old_obj->tzi.tz;
    1647               7 :                         break;
    1648                 :                 case TIMELIB_ZONETYPE_OFFSET:
    1649               0 :                         new_obj->tzi.utc_offset = old_obj->tzi.utc_offset;
    1650               0 :                         break;
    1651                 :                 case TIMELIB_ZONETYPE_ABBR:
    1652               0 :                         new_obj->tzi.z.utc_offset = old_obj->tzi.z.utc_offset;
    1653               0 :                         new_obj->tzi.z.dst        = old_obj->tzi.z.dst;
    1654               0 :                         new_obj->tzi.z.abbr       = old_obj->tzi.z.abbr;
    1655                 :                         break;
    1656                 :         }
    1657                 :         
    1658               7 :         return new_ov;
    1659                 : }
    1660                 : 
    1661                 : static void date_object_free_storage_date(void *object TSRMLS_DC)
    1662             327 : {
    1663             327 :         php_date_obj *intern = (php_date_obj *)object;
    1664                 : 
    1665             327 :         if (intern->time) {
    1666             284 :                 timelib_time_dtor(intern->time);
    1667                 :         }
    1668                 : 
    1669             327 :         zend_object_std_dtor(&intern->std TSRMLS_CC);
    1670             327 :         efree(object);
    1671             327 : }
    1672                 : 
    1673                 : static void date_object_free_storage_timezone(void *object TSRMLS_DC)
    1674             132 : {
    1675             132 :         php_timezone_obj *intern = (php_timezone_obj *)object;
    1676                 : 
    1677             132 :         if (intern->type == TIMELIB_ZONETYPE_ABBR) {
    1678               2 :                 free(intern->tzi.z.abbr);
    1679                 :         }
    1680             132 :         zend_object_std_dtor(&intern->std TSRMLS_CC);
    1681             132 :         efree(object);
    1682             132 : }
    1683                 : 
    1684                 : /* Advanced Interface */
    1685                 : static zval * date_instantiate(zend_class_entry *pce, zval *object TSRMLS_DC)
    1686             214 : {
    1687             214 :         if (!object) {
    1688               0 :                 ALLOC_ZVAL(object);
    1689                 :         }
    1690                 : 
    1691             214 :         Z_TYPE_P(object) = IS_OBJECT;
    1692             214 :         object_init_ex(object, pce);
    1693             214 :         object->refcount = 1;
    1694             214 :         object->is_ref = 0;
    1695             214 :         return object;
    1696                 : }
    1697                 : 
    1698                 : static int date_initialize(php_date_obj *dateobj, /*const*/ char *time_str, int time_str_len, zval *timezone_object, int ctor TSRMLS_DC)
    1699             277 : {
    1700                 :         timelib_time   *now;
    1701                 :         timelib_tzinfo *tzi;
    1702             277 :         timelib_error_container *err = NULL;
    1703             277 :         int type = TIMELIB_ZONETYPE_ID, new_dst, errors_found = 0;
    1704                 :         char *new_abbr;
    1705                 :         timelib_sll     new_offset;
    1706                 :         
    1707             277 :         if (dateobj->time) {
    1708               0 :                 timelib_time_dtor(dateobj->time);
    1709                 :         }
    1710             277 :         dateobj->time = timelib_strtotime(time_str_len ? time_str : "now", time_str_len ? time_str_len : sizeof("now") -1, &err, DATE_TIMEZONEDB);
    1711                 : 
    1712             277 :         if (err && err->error_count) {
    1713              50 :                 if (ctor) {
    1714                 :                         /* spit out the first library error message, at least */
    1715              25 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to parse time string (%s) at position %d (%c): %s", time_str,
    1716                 :                                 err->error_messages[0].position, err->error_messages[0].character, err->error_messages[0].message);
    1717                 :                 }
    1718              50 :                 errors_found = 1;
    1719                 :         }
    1720             277 :         timelib_error_container_dtor(err);
    1721             277 :         if (errors_found) {
    1722              50 :                 return 0;
    1723                 :         }
    1724                 : 
    1725             227 :         if (timezone_object) {
    1726                 :                 php_timezone_obj *tzobj;
    1727                 : 
    1728              33 :                 tzobj = (php_timezone_obj *) zend_object_store_get_object(timezone_object TSRMLS_CC);
    1729              33 :                 switch (tzobj->type) {
    1730                 :                         case TIMELIB_ZONETYPE_ID:
    1731              33 :                                 tzi = tzobj->tzi.tz;
    1732              33 :                                 break;
    1733                 :                         case TIMELIB_ZONETYPE_OFFSET:
    1734               0 :                                 new_offset = tzobj->tzi.utc_offset;
    1735               0 :                                 break;
    1736                 :                         case TIMELIB_ZONETYPE_ABBR:
    1737               0 :                                 new_offset = tzobj->tzi.z.utc_offset;
    1738               0 :                                 new_dst    = tzobj->tzi.z.dst;
    1739               0 :                                 new_abbr   = strdup(tzobj->tzi.z.abbr);
    1740                 :                                 break;
    1741                 :                 }
    1742              33 :                 type = tzobj->type;
    1743             194 :         } else if (dateobj->time->tz_info) {
    1744               7 :                 tzi = dateobj->time->tz_info;
    1745                 :         } else {
    1746             187 :                 tzi = get_timezone_info(TSRMLS_C);
    1747                 :         }
    1748                 : 
    1749             227 :         now = timelib_time_ctor();
    1750             227 :         now->zone_type = type;
    1751             227 :         switch (type) {
    1752                 :                 case TIMELIB_ZONETYPE_ID:
    1753             227 :                         now->tz_info = tzi;
    1754             227 :                         break;
    1755                 :                 case TIMELIB_ZONETYPE_OFFSET:
    1756               0 :                         now->z = new_offset;
    1757               0 :                         break;
    1758                 :                 case TIMELIB_ZONETYPE_ABBR:
    1759               0 :                         now->z = new_offset;
    1760               0 :                         now->dst = new_dst;
    1761               0 :                         now->tz_abbr = new_abbr;
    1762                 :                         break;
    1763                 :         }
    1764             227 :         timelib_unixtime2local(now, (timelib_sll) time(NULL));
    1765                 : 
    1766             227 :         timelib_fill_holes(dateobj->time, now, TIMELIB_NO_CLONE);
    1767             227 :         timelib_update_ts(dateobj->time, tzi);
    1768                 : 
    1769             227 :         dateobj->time->have_weekday_relative = dateobj->time->have_relative = 0;
    1770                 : 
    1771             227 :         timelib_time_dtor(now);
    1772                 : 
    1773             227 :         return 1;
    1774                 : }
    1775                 : 
    1776                 : /* {{{ proto DateTime date_create([string time[, DateTimeZone object]])
    1777                 :    Returns new DateTime object
    1778                 : */
    1779                 : PHP_FUNCTION(date_create)
    1780             206 : {
    1781             206 :         zval           *timezone_object = NULL;
    1782             206 :         char           *time_str = NULL;
    1783             206 :         int             time_str_len = 0;
    1784                 : 
    1785             206 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sO", &time_str, &time_str_len, &timezone_object, date_ce_timezone) == FAILURE) {
    1786              42 :                 RETURN_FALSE;
    1787                 :         }
    1788                 : 
    1789             164 :         date_instantiate(date_ce_date, return_value TSRMLS_CC);
    1790             164 :         if (!date_initialize(zend_object_store_get_object(return_value TSRMLS_CC), time_str, time_str_len, timezone_object, 0 TSRMLS_CC)) {
    1791              25 :                 RETURN_FALSE;
    1792                 :         }
    1793                 : }
    1794                 : /* }}} */
    1795                 : 
    1796                 : /* {{{ proto DateTime::__construct([string time[, DateTimeZone object]])
    1797                 :    Creates new DateTime object
    1798                 : */
    1799                 : PHP_METHOD(DateTime, __construct)
    1800             154 : {
    1801             154 :         zval *timezone_object = NULL;
    1802             154 :         char *time_str = NULL;
    1803             154 :         int time_str_len = 0;
    1804                 :         
    1805             154 :         php_set_error_handling(EH_THROW, NULL TSRMLS_CC);
    1806             154 :         if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sO", &time_str, &time_str_len, &timezone_object, date_ce_timezone)) {
    1807             113 :                 date_initialize(zend_object_store_get_object(getThis() TSRMLS_CC), time_str, time_str_len, timezone_object, 1 TSRMLS_CC);
    1808                 :         }
    1809             154 :         php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
    1810             154 : }
    1811                 : /* }}} */
    1812                 : 
    1813                 : /* {{{ proto array date_parse(string date)
    1814                 :    Returns associative array with detailed info about given date
    1815                 : */
    1816                 : PHP_FUNCTION(date_parse)
    1817              55 : {
    1818                 :         char                           *date;
    1819                 :         int                             date_len, i;
    1820                 :         struct timelib_error_container *error;
    1821                 :         timelib_time                   *parsed_time;
    1822                 :         zval                           *element;
    1823                 :         
    1824              55 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &date, &date_len) == FAILURE) {
    1825               9 :                 RETURN_FALSE;
    1826                 :         }
    1827                 : 
    1828              46 :         parsed_time = timelib_strtotime(date, date_len, &error, DATE_TIMEZONEDB);
    1829              46 :         array_init(return_value);
    1830                 : #define PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT(name, elem) \
    1831                 :         if (parsed_time->elem == -99999) {               \
    1832                 :                 add_assoc_bool(return_value, #name, 0); \
    1833                 :         } else {                                       \
    1834                 :                 add_assoc_long(return_value, #name, parsed_time->elem); \
    1835                 :         }
    1836              46 :         PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT(year,      y);
    1837              46 :         PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT(month,     m);
    1838              46 :         PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT(day,       d);
    1839              46 :         PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT(hour,      h);
    1840              46 :         PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT(minute,    i);
    1841              46 :         PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT(second,    s);
    1842                 :         
    1843              46 :         if (parsed_time->f == -99999) {
    1844              38 :                 add_assoc_bool(return_value, "fraction", 0);
    1845                 :         } else {
    1846               8 :                 add_assoc_double(return_value, "fraction", parsed_time->f);
    1847                 :         }
    1848                 : 
    1849              46 :         add_assoc_long(return_value, "warning_count", error->warning_count);
    1850              46 :         MAKE_STD_ZVAL(element);
    1851              46 :         array_init(element);
    1852              61 :         for (i = 0; i < error->warning_count; i++) {
    1853              15 :                 add_index_string(element, error->warning_messages[i].position, error->warning_messages[i].message, 1);
    1854                 :         }
    1855              46 :         add_assoc_zval(return_value, "warnings", element);
    1856                 : 
    1857              46 :         add_assoc_long(return_value, "error_count", error->error_count);
    1858              46 :         MAKE_STD_ZVAL(element);
    1859              46 :         array_init(element);
    1860              79 :         for (i = 0; i < error->error_count; i++) {
    1861              33 :                 add_index_string(element, error->error_messages[i].position, error->error_messages[i].message, 1);
    1862                 :         }
    1863              46 :         add_assoc_zval(return_value, "errors", element);
    1864              46 :         timelib_error_container_dtor(error);
    1865                 : 
    1866              46 :         add_assoc_bool(return_value, "is_localtime", parsed_time->is_localtime);
    1867                 : 
    1868              46 :         if (parsed_time->is_localtime) {
    1869              19 :                 PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT(zone_type, zone_type);
    1870              19 :                 switch (parsed_time->zone_type) {
    1871                 :                         case TIMELIB_ZONETYPE_OFFSET:
    1872               5 :                                 PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT(zone, z);
    1873               5 :                                 add_assoc_bool(return_value, "is_dst", parsed_time->dst);
    1874               5 :                                 break;
    1875                 :                         case TIMELIB_ZONETYPE_ID:
    1876               0 :                                 if (parsed_time->tz_abbr) {
    1877               0 :                                         add_assoc_string(return_value, "tz_abbr", parsed_time->tz_abbr, 1);
    1878                 :                                 }
    1879               0 :                                 if (parsed_time->tz_info) {
    1880               0 :                                         add_assoc_string(return_value, "tz_id", parsed_time->tz_info->name, 1);
    1881                 :                                 }
    1882               0 :                                 break;
    1883                 :                         case TIMELIB_ZONETYPE_ABBR:
    1884               7 :                                 PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT(zone, z);
    1885               7 :                                 add_assoc_bool(return_value, "is_dst", parsed_time->dst);
    1886               7 :                                 add_assoc_string(return_value, "tz_abbr", parsed_time->tz_abbr, 1);
    1887                 :                                 break;
    1888                 :                 }
    1889                 :         }
    1890              46 :         if (parsed_time->have_relative || parsed_time->have_weekday_relative) {
    1891               0 :                 MAKE_STD_ZVAL(element);
    1892               0 :                 array_init(element);
    1893                 :         }
    1894              46 :         if (parsed_time->have_relative) {
    1895               0 :                 add_assoc_long(element, "year",   parsed_time->relative.y);
    1896               0 :                 add_assoc_long(element, "month",  parsed_time->relative.m);
    1897               0 :                 add_assoc_long(element, "day",    parsed_time->relative.d);
    1898               0 :                 add_assoc_long(element, "hour",   parsed_time->relative.h);
    1899               0 :                 add_assoc_long(element, "minute", parsed_time->relative.i);
    1900               0 :                 add_assoc_long(element, "second", parsed_time->relative.s);
    1901                 :         }
    1902              46 :         if (parsed_time->have_weekday_relative) {
    1903               0 :                 add_assoc_long(element, "weekday", parsed_time->relative.weekday);
    1904                 :         }
    1905              46 :         if (parsed_time->have_relative || parsed_time->have_weekday_relative) {
    1906               0 :                 add_assoc_zval(return_value, "relative", element);
    1907                 :         }
    1908              46 :         timelib_time_dtor(parsed_time);
    1909                 : }
    1910                 : /* }}} */
    1911                 : 
    1912                 : /* {{{ proto string date_format(DateTime object, string format)
    1913                 :    Returns date formatted according to given format
    1914                 : */
    1915                 : PHP_FUNCTION(date_format)
    1916             281 : {
    1917                 :         zval         *object;
    1918                 :         php_date_obj *dateobj;
    1919                 :         char         *format;
    1920                 :         int           format_len;
    1921                 : 
    1922             281 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &object, date_ce_date, &format, &format_len) == FAILURE) {
    1923              48 :                 RETURN_FALSE;
    1924                 :         }
    1925             233 :         dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC);
    1926             233 :         DATE_CHECK_INITIALIZED(dateobj->time, DateTime);
    1927             231 :         RETURN_STRING(date_format(format, format_len, dateobj->time, dateobj->time->is_localtime), 0);
    1928                 : }
    1929                 : /* }}} */
    1930                 : 
    1931                 : /* {{{ proto void date_modify(DateTime object, string modify)
    1932                 :    Alters the timestamp.
    1933                 : */
    1934                 : PHP_FUNCTION(date_modify)
    1935             115 : {
    1936                 :         zval         *object;
    1937                 :         php_date_obj *dateobj;
    1938                 :         char         *modify;
    1939                 :         int           modify_len;
    1940                 :         timelib_time *tmp_time;
    1941                 : 
    1942             115 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &object, date_ce_date, &modify, &modify_len) == FAILURE) {
    1943              48 :                 RETURN_FALSE;
    1944                 :         }
    1945              67 :         dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC);
    1946              67 :         DATE_CHECK_INITIALIZED(dateobj->time, DateTime);
    1947                 : 
    1948              67 :         tmp_time = timelib_strtotime(modify, modify_len, NULL, DATE_TIMEZONEDB);
    1949              67 :         memcpy(&dateobj->time->relative, &tmp_time->relative, sizeof(struct timelib_rel_time));
    1950              67 :         dateobj->time->have_relative = tmp_time->have_relative;
    1951              67 :         dateobj->time->have_weekday_relative = tmp_time->have_weekday_relative;
    1952              67 :         dateobj->time->sse_uptodate = 0;
    1953              67 :         timelib_time_dtor(tmp_time);
    1954                 : 
    1955              67 :         timelib_update_ts(dateobj->time, NULL);
    1956              67 :         timelib_update_from_sse(dateobj->time);
    1957                 : }
    1958                 : /* }}} */
    1959                 : 
    1960                 : /* {{{ proto DateTimeZone date_timezone_get(DateTime object)
    1961                 :    Return new DateTimeZone object relative to give DateTime
    1962                 : */
    1963                 : PHP_FUNCTION(date_timezone_get)
    1964              65 : {
    1965                 :         zval             *object;
    1966                 :         php_date_obj     *dateobj;
    1967                 :         php_timezone_obj *tzobj;
    1968                 : 
    1969              65 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, date_ce_date) == FAILURE) {
    1970              33 :                 RETURN_FALSE;
    1971                 :         }
    1972              32 :         dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC);
    1973              32 :         DATE_CHECK_INITIALIZED(dateobj->time, DateTime);
    1974              32 :         if (dateobj->time->is_localtime/* && dateobj->time->tz_info*/) {
    1975              32 :                 date_instantiate(date_ce_timezone, return_value TSRMLS_CC);
    1976              32 :                 tzobj = (php_timezone_obj *) zend_object_store_get_object(return_value TSRMLS_CC);
    1977              32 :                 tzobj->initialized = 1;
    1978              32 :                 tzobj->type = dateobj->time->zone_type;
    1979              32 :                 switch (dateobj->time->zone_type) {
    1980                 :                         case TIMELIB_ZONETYPE_ID:
    1981              20 :                                 tzobj->tzi.tz = dateobj->time->tz_info;
    1982              20 :                                 break;
    1983                 :                         case TIMELIB_ZONETYPE_OFFSET:
    1984              10 :                                 tzobj->tzi.utc_offset = dateobj->time->z;
    1985              10 :                                 break;
    1986                 :                         case TIMELIB_ZONETYPE_ABBR:
    1987               2 :                                 tzobj->tzi.z.utc_offset = dateobj->time->z;
    1988               2 :                                 tzobj->tzi.z.dst = dateobj->time->dst;
    1989               2 :                                 tzobj->tzi.z.abbr = strdup(dateobj->time->tz_abbr);
    1990                 :                                 break;
    1991                 :                 }
    1992                 :         } else {
    1993               0 :                 RETURN_FALSE;
    1994                 :         }
    1995                 : }
    1996                 : /* }}} */
    1997                 : 
    1998                 : /* {{{ proto void date_timezone_set(DateTime object, DateTimeZone object)
    1999                 :    Sets the timezone for the DateTime object.
    2000                 : */
    2001                 : PHP_FUNCTION(date_timezone_set)
    2002             101 : {
    2003                 :         zval             *object;
    2004                 :         zval             *timezone_object;
    2005                 :         php_date_obj     *dateobj;
    2006                 :         php_timezone_obj *tzobj;
    2007                 : 
    2008             101 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &object, date_ce_date, &timezone_object, date_ce_timezone) == FAILURE) {
    2009              92 :                 RETURN_FALSE;
    2010                 :         }
    2011               9 :         dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC);
    2012               9 :         DATE_CHECK_INITIALIZED(dateobj->time, DateTime);
    2013               9 :         tzobj = (php_timezone_obj *) zend_object_store_get_object(timezone_object TSRMLS_CC);
    2014               9 :         if (tzobj->type != TIMELIB_ZONETYPE_ID) {
    2015               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can only do this for zones with ID for now");
    2016               0 :                 return;
    2017                 :         }
    2018               9 :         timelib_set_timezone(dateobj->time, tzobj->tzi.tz);
    2019               9 :         timelib_unixtime2local(dateobj->time, dateobj->time->sse);
    2020                 : }
    2021                 : /* }}} */
    2022                 : 
    2023                 : /* {{{ proto long date_offset_get(DateTime object)
    2024                 :    Returns the DST offset.
    2025                 : */
    2026                 : PHP_FUNCTION(date_offset_get)
    2027              38 : {
    2028                 :         zval                *object;
    2029                 :         php_date_obj        *dateobj;
    2030                 :         timelib_time_offset *offset;
    2031                 : 
    2032              38 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, date_ce_date) == FAILURE) {
    2033              34 :                 RETURN_FALSE;
    2034                 :         }
    2035               4 :         dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC);
    2036               4 :         DATE_CHECK_INITIALIZED(dateobj->time, DateTime);
    2037               4 :         if (dateobj->time->is_localtime/* && dateobj->time->tz_info*/) {
    2038               4 :                 switch (dateobj->time->zone_type) {
    2039                 :                         case TIMELIB_ZONETYPE_ID:
    2040               4 :                                 offset = timelib_get_time_zone_info(dateobj->time->sse, dateobj->time->tz_info);
    2041               4 :                                 RETVAL_LONG(offset->offset);
    2042               4 :                                 timelib_time_offset_dtor(offset);
    2043               4 :                                 break;
    2044                 :                         case TIMELIB_ZONETYPE_OFFSET:
    2045               0 :                                 RETVAL_LONG(dateobj->time->z * -60);
    2046               0 :                                 break;
    2047                 :                         case TIMELIB_ZONETYPE_ABBR:
    2048               0 :                                 RETVAL_LONG((dateobj->time->z - (60 * dateobj->time->dst)) * -60);
    2049                 :                                 break;
    2050                 :                 }
    2051               4 :                 return;
    2052                 :         } else {
    2053               0 :                 RETURN_LONG(0);
    2054                 :         }
    2055                 : }
    2056                 : /* }}} */
    2057                 : 
    2058                 : /* {{{ proto void date_time_set(DateTime object, long hour, long minute[, long second])
    2059                 :    Sets the time.
    2060                 : */
    2061                 : PHP_FUNCTION(date_time_set)
    2062             223 : {
    2063                 :         zval         *object;
    2064                 :         php_date_obj *dateobj;
    2065             223 :         long          h, i, s = 0;
    2066                 : 
    2067             223 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oll|l", &object, date_ce_date, &h, &i, &s) == FAILURE) {
    2068             116 :                 RETURN_FALSE;
    2069                 :         }
    2070             107 :         dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC);
    2071             107 :         DATE_CHECK_INITIALIZED(dateobj->time, DateTime);
    2072             107 :         dateobj->time->h = h;
    2073             107 :         dateobj->time->i = i;
    2074             107 :         dateobj->time->s = s;
    2075             107 :         timelib_update_ts(dateobj->time, NULL);
    2076                 : }
    2077                 : /* }}} */
    2078                 : 
    2079                 : /* {{{ proto void date_date_set(DateTime object, long year, long month, long day)
    2080                 :    Sets the date.
    2081                 : */
    2082                 : PHP_FUNCTION(date_date_set)
    2083             214 : {
    2084                 :         zval         *object;
    2085                 :         php_date_obj *dateobj;
    2086                 :         long          y, m, d;
    2087                 : 
    2088             214 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Olll", &object, date_ce_date, &y, &m, &d) == FAILURE) {
    2089             117 :                 RETURN_FALSE;
    2090                 :         }
    2091              97 :         dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC);
    2092              97 :         DATE_CHECK_INITIALIZED(dateobj->time, DateTime);
    2093              97 :         dateobj->time->y = y;
    2094              97 :         dateobj->time->m = m;
    2095              97 :         dateobj->time->d = d;
    2096              97 :         timelib_update_ts(dateobj->time, NULL);
    2097                 : }
    2098                 : /* }}} */
    2099                 : 
    2100                 : /* {{{ proto void date_isodate_set(DateTime object, long year, long week[, long day])
    2101                 :    Sets the ISO date.
    2102                 : */
    2103                 : PHP_FUNCTION(date_isodate_set)
    2104             216 : {
    2105                 :         zval         *object;
    2106                 :         php_date_obj *dateobj;
    2107             216 :         long          y, w, d = 1;
    2108                 : 
    2109             216 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oll|l", &object, date_ce_date, &y, &w, &d) == FAILURE) {
    2110             117 :                 RETURN_FALSE;
    2111                 :         }
    2112              99 :         dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC);
    2113              99 :         DATE_CHECK_INITIALIZED(dateobj->time, DateTime);
    2114              99 :         dateobj->time->y = y;
    2115              99 :         dateobj->time->m = 1;
    2116              99 :         dateobj->time->d = 1;
    2117              99 :         dateobj->time->relative.d = timelib_daynr_from_weeknr(y, w, d);
    2118              99 :         dateobj->time->have_relative = 1;
    2119                 :         
    2120              99 :         timelib_update_ts(dateobj->time, NULL);
    2121                 : }
    2122                 : /* }}} */
    2123                 : 
    2124                 : static int timezone_initialize(timelib_tzinfo **tzi, /*const*/ char *tz TSRMLS_DC)
    2125             106 : {
    2126                 :         char *tzid;
    2127                 :         
    2128             106 :         *tzi = NULL;
    2129                 :         
    2130             106 :         if ((tzid = timelib_timezone_id_from_abbr(tz, -1, 0))) {
    2131              10 :                 *tzi = php_date_parse_tzfile(tzid, DATE_TIMEZONEDB TSRMLS_CC);
    2132                 :         } else {
    2133              96 :                 *tzi = php_date_parse_tzfile(tz, DATE_TIMEZONEDB TSRMLS_CC);
    2134                 :         }
    2135                 :         
    2136             106 :         if (*tzi) {
    2137              61 :                 return SUCCESS;
    2138                 :         } else {
    2139              45 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown or bad timezone (%s)", tz);
    2140              45 :                 return FAILURE;
    2141                 :         }
    2142                 : }
    2143                 : 
    2144                 : /* {{{ proto DateTimeZone timezone_open(string timezone)
    2145                 :    Returns new DateTimeZone object
    2146                 : */
    2147                 : PHP_FUNCTION(timezone_open)
    2148              48 : {
    2149                 :         char *tz;
    2150                 :         int   tz_len;
    2151              48 :         timelib_tzinfo *tzi = NULL;
    2152                 :         php_timezone_obj *tzobj;
    2153                 : 
    2154              48 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &tz, &tz_len) == FAILURE) {
    2155               8 :                 RETURN_FALSE;
    2156                 :         }
    2157              40 :         if (SUCCESS != timezone_initialize(&tzi, tz TSRMLS_CC)) {
    2158              22 :                 RETURN_FALSE;
    2159                 :         }
    2160              18 :         tzobj = zend_object_store_get_object(date_instantiate(date_ce_timezone, return_value TSRMLS_CC) TSRMLS_CC);
    2161              18 :         tzobj->type = TIMELIB_ZONETYPE_ID;
    2162              18 :         tzobj->tzi.tz = tzi;
    2163              18 :         tzobj->initialized = 1;
    2164                 : }
    2165                 : /* }}} */
    2166                 : 
    2167                 : /* {{{ proto DateTimeZone::__construct(string timezone)
    2168                 :    Creates new DateTimeZone object.
    2169                 : */
    2170                 : PHP_METHOD(DateTimeZone, __construct)
    2171              73 : {
    2172                 :         char *tz;
    2173                 :         int tz_len;
    2174              73 :         timelib_tzinfo *tzi = NULL;
    2175                 :         php_timezone_obj *tzobj;
    2176                 :         
    2177              73 :         php_set_error_handling(EH_THROW, NULL TSRMLS_CC);
    2178              73 :         if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &tz, &tz_len)) {
    2179              66 :                 if (SUCCESS == timezone_initialize(&tzi, tz TSRMLS_CC)) {
    2180              43 :                         tzobj = zend_object_store_get_object(getThis() TSRMLS_CC);
    2181              43 :                         tzobj->type = TIMELIB_ZONETYPE_ID;
    2182              43 :                         tzobj->tzi.tz = tzi;
    2183              43 :                         tzobj->initialized = 1;
    2184                 :                 } else {
    2185              23 :                         ZVAL_NULL(getThis());
    2186                 :                 }
    2187                 :         }
    2188              73 :         php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
    2189              73 : }
    2190                 : /* }}} */
    2191                 : 
    2192                 : /* {{{ proto string timezone_name_get(DateTimeZone object)
    2193                 :    Returns the name of the timezone.
    2194                 : */
    2195                 : PHP_FUNCTION(timezone_name_get)
    2196              36 : {
    2197                 :         zval             *object;
    2198                 :         php_timezone_obj *tzobj;
    2199                 : 
    2200              36 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, date_ce_timezone) == FAILURE) {
    2201               6 :                 RETURN_FALSE;
    2202                 :         }
    2203              30 :         tzobj = (php_timezone_obj *) zend_object_store_get_object(object TSRMLS_CC);
    2204              30 :         DATE_CHECK_INITIALIZED(tzobj->initialized, DateTimeZone);
    2205                 : 
    2206              28 :         switch (tzobj->type) {
    2207                 :                 case TIMELIB_ZONETYPE_ID:
    2208              23 :                         RETURN_STRING(tzobj->tzi.tz->name, 1);
    2209                 :                         break;
    2210                 :                 case TIMELIB_ZONETYPE_OFFSET: {
    2211               5 :                         char *tmpstr = emalloc(sizeof("UTC+05:00"));
    2212               5 :                         timelib_sll utc_offset = tzobj->tzi.utc_offset;
    2213                 : 
    2214               5 :                         snprintf(tmpstr, sizeof("+05:00"), "%c%02d:%02d",
    2215                 :                                 utc_offset > 0 ? '-' : '+',
    2216                 :                                 abs(utc_offset / 60),
    2217                 :                                 abs((utc_offset % 60)));
    2218                 : 
    2219               5 :                         RETURN_STRING(tmpstr, 0);
    2220                 :                         }
    2221                 :                         break;
    2222                 :                 case TIMELIB_ZONETYPE_ABBR:
    2223               0 :                         RETURN_STRING(tzobj->tzi.z.abbr, 1);
    2224                 :                         break;
    2225                 :         }
    2226                 : }
    2227                 : /* }}} */
    2228                 : 
    2229                 : /* {{{ proto string timezone_name_from_abbr(string abbr[, long gmtOffset[, long isdst]])
    2230                 :    Returns the timezone name from abbrevation
    2231                 : */
    2232                 : PHP_FUNCTION(timezone_name_from_abbr)
    2233             105 : {
    2234                 :         char    *abbr;
    2235                 :         char    *tzid;
    2236                 :         int      abbr_len;
    2237             105 :         long     gmtoffset = -1;
    2238             105 :         long     isdst = -1;
    2239                 : 
    2240             105 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ll", &abbr, &abbr_len, &gmtoffset, &isdst) == FAILURE) {
    2241              35 :                 RETURN_FALSE;
    2242                 :         }
    2243              70 :         tzid = timelib_timezone_id_from_abbr(abbr, gmtoffset, isdst);
    2244                 : 
    2245              70 :         if (tzid) {
    2246              66 :                 RETURN_STRING(tzid, 1);
    2247                 :         } else {
    2248               4 :                 RETURN_FALSE;
    2249                 :         }
    2250                 : }
    2251                 : /* }}} */
    2252                 : 
    2253                 : /* {{{ proto long timezone_offset_get(DateTimeZone object, DateTime object)
    2254                 :    Returns the timezone offset.
    2255                 : */
    2256                 : PHP_FUNCTION(timezone_offset_get)
    2257             115 : {
    2258                 :         zval                *object, *dateobject;
    2259                 :         php_timezone_obj    *tzobj;
    2260                 :         php_date_obj        *dateobj;
    2261                 :         timelib_time_offset *offset;
    2262                 : 
    2263             115 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &object, date_ce_timezone, &dateobject, date_ce_date) == FAILURE) {
    2264              97 :                 RETURN_FALSE;
    2265                 :         }
    2266              18 :         tzobj = (php_timezone_obj *) zend_object_store_get_object(object TSRMLS_CC);
    2267              18 :         DATE_CHECK_INITIALIZED(tzobj->initialized, DateTimeZone);
    2268              18 :         dateobj = (php_date_obj *) zend_object_store_get_object(dateobject TSRMLS_CC);
    2269              18 :         DATE_CHECK_INITIALIZED(dateobj->time, DateTime);
    2270                 : 
    2271              18 :         switch (tzobj->type) {
    2272                 :                 case TIMELIB_ZONETYPE_ID:
    2273              11 :                         offset = timelib_get_time_zone_info(dateobj->time->sse, tzobj->tzi.tz);
    2274              11 :                         RETVAL_LONG(offset->offset);
    2275              11 :                         timelib_time_offset_dtor(offset);
    2276              11 :                         break;
    2277                 :                 case TIMELIB_ZONETYPE_OFFSET:
    2278               5 :                         RETURN_LONG(tzobj->tzi.utc_offset * -60);
    2279                 :                         break;
    2280                 :                 case TIMELIB_ZONETYPE_ABBR:
    2281               2 :                         RETURN_LONG((tzobj->tzi.z.utc_offset - (tzobj->tzi.z.dst*60)) * -60);
    2282                 :                         break;
    2283                 :         }
    2284                 : }
    2285                 : /* }}} */
    2286                 : 
    2287                 : /* {{{ proto array timezone_transitions_get(DateTimeZone object)
    2288                 :    Returns numeracilly indexed array containing associative array for all transitions for the timezone.
    2289                 : */
    2290                 : PHP_FUNCTION(timezone_transitions_get)
    2291              37 : {
    2292                 :         zval                *object, *element;
    2293                 :         php_timezone_obj    *tzobj;
    2294                 :         unsigned int         i;
    2295                 : 
    2296              37 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, date_ce_timezone) == FAILURE) {
    2297              34 :                 RETURN_FALSE;
    2298                 :         }
    2299               3 :         tzobj = (php_timezone_obj *) zend_object_store_get_object(object TSRMLS_CC);
    2300               3 :         DATE_CHECK_INITIALIZED(tzobj->initialized, DateTimeZone);
    2301               3 :         if (tzobj->type != TIMELIB_ZONETYPE_ID) {
    2302               0 :                 RETURN_FALSE;
    2303                 :         }
    2304                 : 
    2305               3 :         array_init(return_value);
    2306             729 :         for (i = 0; i < tzobj->tzi.tz->timecnt; ++i) {
    2307             726 :                 MAKE_STD_ZVAL(element);
    2308             726 :                 array_init(element);
    2309             726 :                 add_assoc_long(element, "ts",     tzobj->tzi.tz->trans[i]);
    2310             726 :                 add_assoc_string(element, "time", php_format_date(DATE_FORMAT_ISO8601, 13, tzobj->tzi.tz->trans[i], 0 TSRMLS_CC), 0);
    2311             726 :                 add_assoc_long(element, "offset", tzobj->tzi.tz->type[tzobj->tzi.tz->trans_idx[i]].offset);
    2312             726 :                 add_assoc_bool(element, "isdst",  tzobj->tzi.tz->type[tzobj->tzi.tz->trans_idx[i]].isdst);
    2313             726 :                 add_assoc_string(element, "abbr", &tzobj->tzi.tz->timezone_abbr[tzobj->tzi.tz->type[tzobj->tzi.tz->trans_idx[i]].abbr_idx], 1);
    2314                 : 
    2315             726 :                 add_next_index_zval(return_value, element);
    2316                 :         }
    2317                 : }
    2318                 : /* }}} */
    2319                 : 
    2320                 : /* {{{ proto array timezone_identifiers_list()
    2321                 :    Returns numerically index array with all timezone identifiers.
    2322                 : */
    2323                 : PHP_FUNCTION(timezone_identifiers_list)
    2324               2 : {
    2325                 :         const timelib_tzdb             *tzdb;
    2326                 :         const timelib_tzdb_index_entry *table;
    2327                 :         int                             i, item_count;
    2328                 : 
    2329               2 :         tzdb = DATE_TIMEZONEDB;
    2330               2 :         item_count = tzdb->index_size;
    2331               2 :         table = tzdb->index;
    2332                 :         
    2333               2 :         array_init(return_value);
    2334                 : 
    2335            1124 :         for (i = 0; i < item_count; ++i) {
    2336            1122 :                 add_next_index_string(return_value, table[i].id, 1);
    2337                 :         };
    2338               2 : }
    2339                 : /* }}} */
    2340                 : 
    2341                 : /* {{{ proto array timezone_abbreviations_list()
    2342                 :    Returns associative array containing dst, offset and the timezone name
    2343                 : */
    2344                 : PHP_FUNCTION(timezone_abbreviations_list)
    2345               3 : {
    2346                 :         const timelib_tz_lookup_table *table, *entry;
    2347                 :         zval                          *element, **abbr_array_pp, *abbr_array;
    2348                 :         
    2349               3 :         table = timelib_timezone_abbreviations_list();
    2350               3 :         array_init(return_value);
    2351               3 :         entry = table;
    2352                 : 
    2353                 :         do {
    2354            5094 :                 MAKE_STD_ZVAL(element);
    2355            5094 :                 array_init(element);
    2356            5094 :                 add_assoc_bool(element, "dst", entry->type);
    2357            5094 :                 add_assoc_long(element, "offset", entry->gmtoffset);
    2358            5094 :                 if (entry->full_tz_name) {
    2359            5019 :                         add_assoc_string(element, "timezone_id", entry->full_tz_name, 1);
    2360                 :                 } else {
    2361              75 :                         add_assoc_null(element, "timezone_id");
    2362                 :                 }
    2363                 : 
    2364            5094 :                 if (zend_hash_find(HASH_OF(return_value), entry->name, strlen(entry->name) + 1, (void **) &abbr_array_pp) == FAILURE) {
    2365            1014 :                         MAKE_STD_ZVAL(abbr_array);
    2366            1014 :                         array_init(abbr_array);
    2367            1014 :                         add_assoc_zval(return_value, entry->name, abbr_array);
    2368                 :                 } else {
    2369            4080 :                         abbr_array = *abbr_array_pp;
    2370                 :                 }
    2371            5094 :                 add_next_index_zval(abbr_array, element);
    2372            5094 :                 entry++;
    2373            5094 :         } while (entry->name);
    2374               3 : }
    2375                 : /* }}} */
    2376                 : 
    2377                 : /* {{{ proto bool date_default_timezone_set(string timezone_identifier)
    2378                 :    Sets the default timezone used by all date/time functions in a script */
    2379                 : PHP_FUNCTION(date_default_timezone_set)
    2380             365 : {
    2381                 :         char *zone;
    2382                 :         int   zone_len;
    2383                 : 
    2384             365 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &zone, &zone_len) == FAILURE) {
    2385               4 :                 RETURN_FALSE;
    2386                 :         }
    2387             361 :         if (!timelib_timezone_id_is_valid(zone, DATE_TIMEZONEDB)) {
    2388              25 :                 php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Timezone ID '%s' is invalid", zone);
    2389              25 :                 RETURN_FALSE;
    2390                 :         }
    2391             336 :         if (DATEG(timezone)) {
    2392              33 :                 efree(DATEG(timezone));
    2393              33 :                 DATEG(timezone) = NULL;
    2394                 :         }
    2395             336 :         DATEG(timezone) = estrndup(zone, zone_len);
    2396             336 :         RETURN_TRUE;
    2397                 : }
    2398                 : /* }}} */
    2399                 : 
    2400                 : /* {{{ proto string date_default_timezone_get()
    2401                 :    Gets the default timezone used by all date/time functions in a script */
    2402                 : PHP_FUNCTION(date_default_timezone_get)
    2403              11 : {
    2404                 :         timelib_tzinfo *default_tz;
    2405                 : 
    2406              11 :         default_tz = get_timezone_info(TSRMLS_C);
    2407              11 :         RETVAL_STRING(default_tz->name, 1);
    2408              11 : }
    2409                 : /* }}} */
    2410                 : 
    2411                 : /* {{{ php_do_date_sunrise_sunset
    2412                 :  *  Common for date_sunrise() and date_sunset() functions
    2413                 :  */
    2414                 : static void php_do_date_sunrise_sunset(INTERNAL_FUNCTION_PARAMETERS, int calc_sunset)
    2415             952 : {
    2416             952 :         double latitude, longitude, zenith, gmt_offset = 0, altitude;
    2417                 :         double h_rise, h_set, N;
    2418                 :         timelib_sll rise, set, transit;
    2419                 :         long time, retformat;
    2420                 :         int             rs;
    2421                 :         timelib_time   *t;
    2422                 :         timelib_tzinfo *tzi;
    2423                 :         char           *retstr;
    2424                 :         
    2425             952 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|ldddd", &time, &retformat, &latitude, &longitude, &zenith, &gmt_offset) == FAILURE) {
    2426             390 :                 RETURN_FALSE;
    2427                 :         }
    2428                 :         
    2429             562 :         switch (ZEND_NUM_ARGS()) {
    2430                 :                 case 1:
    2431               0 :                         retformat = SUNFUNCS_RET_STRING;
    2432                 :                 case 2:
    2433               0 :                         latitude = INI_FLT("date.default_latitude");
    2434                 :                 case 3:
    2435               0 :                         longitude = INI_FLT("date.default_longitude");
    2436                 :                 case 4:
    2437              36 :                         if (calc_sunset) {
    2438              12 :                                 zenith = INI_FLT("date.sunset_zenith");
    2439                 :                         } else {
    2440              24 :                                 zenith = INI_FLT("date.sunrise_zenith");
    2441                 :                         }
    2442                 :                 case 5:
    2443                 :                 case 6:
    2444                 :                         break;
    2445                 :                 default:
    2446               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid format");
    2447               0 :                         RETURN_FALSE;
    2448                 :                         break;
    2449                 :         }
    2450             944 :         if (retformat != SUNFUNCS_RET_TIMESTAMP &&
    2451                 :                 retformat != SUNFUNCS_RET_STRING &&
    2452                 :                 retformat != SUNFUNCS_RET_DOUBLE)
    2453                 :         {
    2454               8 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Wrong return format given, pick one of SUNFUNCS_RET_TIMESTAMP, SUNFUNCS_RET_STRING or SUNFUNCS_RET_DOUBLE");
    2455               8 :                 RETURN_FALSE;
    2456                 :         }
    2457             554 :         altitude = 90 - zenith;
    2458                 : 
    2459                 :         /* Initialize time struct */
    2460             554 :         t = timelib_time_ctor();
    2461             554 :         tzi = get_timezone_info(TSRMLS_C);
    2462             554 :         t->tz_info = tzi;
    2463             554 :         t->zone_type = TIMELIB_ZONETYPE_ID;
    2464                 : 
    2465             554 :         if (ZEND_NUM_ARGS() <= 5) {
    2466              36 :                 gmt_offset = timelib_get_current_offset(t) / 3600;
    2467                 :         }
    2468                 : 
    2469             554 :         timelib_unixtime2local(t, time);
    2470             554 :         rs = timelib_astro_rise_set_altitude(t, longitude, latitude, altitude, 1, &h_rise, &h_set, &rise, &set, &transit);
    2471             554 :         timelib_time_dtor(t);
    2472                 :         
    2473             554 :         if (rs != 0) {
    2474             108 :                 RETURN_FALSE;
    2475                 :         }
    2476                 : 
    2477             446 :         if (retformat == SUNFUNCS_RET_TIMESTAMP) {
    2478             144 :                 RETURN_LONG(calc_sunset ? set : rise);
    2479                 :         }
    2480             302 :         N = (calc_sunset ? h_set : h_rise) + gmt_offset;
    2481                 : 
    2482             302 :         if (N > 24 || N < 0) {
    2483              28 :                 N -= floor(N / 24) * 24;
    2484                 :         }
    2485                 : 
    2486             302 :         switch (retformat) {
    2487                 :                 case SUNFUNCS_RET_STRING:
    2488             172 :                         spprintf(&retstr, 0, "%02d:%02d", (int) N, (int) (60 * (N - (int) N)));
    2489             172 :                         RETURN_STRINGL(retstr, 5, 0);
    2490                 :                         break;
    2491                 :                 case SUNFUNCS_RET_DOUBLE:
    2492             130 :                         RETURN_DOUBLE(N);
    2493                 :                         break;
    2494                 :         }
    2495                 : }
    2496                 : /* }}} */
    2497                 : 
    2498                 : /* {{{ proto mixed date_sunrise(mixed time [, int format [, float latitude [, float longitude [, float zenith [, float gmt_offset]]]]])
    2499                 :    Returns time of sunrise for a given day and location */
    2500                 : PHP_FUNCTION(date_sunrise)
    2501             481 : {
    2502             481 :         php_do_date_sunrise_sunset(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
    2503             481 : }
    2504                 : /* }}} */
    2505                 : 
    2506                 : /* {{{ proto mixed date_sunset(mixed time [, int format [, float latitude [, float longitude [, float zenith [, float gmt_offset]]]]])
    2507                 :    Returns time of sunset for a given day and location */
    2508                 : PHP_FUNCTION(date_sunset)
    2509             471 : {
    2510             471 :         php_do_date_sunrise_sunset(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
    2511             471 : }
    2512                 : /* }}} */
    2513                 : 
    2514                 : /* {{{ proto array date_sun_info(long time, float latitude, float longitude)
    2515                 :    Returns an array with information about sun set/rise and twilight begin/end */
    2516                 : PHP_FUNCTION(date_sun_info)
    2517              77 : {
    2518                 :         long            time;
    2519                 :         double          latitude, longitude;
    2520                 :         timelib_time   *t, *t2;
    2521                 :         timelib_tzinfo *tzi;
    2522                 :         int             rs;
    2523                 :         timelib_sll     rise, set, transit;
    2524                 :         int             dummy;
    2525                 :         double          ddummy;
    2526                 :         
    2527              77 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ldd", &time, &latitude, &longitude) == FAILURE) {
    2528              24 :                 RETURN_FALSE;
    2529                 :         }
    2530                 :         /* Initialize time struct */
    2531              53 :         t = timelib_time_ctor();
    2532              53 :         tzi = get_timezone_info(TSRMLS_C);
    2533              53 :         t->tz_info = tzi;
    2534              53 :         t->zone_type = TIMELIB_ZONETYPE_ID;
    2535              53 :         timelib_unixtime2local(t, time);
    2536                 : 
    2537                 :         /* Setup */
    2538              53 :         t2 = timelib_time_ctor();
    2539              53 :         array_init(return_value);
    2540                 :         
    2541                 :         /* Get sun up/down and transit */
    2542              53 :         rs = timelib_astro_rise_set_altitude(t, longitude, latitude, -35.0/60, 1, &ddummy, &ddummy, &rise, &set, &transit);
    2543              53 :         switch (rs) {
    2544                 :                 case -1: /* always below */
    2545               0 :                         add_assoc_bool(return_value, "sunrise", 0);
    2546               0 :                         add_assoc_bool(return_value, "sunset", 0);
    2547               0 :                         break;
    2548                 :                 case 1: /* always above */
    2549               1 :                         add_assoc_bool(return_value, "sunrise", 1);
    2550               1 :                         add_assoc_bool(return_value, "sunset", 1);
    2551               1 :                         break;
    2552                 :                 default:
    2553              52 :                         t2->sse = rise;
    2554              52 :                         add_assoc_long(return_value, "sunrise", timelib_date_to_int(t2, &dummy));
    2555              52 :                         t2->sse = set;
    2556              52 :                         add_assoc_long(return_value, "sunset", timelib_date_to_int(t2, &dummy));
    2557                 :         }
    2558              53 :         t2->sse = transit;
    2559              53 :         add_assoc_long(return_value, "transit", timelib_date_to_int(t2, &dummy));
    2560                 : 
    2561                 :         /* Get civil twilight */
    2562              53 :         rs = timelib_astro_rise_set_altitude(t, longitude, latitude, -6.0, 0, &ddummy, &ddummy, &rise, &set, &transit);
    2563              53 :         switch (rs) {
    2564                 :                 case -1: /* always below */
    2565               0 :                         add_assoc_bool(return_value, "civil_twilight_begin", 0);
    2566               0 :                         add_assoc_bool(return_value, "civil_twilight_end", 0);
    2567               0 :                         break;
    2568                 :                 case 1: /* always above */
    2569               1 :                         add_assoc_bool(return_value, "civil_twilight_begin", 1);
    2570               1 :                         add_assoc_bool(return_value, "civil_twilight_end", 1);
    2571               1 :                         break;
    2572                 :                 default:
    2573              52 :                         t2->sse = rise;
    2574              52 :                         add_assoc_long(return_value, "civil_twilight_begin", timelib_date_to_int(t2, &dummy));
    2575              52 :                         t2->sse = set;
    2576              52 :                         add_assoc_long(return_value, "civil_twilight_end", timelib_date_to_int(t2, &dummy));
    2577                 :         }
    2578                 : 
    2579                 :         /* Get nautical twilight */
    2580              53 :         rs = timelib_astro_rise_set_altitude(t, longitude, latitude, -12.0, 0, &ddummy, &ddummy, &rise, &set, &transit);
    2581              53 :         switch (rs) {
    2582                 :                 case -1: /* always below */
    2583               0 :                         add_assoc_bool(return_value, "nautical_twilight_begin", 0);
    2584               0 :                         add_assoc_bool(return_value, "nautical_twilight_end", 0);
    2585               0 :                         break;
    2586                 :                 case 1: /* always above */
    2587               0 :                         add_assoc_bool(return_value, "nautical_twilight_begin", 1);
    2588               0 :                         add_assoc_bool(return_value, "nautical_twilight_end", 1);
    2589               0 :                         break;
    2590                 :                 default:
    2591              53 :                         t2->sse = rise;
    2592              53 :                         add_assoc_long(return_value, "nautical_twilight_begin", timelib_date_to_int(t2, &dummy));
    2593              53 :                         t2->sse = set;
    2594              53 :                         add_assoc_long(return_value, "nautical_twilight_end", timelib_date_to_int(t2, &dummy));
    2595                 :         }
    2596                 : 
    2597                 :         /* Get astronomical twilight */
    2598              53 :         rs = timelib_astro_rise_set_altitude(t, longitude, latitude, -18.0, 0, &ddummy, &ddummy, &rise, &set, &transit);
    2599              53 :         switch (rs) {
    2600                 :                 case -1: /* always below */
    2601               0 :                         add_assoc_bool(return_value, "astronomical_twilight_begin", 0);
    2602               0 :                         add_assoc_bool(return_value, "astronomical_twilight_end", 0);
    2603               0 :                         break;
    2604                 :                 case 1: /* always above */
    2605               0 :                         add_assoc_bool(return_value, "astronomical_twilight_begin", 1);
    2606               0 :                         add_assoc_bool(return_value, "astronomical_twilight_end", 1);
    2607               0 :                         break;
    2608                 :                 default:
    2609              53 :                         t2->sse = rise;
    2610              53 :                         add_assoc_long(return_value, "astronomical_twilight_begin", timelib_date_to_int(t2, &dummy));
    2611              53 :                         t2->sse = set;
    2612              53 :                         add_assoc_long(return_value, "astronomical_twilight_end", timelib_date_to_int(t2, &dummy));
    2613                 :         }
    2614              53 :         timelib_time_dtor(t);
    2615              53 :         timelib_time_dtor(t2);
    2616                 : }
    2617                 : /* }}} */
    2618                 : /*
    2619                 :  * Local variables:
    2620                 :  * tab-width: 4
    2621                 :  * c-basic-offset: 4
    2622                 :  * End:
    2623                 :  * vim600: fdm=marker
    2624                 :  * vim: noet sw=4 ts=4
    2625                 :  */

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.