2005-06-15 05:32:29 +08:00
/*
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2014-09-20 00:33:14 +08:00
| PHP Version 7 |
2005-06-15 05:32:29 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2017-01-05 01:14:55 +08:00
| Copyright ( c ) 1997 - 2017 The PHP Group |
2005-06-15 05:32:29 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2006-01-01 20:51:34 +08:00
| This source file is subject to version 3.01 of the PHP license , |
2005-06-15 05:32:29 +08:00
| that is bundled with this package in the file LICENSE , and is |
| available through the world - wide - web at the following url : |
2006-01-01 20:51:34 +08:00
| http : //www.php.net/license/3_01.txt |
2005-06-15 05:32:29 +08:00
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world - wide - web , please send a note to |
| license @ php . net so we can mail you a copy immediately . |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2005-06-17 22:54:00 +08:00
| Authors : Derick Rethans < derick @ derickrethans . nl > |
2005-06-15 05:32:29 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
*/
/* $Id$ */
# include "php.h"
# include "php_streams.h"
# include "php_main.h"
# include "php_globals.h"
# include "php_ini.h"
# include "ext/standard/info.h"
2005-10-04 07:37:10 +08:00
# include "ext/standard/php_versioning.h"
2007-04-13 22:09:20 +08:00
# include "ext/standard/php_math.h"
2005-06-15 05:32:29 +08:00
# include "php_date.h"
2008-05-01 08:12:24 +08:00
# include "zend_interfaces.h"
2005-06-17 01:12:41 +08:00
# include "lib/timelib.h"
2005-06-15 05:32:29 +08:00
# include <time.h>
2009-05-05 00:28:50 +08:00
# ifdef PHP_WIN32
2010-02-12 06:37:50 +08:00
static __inline __int64 php_date_llabs ( __int64 i ) { return i > = 0 ? i : - i ; }
# elif defined(__GNUC__) && __GNUC__ < 3
static __inline __int64_t php_date_llabs ( __int64_t i ) { return i > = 0 ? i : - i ; }
# else
2010-06-09 05:23:48 +08:00
static inline long long php_date_llabs ( long long i ) { return i > = 0 ? i : - i ; }
2010-02-12 06:37:50 +08:00
# endif
2009-06-22 21:43:14 +08:00
2014-08-24 17:48:57 +08:00
# ifdef PHP_WIN32
# define DATE_I64_BUF_LEN 65
# define DATE_I64A(i, s, len) _i64toa_s(i, s, len, 10)
# define DATE_A64I(i, s) i = _atoi64(s)
# else
# define DATE_I64_BUF_LEN 65
# define DATE_I64A(i, s, len) \
do { \
int st = snprintf ( s , len , " %lld " , i ) ; \
s [ st ] = ' \0 ' ; \
} while ( 0 ) ;
# ifdef HAVE_ATOLL
# define DATE_A64I(i, s) i = atoll(s)
# else
# define DATE_A64I(i, s) i = strtoll(s, NULL, 10)
# endif
# endif
2006-06-11 09:42:17 +08:00
/* {{{ arginfo */
ZEND_BEGIN_ARG_INFO_EX ( arginfo_date , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , format )
ZEND_ARG_INFO ( 0 , timestamp )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_gmdate , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , format )
ZEND_ARG_INFO ( 0 , timestamp )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_idate , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , format )
ZEND_ARG_INFO ( 0 , timestamp )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_strtotime , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , time )
ZEND_ARG_INFO ( 0 , now )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_mktime , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , hour )
ZEND_ARG_INFO ( 0 , min )
ZEND_ARG_INFO ( 0 , sec )
ZEND_ARG_INFO ( 0 , mon )
ZEND_ARG_INFO ( 0 , day )
ZEND_ARG_INFO ( 0 , year )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_gmmktime , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , hour )
ZEND_ARG_INFO ( 0 , min )
ZEND_ARG_INFO ( 0 , sec )
ZEND_ARG_INFO ( 0 , mon )
ZEND_ARG_INFO ( 0 , day )
ZEND_ARG_INFO ( 0 , year )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO ( arginfo_checkdate , 0 )
ZEND_ARG_INFO ( 0 , month )
ZEND_ARG_INFO ( 0 , day )
ZEND_ARG_INFO ( 0 , year )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_strftime , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , format )
ZEND_ARG_INFO ( 0 , timestamp )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_gmstrftime , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , format )
ZEND_ARG_INFO ( 0 , timestamp )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO ( arginfo_time , 0 )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_localtime , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , timestamp )
ZEND_ARG_INFO ( 0 , associative_array )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_getdate , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , timestamp )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO ( arginfo_date_default_timezone_set , 0 )
ZEND_ARG_INFO ( 0 , timezone_identifier )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO ( arginfo_date_default_timezone_get , 0 )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_date_sunrise , 0 , 0 , 1 )
2006-07-02 08:11:06 +08:00
ZEND_ARG_INFO ( 0 , time )
2006-06-11 09:42:17 +08:00
ZEND_ARG_INFO ( 0 , format )
ZEND_ARG_INFO ( 0 , latitude )
ZEND_ARG_INFO ( 0 , longitude )
ZEND_ARG_INFO ( 0 , zenith )
ZEND_ARG_INFO ( 0 , gmt_offset )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_date_sunset , 0 , 0 , 1 )
2006-07-02 08:11:06 +08:00
ZEND_ARG_INFO ( 0 , time )
2006-06-11 09:42:17 +08:00
ZEND_ARG_INFO ( 0 , format )
ZEND_ARG_INFO ( 0 , latitude )
ZEND_ARG_INFO ( 0 , longitude )
ZEND_ARG_INFO ( 0 , zenith )
ZEND_ARG_INFO ( 0 , gmt_offset )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO ( arginfo_date_sun_info , 0 )
ZEND_ARG_INFO ( 0 , time )
ZEND_ARG_INFO ( 0 , latitude )
ZEND_ARG_INFO ( 0 , longitude )
ZEND_END_ARG_INFO ( )
2008-07-09 20:50:57 +08:00
ZEND_BEGIN_ARG_INFO_EX ( arginfo_date_create , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , time )
ZEND_ARG_INFO ( 0 , object )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_date_create_from_format , 0 , 0 , 2 )
ZEND_ARG_INFO ( 0 , format )
ZEND_ARG_INFO ( 0 , time )
2015-06-12 23:56:02 +08:00
ZEND_ARG_INFO ( 0 , object )
2008-07-09 20:50:57 +08:00
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_date_parse , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , date )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_date_parse_from_format , 0 , 0 , 2 )
ZEND_ARG_INFO ( 0 , format )
ZEND_ARG_INFO ( 0 , date )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO ( arginfo_date_get_last_errors , 0 )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_date_format , 0 , 0 , 2 )
ZEND_ARG_INFO ( 0 , object )
ZEND_ARG_INFO ( 0 , format )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_date_method_format , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , format )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_date_modify , 0 , 0 , 2 )
ZEND_ARG_INFO ( 0 , object )
ZEND_ARG_INFO ( 0 , modify )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_date_method_modify , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , modify )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_date_add , 0 , 0 , 2 )
ZEND_ARG_INFO ( 0 , object )
ZEND_ARG_INFO ( 0 , interval )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_date_method_add , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , interval )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_date_sub , 0 , 0 , 2 )
ZEND_ARG_INFO ( 0 , object )
ZEND_ARG_INFO ( 0 , interval )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_date_method_sub , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , interval )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_date_timezone_get , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , object )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO ( arginfo_date_method_timezone_get , 0 )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_date_timezone_set , 0 , 0 , 2 )
ZEND_ARG_INFO ( 0 , object )
ZEND_ARG_INFO ( 0 , timezone )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_date_method_timezone_set , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , timezone )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_date_offset_get , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , object )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO ( arginfo_date_method_offset_get , 0 )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_date_diff , 0 , 0 , 2 )
ZEND_ARG_INFO ( 0 , object )
ZEND_ARG_INFO ( 0 , object2 )
ZEND_ARG_INFO ( 0 , absolute )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_date_method_diff , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , object )
ZEND_ARG_INFO ( 0 , absolute )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_date_time_set , 0 , 0 , 3 )
ZEND_ARG_INFO ( 0 , object )
ZEND_ARG_INFO ( 0 , hour )
ZEND_ARG_INFO ( 0 , minute )
ZEND_ARG_INFO ( 0 , second )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_date_method_time_set , 0 , 0 , 2 )
ZEND_ARG_INFO ( 0 , hour )
ZEND_ARG_INFO ( 0 , minute )
ZEND_ARG_INFO ( 0 , second )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_date_date_set , 0 , 0 , 4 )
ZEND_ARG_INFO ( 0 , object )
ZEND_ARG_INFO ( 0 , year )
ZEND_ARG_INFO ( 0 , month )
ZEND_ARG_INFO ( 0 , day )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_date_method_date_set , 0 , 0 , 3 )
ZEND_ARG_INFO ( 0 , year )
ZEND_ARG_INFO ( 0 , month )
ZEND_ARG_INFO ( 0 , day )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_date_isodate_set , 0 , 0 , 3 )
ZEND_ARG_INFO ( 0 , object )
ZEND_ARG_INFO ( 0 , year )
ZEND_ARG_INFO ( 0 , week )
ZEND_ARG_INFO ( 0 , day )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_date_method_isodate_set , 0 , 0 , 2 )
ZEND_ARG_INFO ( 0 , year )
ZEND_ARG_INFO ( 0 , week )
ZEND_ARG_INFO ( 0 , day )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_date_timestamp_set , 0 , 0 , 2 )
ZEND_ARG_INFO ( 0 , object )
ZEND_ARG_INFO ( 0 , unixtimestamp )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_date_method_timestamp_set , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , unixtimestamp )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_date_timestamp_get , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , object )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO ( arginfo_date_method_timestamp_get , 0 )
ZEND_END_ARG_INFO ( )
2014-03-03 03:17:16 +08:00
ZEND_BEGIN_ARG_INFO_EX ( arginfo_date_method_create_from_mutable , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , DateTime )
ZEND_END_ARG_INFO ( )
2008-07-09 20:50:57 +08:00
ZEND_BEGIN_ARG_INFO_EX ( arginfo_timezone_open , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , timezone )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_timezone_name_get , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , object )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO ( arginfo_timezone_method_name_get , 0 )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_timezone_name_from_abbr , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , abbr )
ZEND_ARG_INFO ( 0 , gmtoffset )
ZEND_ARG_INFO ( 0 , isdst )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_timezone_offset_get , 0 , 0 , 2 )
2014-09-21 05:16:39 +08:00
ZEND_ARG_OBJ_INFO ( 0 , object , DateTimeZone , 0 )
ZEND_ARG_OBJ_INFO ( 0 , datetime , DateTimeInterface , 0 )
2008-07-09 20:50:57 +08:00
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_timezone_method_offset_get , 0 , 0 , 1 )
2014-09-21 05:16:39 +08:00
ZEND_ARG_INFO ( 0 , object )
2008-07-09 20:50:57 +08:00
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_timezone_transitions_get , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , object )
ZEND_ARG_INFO ( 0 , timestamp_begin )
ZEND_ARG_INFO ( 0 , timestamp_end )
ZEND_END_ARG_INFO ( )
2017-04-10 19:48:51 +08:00
ZEND_BEGIN_ARG_INFO_EX ( arginfo_timezone_method_transitions_get , 0 , 0 , 0 )
2008-07-09 20:50:57 +08:00
ZEND_ARG_INFO ( 0 , timestamp_begin )
ZEND_ARG_INFO ( 0 , timestamp_end )
ZEND_END_ARG_INFO ( )
2008-07-18 22:33:53 +08:00
ZEND_BEGIN_ARG_INFO_EX ( arginfo_timezone_location_get , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , object )
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO ( arginfo_timezone_method_location_get , 0 )
ZEND_END_ARG_INFO ( )
2008-07-09 20:50:57 +08:00
ZEND_BEGIN_ARG_INFO_EX ( arginfo_timezone_identifiers_list , 0 , 0 , 0 )
ZEND_ARG_INFO ( 0 , what )
2009-06-22 04:40:53 +08:00
ZEND_ARG_INFO ( 0 , country )
2008-07-09 20:50:57 +08:00
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO ( arginfo_timezone_abbreviations_list , 0 )
ZEND_END_ARG_INFO ( )
2009-05-04 03:58:49 +08:00
ZEND_BEGIN_ARG_INFO ( arginfo_timezone_version_get , 0 )
ZEND_END_ARG_INFO ( )
2008-07-09 20:50:57 +08:00
ZEND_BEGIN_ARG_INFO_EX ( arginfo_date_interval_create_from_date_string , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , time )
ZEND_END_ARG_INFO ( )
2009-05-20 03:23:33 +08:00
ZEND_BEGIN_ARG_INFO_EX ( arginfo_date_interval_format , 0 , 0 , 2 )
2008-07-09 20:50:57 +08:00
ZEND_ARG_INFO ( 0 , object )
2009-05-20 03:23:33 +08:00
ZEND_ARG_INFO ( 0 , format )
2008-07-09 20:50:57 +08:00
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO ( arginfo_date_method_interval_format , 0 )
2009-05-20 03:23:33 +08:00
ZEND_ARG_INFO ( 0 , format )
2008-07-09 20:50:57 +08:00
ZEND_END_ARG_INFO ( )
ZEND_BEGIN_ARG_INFO_EX ( arginfo_date_period_construct , 0 , 0 , 3 )
ZEND_ARG_INFO ( 0 , start )
ZEND_ARG_INFO ( 0 , interval )
ZEND_ARG_INFO ( 0 , end )
ZEND_END_ARG_INFO ( )
2015-08-14 20:19:12 +08:00
ZEND_BEGIN_ARG_INFO_EX ( arginfo_date_interval_construct , 0 , 0 , 1 )
2008-07-09 20:50:57 +08:00
ZEND_ARG_INFO ( 0 , interval_spec )
ZEND_END_ARG_INFO ( )
2006-06-11 09:42:17 +08:00
/* }}} */
2005-07-05 05:27:26 +08:00
/* {{{ Function table */
2007-09-28 02:00:48 +08:00
const zend_function_entry date_functions [ ] = {
2006-06-11 09:42:17 +08:00
PHP_FE ( strtotime , arginfo_strtotime )
PHP_FE ( date , arginfo_date )
PHP_FE ( idate , arginfo_idate )
PHP_FE ( gmdate , arginfo_gmdate )
PHP_FE ( mktime , arginfo_mktime )
PHP_FE ( gmmktime , arginfo_gmmktime )
PHP_FE ( checkdate , arginfo_checkdate )
2005-07-04 04:45:08 +08:00
2005-07-04 07:30:52 +08:00
# ifdef HAVE_STRFTIME
2006-06-12 04:12:17 +08:00
PHP_FE ( strftime , arginfo_strftime )
2006-06-11 09:42:17 +08:00
PHP_FE ( gmstrftime , arginfo_gmstrftime )
2005-07-04 04:45:08 +08:00
# endif
2006-06-11 09:42:17 +08:00
PHP_FE ( time , arginfo_time )
PHP_FE ( localtime , arginfo_localtime )
PHP_FE ( getdate , arginfo_getdate )
2005-07-04 04:45:08 +08:00
2005-07-20 16:31:02 +08:00
/* Advanced Interface */
2008-07-09 20:50:57 +08:00
PHP_FE ( date_create , arginfo_date_create )
2012-12-20 00:24:38 +08:00
PHP_FE ( date_create_immutable , arginfo_date_create )
2008-07-09 20:50:57 +08:00
PHP_FE ( date_create_from_format , arginfo_date_create_from_format )
2012-12-20 00:24:38 +08:00
PHP_FE ( date_create_immutable_from_format , arginfo_date_create_from_format )
2008-07-09 20:50:57 +08:00
PHP_FE ( date_parse , arginfo_date_parse )
PHP_FE ( date_parse_from_format , arginfo_date_parse_from_format )
PHP_FE ( date_get_last_errors , arginfo_date_get_last_errors )
PHP_FE ( date_format , arginfo_date_format )
PHP_FE ( date_modify , arginfo_date_modify )
PHP_FE ( date_add , arginfo_date_add )
PHP_FE ( date_sub , arginfo_date_sub )
PHP_FE ( date_timezone_get , arginfo_date_timezone_get )
PHP_FE ( date_timezone_set , arginfo_date_timezone_set )
PHP_FE ( date_offset_get , arginfo_date_offset_get )
PHP_FE ( date_diff , arginfo_date_diff )
PHP_FE ( date_time_set , arginfo_date_time_set )
PHP_FE ( date_date_set , arginfo_date_date_set )
PHP_FE ( date_isodate_set , arginfo_date_isodate_set )
PHP_FE ( date_timestamp_set , arginfo_date_timestamp_set )
PHP_FE ( date_timestamp_get , arginfo_date_timestamp_get )
PHP_FE ( timezone_open , arginfo_timezone_open )
PHP_FE ( timezone_name_get , arginfo_timezone_name_get )
PHP_FE ( timezone_name_from_abbr , arginfo_timezone_name_from_abbr )
PHP_FE ( timezone_offset_get , arginfo_timezone_offset_get )
PHP_FE ( timezone_transitions_get , arginfo_timezone_transitions_get )
2008-07-18 22:33:53 +08:00
PHP_FE ( timezone_location_get , arginfo_timezone_location_get )
2008-07-09 20:50:57 +08:00
PHP_FE ( timezone_identifiers_list , arginfo_timezone_identifiers_list )
PHP_FE ( timezone_abbreviations_list , arginfo_timezone_abbreviations_list )
2009-05-04 03:58:49 +08:00
PHP_FE ( timezone_version_get , arginfo_timezone_version_get )
2008-07-09 20:50:57 +08:00
PHP_FE ( date_interval_create_from_date_string , arginfo_date_interval_create_from_date_string )
PHP_FE ( date_interval_format , arginfo_date_interval_format )
2008-04-25 20:35:58 +08:00
2005-07-20 16:31:02 +08:00
/* Options and Configuration */
2006-06-11 09:42:17 +08:00
PHP_FE ( date_default_timezone_set , arginfo_date_default_timezone_set )
PHP_FE ( date_default_timezone_get , arginfo_date_default_timezone_get )
2006-01-05 05:31:35 +08:00
/* Astronomical functions */
2006-06-11 09:42:17 +08:00
PHP_FE ( date_sunrise , arginfo_date_sunrise )
PHP_FE ( date_sunset , arginfo_date_sunset )
PHP_FE ( date_sun_info , arginfo_date_sun_info )
2011-07-25 19:35:02 +08:00
PHP_FE_END
2005-06-15 05:32:29 +08:00
} ;
2005-07-20 16:31:02 +08:00
2013-03-31 17:37:16 +08:00
static const zend_function_entry date_funcs_interface [ ] = {
PHP_ABSTRACT_ME ( DateTimeInterface , format , arginfo_date_method_format )
PHP_ABSTRACT_ME ( DateTimeInterface , getTimezone , arginfo_date_method_timezone_get )
PHP_ABSTRACT_ME ( DateTimeInterface , getOffset , arginfo_date_method_offset_get )
PHP_ABSTRACT_ME ( DateTimeInterface , getTimestamp , arginfo_date_method_timestamp_get )
PHP_ABSTRACT_ME ( DateTimeInterface , diff , arginfo_date_method_diff )
PHP_ABSTRACT_ME ( DateTimeInterface , __wakeup , NULL )
PHP_FE_END
} ;
2007-09-28 02:00:48 +08:00
const zend_function_entry date_funcs_date [ ] = {
2008-07-09 20:50:57 +08:00
PHP_ME ( DateTime , __construct , arginfo_date_create , ZEND_ACC_CTOR | ZEND_ACC_PUBLIC )
2008-03-15 00:19:52 +08:00
PHP_ME ( DateTime , __wakeup , NULL , ZEND_ACC_PUBLIC )
PHP_ME ( DateTime , __set_state , NULL , ZEND_ACC_PUBLIC | ZEND_ACC_STATIC )
2008-07-09 20:50:57 +08:00
PHP_ME_MAPPING ( createFromFormat , date_create_from_format , arginfo_date_create_from_format , ZEND_ACC_PUBLIC | ZEND_ACC_STATIC )
PHP_ME_MAPPING ( getLastErrors , date_get_last_errors , arginfo_date_get_last_errors , ZEND_ACC_PUBLIC | ZEND_ACC_STATIC )
PHP_ME_MAPPING ( format , date_format , arginfo_date_method_format , 0 )
PHP_ME_MAPPING ( modify , date_modify , arginfo_date_method_modify , 0 )
PHP_ME_MAPPING ( add , date_add , arginfo_date_method_add , 0 )
PHP_ME_MAPPING ( sub , date_sub , arginfo_date_method_sub , 0 )
PHP_ME_MAPPING ( getTimezone , date_timezone_get , arginfo_date_method_timezone_get , 0 )
PHP_ME_MAPPING ( setTimezone , date_timezone_set , arginfo_date_method_timezone_set , 0 )
PHP_ME_MAPPING ( getOffset , date_offset_get , arginfo_date_method_offset_get , 0 )
PHP_ME_MAPPING ( setTime , date_time_set , arginfo_date_method_time_set , 0 )
PHP_ME_MAPPING ( setDate , date_date_set , arginfo_date_method_date_set , 0 )
2009-04-27 22:22:15 +08:00
PHP_ME_MAPPING ( setISODate , date_isodate_set , arginfo_date_method_isodate_set , 0 )
2008-07-09 20:50:57 +08:00
PHP_ME_MAPPING ( setTimestamp , date_timestamp_set , arginfo_date_method_timestamp_set , 0 )
PHP_ME_MAPPING ( getTimestamp , date_timestamp_get , arginfo_date_method_timestamp_get , 0 )
PHP_ME_MAPPING ( diff , date_diff , arginfo_date_method_diff , 0 )
2011-07-25 19:35:02 +08:00
PHP_FE_END
2005-07-20 16:31:02 +08:00
} ;
2012-12-20 00:24:38 +08:00
const zend_function_entry date_funcs_immutable [ ] = {
PHP_ME ( DateTimeImmutable , __construct , arginfo_date_create , ZEND_ACC_CTOR | ZEND_ACC_PUBLIC )
2013-03-31 17:37:16 +08:00
PHP_ME ( DateTime , __wakeup , NULL , ZEND_ACC_PUBLIC )
2012-12-20 00:24:38 +08:00
PHP_ME ( DateTimeImmutable , __set_state , NULL , ZEND_ACC_PUBLIC | ZEND_ACC_STATIC )
2013-09-12 07:50:52 +08:00
PHP_ME_MAPPING ( createFromFormat , date_create_immutable_from_format , arginfo_date_create_from_format , ZEND_ACC_PUBLIC | ZEND_ACC_STATIC )
2013-03-31 17:37:16 +08:00
PHP_ME_MAPPING ( getLastErrors , date_get_last_errors , arginfo_date_get_last_errors , ZEND_ACC_PUBLIC | ZEND_ACC_STATIC )
PHP_ME_MAPPING ( format , date_format , arginfo_date_method_format , 0 )
PHP_ME_MAPPING ( getTimezone , date_timezone_get , arginfo_date_method_timezone_get , 0 )
PHP_ME_MAPPING ( getOffset , date_offset_get , arginfo_date_method_offset_get , 0 )
PHP_ME_MAPPING ( getTimestamp , date_timestamp_get , arginfo_date_method_timestamp_get , 0 )
PHP_ME_MAPPING ( diff , date_diff , arginfo_date_method_diff , 0 )
2012-12-20 00:24:38 +08:00
PHP_ME ( DateTimeImmutable , modify , arginfo_date_method_modify , 0 )
PHP_ME ( DateTimeImmutable , add , arginfo_date_method_add , 0 )
PHP_ME ( DateTimeImmutable , sub , arginfo_date_method_sub , 0 )
PHP_ME ( DateTimeImmutable , setTimezone , arginfo_date_method_timezone_set , 0 )
PHP_ME ( DateTimeImmutable , setTime , arginfo_date_method_time_set , 0 )
PHP_ME ( DateTimeImmutable , setDate , arginfo_date_method_date_set , 0 )
PHP_ME ( DateTimeImmutable , setISODate , arginfo_date_method_isodate_set , 0 )
PHP_ME ( DateTimeImmutable , setTimestamp , arginfo_date_method_timestamp_set , 0 )
2014-03-03 03:17:16 +08:00
PHP_ME ( DateTimeImmutable , createFromMutable , arginfo_date_method_create_from_mutable , ZEND_ACC_PUBLIC | ZEND_ACC_STATIC )
2012-12-17 23:31:23 +08:00
PHP_FE_END
} ;
2007-09-28 02:00:48 +08:00
const zend_function_entry date_funcs_timezone [ ] = {
2008-07-09 20:50:57 +08:00
PHP_ME ( DateTimeZone , __construct , arginfo_timezone_open , ZEND_ACC_CTOR | ZEND_ACC_PUBLIC )
2012-09-28 20:15:20 +08:00
PHP_ME ( DateTimeZone , __wakeup , NULL , ZEND_ACC_PUBLIC )
PHP_ME ( DateTimeZone , __set_state , NULL , ZEND_ACC_PUBLIC | ZEND_ACC_STATIC )
2008-07-09 20:50:57 +08:00
PHP_ME_MAPPING ( getName , timezone_name_get , arginfo_timezone_method_name_get , 0 )
PHP_ME_MAPPING ( getOffset , timezone_offset_get , arginfo_timezone_method_offset_get , 0 )
PHP_ME_MAPPING ( getTransitions , timezone_transitions_get , arginfo_timezone_method_transitions_get , 0 )
2008-07-18 22:33:53 +08:00
PHP_ME_MAPPING ( getLocation , timezone_location_get , arginfo_timezone_method_location_get , 0 )
2008-07-09 20:50:57 +08:00
PHP_ME_MAPPING ( listAbbreviations , timezone_abbreviations_list , arginfo_timezone_abbreviations_list , ZEND_ACC_PUBLIC | ZEND_ACC_STATIC )
PHP_ME_MAPPING ( listIdentifiers , timezone_identifiers_list , arginfo_timezone_identifiers_list , ZEND_ACC_PUBLIC | ZEND_ACC_STATIC )
2011-07-25 19:35:02 +08:00
PHP_FE_END
2005-07-20 16:31:02 +08:00
} ;
2008-04-25 20:35:58 +08:00
const zend_function_entry date_funcs_interval [ ] = {
2008-07-09 20:50:57 +08:00
PHP_ME ( DateInterval , __construct , arginfo_date_interval_construct , ZEND_ACC_CTOR | ZEND_ACC_PUBLIC )
2011-12-06 14:21:08 +08:00
PHP_ME ( DateInterval , __wakeup , NULL , ZEND_ACC_PUBLIC )
PHP_ME ( DateInterval , __set_state , NULL , ZEND_ACC_PUBLIC | ZEND_ACC_STATIC )
2008-07-09 20:50:57 +08:00
PHP_ME_MAPPING ( format , date_interval_format , arginfo_date_method_interval_format , 0 )
PHP_ME_MAPPING ( createFromDateString , date_interval_create_from_date_string , arginfo_date_interval_create_from_date_string , ZEND_ACC_PUBLIC | ZEND_ACC_STATIC )
2011-07-25 19:35:02 +08:00
PHP_FE_END
2008-04-25 20:35:58 +08:00
} ;
2008-05-01 08:12:24 +08:00
const zend_function_entry date_funcs_period [ ] = {
2008-07-09 20:50:57 +08:00
PHP_ME ( DatePeriod , __construct , arginfo_date_period_construct , ZEND_ACC_CTOR | ZEND_ACC_PUBLIC )
2013-03-15 23:59:54 +08:00
PHP_ME ( DatePeriod , __wakeup , NULL , ZEND_ACC_PUBLIC )
PHP_ME ( DatePeriod , __set_state , NULL , ZEND_ACC_PUBLIC | ZEND_ACC_STATIC )
2014-10-20 16:27:56 +08:00
PHP_ME ( DatePeriod , getStartDate , NULL , ZEND_ACC_PUBLIC )
PHP_ME ( DatePeriod , getEndDate , NULL , ZEND_ACC_PUBLIC )
PHP_ME ( DatePeriod , getDateInterval , NULL , ZEND_ACC_PUBLIC )
2011-07-25 19:35:02 +08:00
PHP_FE_END
2008-05-01 08:12:24 +08:00
} ;
2014-12-14 06:06:14 +08:00
static char * guess_timezone ( const timelib_tzdb * tzdb ) ;
static void date_register_classes ( void ) ;
2005-07-05 05:27:26 +08:00
/* }}} */
2005-06-15 05:32:29 +08:00
2005-06-19 04:23:19 +08:00
ZEND_DECLARE_MODULE_GLOBALS ( date )
2006-06-16 02:33:09 +08:00
static PHP_GINIT_FUNCTION ( date ) ;
2005-06-19 04:23:19 +08:00
2005-10-03 19:17:28 +08:00
/* True global */
2006-06-28 05:00:03 +08:00
timelib_tzdb * php_date_global_timezone_db ;
int php_date_global_timezone_db_enabled ;
2005-10-03 19:17:28 +08:00
2006-01-05 05:31:35 +08:00
# define DATE_DEFAULT_LATITUDE "31.7667"
# define DATE_DEFAULT_LONGITUDE "35.2333"
/* on 90'35; common sunset declaration (start of sun body appear) */
# define DATE_SUNSET_ZENITH "90.583333"
/* on 90'35; common sunrise declaration (sun body disappeared) */
# define DATE_SUNRISE_ZENITH "90.583333"
2013-01-06 09:10:16 +08:00
static PHP_INI_MH ( OnUpdate_date_timezone ) ;
2005-07-05 05:27:26 +08:00
/* {{{ INI Settings */
2005-06-15 05:32:29 +08:00
PHP_INI_BEGIN ( )
2013-01-06 09:10:16 +08:00
STD_PHP_INI_ENTRY ( " date.timezone " , " " , PHP_INI_ALL , OnUpdate_date_timezone , default_timezone , zend_date_globals , date_globals )
2006-01-05 05:31:35 +08:00
PHP_INI_ENTRY ( " date.default_latitude " , DATE_DEFAULT_LATITUDE , PHP_INI_ALL , NULL )
PHP_INI_ENTRY ( " date.default_longitude " , DATE_DEFAULT_LONGITUDE , PHP_INI_ALL , NULL )
PHP_INI_ENTRY ( " date.sunset_zenith " , DATE_SUNSET_ZENITH , PHP_INI_ALL , NULL )
PHP_INI_ENTRY ( " date.sunrise_zenith " , DATE_SUNRISE_ZENITH , PHP_INI_ALL , NULL )
2005-06-15 05:32:29 +08:00
PHP_INI_END ( )
2005-07-05 05:27:26 +08:00
/* }}} */
2005-06-15 05:32:29 +08:00
2008-05-01 08:12:24 +08:00
zend_class_entry * date_ce_date , * date_ce_timezone , * date_ce_interval , * date_ce_period ;
2013-03-31 17:37:16 +08:00
zend_class_entry * date_ce_immutable , * date_ce_interface ;
2005-11-18 05:05:30 +08:00
2008-11-06 17:45:58 +08:00
PHPAPI zend_class_entry * php_date_get_date_ce ( void )
{
return date_ce_date ;
}
2012-12-20 00:24:38 +08:00
PHPAPI zend_class_entry * php_date_get_immutable_ce ( void )
2012-12-17 23:31:23 +08:00
{
2012-12-20 00:24:38 +08:00
return date_ce_immutable ;
2012-12-17 23:31:23 +08:00
}
2008-11-06 17:45:58 +08:00
PHPAPI zend_class_entry * php_date_get_timezone_ce ( void )
{
return date_ce_timezone ;
}
2005-11-18 05:05:30 +08:00
static zend_object_handlers date_object_handlers_date ;
2012-12-20 00:24:38 +08:00
static zend_object_handlers date_object_handlers_immutable ;
2005-11-18 05:05:30 +08:00
static zend_object_handlers date_object_handlers_timezone ;
2008-04-25 20:35:58 +08:00
static zend_object_handlers date_object_handlers_interval ;
2008-05-01 08:12:24 +08:00
static zend_object_handlers date_object_handlers_period ;
2005-11-18 05:05:30 +08:00
2005-07-20 16:31:02 +08:00
# define DATE_SET_CONTEXT \
zval * object ; \
object = getThis ( ) ; \
2015-01-03 17:22:58 +08:00
2005-07-20 16:31:02 +08:00
# define DATE_FETCH_OBJECT \
php_date_obj * obj ; \
DATE_SET_CONTEXT ; \
if ( object ) { \
2008-03-11 06:15:36 +08:00
if ( zend_parse_parameters_none ( ) = = FAILURE ) { \
return ; \
2005-07-20 16:31:02 +08:00
} \
} else { \
2014-12-14 06:06:14 +08:00
if ( zend_parse_method_parameters ( ZEND_NUM_ARGS ( ) , NULL , " O " , & object , date_ce_date ) = = FAILURE ) { \
2005-07-20 16:31:02 +08:00
RETURN_FALSE ; \
} \
} \
2014-03-16 17:14:31 +08:00
obj = Z_PHPDATE_P ( object ) ; \
2005-07-20 16:31:02 +08:00
2006-08-01 21:28:28 +08:00
# define DATE_CHECK_INITIALIZED(member, class_name) \
if ( ! ( member ) ) { \
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , E_WARNING , " The " # class_name " object has not been correctly initialized by its constructor " ) ; \
2006-08-01 21:28:28 +08:00
RETURN_FALSE ; \
}
2014-12-14 06:06:14 +08:00
static void date_object_free_storage_date ( zend_object * object ) ;
static void date_object_free_storage_timezone ( zend_object * object ) ;
static void date_object_free_storage_interval ( zend_object * object ) ;
static void date_object_free_storage_period ( zend_object * object ) ;
static zend_object * date_object_new_date ( zend_class_entry * class_type ) ;
static zend_object * date_object_new_timezone ( zend_class_entry * class_type ) ;
static zend_object * date_object_new_interval ( zend_class_entry * class_type ) ;
static zend_object * date_object_new_period ( zend_class_entry * class_type ) ;
static zend_object * date_object_clone_date ( zval * this_ptr ) ;
static zend_object * date_object_clone_timezone ( zval * this_ptr ) ;
static zend_object * date_object_clone_interval ( zval * this_ptr ) ;
static zend_object * date_object_clone_period ( zval * this_ptr ) ;
static int date_object_compare_date ( zval * d1 , zval * d2 ) ;
static HashTable * date_object_get_gc ( zval * object , zval * * table , int * n ) ;
static HashTable * date_object_get_properties ( zval * object ) ;
static HashTable * date_object_get_gc_interval ( zval * object , zval * * table , int * n ) ;
static HashTable * date_object_get_properties_interval ( zval * object ) ;
static HashTable * date_object_get_gc_period ( zval * object , zval * * table , int * n ) ;
static HashTable * date_object_get_properties_period ( zval * object ) ;
static HashTable * date_object_get_properties_timezone ( zval * object ) ;
static HashTable * date_object_get_gc_timezone ( zval * object , zval * * table , int * n ) ;
zval * date_interval_read_property ( zval * object , zval * member , int type , void * * cache_slot , zval * rv ) ;
void date_interval_write_property ( zval * object , zval * member , zval * value , void * * cache_slot ) ;
2017-10-09 21:35:38 +08:00
static zval * date_interval_get_property_ptr_ptr ( zval * object , zval * member , int type , void * * cache_slot ) ;
2014-12-14 06:06:14 +08:00
static zval * date_period_read_property ( zval * object , zval * member , int type , void * * cache_slot , zval * rv ) ;
static void date_period_write_property ( zval * object , zval * member , zval * value , void * * cache_slot ) ;
2005-07-20 16:31:02 +08:00
2005-07-05 05:27:26 +08:00
/* {{{ Module struct */
2005-06-15 05:32:29 +08:00
zend_module_entry date_module_entry = {
2006-08-23 00:47:23 +08:00
STANDARD_MODULE_HEADER_EX ,
NULL ,
2009-05-14 02:48:20 +08:00
NULL ,
2005-06-15 05:32:29 +08:00
" date " , /* extension name */
date_functions , /* function list */
PHP_MINIT ( date ) , /* process startup */
PHP_MSHUTDOWN ( date ) , /* process shutdown */
2005-07-03 05:19:25 +08:00
PHP_RINIT ( date ) , /* request startup */
PHP_RSHUTDOWN ( date ) , /* request shutdown */
2005-06-15 05:32:29 +08:00
PHP_MINFO ( date ) , /* extension info */
2015-03-24 03:13:59 +08:00
PHP_DATE_VERSION , /* extension version */
2006-06-16 02:33:09 +08:00
PHP_MODULE_GLOBALS ( date ) , /* globals descriptor */
PHP_GINIT ( date ) , /* globals ctor */
NULL , /* globals dtor */
NULL , /* post deactivate */
STANDARD_MODULE_PROPERTIES_EX
2005-06-15 05:32:29 +08:00
} ;
2005-07-05 05:27:26 +08:00
/* }}} */
2005-06-15 05:32:29 +08:00
2006-06-16 02:33:09 +08:00
/* {{{ PHP_GINIT_FUNCTION */
static PHP_GINIT_FUNCTION ( date )
2005-06-19 04:23:19 +08:00
{
date_globals - > default_timezone = NULL ;
2005-07-03 05:19:25 +08:00
date_globals - > timezone = NULL ;
2009-06-01 05:28:38 +08:00
date_globals - > tzcache = NULL ;
2013-01-06 09:10:16 +08:00
date_globals - > timezone_valid = 0 ;
2005-06-19 04:23:19 +08:00
}
/* }}} */
2005-06-15 05:32:29 +08:00
2005-10-05 16:20:44 +08:00
2014-03-16 17:14:31 +08:00
static void _php_date_tzinfo_dtor ( zval * zv ) /* { { { */
2005-10-05 16:20:44 +08:00
{
2014-02-10 14:04:30 +08:00
timelib_tzinfo * tzi = ( timelib_tzinfo * ) Z_PTR_P ( zv ) ;
2005-10-05 16:20:44 +08:00
2014-02-10 14:04:30 +08:00
timelib_tzinfo_dtor ( tzi ) ;
2014-03-16 17:14:31 +08:00
} /* }}} */
2005-10-05 16:20:44 +08:00
2005-07-05 05:27:26 +08:00
/* {{{ PHP_RINIT_FUNCTION */
2005-07-03 05:19:25 +08:00
PHP_RINIT_FUNCTION ( date )
{
if ( DATEG ( timezone ) ) {
efree ( DATEG ( timezone ) ) ;
}
DATEG ( timezone ) = NULL ;
2009-06-01 05:28:38 +08:00
DATEG ( tzcache ) = NULL ;
2009-10-27 18:41:45 +08:00
DATEG ( last_errors ) = NULL ;
2005-07-03 05:19:25 +08:00
return SUCCESS ;
}
2005-07-05 05:27:26 +08:00
/* }}} */
2005-07-03 05:19:25 +08:00
2005-07-05 05:27:26 +08:00
/* {{{ PHP_RSHUTDOWN_FUNCTION */
2005-07-03 05:19:25 +08:00
PHP_RSHUTDOWN_FUNCTION ( date )
{
if ( DATEG ( timezone ) ) {
efree ( DATEG ( timezone ) ) ;
}
DATEG ( timezone ) = NULL ;
2009-06-01 05:28:38 +08:00
if ( DATEG ( tzcache ) ) {
zend_hash_destroy ( DATEG ( tzcache ) ) ;
FREE_HASHTABLE ( DATEG ( tzcache ) ) ;
DATEG ( tzcache ) = NULL ;
}
2009-10-27 18:41:45 +08:00
if ( DATEG ( last_errors ) ) {
timelib_error_container_dtor ( DATEG ( last_errors ) ) ;
DATEG ( last_errors ) = NULL ;
}
2005-07-03 05:19:25 +08:00
return SUCCESS ;
}
2005-07-05 05:27:26 +08:00
/* }}} */
2005-06-15 05:32:29 +08:00
2005-10-03 19:17:28 +08:00
# define DATE_TIMEZONEDB php_date_global_timezone_db ? php_date_global_timezone_db : timelib_builtin_db()
2006-05-30 21:12:21 +08:00
/*
* RFC822 , Section 5.1 : http : //www.ietf.org/rfc/rfc822.txt
* date - time = [ day " , " ] date time ; dd mm yy hh : mm : ss zzz
* day = " Mon " / " Tue " / " Wed " / " Thu " / " Fri " / " Sat " / " Sun "
* date = 1 * 2 DIGIT month 2 DIGIT ; day month year e . g . 20 Jun 82
* month = " Jan " / " Feb " / " Mar " / " Apr " / " May " / " Jun " / " Jul " / " Aug " / " Sep " / " Oct " / " Nov " / " Dec "
* time = hour zone ; ANSI and Military
* hour = 2 DIGIT " : " 2 DIGIT [ " : " 2 DIGIT ] ; 00 : 00 : 00 - 23 : 59 : 59
* zone = " UT " / " GMT " / " EST " / " EDT " / " CST " / " CDT " / " MST " / " MDT " / " PST " / " PDT " / 1 ALPHA / ( ( " + " / " - " ) 4 DIGIT )
*/
# define DATE_FORMAT_RFC822 "D, d M y H:i:s O"
/*
* RFC850 , Section 2.1 .4 : http : //www.ietf.org/rfc/rfc850.txt
* Format must be acceptable both to the ARPANET and to the getdate routine .
* One format that is acceptable to both is Weekday , DD - Mon - YY HH : MM : SS TIMEZONE
* TIMEZONE can be any timezone name ( 3 or more letters )
*/
# define DATE_FORMAT_RFC850 "l, d-M-y H:i:s T"
/*
* RFC1036 , Section 2.1 .2 : http : //www.ietf.org/rfc/rfc1036.txt
* Its format must be acceptable both in RFC - 822 and to the getdate ( 3 )
* Wdy , DD Mon YY HH : MM : SS TIMEZONE
* There is no hope of having a complete list of timezones . Universal
* Time ( GMT ) , the North American timezones ( PST , PDT , MST , MDT , CST ,
* CDT , EST , EDT ) and the + / - hhmm offset specifed in RFC - 822 should be supported .
*/
# define DATE_FORMAT_RFC1036 "D, d M y H:i:s O"
/*
* RFC1123 , Section 5.2 .14 : http : //www.ietf.org/rfc/rfc1123.txt
* RFC - 822 Date and Time Specification : RFC - 822 Section 5
* The syntax for the date is hereby changed to : date = 1 * 2 DIGIT month 2 * 4 DIGIT
*/
# define DATE_FORMAT_RFC1123 "D, d M Y H:i:s O"
2017-04-02 00:56:31 +08:00
/*
* RFC7231 , Section 7.1 .1 : http : //tools.ietf.org/html/rfc7231
*/
# define DATE_FORMAT_RFC7231 "D, d M Y H:i:s \\G\\M\\T"
2006-05-30 21:12:21 +08:00
/*
* RFC2822 , Section 3.3 : http : //www.ietf.org/rfc/rfc2822.txt
* FWS = ( [ * WSP CRLF ] 1 * WSP ) / ; Folding white space
* CFWS = * ( [ FWS ] comment ) ( ( [ FWS ] comment ) / FWS )
2015-01-03 17:22:58 +08:00
*
2006-05-30 21:12:21 +08:00
* date - time = [ day - of - week " , " ] date FWS time [ CFWS ]
* day - of - week = ( [ FWS ] day - name )
* day - name = " Mon " / " Tue " / " Wed " / " Thu " / " Fri " / " Sat " / " Sun "
* date = day month year
* year = 4 * DIGIT
* month = ( FWS month - name FWS )
* month - name = " Jan " / " Feb " / " Mar " / " Apr " / " May " / " Jun " / " Jul " / " Aug " / " Sep " / " Oct " / " Nov " / " Dec "
* day = ( [ FWS ] 1 * 2 DIGIT )
* time = time - of - day FWS zone
* time - of - day = hour " : " minute [ " : " second ]
* hour = 2 DIGIT
* minute = 2 DIGIT
* second = 2 DIGIT
* zone = ( ( " + " / " - " ) 4 DIGIT )
*/
# define DATE_FORMAT_RFC2822 "D, d M Y H:i:s O"
/*
* RFC3339 , Section 5.6 : http : //www.ietf.org/rfc/rfc3339.txt
* date - fullyear = 4 DIGIT
* date - month = 2 DIGIT ; 01 - 12
* date - mday = 2 DIGIT ; 01 - 28 , 01 - 29 , 01 - 30 , 01 - 31 based on month / year
2015-01-03 17:22:58 +08:00
*
2006-05-30 21:12:21 +08:00
* time - hour = 2 DIGIT ; 00 - 23
* time - minute = 2 DIGIT ; 00 - 59
* time - second = 2 DIGIT ; 00 - 58 , 00 - 59 , 00 - 60 based on leap second rules
2015-01-03 17:22:58 +08:00
*
2006-05-30 21:12:21 +08:00
* time - secfrac = " . " 1 * DIGIT
* time - numoffset = ( " + " / " - " ) time - hour " : " time - minute
* time - offset = " Z " / time - numoffset
2015-01-03 17:22:58 +08:00
*
2006-05-30 21:12:21 +08:00
* partial - time = time - hour " : " time - minute " : " time - second [ time - secfrac ]
* full - date = date - fullyear " - " date - month " - " date - mday
* full - time = partial - time time - offset
2015-01-03 17:22:58 +08:00
*
2006-05-30 21:12:21 +08:00
* date - time = full - date " T " full - time
*/
2006-02-01 02:44:19 +08:00
# define DATE_FORMAT_RFC3339 "Y-m-d\\TH:i:sP"
2006-05-30 21:12:21 +08:00
2005-07-20 16:31:02 +08:00
# define DATE_FORMAT_ISO8601 "Y-m-d\\TH:i:sO"
2015-02-19 23:46:00 +08:00
/*
* RFC3339 , Appendix A : http : //www.ietf.org/rfc/rfc3339.txt
* ISO 8601 also requires ( in section 5.3 .1 .3 ) that a decimal fraction
* be proceeded by a " 0 " if less than unity . Annex B .2 of ISO 8601
* gives examples where the decimal fractions are not preceded by a " 0 " .
* This grammar assumes section 5.3 .1 .3 is correct and that Annex B .2 is
* in error .
*/
# define DATE_FORMAT_RFC3339_EXTENDED "Y-m-d\\TH:i:s.vP"
2013-11-28 05:59:46 +08:00
/*
* This comes from various sources that like to contradict . I ' m going with the
* format here because of :
* http : //msdn.microsoft.com/en-us/library/windows/desktop/aa384321%28v=vs.85%29.aspx
* and http : //curl.haxx.se/rfc/cookie_spec.html
*/
# define DATE_FORMAT_COOKIE "l, d-M-Y H:i:s T"
2006-01-05 05:31:35 +08:00
# define SUNFUNCS_RET_TIMESTAMP 0
# define SUNFUNCS_RET_STRING 1
# define SUNFUNCS_RET_DOUBLE 2
2005-07-05 05:27:26 +08:00
/* {{{ PHP_MINIT_FUNCTION */
2005-06-15 05:32:29 +08:00
PHP_MINIT_FUNCTION ( date )
{
REGISTER_INI_ENTRIES ( ) ;
2014-12-14 06:06:14 +08:00
date_register_classes ( ) ;
2006-05-30 22:46:46 +08:00
/*
* RFC4287 , Section 3.3 : http : //www.ietf.org/rfc/rfc4287.txt
2006-05-30 23:14:22 +08:00
* A Date construct is an element whose content MUST conform to the
* " date-time " production in [ RFC3339 ] . In addition , an uppercase " T "
* character MUST be used to separate date and time , and an uppercase
* " Z " character MUST be present in the absence of a numeric time zone offset .
2006-05-30 22:46:46 +08:00
*/
2006-02-01 02:44:19 +08:00
REGISTER_STRING_CONSTANT ( " DATE_ATOM " , DATE_FORMAT_RFC3339 , CONST_CS | CONST_PERSISTENT ) ;
2006-05-30 22:46:46 +08:00
/*
* Preliminary specification : http : //wp.netscape.com/newsref/std/cookie_spec.html
* " This is based on RFC 822, RFC 850, RFC 1036, and RFC 1123,
* with the variations that the only legal time zone is GMT
* and the separators between the elements of the date must be dashes . "
*/
2013-11-28 05:59:46 +08:00
REGISTER_STRING_CONSTANT ( " DATE_COOKIE " , DATE_FORMAT_COOKIE , CONST_CS | CONST_PERSISTENT ) ;
2005-11-27 14:51:43 +08:00
REGISTER_STRING_CONSTANT ( " DATE_ISO8601 " , DATE_FORMAT_ISO8601 , CONST_CS | CONST_PERSISTENT ) ;
2015-02-19 23:46:00 +08:00
2006-05-30 21:12:21 +08:00
REGISTER_STRING_CONSTANT ( " DATE_RFC822 " , DATE_FORMAT_RFC822 , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_STRING_CONSTANT ( " DATE_RFC850 " , DATE_FORMAT_RFC850 , CONST_CS | CONST_PERSISTENT ) ;
2005-11-27 14:51:43 +08:00
REGISTER_STRING_CONSTANT ( " DATE_RFC1036 " , DATE_FORMAT_RFC1036 , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_STRING_CONSTANT ( " DATE_RFC1123 " , DATE_FORMAT_RFC1123 , CONST_CS | CONST_PERSISTENT ) ;
2017-04-02 00:56:31 +08:00
REGISTER_STRING_CONSTANT ( " DATE_RFC7231 " , DATE_FORMAT_RFC7231 , CONST_CS | CONST_PERSISTENT ) ;
2005-11-27 14:51:43 +08:00
REGISTER_STRING_CONSTANT ( " DATE_RFC2822 " , DATE_FORMAT_RFC2822 , CONST_CS | CONST_PERSISTENT ) ;
2015-02-19 23:46:00 +08:00
REGISTER_STRING_CONSTANT ( " DATE_RFC3339 " , DATE_FORMAT_RFC3339 , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_STRING_CONSTANT ( " DATE_RFC3339_EXTENDED " , DATE_FORMAT_RFC3339_EXTENDED , CONST_CS | CONST_PERSISTENT ) ;
2006-05-30 22:46:46 +08:00
/*
* RSS 2.0 Specification : http : //blogs.law.harvard.edu/tech/rss
2006-05-30 23:14:22 +08:00
* " All date-times in RSS conform to the Date and Time Specification of RFC 822,
* with the exception that the year may be expressed with two characters or four characters ( four preferred ) "
2006-05-30 22:46:46 +08:00
*/
2006-05-30 23:14:22 +08:00
REGISTER_STRING_CONSTANT ( " DATE_RSS " , DATE_FORMAT_RFC1123 , CONST_CS | CONST_PERSISTENT ) ;
2006-03-03 15:52:55 +08:00
REGISTER_STRING_CONSTANT ( " DATE_W3C " , DATE_FORMAT_RFC3339 , CONST_CS | CONST_PERSISTENT ) ;
2005-07-20 16:31:02 +08:00
2014-08-26 01:24:55 +08:00
REGISTER_LONG_CONSTANT ( " SUNFUNCS_RET_TIMESTAMP " , SUNFUNCS_RET_TIMESTAMP , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SUNFUNCS_RET_STRING " , SUNFUNCS_RET_STRING , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " SUNFUNCS_RET_DOUBLE " , SUNFUNCS_RET_DOUBLE , CONST_CS | CONST_PERSISTENT ) ;
2006-01-05 05:31:35 +08:00
2005-10-03 19:17:28 +08:00
php_date_global_timezone_db = NULL ;
php_date_global_timezone_db_enabled = 0 ;
2008-01-13 23:16:02 +08:00
DATEG ( last_errors ) = NULL ;
2005-06-15 05:32:29 +08:00
return SUCCESS ;
}
2005-07-05 05:27:26 +08:00
/* }}} */
2005-06-15 05:32:29 +08:00
2005-07-05 05:27:26 +08:00
/* {{{ PHP_MSHUTDOWN_FUNCTION */
2005-06-15 05:32:29 +08:00
PHP_MSHUTDOWN_FUNCTION ( date )
{
UNREGISTER_INI_ENTRIES ( ) ;
2008-01-13 23:16:02 +08:00
if ( DATEG ( last_errors ) ) {
timelib_error_container_dtor ( DATEG ( last_errors ) ) ;
}
2015-06-04 21:08:36 +08:00
# ifndef ZTS
DATEG ( default_timezone ) = NULL ;
# endif
2005-06-15 05:32:29 +08:00
return SUCCESS ;
}
2005-07-05 05:27:26 +08:00
/* }}} */
2005-06-15 05:32:29 +08:00
2005-07-05 05:27:26 +08:00
/* {{{ PHP_MINFO_FUNCTION */
2005-06-15 05:32:29 +08:00
PHP_MINFO_FUNCTION ( date )
{
2006-05-15 01:36:05 +08:00
const timelib_tzdb * tzdb = DATE_TIMEZONEDB ;
2015-01-03 17:22:58 +08:00
2005-06-15 05:32:29 +08:00
php_info_print_table_start ( ) ;
php_info_print_table_row ( 2 , " date/time support " , " enabled " ) ;
2017-08-16 16:51:21 +08:00
php_info_print_table_row ( 2 , " timelib version " , TIMELIB_ASCII_VERSION ) ;
2007-02-15 03:35:09 +08:00
php_info_print_table_row ( 2 , " \" Olson \" Timezone Database Version " , tzdb - > version ) ;
2005-10-03 19:17:28 +08:00
php_info_print_table_row ( 2 , " Timezone Database " , php_date_global_timezone_db_enabled ? " external " : " internal " ) ;
2014-12-14 06:06:14 +08:00
php_info_print_table_row ( 2 , " Default timezone " , guess_timezone ( tzdb ) ) ;
2005-06-15 05:32:29 +08:00
php_info_print_table_end ( ) ;
2005-08-10 05:10:22 +08:00
DISPLAY_INI_ENTRIES ( ) ;
2005-06-15 05:32:29 +08:00
}
2005-07-05 05:27:26 +08:00
/* }}} */
2005-06-15 05:32:29 +08:00
2005-10-05 16:20:44 +08:00
/* {{{ Timezone Cache functions */
2014-12-14 06:06:14 +08:00
static timelib_tzinfo * php_date_parse_tzfile ( char * formal_tzname , const timelib_tzdb * tzdb )
2005-10-05 16:20:44 +08:00
{
2014-02-10 14:04:30 +08:00
timelib_tzinfo * tzi ;
2005-10-05 16:20:44 +08:00
2009-06-01 05:28:38 +08:00
if ( ! DATEG ( tzcache ) ) {
ALLOC_HASHTABLE ( DATEG ( tzcache ) ) ;
zend_hash_init ( DATEG ( tzcache ) , 4 , NULL , _php_date_tzinfo_dtor , 0 ) ;
}
2014-02-10 14:04:30 +08:00
if ( ( tzi = zend_hash_str_find_ptr ( DATEG ( tzcache ) , formal_tzname , strlen ( formal_tzname ) ) ) ! = NULL ) {
return tzi ;
2005-10-05 16:20:44 +08:00
}
2017-08-16 22:19:18 +08:00
tzi = timelib_parse_tzfile ( formal_tzname , tzdb ) ;
2005-10-13 03:49:59 +08:00
if ( tzi ) {
2014-02-10 14:04:30 +08:00
zend_hash_str_add_ptr ( DATEG ( tzcache ) , formal_tzname , strlen ( formal_tzname ) , tzi ) ;
2005-10-13 03:49:59 +08:00
}
2005-10-05 16:20:44 +08:00
return tzi ;
}
2011-12-06 14:21:08 +08:00
2017-08-16 22:19:18 +08:00
timelib_tzinfo * php_date_parse_tzfile_wrapper ( char * formal_tzname , const timelib_tzdb * tzdb )
2011-12-06 14:21:08 +08:00
{
2014-12-14 06:06:14 +08:00
return php_date_parse_tzfile ( formal_tzname , tzdb ) ;
2011-12-06 14:21:08 +08:00
}
2005-10-05 16:20:44 +08:00
/* }}} */
2005-07-01 05:38:06 +08:00
2013-01-06 21:08:23 +08:00
/* Callback to check the date.timezone only when changed increases performance */
2013-01-06 09:10:16 +08:00
/* {{{ static PHP_INI_MH(OnUpdate_date_timezone) */
static PHP_INI_MH ( OnUpdate_date_timezone )
{
2014-12-14 06:06:14 +08:00
if ( OnUpdateString ( entry , new_value , mh_arg1 , mh_arg2 , mh_arg3 , stage ) = = FAILURE ) {
2013-01-06 09:10:16 +08:00
return FAILURE ;
}
DATEG ( timezone_valid ) = 0 ;
if ( stage = = PHP_INI_STAGE_RUNTIME ) {
if ( ! timelib_timezone_id_is_valid ( DATEG ( default_timezone ) , DATE_TIMEZONEDB ) ) {
2015-01-27 08:55:19 +08:00
if ( DATEG ( default_timezone ) & & * DATEG ( default_timezone ) ) {
php_error_docref ( NULL , E_WARNING , " Invalid date.timezone value '%s', we selected the timezone 'UTC' for now. " , DATEG ( default_timezone ) ) ;
}
2013-01-06 09:10:16 +08:00
} else {
DATEG ( timezone_valid ) = 1 ;
}
}
return SUCCESS ;
}
/* }}} */
2005-07-05 05:27:26 +08:00
/* {{{ Helper functions */
2014-12-14 06:06:14 +08:00
static char * guess_timezone ( const timelib_tzdb * tzdb )
2005-07-01 05:38:06 +08:00
{
2005-07-03 05:19:25 +08:00
/* Checking configure timezone */
2013-01-06 21:08:23 +08:00
if ( DATEG ( timezone ) & & ( strlen ( DATEG ( timezone ) ) ) > 0 ) {
2005-07-03 05:19:25 +08:00
return DATEG ( timezone ) ;
}
/* Check config setting for default timezone */
2009-10-05 21:56:49 +08:00
if ( ! DATEG ( default_timezone ) ) {
/* Special case: ext/date wasn't initialized yet */
2014-09-02 00:57:33 +08:00
zval * ztz ;
2013-01-06 09:10:16 +08:00
2014-09-02 00:57:33 +08:00
if ( NULL ! = ( ztz = cfg_get_entry ( " date.timezone " , sizeof ( " date.timezone " ) ) )
& & Z_TYPE_P ( ztz ) = = IS_STRING & & Z_STRLEN_P ( ztz ) > 0 & & timelib_timezone_id_is_valid ( Z_STRVAL_P ( ztz ) , tzdb ) ) {
return Z_STRVAL_P ( ztz ) ;
2009-10-05 21:56:49 +08:00
}
2012-09-11 17:14:51 +08:00
} else if ( * DATEG ( default_timezone ) ) {
2013-01-06 21:08:23 +08:00
if ( DATEG ( timezone_valid ) = = 1 ) {
2012-09-11 18:02:19 +08:00
return DATEG ( default_timezone ) ;
}
2013-01-06 09:10:16 +08:00
if ( ! timelib_timezone_id_is_valid ( DATEG ( default_timezone ) , tzdb ) ) {
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , E_WARNING , " Invalid date.timezone value '%s', we selected the timezone 'UTC' for now. " , DATEG ( default_timezone ) ) ;
2013-01-06 09:10:16 +08:00
return " UTC " ;
}
DATEG ( timezone_valid ) = 1 ;
return DATEG ( default_timezone ) ;
2005-07-01 05:38:06 +08:00
}
2005-07-03 05:19:25 +08:00
/* Fallback to UTC */
return " UTC " ;
}
2014-12-14 06:06:14 +08:00
PHPAPI timelib_tzinfo * get_timezone_info ( void )
2005-07-03 05:19:25 +08:00
{
char * tz ;
timelib_tzinfo * tzi ;
2009-06-01 05:28:38 +08:00
2014-12-14 06:06:14 +08:00
tz = guess_timezone ( DATE_TIMEZONEDB ) ;
tzi = php_date_parse_tzfile ( tz , DATE_TIMEZONEDB ) ;
2005-07-03 05:19:25 +08:00
if ( ! tzi ) {
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , E_ERROR , " Timezone database is corrupt - this should *never* happen! " ) ;
2005-07-03 05:19:25 +08:00
}
return tzi ;
2005-07-01 05:38:06 +08:00
}
2005-07-05 05:27:26 +08:00
/* }}} */
2013-01-06 09:10:16 +08:00
2005-07-05 05:27:26 +08:00
/* {{{ date() and gmdate() data */
2014-09-21 04:42:02 +08:00
# include "zend_smart_str.h"
2005-07-01 05:38:06 +08:00
2006-06-28 05:00:03 +08:00
static char * mon_full_names [ ] = {
2005-07-01 05:38:06 +08:00
" January " , " February " , " March " , " April " ,
" May " , " June " , " July " , " August " ,
" September " , " October " , " November " , " December "
} ;
2006-06-28 05:00:03 +08:00
static char * mon_short_names [ ] = {
2005-07-01 05:38:06 +08:00
" Jan " , " Feb " , " Mar " , " Apr " , " May " , " Jun " , " Jul " , " Aug " , " Sep " , " Oct " , " Nov " , " Dec "
} ;
2006-06-28 05:00:03 +08:00
static char * day_full_names [ ] = {
2005-07-01 05:38:06 +08:00
" Sunday " , " Monday " , " Tuesday " , " Wednesday " , " Thursday " , " Friday " , " Saturday "
} ;
2006-06-28 05:00:03 +08:00
static char * day_short_names [ ] = {
2005-07-01 05:38:06 +08:00
" Sun " , " Mon " , " Tue " , " Wed " , " Thu " , " Fri " , " Sat "
} ;
2006-06-28 05:00:03 +08:00
static char * english_suffix ( timelib_sll number )
2005-07-01 05:38:06 +08:00
{
if ( number > = 10 & & number < = 19 ) {
return " th " ;
} else {
switch ( number % 10 ) {
case 1 : return " st " ;
case 2 : return " nd " ;
case 3 : return " rd " ;
}
}
return " th " ;
}
2005-07-05 05:27:26 +08:00
/* }}} */
2005-07-01 05:38:06 +08:00
2006-06-23 05:04:32 +08:00
/* {{{ day of week helpers */
2006-06-28 05:00:03 +08:00
char * php_date_full_day_name ( timelib_sll y , timelib_sll m , timelib_sll d )
2006-06-23 05:04:32 +08:00
{
timelib_sll day_of_week = timelib_day_of_week ( y , m , d ) ;
if ( day_of_week < 0 ) {
return " Unknown " ;
2015-01-03 17:22:58 +08:00
}
return day_full_names [ day_of_week ] ;
2006-06-23 05:04:32 +08:00
}
2006-06-28 05:00:03 +08:00
char * php_date_short_day_name ( timelib_sll y , timelib_sll m , timelib_sll d )
2006-06-23 05:04:32 +08:00
{
timelib_sll day_of_week = timelib_day_of_week ( y , m , d ) ;
if ( day_of_week < 0 ) {
return " Unknown " ;
2015-01-03 17:22:58 +08:00
}
return day_short_names [ day_of_week ] ;
2006-06-23 05:04:32 +08:00
}
/* }}} */
2005-07-08 20:26:30 +08:00
/* {{{ date_format - (gm)date helper */
2014-12-14 06:06:14 +08:00
static zend_string * date_format ( char * format , size_t format_len , timelib_time * t , int localtime )
2005-07-01 05:38:06 +08:00
{
smart_str string = { 0 } ;
2013-08-15 11:36:50 +08:00
int i , length = 0 ;
2010-02-11 00:23:30 +08:00
char buffer [ 97 ] ;
2006-07-10 19:26:22 +08:00
timelib_time_offset * offset = NULL ;
2005-07-01 05:38:06 +08:00
timelib_sll isoweek , isoyear ;
2008-05-03 05:33:05 +08:00
int rfc_colon ;
2012-12-05 13:02:09 +08:00
int weekYearSet = 0 ;
2005-07-01 05:38:06 +08:00
2005-08-09 00:49:30 +08:00
if ( ! format_len ) {
2015-06-29 21:44:54 +08:00
return ZSTR_EMPTY_ALLOC ( ) ;
2005-08-09 00:49:30 +08:00
}
2005-07-01 05:38:06 +08:00
if ( localtime ) {
2005-07-20 16:31:02 +08:00
if ( t - > zone_type = = TIMELIB_ZONETYPE_ABBR ) {
offset = timelib_time_offset_ctor ( ) ;
2017-08-16 22:19:18 +08:00
offset - > offset = ( t - > z - ( t - > dst * 60 ) ) * - 60 ;
2005-07-20 16:31:02 +08:00
offset - > leap_secs = 0 ;
offset - > is_dst = t - > dst ;
2015-09-22 16:17:50 +08:00
offset - > abbr = timelib_strdup ( t - > tz_abbr ) ;
2005-07-20 16:31:02 +08:00
} else if ( t - > zone_type = = TIMELIB_ZONETYPE_OFFSET ) {
offset = timelib_time_offset_ctor ( ) ;
2017-08-16 22:19:18 +08:00
offset - > offset = ( t - > z ) * - 60 ;
2005-07-20 16:31:02 +08:00
offset - > leap_secs = 0 ;
2008-03-31 17:11:30 +08:00
offset - > is_dst = 0 ;
2015-09-22 16:17:50 +08:00
offset - > abbr = timelib_malloc ( 9 ) ; /* GMT±xxxx\0 */
2015-01-03 17:22:58 +08:00
snprintf ( offset - > abbr , 9 , " GMT%c%02d%02d " ,
2005-07-20 16:31:02 +08:00
localtime ? ( ( offset - > offset < 0 ) ? ' - ' : ' + ' ) : ' + ' ,
localtime ? abs ( offset - > offset / 3600 ) : 0 ,
localtime ? abs ( ( offset - > offset % 3600 ) / 60 ) : 0 ) ;
} else {
offset = timelib_get_time_zone_info ( t - > sse , t - > tz_info ) ;
}
2005-07-01 05:38:06 +08:00
}
for ( i = 0 ; i < format_len ; i + + ) {
2008-05-03 05:33:05 +08:00
rfc_colon = 0 ;
2005-07-01 05:38:06 +08:00
switch ( format [ i ] ) {
/* day */
2007-02-27 11:04:40 +08:00
case ' d ' : length = slprintf ( buffer , 32 , " %02d " , ( int ) t - > d ) ; break ;
case ' D ' : length = slprintf ( buffer , 32 , " %s " , php_date_short_day_name ( t - > y , t - > m , t - > d ) ) ; break ;
case ' j ' : length = slprintf ( buffer , 32 , " %d " , ( int ) t - > d ) ; break ;
case ' l ' : length = slprintf ( buffer , 32 , " %s " , php_date_full_day_name ( t - > y , t - > m , t - > d ) ) ; break ;
case ' S ' : length = slprintf ( buffer , 32 , " %s " , english_suffix ( t - > d ) ) ; break ;
case ' w ' : length = slprintf ( buffer , 32 , " %d " , ( int ) timelib_day_of_week ( t - > y , t - > m , t - > d ) ) ; break ;
case ' N ' : length = slprintf ( buffer , 32 , " %d " , ( int ) timelib_iso_day_of_week ( t - > y , t - > m , t - > d ) ) ; break ;
case ' z ' : length = slprintf ( buffer , 32 , " %d " , ( int ) timelib_day_of_year ( t - > y , t - > m , t - > d ) ) ; break ;
2005-07-01 05:38:06 +08:00
/* week */
2012-12-05 13:02:09 +08:00
case ' W ' :
if ( ! weekYearSet ) { timelib_isoweek_from_date ( t - > y , t - > m , t - > d , & isoweek , & isoyear ) ; weekYearSet = 1 ; }
length = slprintf ( buffer , 32 , " %02d " , ( int ) isoweek ) ; break ; /* iso weeknr */
case ' o ' :
if ( ! weekYearSet ) { timelib_isoweek_from_date ( t - > y , t - > m , t - > d , & isoweek , & isoyear ) ; weekYearSet = 1 ; }
length = slprintf ( buffer , 32 , " %d " , ( int ) isoyear ) ; break ; /* iso year */
2005-07-01 05:38:06 +08:00
/* month */
2007-02-27 11:04:40 +08:00
case ' F ' : length = slprintf ( buffer , 32 , " %s " , mon_full_names [ t - > m - 1 ] ) ; break ;
case ' m ' : length = slprintf ( buffer , 32 , " %02d " , ( int ) t - > m ) ; break ;
case ' M ' : length = slprintf ( buffer , 32 , " %s " , mon_short_names [ t - > m - 1 ] ) ; break ;
case ' n ' : length = slprintf ( buffer , 32 , " %d " , ( int ) t - > m ) ; break ;
case ' t ' : length = slprintf ( buffer , 32 , " %d " , ( int ) timelib_days_in_month ( t - > y , t - > m ) ) ; break ;
2005-07-01 05:38:06 +08:00
/* year */
2007-02-27 11:04:40 +08:00
case ' L ' : length = slprintf ( buffer , 32 , " %d " , timelib_is_leap ( ( int ) t - > y ) ) ; break ;
case ' y ' : length = slprintf ( buffer , 32 , " %02d " , ( int ) t - > y % 100 ) ; break ;
2010-02-11 00:23:30 +08:00
case ' Y ' : length = slprintf ( buffer , 32 , " %s%04lld " , t - > y < 0 ? " - " : " " , php_date_llabs ( ( timelib_sll ) t - > y ) ) ; break ;
2005-07-01 05:38:06 +08:00
/* time */
2007-02-27 11:04:40 +08:00
case ' a ' : length = slprintf ( buffer , 32 , " %s " , t - > h > = 12 ? " pm " : " am " ) ; break ;
case ' A ' : length = slprintf ( buffer , 32 , " %s " , t - > h > = 12 ? " PM " : " AM " ) ; break ;
2005-11-30 04:43:53 +08:00
case ' B ' : {
2016-06-04 03:28:20 +08:00
int retval = ( ( ( ( long ) t - > sse ) - ( ( ( long ) t - > sse ) - ( ( ( ( long ) t - > sse ) % 86400 ) + 3600 ) ) ) * 10 ) ;
if ( retval < 0 ) {
retval + = 864000 ;
2005-11-30 04:43:53 +08:00
}
2016-06-04 03:28:20 +08:00
/* Make sure to do this on a positive int to avoid rounding errors */
retval = ( retval / 864 ) % 1000 ;
2007-02-27 11:04:40 +08:00
length = slprintf ( buffer , 32 , " %03d " , retval ) ;
2005-11-30 04:43:53 +08:00
break ;
}
2007-02-27 11:04:40 +08:00
case ' g ' : length = slprintf ( buffer , 32 , " %d " , ( t - > h % 12 ) ? ( int ) t - > h % 12 : 12 ) ; break ;
case ' G ' : length = slprintf ( buffer , 32 , " %d " , ( int ) t - > h ) ; break ;
case ' h ' : length = slprintf ( buffer , 32 , " %02d " , ( t - > h % 12 ) ? ( int ) t - > h % 12 : 12 ) ; break ;
case ' H ' : length = slprintf ( buffer , 32 , " %02d " , ( int ) t - > h ) ; break ;
case ' i ' : length = slprintf ( buffer , 32 , " %02d " , ( int ) t - > i ) ; break ;
case ' s ' : length = slprintf ( buffer , 32 , " %02d " , ( int ) t - > s ) ; break ;
2017-08-16 22:19:18 +08:00
case ' u ' : length = slprintf ( buffer , 32 , " %06d " , ( int ) floor ( t - > f * 1000000 + 0.5 ) ) ; break ;
case ' v ' : length = slprintf ( buffer , 32 , " %03d " , ( int ) floor ( t - > f * 1000 + 0.5 ) ) ; break ;
2005-07-01 05:38:06 +08:00
/* timezone */
2007-02-27 11:04:40 +08:00
case ' I ' : length = slprintf ( buffer , 32 , " %d " , localtime ? offset - > is_dst : 0 ) ; break ;
2006-02-01 02:44:19 +08:00
case ' P ' : rfc_colon = 1 ; /* break intentionally missing */
2007-02-27 11:04:40 +08:00
case ' O ' : length = slprintf ( buffer , 32 , " %c%02d%s%02d " ,
2005-07-01 05:38:06 +08:00
localtime ? ( ( offset - > offset < 0 ) ? ' - ' : ' + ' ) : ' + ' ,
localtime ? abs ( offset - > offset / 3600 ) : 0 ,
2006-02-01 02:44:19 +08:00
rfc_colon ? " : " : " " ,
2005-07-01 05:38:06 +08:00
localtime ? abs ( ( offset - > offset % 3600 ) / 60 ) : 0
) ;
break ;
2007-02-27 11:04:40 +08:00
case ' T ' : length = slprintf ( buffer , 32 , " %s " , localtime ? offset - > abbr : " GMT " ) ; break ;
2008-01-18 02:49:45 +08:00
case ' e ' : if ( ! localtime ) {
length = slprintf ( buffer , 32 , " %s " , " UTC " ) ;
} else {
switch ( t - > zone_type ) {
case TIMELIB_ZONETYPE_ID :
length = slprintf ( buffer , 32 , " %s " , t - > tz_info - > name ) ;
break ;
case TIMELIB_ZONETYPE_ABBR :
length = slprintf ( buffer , 32 , " %s " , offset - > abbr ) ;
break ;
case TIMELIB_ZONETYPE_OFFSET :
length = slprintf ( buffer , 32 , " %c%02d:%02d " ,
( ( offset - > offset < 0 ) ? ' - ' : ' + ' ) ,
abs ( offset - > offset / 3600 ) ,
abs ( ( offset - > offset % 3600 ) / 60 )
) ;
break ;
}
}
break ;
2007-02-27 11:04:40 +08:00
case ' Z ' : length = slprintf ( buffer , 32 , " %d " , localtime ? offset - > offset : 0 ) ; break ;
2005-07-01 05:38:06 +08:00
/* full date/time */
2010-02-11 00:55:40 +08:00
case ' c ' : length = slprintf ( buffer , 96 , " %04d-%02d-%02dT%02d:%02d:%02d%c%02d:%02d " ,
2005-07-01 05:38:06 +08:00
( int ) t - > y , ( int ) t - > m , ( int ) t - > d ,
( int ) t - > h , ( int ) t - > i , ( int ) t - > s ,
localtime ? ( ( offset - > offset < 0 ) ? ' - ' : ' + ' ) : ' + ' ,
localtime ? abs ( offset - > offset / 3600 ) : 0 ,
localtime ? abs ( ( offset - > offset % 3600 ) / 60 ) : 0
) ;
break ;
2010-02-11 00:23:30 +08:00
case ' r ' : length = slprintf ( buffer , 96 , " %3s, %02d %3s %04d %02d:%02d:%02d %c%02d%02d " ,
2006-06-23 05:04:32 +08:00
php_date_short_day_name ( t - > y , t - > m , t - > d ) ,
2005-07-01 05:38:06 +08:00
( int ) t - > d , mon_short_names [ t - > m - 1 ] ,
( int ) t - > y , ( int ) t - > h , ( int ) t - > i , ( int ) t - > s ,
localtime ? ( ( offset - > offset < 0 ) ? ' - ' : ' + ' ) : ' + ' ,
localtime ? abs ( offset - > offset / 3600 ) : 0 ,
localtime ? abs ( ( offset - > offset % 3600 ) / 60 ) : 0
) ;
break ;
2007-02-27 11:04:40 +08:00
case ' U ' : length = slprintf ( buffer , 32 , " %lld " , ( timelib_sll ) t - > sse ) ; break ;
2005-07-01 05:38:06 +08:00
2006-12-22 23:21:34 +08:00
case ' \\ ' : if ( i < format_len ) i + + ; /* break intentionally missing */
2005-07-01 05:38:06 +08:00
2006-12-22 23:21:34 +08:00
default : buffer [ 0 ] = format [ i ] ; buffer [ 1 ] = ' \0 ' ; length = 1 ; break ;
2005-07-01 05:38:06 +08:00
}
2006-12-22 23:21:34 +08:00
smart_str_appendl ( & string , buffer , length ) ;
2005-07-01 05:38:06 +08:00
}
smart_str_0 ( & string ) ;
2005-07-01 07:33:37 +08:00
if ( localtime ) {
timelib_time_offset_dtor ( offset ) ;
}
2014-02-18 17:42:46 +08:00
return string . s ;
2005-07-01 05:38:06 +08:00
}
static void php_date ( INTERNAL_FUNCTION_PARAMETERS , int localtime )
{
2005-10-05 16:20:44 +08:00
char * format ;
2014-08-27 21:31:48 +08:00
size_t format_len ;
2014-08-26 01:24:55 +08:00
zend_long ts ;
2005-07-01 05:38:06 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " s|l " , & format , & format_len , & ts ) = = FAILURE ) {
2005-07-01 05:38:06 +08:00
RETURN_FALSE ;
}
2008-03-10 02:09:53 +08:00
if ( ZEND_NUM_ARGS ( ) = = 1 ) {
ts = time ( NULL ) ;
}
2005-07-01 05:38:06 +08:00
2014-12-14 06:06:14 +08:00
RETURN_STR ( php_format_date ( format , format_len , ts , localtime ) ) ;
2005-07-08 20:26:30 +08:00
}
/* }}} */
2014-12-14 06:06:14 +08:00
PHPAPI zend_string * php_format_date ( char * format , size_t format_len , time_t ts , int localtime ) /* { { { */
2005-07-08 20:26:30 +08:00
{
timelib_time * t ;
timelib_tzinfo * tzi ;
2014-02-18 17:42:46 +08:00
zend_string * string ;
2005-07-08 20:26:30 +08:00
2005-07-01 06:44:28 +08:00
t = timelib_time_ctor ( ) ;
2005-07-01 05:38:06 +08:00
if ( localtime ) {
2014-12-14 06:06:14 +08:00
tzi = get_timezone_info ( ) ;
2005-12-19 21:00:37 +08:00
t - > tz_info = tzi ;
t - > zone_type = TIMELIB_ZONETYPE_ID ;
timelib_unixtime2local ( t , ts ) ;
2005-07-01 05:38:06 +08:00
} else {
tzi = NULL ;
timelib_unixtime2gmt ( t , ts ) ;
}
2005-07-08 20:26:30 +08:00
2014-12-14 06:06:14 +08:00
string = date_format ( format , format_len , t , localtime ) ;
2015-01-03 17:22:58 +08:00
2005-07-01 05:38:06 +08:00
timelib_time_dtor ( t ) ;
2005-07-08 20:26:30 +08:00
return string ;
2005-07-01 05:38:06 +08:00
}
2005-07-05 05:27:26 +08:00
/* }}} */
2005-07-01 05:38:06 +08:00
2005-11-30 04:19:56 +08:00
/* {{{ php_idate
*/
2014-12-14 06:06:14 +08:00
PHPAPI int php_idate ( char format , time_t ts , int localtime )
2005-11-30 04:19:56 +08:00
{
timelib_time * t ;
timelib_tzinfo * tzi ;
int retval = - 1 ;
2006-07-10 19:26:22 +08:00
timelib_time_offset * offset = NULL ;
2005-11-30 04:19:56 +08:00
timelib_sll isoweek , isoyear ;
t = timelib_time_ctor ( ) ;
if ( ! localtime ) {
2014-12-14 06:06:14 +08:00
tzi = get_timezone_info ( ) ;
2005-12-19 21:00:37 +08:00
t - > tz_info = tzi ;
t - > zone_type = TIMELIB_ZONETYPE_ID ;
timelib_unixtime2local ( t , ts ) ;
2005-11-30 04:19:56 +08:00
} else {
tzi = NULL ;
timelib_unixtime2gmt ( t , ts ) ;
}
if ( ! localtime ) {
if ( t - > zone_type = = TIMELIB_ZONETYPE_ABBR ) {
offset = timelib_time_offset_ctor ( ) ;
2017-08-16 22:19:18 +08:00
offset - > offset = ( t - > z - ( t - > dst * 60 ) ) * - 60 ;
2005-11-30 04:19:56 +08:00
offset - > leap_secs = 0 ;
offset - > is_dst = t - > dst ;
2015-09-22 16:17:50 +08:00
offset - > abbr = timelib_strdup ( t - > tz_abbr ) ;
2005-11-30 04:19:56 +08:00
} else if ( t - > zone_type = = TIMELIB_ZONETYPE_OFFSET ) {
offset = timelib_time_offset_ctor ( ) ;
2017-08-16 22:19:18 +08:00
offset - > offset = ( t - > z - ( t - > dst * 60 ) ) * - 60 ;
2005-11-30 04:19:56 +08:00
offset - > leap_secs = 0 ;
offset - > is_dst = t - > dst ;
2015-09-22 16:17:50 +08:00
offset - > abbr = timelib_malloc ( 9 ) ; /* GMT±xxxx\0 */
2015-01-03 17:22:58 +08:00
snprintf ( offset - > abbr , 9 , " GMT%c%02d%02d " ,
2005-11-30 04:19:56 +08:00
! localtime ? ( ( offset - > offset < 0 ) ? ' - ' : ' + ' ) : ' + ' ,
! localtime ? abs ( offset - > offset / 3600 ) : 0 ,
! localtime ? abs ( ( offset - > offset % 3600 ) / 60 ) : 0 ) ;
} else {
offset = timelib_get_time_zone_info ( t - > sse , t - > tz_info ) ;
}
}
timelib_isoweek_from_date ( t - > y , t - > m , t - > d , & isoweek , & isoyear ) ;
switch ( format ) {
/* day */
case ' d ' : case ' j ' : retval = ( int ) t - > d ; break ;
case ' w ' : retval = ( int ) timelib_day_of_week ( t - > y , t - > m , t - > d ) ; break ;
case ' z ' : retval = ( int ) timelib_day_of_year ( t - > y , t - > m , t - > d ) ; break ;
/* week */
case ' W ' : retval = ( int ) isoweek ; break ; /* iso weeknr */
/* month */
case ' m ' : case ' n ' : retval = ( int ) t - > m ; break ;
case ' t ' : retval = ( int ) timelib_days_in_month ( t - > y , t - > m ) ; break ;
/* year */
case ' L ' : retval = ( int ) timelib_is_leap ( ( int ) t - > y ) ; break ;
case ' y ' : retval = ( int ) ( t - > y % 100 ) ; break ;
case ' Y ' : retval = ( int ) t - > y ; break ;
/* Swatch Beat a.k.a. Internet Time */
case ' B ' :
2016-06-04 03:28:20 +08:00
retval = ( ( ( ( long ) t - > sse ) - ( ( ( long ) t - > sse ) - ( ( ( ( long ) t - > sse ) % 86400 ) + 3600 ) ) ) * 10 ) ;
if ( retval < 0 ) {
retval + = 864000 ;
2005-11-30 04:19:56 +08:00
}
2016-06-04 03:28:20 +08:00
/* Make sure to do this on a positive int to avoid rounding errors */
retval = ( retval / 864 ) % 1000 ;
2005-11-30 04:19:56 +08:00
break ;
/* time */
case ' g ' : case ' h ' : retval = ( int ) ( ( t - > h % 12 ) ? ( int ) t - > h % 12 : 12 ) ; break ;
case ' H ' : case ' G ' : retval = ( int ) t - > h ; break ;
case ' i ' : retval = ( int ) t - > i ; break ;
case ' s ' : retval = ( int ) t - > s ; break ;
/* timezone */
case ' I ' : retval = ( int ) ( ! localtime ? offset - > is_dst : 0 ) ; break ;
case ' Z ' : retval = ( int ) ( ! localtime ? offset - > offset : 0 ) ; break ;
case ' U ' : retval = ( int ) t - > sse ; break ;
}
if ( ! localtime ) {
timelib_time_offset_dtor ( offset ) ;
}
timelib_time_dtor ( t ) ;
return retval ;
}
/* }}} */
2005-07-05 05:27:26 +08:00
/* {{{ proto string date(string format [, long timestamp])
Format a local date / time */
2005-07-01 05:38:06 +08:00
PHP_FUNCTION ( date )
{
php_date ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 1 ) ;
}
2005-07-05 05:27:26 +08:00
/* }}} */
2005-07-01 05:38:06 +08:00
2005-07-05 05:27:26 +08:00
/* {{{ proto string gmdate(string format [, long timestamp])
Format a GMT date / time */
2005-07-01 05:38:06 +08:00
PHP_FUNCTION ( gmdate )
{
php_date ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 0 ) ;
}
2005-07-05 05:27:26 +08:00
/* }}} */
2005-07-01 05:38:06 +08:00
2005-11-30 04:19:56 +08:00
/* {{{ proto int idate(string format [, int timestamp])
Format a local time / date as integer */
PHP_FUNCTION ( idate )
{
char * format ;
2014-08-27 23:31:24 +08:00
size_t format_len ;
2014-08-26 01:24:55 +08:00
zend_long ts = 0 ;
2015-01-03 17:22:58 +08:00
int ret ;
2005-11-30 04:19:56 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " s|l " , & format , & format_len , & ts ) = = FAILURE ) {
2005-11-30 04:19:56 +08:00
RETURN_FALSE ;
}
if ( format_len ! = 1 ) {
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , E_WARNING , " idate format is one char " ) ;
2005-11-30 04:19:56 +08:00
RETURN_FALSE ;
}
if ( ZEND_NUM_ARGS ( ) = = 1 ) {
ts = time ( NULL ) ;
}
2014-12-14 06:06:14 +08:00
ret = php_idate ( format [ 0 ] , ts , 0 ) ;
2005-11-30 07:10:15 +08:00
if ( ret = = - 1 ) {
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , E_WARNING , " Unrecognized date format token. " ) ;
2005-11-30 07:10:15 +08:00
RETURN_FALSE ;
}
2014-08-26 01:24:55 +08:00
RETURN_LONG ( ret ) ;
2005-11-30 04:19:56 +08:00
}
/* }}} */
2005-10-03 19:17:28 +08:00
/* {{{ php_date_set_tzdb - NOT THREADSAFE */
PHPAPI void php_date_set_tzdb ( timelib_tzdb * tzdb )
{
2006-05-15 01:36:05 +08:00
const timelib_tzdb * builtin = timelib_builtin_db ( ) ;
2015-01-03 17:22:58 +08:00
2005-10-03 19:34:51 +08:00
if ( php_version_compare ( tzdb - > version , builtin - > version ) > 0 ) {
php_date_global_timezone_db = tzdb ;
php_date_global_timezone_db_enabled = 1 ;
}
2005-10-03 19:17:28 +08:00
}
/* }}} */
2005-07-05 05:27:26 +08:00
2013-07-24 07:55:43 +08:00
/* {{{ php_parse_date: Backwards compatibility function */
2014-08-26 01:24:55 +08:00
PHPAPI zend_long php_parse_date ( char * string , zend_long * now )
2005-06-20 06:15:27 +08:00
{
timelib_time * parsed_time ;
2010-05-12 17:37:25 +08:00
timelib_error_container * error = NULL ;
2006-04-12 02:03:52 +08:00
int error2 ;
2014-08-26 01:24:55 +08:00
zend_long retval ;
2005-06-20 06:15:27 +08:00
2011-12-06 14:21:08 +08:00
parsed_time = timelib_strtotime ( string , strlen ( string ) , & error , DATE_TIMEZONEDB , php_date_parse_tzfile_wrapper ) ;
2010-05-12 17:37:25 +08:00
if ( error - > error_count ) {
2013-10-21 15:01:24 +08:00
timelib_time_dtor ( parsed_time ) ;
2010-05-12 17:37:25 +08:00
timelib_error_container_dtor ( error ) ;
return - 1 ;
}
timelib_error_container_dtor ( error ) ;
2005-06-20 06:15:27 +08:00
timelib_update_ts ( parsed_time , NULL ) ;
2005-07-04 05:38:54 +08:00
retval = timelib_date_to_int ( parsed_time , & error2 ) ;
2005-06-20 06:15:27 +08:00
timelib_time_dtor ( parsed_time ) ;
2006-04-12 02:03:52 +08:00
if ( error2 ) {
2005-06-20 06:15:27 +08:00
return - 1 ;
}
return retval ;
}
2005-07-05 05:27:26 +08:00
/* }}} */
2005-06-20 06:15:27 +08:00
2006-04-12 02:03:52 +08:00
/* {{{ proto int strtotime(string time [, int now ])
2005-06-15 05:32:29 +08:00
Convert string representation of date and time to a timestamp */
PHP_FUNCTION ( strtotime )
{
2015-01-30 17:28:57 +08:00
char * times ;
2014-08-27 21:31:48 +08:00
size_t time_len ;
int error1 , error2 ;
2006-04-12 02:03:52 +08:00
struct timelib_error_container * error ;
2014-08-26 01:24:55 +08:00
zend_long preset_ts = 0 , ts ;
2005-06-15 05:32:29 +08:00
timelib_time * t , * now ;
timelib_tzinfo * tzi ;
2015-08-13 01:01:04 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " s|l " , & times , & time_len , & preset_ts ) = = FAILURE | | ! time_len ) {
2005-06-15 05:32:29 +08:00
RETURN_FALSE ;
}
2014-12-19 10:07:47 +08:00
tzi = get_timezone_info ( ) ;
now = timelib_time_ctor ( ) ;
now - > tz_info = tzi ;
now - > zone_type = TIMELIB_ZONETYPE_ID ;
2015-01-03 17:22:58 +08:00
timelib_unixtime2local ( now ,
2014-12-19 10:07:47 +08:00
( ZEND_NUM_ARGS ( ) = = 2 ) ? ( timelib_sll ) preset_ts : ( timelib_sll ) time ( NULL ) ) ;
2008-01-30 04:12:53 +08:00
2011-12-06 14:21:08 +08:00
t = timelib_strtotime ( times , time_len , & error , DATE_TIMEZONEDB , php_date_parse_tzfile_wrapper ) ;
2006-04-12 02:03:52 +08:00
error1 = error - > error_count ;
timelib_error_container_dtor ( error ) ;
2008-12-18 22:55:36 +08:00
timelib_fill_holes ( t , now , TIMELIB_NO_CLONE ) ;
2005-06-15 05:32:29 +08:00
timelib_update_ts ( t , tzi ) ;
2005-07-04 05:38:54 +08:00
ts = timelib_date_to_int ( t , & error2 ) ;
2005-06-15 07:40:57 +08:00
2006-06-23 02:44:31 +08:00
timelib_time_dtor ( now ) ;
2005-06-15 07:40:57 +08:00
timelib_time_dtor ( t ) ;
2005-07-04 05:38:54 +08:00
if ( error1 | | error2 ) {
2005-06-15 05:32:29 +08:00
RETURN_FALSE ;
} else {
2014-08-26 01:24:55 +08:00
RETURN_LONG ( ts ) ;
2005-06-15 05:32:29 +08:00
}
}
/* }}} */
2005-07-05 05:27:26 +08:00
/* {{{ php_mktime - (gm)mktime helper */
2005-07-04 21:21:39 +08:00
PHPAPI void php_mktime ( INTERNAL_FUNCTION_PARAMETERS , int gmt )
2005-07-03 22:27:31 +08:00
{
2014-09-11 00:18:02 +08:00
zend_long hou = 0 , min = 0 , sec = 0 , mon = 0 , day = 0 , yea = 0 ;
2005-07-03 22:27:31 +08:00
timelib_time * now ;
2006-07-10 19:26:22 +08:00
timelib_tzinfo * tzi = NULL ;
2014-08-26 01:24:55 +08:00
zend_long ts , adjust_seconds = 0 ;
2005-07-03 22:27:31 +08:00
int error ;
2014-09-11 00:18:02 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " |llllll " , & hou , & min , & sec , & mon , & day , & yea ) = = FAILURE ) {
2005-07-03 22:27:31 +08:00
RETURN_FALSE ;
}
/* Initialize structure with current time */
now = timelib_time_ctor ( ) ;
if ( gmt ) {
timelib_unixtime2gmt ( now , ( timelib_sll ) time ( NULL ) ) ;
} else {
2014-12-14 06:06:14 +08:00
tzi = get_timezone_info ( ) ;
2005-12-19 21:00:37 +08:00
now - > tz_info = tzi ;
now - > zone_type = TIMELIB_ZONETYPE_ID ;
timelib_unixtime2local ( now , ( timelib_sll ) time ( NULL ) ) ;
2005-07-03 22:27:31 +08:00
}
/* Fill in the new data */
switch ( ZEND_NUM_ARGS ( ) ) {
case 7 :
/* break intentionally missing */
case 6 :
2005-07-21 18:09:40 +08:00
if ( yea > = 0 & & yea < 70 ) {
yea + = 2000 ;
2008-12-03 02:02:16 +08:00
} else if ( yea > = 70 & & yea < = 100 ) {
2005-07-21 18:09:40 +08:00
yea + = 1900 ;
}
2005-07-03 22:27:31 +08:00
now - > y = yea ;
/* break intentionally missing again */
case 5 :
now - > d = day ;
/* break missing intentionally here too */
case 4 :
now - > m = mon ;
/* and here */
case 3 :
now - > s = sec ;
/* yup, this break isn't here on purpose too */
case 2 :
now - > i = min ;
/* last intentionally missing break */
case 1 :
now - > h = hou ;
break ;
default :
2015-07-30 19:53:44 +08:00
php_error_docref ( NULL , E_DEPRECATED , " You should be using the time() function instead " ) ;
2005-07-03 22:27:31 +08:00
}
/* Update the timestamp */
if ( gmt ) {
timelib_update_ts ( now , NULL ) ;
} else {
timelib_update_ts ( now , tzi ) ;
}
2014-09-11 00:18:02 +08:00
2005-07-03 22:27:31 +08:00
/* Clean up and return */
ts = timelib_date_to_int ( now , & error ) ;
ts + = adjust_seconds ;
timelib_time_dtor ( now ) ;
if ( error ) {
RETURN_FALSE ;
} else {
2014-08-26 01:24:55 +08:00
RETURN_LONG ( ts ) ;
2005-07-03 22:27:31 +08:00
}
}
2005-07-05 05:27:26 +08:00
/* }}} */
2005-07-03 22:27:31 +08:00
2006-06-11 09:42:17 +08:00
/* {{{ proto int mktime([int hour [, int min [, int sec [, int mon [, int day [, int year]]]]]])
2005-07-03 22:27:31 +08:00
Get UNIX timestamp for a date */
PHP_FUNCTION ( mktime )
{
php_mktime ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 0 ) ;
}
/* }}} */
2006-06-11 09:42:17 +08:00
/* {{{ proto int gmmktime([int hour [, int min [, int sec [, int mon [, int day [, int year]]]]]])
2005-07-03 22:27:31 +08:00
Get UNIX timestamp for a GMT date */
PHP_FUNCTION ( gmmktime )
{
php_mktime ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 1 ) ;
}
/* }}} */
2005-07-04 03:14:55 +08:00
/* {{{ proto bool checkdate(int month, int day, int year)
Returns true ( 1 ) if it is a valid date in gregorian calendar */
PHP_FUNCTION ( checkdate )
{
2014-08-26 01:24:55 +08:00
zend_long m , d , y ;
2005-07-04 03:14:55 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " lll " , & m , & d , & y ) = = FAILURE ) {
2005-07-04 03:14:55 +08:00
RETURN_FALSE ;
}
2008-07-15 01:38:33 +08:00
if ( y < 1 | | y > 32767 | | ! timelib_valid_date ( y , m , d ) ) {
2005-07-04 03:14:55 +08:00
RETURN_FALSE ;
}
RETURN_TRUE ; /* True : This month, day, year arguments are valid */
}
/* }}} */
2005-07-04 07:30:52 +08:00
# ifdef HAVE_STRFTIME
2005-07-05 05:27:26 +08:00
/* {{{ php_strftime - (gm)strftime helper */
2005-07-04 03:14:55 +08:00
PHPAPI void php_strftime ( INTERNAL_FUNCTION_PARAMETERS , int gmt )
{
2014-03-06 18:51:20 +08:00
char * format ;
2014-08-27 23:31:24 +08:00
size_t format_len ;
2014-08-26 01:24:55 +08:00
zend_long timestamp = 0 ;
2005-07-04 03:14:55 +08:00
struct tm ta ;
int max_reallocs = 5 ;
2013-03-06 23:48:51 +08:00
size_t buf_len = 256 , real_len ;
2005-07-04 03:14:55 +08:00
timelib_time * ts ;
timelib_tzinfo * tzi ;
2006-07-10 19:26:22 +08:00
timelib_time_offset * offset = NULL ;
2014-03-06 18:51:20 +08:00
zend_string * buf ;
2005-07-04 03:14:55 +08:00
2014-08-26 01:24:55 +08:00
timestamp = ( zend_long ) time ( NULL ) ;
2005-07-04 03:14:55 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " s|l " , & format , & format_len , & timestamp ) = = FAILURE ) {
2005-07-04 03:14:55 +08:00
RETURN_FALSE ;
}
if ( format_len = = 0 ) {
RETURN_FALSE ;
}
ts = timelib_time_ctor ( ) ;
if ( gmt ) {
tzi = NULL ;
timelib_unixtime2gmt ( ts , ( timelib_sll ) timestamp ) ;
} else {
2014-12-14 06:06:14 +08:00
tzi = get_timezone_info ( ) ;
2005-12-19 21:00:37 +08:00
ts - > tz_info = tzi ;
ts - > zone_type = TIMELIB_ZONETYPE_ID ;
timelib_unixtime2local ( ts , ( timelib_sll ) timestamp ) ;
2005-07-04 03:14:55 +08:00
}
ta . tm_sec = ts - > s ;
ta . tm_min = ts - > i ;
ta . tm_hour = ts - > h ;
ta . tm_mday = ts - > d ;
ta . tm_mon = ts - > m - 1 ;
ta . tm_year = ts - > y - 1900 ;
ta . tm_wday = timelib_day_of_week ( ts - > y , ts - > m , ts - > d ) ;
ta . tm_yday = timelib_day_of_year ( ts - > y , ts - > m , ts - > d ) ;
if ( gmt ) {
ta . tm_isdst = 0 ;
# if HAVE_TM_GMTOFF
ta . tm_gmtoff = 0 ;
# endif
# if HAVE_TM_ZONE
ta . tm_zone = " GMT " ;
# endif
} else {
offset = timelib_get_time_zone_info ( timestamp , tzi ) ;
ta . tm_isdst = offset - > is_dst ;
# if HAVE_TM_GMTOFF
ta . tm_gmtoff = offset - > offset ;
# endif
# if HAVE_TM_ZONE
ta . tm_zone = offset - > abbr ;
# endif
}
2013-03-06 23:48:51 +08:00
/* VS2012 crt has a bug where strftime crash with %z and %Z format when the
initial buffer is too small . See
http : //connect.microsoft.com/VisualStudio/feedback/details/759720/vs2012-strftime-crash-with-z-formatting-code */
2014-08-26 01:24:55 +08:00
buf = zend_string_alloc ( buf_len , 0 ) ;
2015-06-30 09:05:24 +08:00
while ( ( real_len = strftime ( ZSTR_VAL ( buf ) , buf_len , format , & ta ) ) = = buf_len | | real_len = = 0 ) {
2005-07-04 03:14:55 +08:00
buf_len * = 2 ;
2015-03-20 07:02:42 +08:00
buf = zend_string_extend ( buf , buf_len , 0 ) ;
2005-07-04 03:14:55 +08:00
if ( ! - - max_reallocs ) {
break ;
}
}
2015-03-29 13:14:54 +08:00
# ifdef PHP_WIN32
2013-07-03 17:12:46 +08:00
/* VS2012 strftime() returns number of characters, not bytes.
See VC + + 11 bug id 766205. */
if ( real_len > 0 ) {
2014-08-19 00:57:55 +08:00
real_len = strlen ( buf - > val ) ;
2013-07-03 17:12:46 +08:00
}
# endif
2005-07-04 03:14:55 +08:00
timelib_time_dtor ( ts ) ;
2005-07-04 22:32:50 +08:00
if ( ! gmt ) {
2005-07-04 03:14:55 +08:00
timelib_time_offset_dtor ( offset ) ;
}
if ( real_len & & real_len ! = buf_len ) {
2015-03-20 07:02:42 +08:00
buf = zend_string_truncate ( buf , real_len , 0 ) ;
2015-03-12 21:53:51 +08:00
RETURN_NEW_STR ( buf ) ;
2005-07-04 03:14:55 +08:00
}
2014-08-26 01:24:55 +08:00
zend_string_free ( buf ) ;
2005-07-04 03:14:55 +08:00
RETURN_FALSE ;
}
/* }}} */
/* {{{ proto string strftime(string format [, int timestamp])
Format a local time / date according to locale settings */
PHP_FUNCTION ( strftime )
{
2005-07-05 05:27:26 +08:00
php_strftime ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 0 ) ;
2005-07-04 03:14:55 +08:00
}
/* }}} */
/* {{{ proto string gmstrftime(string format [, int timestamp])
Format a GMT / UCT time / date according to locale settings */
PHP_FUNCTION ( gmstrftime )
{
2005-07-05 05:27:26 +08:00
php_strftime ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 1 ) ;
2005-07-04 03:14:55 +08:00
}
/* }}} */
# endif
2005-07-04 04:45:08 +08:00
/* {{{ proto int time(void)
Return current UNIX timestamp */
PHP_FUNCTION ( time )
{
2014-08-26 01:24:55 +08:00
RETURN_LONG ( ( zend_long ) time ( NULL ) ) ;
2005-07-04 04:45:08 +08:00
}
/* }}} */
/* {{{ proto array localtime([int timestamp [, bool associative_array]])
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 */
PHP_FUNCTION ( localtime )
{
2014-08-26 01:24:55 +08:00
zend_long timestamp = ( zend_long ) time ( NULL ) ;
2006-09-05 20:39:20 +08:00
zend_bool associative = 0 ;
2005-07-04 04:45:08 +08:00
timelib_tzinfo * tzi ;
timelib_time * ts ;
2014-12-14 06:06:14 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " |lb " , & timestamp , & associative ) = = FAILURE ) {
2005-07-04 04:45:08 +08:00
RETURN_FALSE ;
}
2014-12-14 06:06:14 +08:00
tzi = get_timezone_info ( ) ;
2005-07-04 04:45:08 +08:00
ts = timelib_time_ctor ( ) ;
2005-12-19 21:00:37 +08:00
ts - > tz_info = tzi ;
ts - > zone_type = TIMELIB_ZONETYPE_ID ;
timelib_unixtime2local ( ts , ( timelib_sll ) timestamp ) ;
2005-07-04 04:45:08 +08:00
array_init ( return_value ) ;
if ( associative ) {
2014-08-26 01:24:55 +08:00
add_assoc_long ( return_value , " tm_sec " , ts - > s ) ;
add_assoc_long ( return_value , " tm_min " , ts - > i ) ;
add_assoc_long ( return_value , " tm_hour " , ts - > h ) ;
add_assoc_long ( return_value , " tm_mday " , ts - > d ) ;
add_assoc_long ( return_value , " tm_mon " , ts - > m - 1 ) ;
add_assoc_long ( return_value , " tm_year " , ts - > y - 1900 ) ;
add_assoc_long ( return_value , " tm_wday " , timelib_day_of_week ( ts - > y , ts - > m , ts - > d ) ) ;
add_assoc_long ( return_value , " tm_yday " , timelib_day_of_year ( ts - > y , ts - > m , ts - > d ) ) ;
add_assoc_long ( return_value , " tm_isdst " , ts - > dst ) ;
2005-07-04 04:45:08 +08:00
} else {
2014-08-26 01:24:55 +08:00
add_next_index_long ( return_value , ts - > s ) ;
add_next_index_long ( return_value , ts - > i ) ;
add_next_index_long ( return_value , ts - > h ) ;
add_next_index_long ( return_value , ts - > d ) ;
add_next_index_long ( return_value , ts - > m - 1 ) ;
add_next_index_long ( return_value , ts - > y - 1900 ) ;
add_next_index_long ( return_value , timelib_day_of_week ( ts - > y , ts - > m , ts - > d ) ) ;
add_next_index_long ( return_value , timelib_day_of_year ( ts - > y , ts - > m , ts - > d ) ) ;
add_next_index_long ( return_value , ts - > dst ) ;
2005-07-04 04:45:08 +08:00
}
timelib_time_dtor ( ts ) ;
}
/* }}} */
/* {{{ proto array getdate([int timestamp])
Get date / time information */
PHP_FUNCTION ( getdate )
{
2014-08-26 01:24:55 +08:00
zend_long timestamp = ( zend_long ) time ( NULL ) ;
2005-07-04 04:45:08 +08:00
timelib_tzinfo * tzi ;
timelib_time * ts ;
2014-12-14 06:06:14 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " |l " , & timestamp ) = = FAILURE ) {
2005-07-04 04:45:08 +08:00
RETURN_FALSE ;
}
2014-12-14 06:06:14 +08:00
tzi = get_timezone_info ( ) ;
2005-07-04 04:45:08 +08:00
ts = timelib_time_ctor ( ) ;
2005-12-19 21:00:37 +08:00
ts - > tz_info = tzi ;
ts - > zone_type = TIMELIB_ZONETYPE_ID ;
timelib_unixtime2local ( ts , ( timelib_sll ) timestamp ) ;
2005-07-04 04:45:08 +08:00
array_init ( return_value ) ;
2014-08-26 01:24:55 +08:00
add_assoc_long ( return_value , " seconds " , ts - > s ) ;
add_assoc_long ( return_value , " minutes " , ts - > i ) ;
add_assoc_long ( return_value , " hours " , ts - > h ) ;
add_assoc_long ( return_value , " mday " , ts - > d ) ;
add_assoc_long ( return_value , " wday " , timelib_day_of_week ( ts - > y , ts - > m , ts - > d ) ) ;
add_assoc_long ( return_value , " mon " , ts - > m ) ;
add_assoc_long ( return_value , " year " , ts - > y ) ;
add_assoc_long ( return_value , " yday " , timelib_day_of_year ( ts - > y , ts - > m , ts - > d ) ) ;
2014-04-15 19:40:40 +08:00
add_assoc_string ( return_value , " weekday " , php_date_full_day_name ( ts - > y , ts - > m , ts - > d ) ) ;
add_assoc_string ( return_value , " month " , mon_full_names [ ts - > m - 1 ] ) ;
2014-08-26 01:24:55 +08:00
add_index_long ( return_value , 0 , timestamp ) ;
2005-07-04 04:45:08 +08:00
timelib_time_dtor ( ts ) ;
}
/* }}} */
2008-02-27 17:47:35 +08:00
# define PHP_DATE_TIMEZONE_GROUP_AFRICA 0x0001
# define PHP_DATE_TIMEZONE_GROUP_AMERICA 0x0002
# define PHP_DATE_TIMEZONE_GROUP_ANTARCTICA 0x0004
# define PHP_DATE_TIMEZONE_GROUP_ARCTIC 0x0008
# define PHP_DATE_TIMEZONE_GROUP_ASIA 0x0010
# define PHP_DATE_TIMEZONE_GROUP_ATLANTIC 0x0020
# define PHP_DATE_TIMEZONE_GROUP_AUSTRALIA 0x0040
# define PHP_DATE_TIMEZONE_GROUP_EUROPE 0x0080
# define PHP_DATE_TIMEZONE_GROUP_INDIAN 0x0100
# define PHP_DATE_TIMEZONE_GROUP_PACIFIC 0x0200
# define PHP_DATE_TIMEZONE_GROUP_UTC 0x0400
# define PHP_DATE_TIMEZONE_GROUP_ALL 0x07FF
# define PHP_DATE_TIMEZONE_GROUP_ALL_W_BC 0x0FFF
2008-07-18 22:33:53 +08:00
# define PHP_DATE_TIMEZONE_PER_COUNTRY 0x1000
2008-01-28 01:29:14 +08:00
2008-05-01 21:31:22 +08:00
# define PHP_DATE_PERIOD_EXCLUDE_START_DATE 0x0001
2008-05-01 08:12:24 +08:00
/* define an overloaded iterator structure */
typedef struct {
zend_object_iterator intern ;
2014-02-10 14:04:30 +08:00
zval current ;
2008-05-01 08:12:24 +08:00
php_period_obj * object ;
int current_index ;
} date_period_it ;
/* {{{ date_period_it_invalidate_current */
2014-12-14 06:06:14 +08:00
static void date_period_it_invalidate_current ( zend_object_iterator * iter )
2008-05-01 08:12:24 +08:00
{
date_period_it * iterator = ( date_period_it * ) iter ;
2014-02-10 14:04:30 +08:00
if ( Z_TYPE ( iterator - > current ) ! = IS_UNDEF ) {
2008-05-01 08:12:24 +08:00
zval_ptr_dtor ( & iterator - > current ) ;
2014-02-10 14:04:30 +08:00
ZVAL_UNDEF ( & iterator - > current ) ;
2008-05-01 08:12:24 +08:00
}
}
/* }}} */
/* {{{ date_period_it_dtor */
2014-12-14 06:06:14 +08:00
static void date_period_it_dtor ( zend_object_iterator * iter )
2008-05-01 08:12:24 +08:00
{
date_period_it * iterator = ( date_period_it * ) iter ;
2014-12-14 06:06:14 +08:00
date_period_it_invalidate_current ( iter ) ;
2008-05-01 08:12:24 +08:00
2014-02-27 19:19:02 +08:00
zval_ptr_dtor ( & iterator - > intern . data ) ;
2008-05-01 08:12:24 +08:00
}
/* }}} */
/* {{{ date_period_it_has_more */
2014-12-14 06:06:14 +08:00
static int date_period_it_has_more ( zend_object_iterator * iter )
2008-05-01 08:12:24 +08:00
{
2008-05-03 18:59:36 +08:00
date_period_it * iterator = ( date_period_it * ) iter ;
2014-03-16 17:14:31 +08:00
php_period_obj * object = Z_PHPPERIOD_P ( & iterator - > intern . data ) ;
2010-08-30 23:32:09 +08:00
timelib_time * it_time = object - > current ;
2008-05-01 08:12:24 +08:00
2008-05-01 21:31:22 +08:00
/* apply modification if it's not the first iteration */
if ( ! object - > include_start_date | | iterator - > current_index > 0 ) {
2008-05-02 20:49:16 +08:00
it_time - > have_relative = 1 ;
2008-05-03 18:59:36 +08:00
it_time - > relative = * object - > interval ;
2008-05-01 21:31:22 +08:00
it_time - > sse_uptodate = 0 ;
timelib_update_ts ( it_time , NULL ) ;
timelib_update_from_sse ( it_time ) ;
}
2008-05-01 08:12:24 +08:00
2008-05-03 18:59:36 +08:00
if ( object - > end ) {
2010-08-30 23:32:09 +08:00
return object - > current - > sse < object - > end - > sse ? SUCCESS : FAILURE ;
2008-05-03 18:59:36 +08:00
} else {
return ( iterator - > current_index < object - > recurrences ) ? SUCCESS : FAILURE ;
}
}
/* }}} */
/* {{{ date_period_it_current_data */
2014-12-14 06:06:14 +08:00
static zval * date_period_it_current_data ( zend_object_iterator * iter )
2008-05-03 18:59:36 +08:00
{
date_period_it * iterator = ( date_period_it * ) iter ;
2014-03-16 17:14:31 +08:00
php_period_obj * object = Z_PHPPERIOD_P ( & iterator - > intern . data ) ;
2010-08-30 23:32:09 +08:00
timelib_time * it_time = object - > current ;
2008-05-03 18:59:36 +08:00
php_date_obj * newdateobj ;
2008-05-01 08:12:24 +08:00
/* Create new object */
2014-12-14 06:06:14 +08:00
php_date_instantiate ( object - > start_ce , & iterator - > current ) ;
2014-03-16 17:14:31 +08:00
newdateobj = Z_PHPDATE_P ( & iterator - > current ) ;
2008-05-01 08:12:24 +08:00
newdateobj - > time = timelib_time_ctor ( ) ;
* newdateobj - > time = * it_time ;
if ( it_time - > tz_abbr ) {
2015-09-22 16:17:50 +08:00
newdateobj - > time - > tz_abbr = timelib_strdup ( it_time - > tz_abbr ) ;
2008-05-01 08:12:24 +08:00
}
if ( it_time - > tz_info ) {
2008-07-09 01:41:51 +08:00
newdateobj - > time - > tz_info = it_time - > tz_info ;
2008-05-01 08:12:24 +08:00
}
2015-01-03 17:22:58 +08:00
2014-02-10 14:04:30 +08:00
return & iterator - > current ;
2008-05-01 08:12:24 +08:00
}
/* }}} */
/* {{{ date_period_it_current_key */
2014-12-14 06:06:14 +08:00
static void date_period_it_current_key ( zend_object_iterator * iter , zval * key )
2008-05-01 08:12:24 +08:00
{
2013-02-17 02:13:36 +08:00
date_period_it * iterator = ( date_period_it * ) iter ;
2014-08-26 01:24:55 +08:00
ZVAL_LONG ( key , iterator - > current_index ) ;
2008-05-01 08:12:24 +08:00
}
/* }}} */
/* {{{ date_period_it_move_forward */
2014-12-14 06:06:14 +08:00
static void date_period_it_move_forward ( zend_object_iterator * iter )
2008-05-01 08:12:24 +08:00
{
2008-05-03 18:59:36 +08:00
date_period_it * iterator = ( date_period_it * ) iter ;
2008-05-01 08:12:24 +08:00
iterator - > current_index + + ;
2014-12-14 06:06:14 +08:00
date_period_it_invalidate_current ( iter ) ;
2008-05-01 08:12:24 +08:00
}
/* }}} */
/* {{{ date_period_it_rewind */
2014-12-14 06:06:14 +08:00
static void date_period_it_rewind ( zend_object_iterator * iter )
2008-05-01 08:12:24 +08:00
{
2014-03-16 17:14:31 +08:00
date_period_it * iterator = ( date_period_it * ) iter ;
2008-05-01 08:12:24 +08:00
iterator - > current_index = 0 ;
2010-08-30 23:32:09 +08:00
if ( iterator - > object - > current ) {
timelib_time_dtor ( iterator - > object - > current ) ;
}
2017-08-02 22:40:48 +08:00
if ( ! iterator - > object - > start ) {
zend_throw_error ( NULL , " DatePeriod has not been initialized correctly " ) ;
return ;
}
2010-08-30 23:32:09 +08:00
iterator - > object - > current = timelib_time_clone ( iterator - > object - > start ) ;
2014-12-14 06:06:14 +08:00
date_period_it_invalidate_current ( iter ) ;
2008-05-01 08:12:24 +08:00
}
/* }}} */
/* iterator handler table */
zend_object_iterator_funcs date_period_it_funcs = {
date_period_it_dtor ,
date_period_it_has_more ,
date_period_it_current_data ,
date_period_it_current_key ,
date_period_it_move_forward ,
date_period_it_rewind ,
date_period_it_invalidate_current
} ;
2014-12-14 06:06:14 +08:00
zend_object_iterator * date_object_period_get_iterator ( zend_class_entry * ce , zval * object , int by_ref ) /* { { { */
2008-05-01 08:12:24 +08:00
{
2014-03-16 17:14:31 +08:00
date_period_it * iterator = emalloc ( sizeof ( date_period_it ) ) ;
2008-05-01 08:12:24 +08:00
2008-07-30 16:18:05 +08:00
if ( by_ref ) {
zend_error ( E_ERROR , " An iterator cannot be used with foreach by reference " ) ;
}
2008-05-01 08:12:24 +08:00
2014-12-14 06:06:14 +08:00
zend_iterator_init ( ( zend_object_iterator * ) iterator ) ;
2014-02-26 19:01:08 +08:00
2014-02-27 19:19:02 +08:00
ZVAL_COPY ( & iterator - > intern . data , object ) ;
2008-07-30 16:18:05 +08:00
iterator - > intern . funcs = & date_period_it_funcs ;
2014-03-16 17:14:31 +08:00
iterator - > object = Z_PHPPERIOD_P ( object ) ;
2014-02-10 14:04:30 +08:00
ZVAL_UNDEF ( & iterator - > current ) ;
2008-05-01 08:12:24 +08:00
2008-07-30 16:18:05 +08:00
return ( zend_object_iterator * ) iterator ;
2014-03-16 17:14:31 +08:00
} /* }}} */
2008-05-01 08:12:24 +08:00
2014-12-14 06:06:14 +08:00
static int implement_date_interface_handler ( zend_class_entry * interface , zend_class_entry * implementor ) /* { { { */
2013-10-29 23:40:17 +08:00
{
if ( implementor - > type = = ZEND_USER_CLASS & &
2014-12-14 06:06:14 +08:00
! instanceof_function ( implementor , date_ce_date ) & &
! instanceof_function ( implementor , date_ce_immutable )
2013-10-29 23:40:17 +08:00
) {
zend_error ( E_ERROR , " DateTimeInterface can't be implemented by user classes " ) ;
}
return SUCCESS ;
2014-03-16 17:14:31 +08:00
} /* }}} */
2013-10-29 23:40:17 +08:00
2016-04-20 23:37:26 +08:00
static int date_interval_has_property ( zval * object , zval * member , int type , void * * cache_slot ) /* { { { */
{
php_interval_obj * obj ;
2016-07-11 21:12:23 +08:00
zval tmp_member ;
zval rv ;
zval * prop ;
2016-04-20 23:37:26 +08:00
int retval = 0 ;
2017-07-08 20:04:25 +08:00
if ( UNEXPECTED ( Z_TYPE_P ( member ) ! = IS_STRING ) ) {
2016-04-20 23:37:26 +08:00
ZVAL_COPY ( & tmp_member , member ) ;
convert_to_string ( & tmp_member ) ;
member = & tmp_member ;
cache_slot = NULL ;
}
obj = Z_PHPINTERVAL_P ( object ) ;
if ( ! obj - > initialized ) {
retval = ( zend_get_std_object_handlers ( ) ) - > has_property ( object , member , type , cache_slot ) ;
if ( member = = & tmp_member ) {
zval_dtor ( member ) ;
}
return retval ;
}
2017-07-08 20:04:25 +08:00
prop = date_interval_read_property ( object , member , BP_VAR_IS , cache_slot , & rv ) ;
if ( prop ! = & EG ( uninitialized_zval ) ) {
2016-04-20 23:37:26 +08:00
if ( type = = 2 ) {
retval = 1 ;
} else if ( type = = 1 ) {
retval = zend_is_true ( prop ) ;
} else if ( type = = 0 ) {
retval = ( Z_TYPE ( * prop ) ! = IS_NULL ) ;
}
} else {
retval = ( zend_get_std_object_handlers ( ) ) - > has_property ( object , member , type , cache_slot ) ;
}
if ( member = = & tmp_member ) {
zval_dtor ( member ) ;
}
return retval ;
}
/* }}} */
2014-12-14 06:06:14 +08:00
static void date_register_classes ( void ) /* { { { */
2005-11-18 05:05:30 +08:00
{
2013-03-31 17:37:16 +08:00
zend_class_entry ce_date , ce_immutable , ce_timezone , ce_interval , ce_period , ce_interface ;
INIT_CLASS_ENTRY ( ce_interface , " DateTimeInterface " , date_funcs_interface ) ;
2014-12-14 06:06:14 +08:00
date_ce_interface = zend_register_internal_interface ( & ce_interface ) ;
2013-10-29 23:40:17 +08:00
date_ce_interface - > interface_gets_implemented = implement_date_interface_handler ;
2005-11-18 05:05:30 +08:00
2006-07-20 23:49:02 +08:00
INIT_CLASS_ENTRY ( ce_date , " DateTime " , date_funcs_date ) ;
2005-11-18 05:05:30 +08:00
ce_date . create_object = date_object_new_date ;
2014-12-14 06:06:14 +08:00
date_ce_date = zend_register_internal_class_ex ( & ce_date , NULL ) ;
2005-11-18 05:05:30 +08:00
memcpy ( & date_object_handlers_date , zend_get_std_object_handlers ( ) , sizeof ( zend_object_handlers ) ) ;
2014-04-09 05:50:15 +08:00
date_object_handlers_date . offset = XtOffsetOf ( php_date_obj , std ) ;
2014-02-10 14:04:30 +08:00
date_object_handlers_date . free_obj = date_object_free_storage_date ;
2006-08-15 04:03:11 +08:00
date_object_handlers_date . clone_obj = date_object_clone_date ;
2007-03-05 22:05:55 +08:00
date_object_handlers_date . compare_objects = date_object_compare_date ;
2008-03-15 00:19:52 +08:00
date_object_handlers_date . get_properties = date_object_get_properties ;
2012-12-05 21:58:36 +08:00
date_object_handlers_date . get_gc = date_object_get_gc ;
2014-12-14 06:06:14 +08:00
zend_class_implements ( date_ce_date , 1 , date_ce_interface ) ;
2005-11-18 05:05:30 +08:00
# define REGISTER_DATE_CLASS_CONST_STRING(const_name, value) \
2014-12-14 06:06:14 +08:00
zend_declare_class_constant_stringl ( date_ce_date , const_name , sizeof ( const_name ) - 1 , value , sizeof ( value ) - 1 ) ;
2005-11-18 05:05:30 +08:00
2015-02-19 23:46:00 +08:00
REGISTER_DATE_CLASS_CONST_STRING ( " ATOM " , DATE_FORMAT_RFC3339 ) ;
REGISTER_DATE_CLASS_CONST_STRING ( " COOKIE " , DATE_FORMAT_COOKIE ) ;
REGISTER_DATE_CLASS_CONST_STRING ( " ISO8601 " , DATE_FORMAT_ISO8601 ) ;
REGISTER_DATE_CLASS_CONST_STRING ( " RFC822 " , DATE_FORMAT_RFC822 ) ;
REGISTER_DATE_CLASS_CONST_STRING ( " RFC850 " , DATE_FORMAT_RFC850 ) ;
REGISTER_DATE_CLASS_CONST_STRING ( " RFC1036 " , DATE_FORMAT_RFC1036 ) ;
REGISTER_DATE_CLASS_CONST_STRING ( " RFC1123 " , DATE_FORMAT_RFC1123 ) ;
2017-04-02 00:56:31 +08:00
REGISTER_DATE_CLASS_CONST_STRING ( " RFC7231 " , DATE_FORMAT_RFC7231 ) ;
2015-02-19 23:46:00 +08:00
REGISTER_DATE_CLASS_CONST_STRING ( " RFC2822 " , DATE_FORMAT_RFC2822 ) ;
REGISTER_DATE_CLASS_CONST_STRING ( " RFC3339 " , DATE_FORMAT_RFC3339 ) ;
REGISTER_DATE_CLASS_CONST_STRING ( " RFC3339_EXTENDED " , DATE_FORMAT_RFC3339_EXTENDED ) ;
REGISTER_DATE_CLASS_CONST_STRING ( " RSS " , DATE_FORMAT_RFC1123 ) ;
REGISTER_DATE_CLASS_CONST_STRING ( " W3C " , DATE_FORMAT_RFC3339 ) ;
2005-11-18 05:05:30 +08:00
2012-12-20 00:24:38 +08:00
INIT_CLASS_ENTRY ( ce_immutable , " DateTimeImmutable " , date_funcs_immutable ) ;
ce_immutable . create_object = date_object_new_date ;
2014-12-14 06:06:14 +08:00
date_ce_immutable = zend_register_internal_class_ex ( & ce_immutable , NULL ) ;
2012-12-20 00:24:38 +08:00
memcpy ( & date_object_handlers_immutable , zend_get_std_object_handlers ( ) , sizeof ( zend_object_handlers ) ) ;
date_object_handlers_immutable . clone_obj = date_object_clone_date ;
date_object_handlers_immutable . compare_objects = date_object_compare_date ;
date_object_handlers_immutable . get_properties = date_object_get_properties ;
2016-06-15 04:36:09 +08:00
date_object_handlers_immutable . get_gc = date_object_get_gc ;
2014-12-14 06:06:14 +08:00
zend_class_implements ( date_ce_immutable , 1 , date_ce_interface ) ;
2005-11-18 05:05:30 +08:00
2006-07-20 23:49:02 +08:00
INIT_CLASS_ENTRY ( ce_timezone , " DateTimeZone " , date_funcs_timezone ) ;
2005-11-18 05:05:30 +08:00
ce_timezone . create_object = date_object_new_timezone ;
2014-12-14 06:06:14 +08:00
date_ce_timezone = zend_register_internal_class_ex ( & ce_timezone , NULL ) ;
2005-11-18 05:05:30 +08:00
memcpy ( & date_object_handlers_timezone , zend_get_std_object_handlers ( ) , sizeof ( zend_object_handlers ) ) ;
2014-04-09 05:50:15 +08:00
date_object_handlers_timezone . offset = XtOffsetOf ( php_timezone_obj , std ) ;
2014-02-10 14:04:30 +08:00
date_object_handlers_timezone . free_obj = date_object_free_storage_timezone ;
2006-08-15 04:03:11 +08:00
date_object_handlers_timezone . clone_obj = date_object_clone_timezone ;
2012-09-28 20:15:20 +08:00
date_object_handlers_timezone . get_properties = date_object_get_properties_timezone ;
2013-01-15 07:03:52 +08:00
date_object_handlers_timezone . get_gc = date_object_get_gc_timezone ;
2008-01-28 01:29:14 +08:00
# define REGISTER_TIMEZONE_CLASS_CONST_STRING(const_name, value) \
2014-12-14 06:06:14 +08:00
zend_declare_class_constant_long ( date_ce_timezone , const_name , sizeof ( const_name ) - 1 , value ) ;
2008-01-28 01:29:14 +08:00
2008-02-27 17:47:35 +08:00
REGISTER_TIMEZONE_CLASS_CONST_STRING ( " AFRICA " , PHP_DATE_TIMEZONE_GROUP_AFRICA ) ;
2008-01-28 01:29:14 +08:00
REGISTER_TIMEZONE_CLASS_CONST_STRING ( " AMERICA " , PHP_DATE_TIMEZONE_GROUP_AMERICA ) ;
REGISTER_TIMEZONE_CLASS_CONST_STRING ( " ANTARCTICA " , PHP_DATE_TIMEZONE_GROUP_ANTARCTICA ) ;
REGISTER_TIMEZONE_CLASS_CONST_STRING ( " ARCTIC " , PHP_DATE_TIMEZONE_GROUP_ARCTIC ) ;
REGISTER_TIMEZONE_CLASS_CONST_STRING ( " ASIA " , PHP_DATE_TIMEZONE_GROUP_ASIA ) ;
REGISTER_TIMEZONE_CLASS_CONST_STRING ( " ATLANTIC " , PHP_DATE_TIMEZONE_GROUP_ATLANTIC ) ;
REGISTER_TIMEZONE_CLASS_CONST_STRING ( " AUSTRALIA " , PHP_DATE_TIMEZONE_GROUP_AUSTRALIA ) ;
REGISTER_TIMEZONE_CLASS_CONST_STRING ( " EUROPE " , PHP_DATE_TIMEZONE_GROUP_EUROPE ) ;
REGISTER_TIMEZONE_CLASS_CONST_STRING ( " INDIAN " , PHP_DATE_TIMEZONE_GROUP_INDIAN ) ;
REGISTER_TIMEZONE_CLASS_CONST_STRING ( " PACIFIC " , PHP_DATE_TIMEZONE_GROUP_PACIFIC ) ;
REGISTER_TIMEZONE_CLASS_CONST_STRING ( " UTC " , PHP_DATE_TIMEZONE_GROUP_UTC ) ;
REGISTER_TIMEZONE_CLASS_CONST_STRING ( " ALL " , PHP_DATE_TIMEZONE_GROUP_ALL ) ;
REGISTER_TIMEZONE_CLASS_CONST_STRING ( " ALL_WITH_BC " , PHP_DATE_TIMEZONE_GROUP_ALL_W_BC ) ;
2008-07-18 22:33:53 +08:00
REGISTER_TIMEZONE_CLASS_CONST_STRING ( " PER_COUNTRY " , PHP_DATE_TIMEZONE_PER_COUNTRY ) ;
2008-04-25 20:35:58 +08:00
INIT_CLASS_ENTRY ( ce_interval , " DateInterval " , date_funcs_interval ) ;
ce_interval . create_object = date_object_new_interval ;
2014-12-14 06:06:14 +08:00
date_ce_interval = zend_register_internal_class_ex ( & ce_interval , NULL ) ;
2008-04-25 20:35:58 +08:00
memcpy ( & date_object_handlers_interval , zend_get_std_object_handlers ( ) , sizeof ( zend_object_handlers ) ) ;
2014-04-09 05:50:15 +08:00
date_object_handlers_interval . offset = XtOffsetOf ( php_interval_obj , std ) ;
2014-02-10 14:04:30 +08:00
date_object_handlers_interval . free_obj = date_object_free_storage_interval ;
2008-04-25 20:35:58 +08:00
date_object_handlers_interval . clone_obj = date_object_clone_interval ;
2016-04-20 23:37:26 +08:00
date_object_handlers_interval . has_property = date_interval_has_property ;
2008-04-25 20:35:58 +08:00
date_object_handlers_interval . read_property = date_interval_read_property ;
date_object_handlers_interval . write_property = date_interval_write_property ;
2009-05-04 02:46:28 +08:00
date_object_handlers_interval . get_properties = date_object_get_properties_interval ;
2017-10-09 21:35:38 +08:00
date_object_handlers_interval . get_property_ptr_ptr = date_interval_get_property_ptr_ptr ;
2012-12-05 21:58:36 +08:00
date_object_handlers_interval . get_gc = date_object_get_gc_interval ;
2008-05-01 08:12:24 +08:00
INIT_CLASS_ENTRY ( ce_period , " DatePeriod " , date_funcs_period ) ;
ce_period . create_object = date_object_new_period ;
2014-12-14 06:06:14 +08:00
date_ce_period = zend_register_internal_class_ex ( & ce_period , NULL ) ;
2008-05-01 08:12:24 +08:00
date_ce_period - > get_iterator = date_object_period_get_iterator ;
date_ce_period - > iterator_funcs . funcs = & date_period_it_funcs ;
2014-12-14 06:06:14 +08:00
zend_class_implements ( date_ce_period , 1 , zend_ce_traversable ) ;
2008-05-01 08:12:24 +08:00
memcpy ( & date_object_handlers_period , zend_get_std_object_handlers ( ) , sizeof ( zend_object_handlers ) ) ;
2014-04-09 05:50:15 +08:00
date_object_handlers_period . offset = XtOffsetOf ( php_period_obj , std ) ;
2014-02-10 14:04:30 +08:00
date_object_handlers_period . free_obj = date_object_free_storage_period ;
2008-05-01 08:12:24 +08:00
date_object_handlers_period . clone_obj = date_object_clone_period ;
2013-03-15 23:59:54 +08:00
date_object_handlers_period . get_properties = date_object_get_properties_period ;
date_object_handlers_period . get_property_ptr_ptr = NULL ;
date_object_handlers_period . get_gc = date_object_get_gc_period ;
date_object_handlers_period . read_property = date_period_read_property ;
date_object_handlers_period . write_property = date_period_write_property ;
2008-05-01 21:31:22 +08:00
# define REGISTER_PERIOD_CLASS_CONST_STRING(const_name, value) \
2014-12-14 06:06:14 +08:00
zend_declare_class_constant_long ( date_ce_period , const_name , sizeof ( const_name ) - 1 , value ) ;
2008-05-01 21:31:22 +08:00
REGISTER_PERIOD_CLASS_CONST_STRING ( " EXCLUDE_START_DATE " , PHP_DATE_PERIOD_EXCLUDE_START_DATE ) ;
2014-03-16 17:14:31 +08:00
} /* }}} */
2005-11-18 05:05:30 +08:00
2014-12-14 06:06:14 +08:00
static inline zend_object * date_object_new_date_ex ( zend_class_entry * class_type , int init_props ) /* { { { */
2005-07-20 16:31:02 +08:00
{
php_date_obj * intern ;
2015-02-04 20:24:13 +08:00
intern = ecalloc ( 1 , sizeof ( php_date_obj ) + zend_object_properties_size ( class_type ) ) ;
2015-01-03 17:22:58 +08:00
2014-12-14 06:06:14 +08:00
zend_object_std_init ( & intern - > std , class_type ) ;
2014-03-16 18:09:27 +08:00
if ( init_props ) {
object_properties_init ( & intern - > std , class_type ) ;
}
2014-02-10 14:04:30 +08:00
intern - > std . handlers = & date_object_handlers_date ;
2015-01-03 17:22:58 +08:00
2014-03-16 17:14:31 +08:00
return & intern - > std ;
} /* }}} */
2005-07-20 16:31:02 +08:00
2014-12-14 06:06:14 +08:00
static zend_object * date_object_new_date ( zend_class_entry * class_type ) /* { { { */
2006-08-15 04:03:11 +08:00
{
2014-12-14 06:06:14 +08:00
return date_object_new_date_ex ( class_type , 1 ) ;
2014-03-16 17:14:31 +08:00
} /* }}} */
2006-08-15 04:03:11 +08:00
2014-12-14 06:06:14 +08:00
static zend_object * date_object_clone_date ( zval * this_ptr ) /* { { { */
2006-08-15 04:03:11 +08:00
{
2014-03-16 17:14:31 +08:00
php_date_obj * old_obj = Z_PHPDATE_P ( this_ptr ) ;
2014-12-14 06:06:14 +08:00
php_date_obj * new_obj = php_date_obj_from_obj ( date_object_new_date_ex ( old_obj - > std . ce , 0 ) ) ;
2015-01-03 17:22:58 +08:00
2014-12-14 06:06:14 +08:00
zend_objects_clone_members ( & new_obj - > std , & old_obj - > std ) ;
2011-08-30 21:41:57 +08:00
if ( ! old_obj - > time ) {
2014-03-16 17:14:31 +08:00
return & new_obj - > std ;
2011-08-30 21:41:57 +08:00
}
2015-01-03 17:22:58 +08:00
2006-08-15 04:03:11 +08:00
/* this should probably moved to a new `timelib_time *timelime_time_clone(timelib_time *)` */
new_obj - > time = timelib_time_ctor ( ) ;
* new_obj - > time = * old_obj - > time ;
if ( old_obj - > time - > tz_abbr ) {
2015-09-22 16:17:50 +08:00
new_obj - > time - > tz_abbr = timelib_strdup ( old_obj - > time - > tz_abbr ) ;
2006-08-15 04:03:11 +08:00
}
if ( old_obj - > time - > tz_info ) {
2008-07-09 01:41:51 +08:00
new_obj - > time - > tz_info = old_obj - > time - > tz_info ;
2006-08-15 04:03:11 +08:00
}
2015-01-03 17:22:58 +08:00
2014-03-16 17:14:31 +08:00
return & new_obj - > std ;
} /* }}} */
2006-08-15 04:03:11 +08:00
2014-12-14 06:06:14 +08:00
static void date_clone_immutable ( zval * object , zval * new_object ) /* { { { */
2012-12-17 23:31:23 +08:00
{
2014-12-14 06:06:14 +08:00
ZVAL_OBJ ( new_object , date_object_clone_date ( object ) ) ;
2014-03-16 17:14:31 +08:00
} /* }}} */
2012-12-17 23:31:23 +08:00
2014-12-14 06:06:14 +08:00
static int date_object_compare_date ( zval * d1 , zval * d2 ) /* { { { */
2007-03-05 22:05:55 +08:00
{
2014-03-16 17:14:31 +08:00
php_date_obj * o1 = Z_PHPDATE_P ( d1 ) ;
php_date_obj * o2 = Z_PHPDATE_P ( d2 ) ;
2013-09-12 07:15:54 +08:00
if ( ! o1 - > time | | ! o2 - > time ) {
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , E_WARNING , " Trying to compare an incomplete DateTime or DateTimeImmutable object " ) ;
2013-09-12 07:15:54 +08:00
return 1 ;
}
if ( ! o1 - > time - > sse_uptodate ) {
timelib_update_ts ( o1 - > time , o1 - > time - > tz_info ) ;
}
if ( ! o2 - > time - > sse_uptodate ) {
timelib_update_ts ( o2 - > time , o2 - > time - > tz_info ) ;
2007-03-05 22:05:55 +08:00
}
2015-01-03 17:22:58 +08:00
2016-01-29 22:28:11 +08:00
return timelib_time_compare ( o1 - > time , o2 - > time ) ;
2014-03-16 17:14:31 +08:00
} /* }}} */
2007-03-05 22:05:55 +08:00
2014-12-14 06:06:14 +08:00
static HashTable * date_object_get_gc ( zval * object , zval * * table , int * n ) /* { { { */
2012-12-05 21:58:36 +08:00
{
* table = NULL ;
* n = 0 ;
2014-12-14 06:06:14 +08:00
return zend_std_get_properties ( object ) ;
2014-03-16 17:14:31 +08:00
} /* }}} */
2012-12-05 21:58:36 +08:00
2014-12-14 06:06:14 +08:00
static HashTable * date_object_get_gc_timezone ( zval * object , zval * * table , int * n ) /* { { { */
2013-01-15 07:03:52 +08:00
{
* table = NULL ;
* n = 0 ;
2014-12-14 06:06:14 +08:00
return zend_std_get_properties ( object ) ;
2014-03-16 17:14:31 +08:00
} /* }}} */
2013-01-15 07:03:52 +08:00
2014-12-14 06:06:14 +08:00
static HashTable * date_object_get_properties ( zval * object ) /* { { { */
2008-03-15 00:19:52 +08:00
{
HashTable * props ;
2014-02-10 14:04:30 +08:00
zval zv ;
2008-03-15 00:19:52 +08:00
php_date_obj * dateobj ;
2014-03-16 17:14:31 +08:00
dateobj = Z_PHPDATE_P ( object ) ;
2008-03-15 00:19:52 +08:00
2014-12-14 06:06:14 +08:00
props = zend_std_get_properties ( object ) ;
2008-03-15 00:19:52 +08:00
2016-06-15 04:36:09 +08:00
if ( ! dateobj - > time ) {
2008-03-15 00:19:52 +08:00
return props ;
}
2008-07-09 01:55:59 +08:00
/* first we add the date and time in ISO format */
2014-12-14 06:06:14 +08:00
ZVAL_STR ( & zv , date_format ( " Y-m-d H:i:s.u " , sizeof ( " Y-m-d H:i:s.u " ) - 1 , dateobj - > time , 1 ) ) ;
2014-02-10 14:04:30 +08:00
zend_hash_str_update ( props , " date " , sizeof ( " date " ) - 1 , & zv ) ;
2008-03-15 00:19:52 +08:00
2008-07-09 01:55:59 +08:00
/* then we add the timezone name (or similar) */
2008-03-15 00:19:52 +08:00
if ( dateobj - > time - > is_localtime ) {
2014-08-26 01:24:55 +08:00
ZVAL_LONG ( & zv , dateobj - > time - > zone_type ) ;
2014-02-10 14:04:30 +08:00
zend_hash_str_update ( props , " timezone_type " , sizeof ( " timezone_type " ) - 1 , & zv ) ;
2008-03-15 00:19:52 +08:00
switch ( dateobj - > time - > zone_type ) {
case TIMELIB_ZONETYPE_ID :
2014-02-10 14:04:30 +08:00
ZVAL_STRING ( & zv , dateobj - > time - > tz_info - > name ) ;
2008-03-15 00:19:52 +08:00
break ;
case TIMELIB_ZONETYPE_OFFSET : {
2014-08-26 01:24:55 +08:00
zend_string * tmpstr = zend_string_alloc ( sizeof ( " UTC+05:00 " ) - 1 , 0 ) ;
2008-03-15 00:19:52 +08:00
timelib_sll utc_offset = dateobj - > time - > z ;
2015-06-30 09:05:24 +08:00
ZSTR_LEN ( tmpstr ) = snprintf ( ZSTR_VAL ( tmpstr ) , sizeof ( " +05:00 " ) , " %c%02d:%02d " ,
2017-08-16 22:19:18 +08:00
utc_offset > 0 ? ' - ' : ' + ' ,
abs ( utc_offset / 60 ) ,
abs ( ( utc_offset % 60 ) ) ) ;
2008-03-15 00:19:52 +08:00
2014-09-19 19:41:01 +08:00
ZVAL_NEW_STR ( & zv , tmpstr ) ;
2008-03-15 00:19:52 +08:00
}
break ;
case TIMELIB_ZONETYPE_ABBR :
2014-02-10 14:04:30 +08:00
ZVAL_STRING ( & zv , dateobj - > time - > tz_abbr ) ;
2008-03-15 00:19:52 +08:00
break ;
}
2014-02-10 14:04:30 +08:00
zend_hash_str_update ( props , " timezone " , sizeof ( " timezone " ) - 1 , & zv ) ;
2008-03-15 00:19:52 +08:00
}
return props ;
2014-03-16 17:14:31 +08:00
} /* }}} */
2008-03-15 00:19:52 +08:00
2014-12-14 06:06:14 +08:00
static inline zend_object * date_object_new_timezone_ex ( zend_class_entry * class_type , int init_props ) /* { { { */
2005-07-20 16:31:02 +08:00
{
php_timezone_obj * intern ;
2015-02-04 20:24:13 +08:00
intern = ecalloc ( 1 , sizeof ( php_timezone_obj ) + zend_object_properties_size ( class_type ) ) ;
2005-07-20 16:31:02 +08:00
2014-12-14 06:06:14 +08:00
zend_object_std_init ( & intern - > std , class_type ) ;
2014-03-16 18:09:27 +08:00
if ( init_props ) {
object_properties_init ( & intern - > std , class_type ) ;
}
2014-02-10 14:04:30 +08:00
intern - > std . handlers = & date_object_handlers_timezone ;
2015-01-03 17:22:58 +08:00
2014-03-16 17:14:31 +08:00
return & intern - > std ;
} /* }}} */
2005-07-20 16:31:02 +08:00
2014-12-14 06:06:14 +08:00
static zend_object * date_object_new_timezone ( zend_class_entry * class_type ) /* { { { */
2006-08-15 04:03:11 +08:00
{
2014-12-14 06:06:14 +08:00
return date_object_new_timezone_ex ( class_type , 1 ) ;
2014-03-16 17:14:31 +08:00
} /* }}} */
2006-08-15 04:03:11 +08:00
2014-12-14 06:06:14 +08:00
static zend_object * date_object_clone_timezone ( zval * this_ptr ) /* { { { */
2006-08-15 04:03:11 +08:00
{
2014-03-16 17:14:31 +08:00
php_timezone_obj * old_obj = Z_PHPTIMEZONE_P ( this_ptr ) ;
2014-12-14 06:06:14 +08:00
php_timezone_obj * new_obj = php_timezone_obj_from_obj ( date_object_new_timezone_ex ( old_obj - > std . ce , 0 ) ) ;
2015-01-03 17:22:58 +08:00
2014-12-14 06:06:14 +08:00
zend_objects_clone_members ( & new_obj - > std , & old_obj - > std ) ;
2011-08-30 21:41:57 +08:00
if ( ! old_obj - > initialized ) {
2014-03-16 17:14:31 +08:00
return & new_obj - > std ;
2011-08-30 21:41:57 +08:00
}
2015-01-03 17:22:58 +08:00
2008-01-18 02:49:45 +08:00
new_obj - > type = old_obj - > type ;
2008-01-18 03:59:00 +08:00
new_obj - > initialized = 1 ;
2008-01-18 02:49:45 +08:00
switch ( new_obj - > type ) {
case TIMELIB_ZONETYPE_ID :
new_obj - > tzi . tz = old_obj - > tzi . tz ;
break ;
case TIMELIB_ZONETYPE_OFFSET :
new_obj - > tzi . utc_offset = old_obj - > tzi . utc_offset ;
break ;
case TIMELIB_ZONETYPE_ABBR :
new_obj - > tzi . z . utc_offset = old_obj - > tzi . z . utc_offset ;
new_obj - > tzi . z . dst = old_obj - > tzi . z . dst ;
2015-09-22 16:17:50 +08:00
new_obj - > tzi . z . abbr = timelib_strdup ( old_obj - > tzi . z . abbr ) ;
2008-01-18 02:49:45 +08:00
break ;
}
2015-01-03 17:22:58 +08:00
2014-03-16 17:14:31 +08:00
return & new_obj - > std ;
} /* }}} */
2006-08-15 04:03:11 +08:00
2014-12-14 06:06:14 +08:00
static HashTable * date_object_get_properties_timezone ( zval * object ) /* { { { */
2012-09-28 20:15:20 +08:00
{
HashTable * props ;
2014-02-10 14:04:30 +08:00
zval zv ;
2012-09-28 20:15:20 +08:00
php_timezone_obj * tzobj ;
2014-03-16 17:14:31 +08:00
tzobj = Z_PHPTIMEZONE_P ( object ) ;
2012-09-28 20:15:20 +08:00
2014-12-14 06:06:14 +08:00
props = zend_std_get_properties ( object ) ;
2012-09-28 20:15:20 +08:00
2013-01-15 07:03:52 +08:00
if ( ! tzobj - > initialized ) {
2012-09-28 20:15:20 +08:00
return props ;
}
2014-08-26 01:24:55 +08:00
ZVAL_LONG ( & zv , tzobj - > type ) ;
2014-02-10 14:04:30 +08:00
zend_hash_str_update ( props , " timezone_type " , sizeof ( " timezone_type " ) - 1 , & zv ) ;
2012-09-28 20:15:20 +08:00
switch ( tzobj - > type ) {
case TIMELIB_ZONETYPE_ID :
2014-02-10 14:04:30 +08:00
ZVAL_STRING ( & zv , tzobj - > tzi . tz - > name ) ;
2012-09-28 20:15:20 +08:00
break ;
case TIMELIB_ZONETYPE_OFFSET : {
2014-08-26 01:24:55 +08:00
zend_string * tmpstr = zend_string_alloc ( sizeof ( " UTC+05:00 " ) - 1 , 0 ) ;
2012-09-28 20:15:20 +08:00
2015-06-30 09:05:24 +08:00
ZSTR_LEN ( tmpstr ) = snprintf ( ZSTR_VAL ( tmpstr ) , sizeof ( " +05:00 " ) , " %c%02d:%02d " ,
2017-08-16 22:19:18 +08:00
tzobj - > tzi . utc_offset > 0 ? ' - ' : ' + ' ,
abs ( tzobj - > tzi . utc_offset / 60 ) ,
abs ( ( tzobj - > tzi . utc_offset % 60 ) ) ) ;
2012-09-28 20:15:20 +08:00
2014-09-19 19:41:01 +08:00
ZVAL_NEW_STR ( & zv , tmpstr ) ;
2012-09-28 20:15:20 +08:00
}
break ;
case TIMELIB_ZONETYPE_ABBR :
2014-02-10 14:04:30 +08:00
ZVAL_STRING ( & zv , tzobj - > tzi . z . abbr ) ;
2012-09-28 20:15:20 +08:00
break ;
}
2014-02-10 14:04:30 +08:00
zend_hash_str_update ( props , " timezone " , sizeof ( " timezone " ) - 1 , & zv ) ;
2012-09-28 20:15:20 +08:00
return props ;
2014-03-16 17:14:31 +08:00
} /* }}} */
2012-09-28 20:15:20 +08:00
2014-12-14 06:06:14 +08:00
static inline zend_object * date_object_new_interval_ex ( zend_class_entry * class_type , int init_props ) /* { { { */
2008-04-25 20:35:58 +08:00
{
php_interval_obj * intern ;
2015-02-04 20:24:13 +08:00
intern = ecalloc ( 1 , sizeof ( php_interval_obj ) + zend_object_properties_size ( class_type ) ) ;
2008-04-25 20:35:58 +08:00
2014-12-14 06:06:14 +08:00
zend_object_std_init ( & intern - > std , class_type ) ;
2014-03-16 18:09:27 +08:00
if ( init_props ) {
object_properties_init ( & intern - > std , class_type ) ;
}
2014-02-10 14:04:30 +08:00
intern - > std . handlers = & date_object_handlers_interval ;
2015-01-03 17:22:58 +08:00
2014-03-16 17:14:31 +08:00
return & intern - > std ;
} /* }}} */
2008-04-25 20:35:58 +08:00
2014-12-14 06:06:14 +08:00
static zend_object * date_object_new_interval ( zend_class_entry * class_type ) /* { { { */
2008-04-25 20:35:58 +08:00
{
2014-12-14 06:06:14 +08:00
return date_object_new_interval_ex ( class_type , 1 ) ;
2014-03-16 17:14:31 +08:00
} /* }}} */
2008-04-25 20:35:58 +08:00
2014-12-14 06:06:14 +08:00
static zend_object * date_object_clone_interval ( zval * this_ptr ) /* { { { */
2008-04-25 20:35:58 +08:00
{
2014-03-16 17:14:31 +08:00
php_interval_obj * old_obj = Z_PHPINTERVAL_P ( this_ptr ) ;
2014-12-14 06:06:14 +08:00
php_interval_obj * new_obj = php_interval_obj_from_obj ( date_object_new_interval_ex ( old_obj - > std . ce , 0 ) ) ;
2015-01-03 17:22:58 +08:00
2014-12-14 06:06:14 +08:00
zend_objects_clone_members ( & new_obj - > std , & old_obj - > std ) ;
2008-04-25 20:35:58 +08:00
/** FIX ME ADD CLONE STUFF **/
2014-03-16 17:14:31 +08:00
return & new_obj - > std ;
} /* }}} */
2008-04-25 20:35:58 +08:00
2014-12-14 06:06:14 +08:00
static HashTable * date_object_get_gc_interval ( zval * object , zval * * table , int * n ) /* { { { */
2012-12-05 21:58:36 +08:00
{
* table = NULL ;
* n = 0 ;
2014-12-14 06:06:14 +08:00
return zend_std_get_properties ( object ) ;
2014-03-16 17:14:31 +08:00
} /* }}} */
2012-12-05 21:58:36 +08:00
2014-12-14 06:06:14 +08:00
static HashTable * date_object_get_properties_interval ( zval * object ) /* { { { */
2009-05-04 02:46:28 +08:00
{
HashTable * props ;
2014-02-10 14:04:30 +08:00
zval zv ;
2009-05-04 02:46:28 +08:00
php_interval_obj * intervalobj ;
2014-03-16 17:14:31 +08:00
intervalobj = Z_PHPINTERVAL_P ( object ) ;
2009-05-04 02:46:28 +08:00
2014-12-14 06:06:14 +08:00
props = zend_std_get_properties ( object ) ;
2009-05-04 02:46:28 +08:00
2012-12-05 21:58:36 +08:00
if ( ! intervalobj - > initialized ) {
2009-06-25 23:07:36 +08:00
return props ;
}
2009-05-04 02:46:28 +08:00
# define PHP_DATE_INTERVAL_ADD_PROPERTY(n,f) \
2014-08-26 01:24:55 +08:00
ZVAL_LONG ( & zv , ( zend_long ) intervalobj - > diff - > f ) ; \
2014-02-10 14:04:30 +08:00
zend_hash_str_update ( props , n , sizeof ( n ) - 1 , & zv ) ;
2009-05-04 02:46:28 +08:00
PHP_DATE_INTERVAL_ADD_PROPERTY ( " y " , y ) ;
PHP_DATE_INTERVAL_ADD_PROPERTY ( " m " , m ) ;
PHP_DATE_INTERVAL_ADD_PROPERTY ( " d " , d ) ;
PHP_DATE_INTERVAL_ADD_PROPERTY ( " h " , h ) ;
PHP_DATE_INTERVAL_ADD_PROPERTY ( " i " , i ) ;
PHP_DATE_INTERVAL_ADD_PROPERTY ( " s " , s ) ;
2013-03-15 23:59:54 +08:00
PHP_DATE_INTERVAL_ADD_PROPERTY ( " weekday " , weekday ) ;
PHP_DATE_INTERVAL_ADD_PROPERTY ( " weekday_behavior " , weekday_behavior ) ;
PHP_DATE_INTERVAL_ADD_PROPERTY ( " first_last_day_of " , first_last_day_of ) ;
2009-05-04 02:46:28 +08:00
PHP_DATE_INTERVAL_ADD_PROPERTY ( " invert " , invert ) ;
2010-03-07 23:26:39 +08:00
if ( intervalobj - > diff - > days ! = - 99999 ) {
2013-06-10 23:48:13 +08:00
PHP_DATE_INTERVAL_ADD_PROPERTY ( " days " , days ) ;
2010-03-07 23:26:39 +08:00
} else {
2014-02-10 14:04:30 +08:00
ZVAL_FALSE ( & zv ) ;
zend_hash_str_update ( props , " days " , sizeof ( " days " ) - 1 , & zv ) ;
2010-03-07 23:26:39 +08:00
}
2013-03-15 23:59:54 +08:00
PHP_DATE_INTERVAL_ADD_PROPERTY ( " special_type " , special . type ) ;
2013-06-10 23:48:13 +08:00
PHP_DATE_INTERVAL_ADD_PROPERTY ( " special_amount " , special . amount ) ;
2013-03-15 23:59:54 +08:00
PHP_DATE_INTERVAL_ADD_PROPERTY ( " have_weekday_relative " , have_weekday_relative ) ;
PHP_DATE_INTERVAL_ADD_PROPERTY ( " have_special_relative " , have_special_relative ) ;
2009-05-04 02:46:28 +08:00
return props ;
2014-03-16 17:14:31 +08:00
} /* }}} */
2009-05-04 02:46:28 +08:00
2014-12-14 06:06:14 +08:00
static inline zend_object * date_object_new_period_ex ( zend_class_entry * class_type , int init_props ) /* { { { */
2008-05-01 08:12:24 +08:00
{
php_period_obj * intern ;
2015-02-04 20:24:13 +08:00
intern = ecalloc ( 1 , sizeof ( php_period_obj ) + zend_object_properties_size ( class_type ) ) ;
2008-05-01 08:12:24 +08:00
2014-12-14 06:06:14 +08:00
zend_object_std_init ( & intern - > std , class_type ) ;
2014-03-16 18:09:27 +08:00
if ( init_props ) {
object_properties_init ( & intern - > std , class_type ) ;
}
2014-08-14 12:15:24 +08:00
2014-02-10 14:04:30 +08:00
intern - > std . handlers = & date_object_handlers_period ;
2015-01-03 17:22:58 +08:00
2014-03-16 17:14:31 +08:00
return & intern - > std ;
} /* }}} */
2008-05-01 08:12:24 +08:00
2014-12-14 06:06:14 +08:00
static zend_object * date_object_new_period ( zend_class_entry * class_type ) /* { { { */
2008-05-01 08:12:24 +08:00
{
2014-12-14 06:06:14 +08:00
return date_object_new_period_ex ( class_type , 1 ) ;
2014-03-16 17:14:31 +08:00
} /* }}} */
2008-05-01 08:12:24 +08:00
2014-12-14 06:06:14 +08:00
static zend_object * date_object_clone_period ( zval * this_ptr ) /* { { { */
2008-05-01 08:12:24 +08:00
{
2014-03-16 17:14:31 +08:00
php_period_obj * old_obj = Z_PHPPERIOD_P ( this_ptr ) ;
2014-12-14 06:06:14 +08:00
php_period_obj * new_obj = php_period_obj_from_obj ( date_object_new_period_ex ( old_obj - > std . ce , 0 ) ) ;
2015-01-03 17:22:58 +08:00
2014-12-14 06:06:14 +08:00
zend_objects_clone_members ( & new_obj - > std , & old_obj - > std ) ;
2008-05-01 08:12:24 +08:00
/** FIX ME ADD CLONE STUFF **/
2014-03-16 17:14:31 +08:00
return & new_obj - > std ;
} /* }}} */
2008-05-01 08:12:24 +08:00
2014-12-14 06:06:14 +08:00
static void date_object_free_storage_date ( zend_object * object ) /* { { { */
2005-07-20 16:31:02 +08:00
{
2014-03-16 17:14:31 +08:00
php_date_obj * intern = php_date_obj_from_obj ( object ) ;
2005-07-20 16:31:02 +08:00
2005-11-15 22:08:03 +08:00
if ( intern - > time ) {
timelib_time_dtor ( intern - > time ) ;
2005-07-20 16:31:02 +08:00
}
2014-12-14 06:06:14 +08:00
zend_object_std_dtor ( & intern - > std ) ;
2014-03-16 17:14:31 +08:00
} /* }}} */
2005-07-20 16:31:02 +08:00
2014-12-14 06:06:14 +08:00
static void date_object_free_storage_timezone ( zend_object * object ) /* { { { */
2005-07-20 16:31:02 +08:00
{
2014-03-16 17:14:31 +08:00
php_timezone_obj * intern = php_timezone_obj_from_obj ( object ) ;
2005-12-19 21:00:37 +08:00
2008-01-18 02:49:45 +08:00
if ( intern - > type = = TIMELIB_ZONETYPE_ABBR ) {
2015-09-22 16:17:50 +08:00
timelib_free ( intern - > tzi . z . abbr ) ;
2008-01-18 02:49:45 +08:00
}
2014-12-14 06:06:14 +08:00
zend_object_std_dtor ( & intern - > std ) ;
2014-03-16 17:14:31 +08:00
} /* }}} */
2005-07-20 16:31:02 +08:00
2014-12-14 06:06:14 +08:00
static void date_object_free_storage_interval ( zend_object * object ) /* { { { */
2008-04-25 20:35:58 +08:00
{
2014-03-16 17:14:31 +08:00
php_interval_obj * intern = php_interval_obj_from_obj ( object ) ;
2008-04-25 20:35:58 +08:00
timelib_rel_time_dtor ( intern - > diff ) ;
2014-12-14 06:06:14 +08:00
zend_object_std_dtor ( & intern - > std ) ;
2014-03-16 17:14:31 +08:00
} /* }}} */
2008-04-25 20:35:58 +08:00
2014-12-14 06:06:14 +08:00
static void date_object_free_storage_period ( zend_object * object ) /* { { { */
2008-05-01 08:12:24 +08:00
{
2014-03-16 17:14:31 +08:00
php_period_obj * intern = php_period_obj_from_obj ( object ) ;
2008-05-01 08:12:24 +08:00
if ( intern - > start ) {
timelib_time_dtor ( intern - > start ) ;
}
2010-08-30 23:32:09 +08:00
if ( intern - > current ) {
timelib_time_dtor ( intern - > current ) ;
}
2008-05-01 08:12:24 +08:00
if ( intern - > end ) {
timelib_time_dtor ( intern - > end ) ;
}
timelib_rel_time_dtor ( intern - > interval ) ;
2014-12-14 06:06:14 +08:00
zend_object_std_dtor ( & intern - > std ) ;
2014-03-16 17:14:31 +08:00
} /* }}} */
2008-05-01 08:12:24 +08:00
2005-07-20 16:31:02 +08:00
/* Advanced Interface */
2014-12-14 06:06:14 +08:00
PHPAPI zval * php_date_instantiate ( zend_class_entry * pce , zval * object ) /* { { { */
2005-07-20 16:31:02 +08:00
{
object_init_ex ( object , pce ) ;
return object ;
2014-03-16 17:14:31 +08:00
} /* }}} */
2005-07-20 16:31:02 +08:00
2008-01-13 23:16:02 +08:00
/* Helper function used to store the latest found warnings and errors while
* parsing , from either strtotime or parse_from_format . */
2014-12-14 06:06:14 +08:00
static void update_errors_warnings ( timelib_error_container * last_errors ) /* { { { */
2008-01-13 23:16:02 +08:00
{
if ( DATEG ( last_errors ) ) {
timelib_error_container_dtor ( DATEG ( last_errors ) ) ;
DATEG ( last_errors ) = NULL ;
}
DATEG ( last_errors ) = last_errors ;
2014-03-16 17:14:31 +08:00
} /* }}} */
2008-01-13 23:16:02 +08:00
2014-12-14 06:06:14 +08:00
PHPAPI int php_date_initialize ( php_date_obj * dateobj , /*const*/ char * time_str , size_t time_str_len , char * format , zval * timezone_object , int ctor ) /* { { { */
2005-07-20 16:31:02 +08:00
{
timelib_time * now ;
2011-08-08 02:12:52 +08:00
timelib_tzinfo * tzi = NULL ;
2006-08-01 23:55:03 +08:00
timelib_error_container * err = NULL ;
2013-08-15 11:36:50 +08:00
int type = TIMELIB_ZONETYPE_ID , new_dst = 0 ;
char * new_abbr = NULL ;
2014-04-22 21:46:34 +08:00
timelib_sll new_offset = 0 ;
2015-01-03 17:22:58 +08:00
2006-08-01 23:55:03 +08:00
if ( dateobj - > time ) {
timelib_time_dtor ( dateobj - > time ) ;
}
2008-01-13 23:16:02 +08:00
if ( format ) {
2011-12-06 14:21:08 +08:00
dateobj - > time = timelib_parse_from_format ( format , time_str_len ? time_str : " " , time_str_len ? time_str_len : 0 , & err , DATE_TIMEZONEDB , php_date_parse_tzfile_wrapper ) ;
2008-01-13 23:16:02 +08:00
} else {
2011-12-06 14:21:08 +08:00
dateobj - > time = timelib_strtotime ( time_str_len ? time_str : " now " , time_str_len ? time_str_len : sizeof ( " now " ) - 1 , & err , DATE_TIMEZONEDB , php_date_parse_tzfile_wrapper ) ;
2006-08-01 23:55:03 +08:00
}
2005-07-20 16:31:02 +08:00
2008-07-09 01:55:59 +08:00
/* update last errors and warnings */
2014-12-14 06:06:14 +08:00
update_errors_warnings ( err ) ;
2008-01-13 23:16:02 +08:00
2008-01-18 04:35:02 +08:00
if ( ctor & & err & & err - > error_count ) {
/* spit out the first library error message, at least */
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , E_WARNING , " Failed to parse time string (%s) at position %d (%c): %s " , time_str ,
2008-01-18 04:35:02 +08:00
err - > error_messages [ 0 ] . position , err - > error_messages [ 0 ] . character , err - > error_messages [ 0 ] . message ) ;
}
if ( err & & err - > error_count ) {
2014-06-05 19:39:46 +08:00
timelib_time_dtor ( dateobj - > time ) ;
dateobj - > time = 0 ;
2008-01-18 04:35:02 +08:00
return 0 ;
}
2005-07-20 16:31:02 +08:00
if ( timezone_object ) {
php_timezone_obj * tzobj ;
2014-03-16 17:14:31 +08:00
tzobj = Z_PHPTIMEZONE_P ( timezone_object ) ;
2008-01-18 02:49:45 +08:00
switch ( tzobj - > type ) {
case TIMELIB_ZONETYPE_ID :
2008-07-09 01:41:51 +08:00
tzi = tzobj - > tzi . tz ;
2008-01-18 02:49:45 +08:00
break ;
case TIMELIB_ZONETYPE_OFFSET :
new_offset = tzobj - > tzi . utc_offset ;
break ;
case TIMELIB_ZONETYPE_ABBR :
new_offset = tzobj - > tzi . z . utc_offset ;
new_dst = tzobj - > tzi . z . dst ;
2015-09-22 16:17:50 +08:00
new_abbr = timelib_strdup ( tzobj - > tzi . z . abbr ) ;
2008-01-18 02:49:45 +08:00
break ;
}
type = tzobj - > type ;
2005-07-20 16:31:02 +08:00
} else if ( dateobj - > time - > tz_info ) {
2008-07-09 01:41:51 +08:00
tzi = dateobj - > time - > tz_info ;
2005-07-20 16:31:02 +08:00
} else {
2014-12-14 06:06:14 +08:00
tzi = get_timezone_info ( ) ;
2005-07-20 16:31:02 +08:00
}
now = timelib_time_ctor ( ) ;
2008-01-18 02:49:45 +08:00
now - > zone_type = type ;
switch ( type ) {
case TIMELIB_ZONETYPE_ID :
now - > tz_info = tzi ;
break ;
case TIMELIB_ZONETYPE_OFFSET :
now - > z = new_offset ;
break ;
case TIMELIB_ZONETYPE_ABBR :
now - > z = new_offset ;
now - > dst = new_dst ;
now - > tz_abbr = new_abbr ;
break ;
}
2005-12-19 21:00:37 +08:00
timelib_unixtime2local ( now , ( timelib_sll ) time ( NULL ) ) ;
2005-07-20 16:31:02 +08:00
2009-07-01 00:17:30 +08:00
timelib_fill_holes ( dateobj - > time , now , TIMELIB_NO_CLONE ) ;
2005-07-20 16:31:02 +08:00
timelib_update_ts ( dateobj - > time , tzi ) ;
2013-04-01 01:11:35 +08:00
timelib_update_from_sse ( dateobj - > time ) ;
2005-07-20 16:31:02 +08:00
2008-05-02 00:15:45 +08:00
dateobj - > time - > have_relative = 0 ;
2006-12-12 05:04:40 +08:00
2008-01-18 04:35:02 +08:00
timelib_time_dtor ( now ) ;
return 1 ;
2014-03-16 17:14:31 +08:00
} /* }}} */
2005-07-20 16:31:02 +08:00
2006-09-11 01:01:51 +08:00
/* {{{ proto DateTime date_create([string time[, DateTimeZone object]])
2006-11-03 22:38:45 +08:00
Returns new DateTime object
2006-09-11 01:01:51 +08:00
*/
2006-08-01 21:28:28 +08:00
PHP_FUNCTION ( date_create )
{
zval * timezone_object = NULL ;
char * time_str = NULL ;
2014-08-27 23:31:24 +08:00
size_t time_str_len = 0 ;
2006-08-01 21:28:28 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " |sO! " , & time_str , & time_str_len , & timezone_object , date_ce_timezone ) = = FAILURE ) {
2006-08-01 21:28:28 +08:00
RETURN_FALSE ;
}
2015-06-12 17:33:23 +08:00
php_date_instantiate ( date_ce_date , return_value ) ;
if ( ! php_date_initialize ( Z_PHPDATE_P ( return_value ) , time_str , time_str_len , NULL , timezone_object , 0 ) ) {
zval_ptr_dtor ( return_value ) ;
2008-01-18 04:35:02 +08:00
RETURN_FALSE ;
}
2008-01-13 23:16:02 +08:00
}
/* }}} */
2012-12-20 00:24:38 +08:00
/* {{{ proto DateTime date_create_immutable([string time[, DateTimeZone object]])
2012-12-17 23:31:23 +08:00
Returns new DateTime object
*/
2012-12-20 00:24:38 +08:00
PHP_FUNCTION ( date_create_immutable )
2012-12-17 23:31:23 +08:00
{
zval * timezone_object = NULL ;
char * time_str = NULL ;
2014-08-27 23:31:24 +08:00
size_t time_str_len = 0 ;
2012-12-17 23:31:23 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " |sO! " , & time_str , & time_str_len , & timezone_object , date_ce_timezone ) = = FAILURE ) {
2012-12-17 23:31:23 +08:00
RETURN_FALSE ;
}
2015-06-12 17:33:23 +08:00
php_date_instantiate ( date_ce_immutable , return_value ) ;
if ( ! php_date_initialize ( Z_PHPDATE_P ( return_value ) , time_str , time_str_len , NULL , timezone_object , 0 ) ) {
zval_ptr_dtor ( return_value ) ;
2012-12-17 23:31:23 +08:00
RETURN_FALSE ;
}
}
/* }}} */
2008-05-02 20:49:16 +08:00
/* {{{ proto DateTime date_create_from_format(string format, string time[, DateTimeZone object])
Returns new DateTime object formatted according to the specified format
2008-01-13 23:16:02 +08:00
*/
PHP_FUNCTION ( date_create_from_format )
{
zval * timezone_object = NULL ;
char * time_str = NULL , * format_str = NULL ;
2014-08-27 21:31:48 +08:00
size_t time_str_len = 0 , format_str_len = 0 ;
2008-01-13 23:16:02 +08:00
2014-12-31 05:54:02 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " ss|O! " , & format_str , & format_str_len , & time_str , & time_str_len , & timezone_object , date_ce_timezone ) = = FAILURE ) {
2008-01-13 23:16:02 +08:00
RETURN_FALSE ;
}
2015-06-12 17:33:23 +08:00
php_date_instantiate ( date_ce_date , return_value ) ;
if ( ! php_date_initialize ( Z_PHPDATE_P ( return_value ) , time_str , time_str_len , format_str , timezone_object , 0 ) ) {
zval_ptr_dtor ( return_value ) ;
2008-01-18 04:35:02 +08:00
RETURN_FALSE ;
}
2006-08-01 21:28:28 +08:00
}
2006-09-11 01:01:51 +08:00
/* }}} */
2006-08-01 21:28:28 +08:00
2012-12-20 00:24:38 +08:00
/* {{{ proto DateTime date_create_immutable_from_format(string format, string time[, DateTimeZone object])
2012-12-17 23:31:23 +08:00
Returns new DateTime object formatted according to the specified format
*/
2012-12-20 00:24:38 +08:00
PHP_FUNCTION ( date_create_immutable_from_format )
2012-12-17 23:31:23 +08:00
{
zval * timezone_object = NULL ;
char * time_str = NULL , * format_str = NULL ;
2014-08-27 23:31:24 +08:00
size_t time_str_len = 0 , format_str_len = 0 ;
2012-12-17 23:31:23 +08:00
2014-12-31 05:54:02 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " ss|O! " , & format_str , & format_str_len , & time_str , & time_str_len , & timezone_object , date_ce_timezone ) = = FAILURE ) {
2012-12-17 23:31:23 +08:00
RETURN_FALSE ;
}
2015-06-12 17:33:23 +08:00
php_date_instantiate ( date_ce_immutable , return_value ) ;
if ( ! php_date_initialize ( Z_PHPDATE_P ( return_value ) , time_str , time_str_len , format_str , timezone_object , 0 ) ) {
zval_ptr_dtor ( return_value ) ;
2012-12-17 23:31:23 +08:00
RETURN_FALSE ;
}
}
/* }}} */
2006-09-11 01:01:51 +08:00
/* {{{ proto DateTime::__construct([string time[, DateTimeZone object]])
2006-11-03 22:38:45 +08:00
Creates new DateTime object
2006-09-11 01:01:51 +08:00
*/
2006-08-01 21:28:28 +08:00
PHP_METHOD ( DateTime , __construct )
{
zval * timezone_object = NULL ;
char * time_str = NULL ;
2014-08-27 23:31:24 +08:00
size_t time_str_len = 0 ;
2008-11-19 10:00:53 +08:00
zend_error_handling error_handling ;
2008-08-09 06:07:07 +08:00
2015-04-03 00:52:32 +08:00
if ( FAILURE = = zend_parse_parameters_throw ( ZEND_NUM_ARGS ( ) , " |sO! " , & time_str , & time_str_len , & timezone_object , date_ce_timezone ) ) {
return ;
2006-08-01 21:28:28 +08:00
}
2015-04-03 00:52:32 +08:00
zend_replace_error_handling ( EH_THROW , NULL , & error_handling ) ;
php_date_initialize ( Z_PHPDATE_P ( getThis ( ) ) , time_str , time_str_len , NULL , timezone_object , 1 ) ;
2014-12-14 06:06:14 +08:00
zend_restore_error_handling ( & error_handling ) ;
2006-08-01 21:28:28 +08:00
}
2006-09-11 01:01:51 +08:00
/* }}} */
2006-08-01 21:28:28 +08:00
2012-12-20 00:24:38 +08:00
/* {{{ proto DateTimeImmutable::__construct([string time[, DateTimeZone object]])
Creates new DateTimeImmutable object
2012-12-17 23:31:23 +08:00
*/
2012-12-20 00:24:38 +08:00
PHP_METHOD ( DateTimeImmutable , __construct )
2012-12-17 23:31:23 +08:00
{
zval * timezone_object = NULL ;
char * time_str = NULL ;
2014-08-27 23:31:24 +08:00
size_t time_str_len = 0 ;
2012-12-17 23:31:23 +08:00
zend_error_handling error_handling ;
2015-04-03 00:52:32 +08:00
if ( FAILURE = = zend_parse_parameters_throw ( ZEND_NUM_ARGS ( ) , " |sO! " , & time_str , & time_str_len , & timezone_object , date_ce_timezone ) ) {
return ;
2012-12-17 23:31:23 +08:00
}
2015-04-03 00:52:32 +08:00
zend_replace_error_handling ( EH_THROW , NULL , & error_handling ) ;
php_date_initialize ( Z_PHPDATE_P ( getThis ( ) ) , time_str , time_str_len , NULL , timezone_object , 1 ) ;
2014-12-14 06:06:14 +08:00
zend_restore_error_handling ( & error_handling ) ;
2012-12-17 23:31:23 +08:00
}
/* }}} */
2014-03-03 03:17:16 +08:00
/* {{{ proto DateTimeImmutable::createFromMutable(DateTimeZone object)
Creates new DateTimeImmutable object from an existing mutable DateTime object .
*/
PHP_METHOD ( DateTimeImmutable , createFromMutable )
{
zval * datetime_object = NULL ;
php_date_obj * new_obj = NULL ;
php_date_obj * old_obj = NULL ;
2015-03-23 12:05:39 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " O " , & datetime_object , date_ce_date ) = = FAILURE ) {
2014-03-03 03:17:16 +08:00
return ;
}
2014-12-14 06:06:14 +08:00
php_date_instantiate ( date_ce_immutable , return_value ) ;
2014-04-26 04:32:51 +08:00
old_obj = Z_PHPDATE_P ( datetime_object ) ;
new_obj = Z_PHPDATE_P ( return_value ) ;
2014-03-03 03:17:16 +08:00
new_obj - > time = timelib_time_ctor ( ) ;
* new_obj - > time = * old_obj - > time ;
if ( old_obj - > time - > tz_abbr ) {
2015-09-22 16:17:50 +08:00
new_obj - > time - > tz_abbr = timelib_strdup ( old_obj - > time - > tz_abbr ) ;
2014-03-03 03:17:16 +08:00
}
if ( old_obj - > time - > tz_info ) {
new_obj - > time - > tz_info = old_obj - > time - > tz_info ;
}
}
/* }}} */
2014-12-14 06:06:14 +08:00
static int php_date_initialize_from_hash ( php_date_obj * * dateobj , HashTable * myht )
2008-03-15 00:19:52 +08:00
{
2014-02-10 14:04:30 +08:00
zval * z_date ;
zval * z_timezone ;
zval * z_timezone_type ;
zval tmp_obj ;
2008-03-15 00:19:52 +08:00
timelib_tzinfo * tzi ;
php_timezone_obj * tzobj ;
2014-02-10 14:04:30 +08:00
z_date = zend_hash_str_find ( myht , " date " , sizeof ( " data " ) - 1 ) ;
2015-02-17 14:02:20 +08:00
if ( z_date & & Z_TYPE_P ( z_date ) = = IS_STRING ) {
2014-02-10 14:04:30 +08:00
z_timezone_type = zend_hash_str_find ( myht , " timezone_type " , sizeof ( " timezone_type " ) - 1 ) ;
2015-02-17 14:02:20 +08:00
if ( z_timezone_type & & Z_TYPE_P ( z_timezone_type ) = = IS_LONG ) {
2014-02-10 14:04:30 +08:00
z_timezone = zend_hash_str_find ( myht , " timezone " , sizeof ( " timezone " ) - 1 ) ;
2015-02-17 14:02:20 +08:00
if ( z_timezone & & Z_TYPE_P ( z_timezone ) = = IS_STRING ) {
2014-08-26 01:24:55 +08:00
switch ( Z_LVAL_P ( z_timezone_type ) ) {
2008-03-15 00:19:52 +08:00
case TIMELIB_ZONETYPE_OFFSET :
case TIMELIB_ZONETYPE_ABBR : {
2014-08-26 01:24:55 +08:00
char * tmp = emalloc ( Z_STRLEN_P ( z_date ) + Z_STRLEN_P ( z_timezone ) + 2 ) ;
2013-03-16 04:22:35 +08:00
int ret ;
2014-08-26 01:24:55 +08:00
snprintf ( tmp , Z_STRLEN_P ( z_date ) + Z_STRLEN_P ( z_timezone ) + 2 , " %s %s " , Z_STRVAL_P ( z_date ) , Z_STRVAL_P ( z_timezone ) ) ;
2014-12-14 06:06:14 +08:00
ret = php_date_initialize ( * dateobj , tmp , Z_STRLEN_P ( z_date ) + Z_STRLEN_P ( z_timezone ) + 1 , NULL , NULL , 0 ) ;
2008-03-15 00:19:52 +08:00
efree ( tmp ) ;
2013-03-16 04:22:35 +08:00
return 1 = = ret ;
2008-03-15 00:19:52 +08:00
}
2013-03-16 04:22:35 +08:00
case TIMELIB_ZONETYPE_ID : {
int ret ;
2008-03-15 00:19:52 +08:00
2014-12-14 06:06:14 +08:00
tzi = php_date_parse_tzfile ( Z_STRVAL_P ( z_timezone ) , DATE_TIMEZONEDB ) ;
2008-03-15 00:19:52 +08:00
2014-02-17 08:07:52 +08:00
if ( tzi = = NULL ) {
return 0 ;
}
2014-12-14 06:06:14 +08:00
tzobj = Z_PHPTIMEZONE_P ( php_date_instantiate ( date_ce_timezone , & tmp_obj ) ) ;
2008-03-15 00:19:52 +08:00
tzobj - > type = TIMELIB_ZONETYPE_ID ;
tzobj - > tzi . tz = tzi ;
tzobj - > initialized = 1 ;
2014-12-14 06:06:14 +08:00
ret = php_date_initialize ( * dateobj , Z_STRVAL_P ( z_date ) , Z_STRLEN_P ( z_date ) , NULL , & tmp_obj , 0 ) ;
2009-04-08 04:05:50 +08:00
zval_ptr_dtor ( & tmp_obj ) ;
2013-03-16 04:22:35 +08:00
return 1 = = ret ;
}
2008-03-15 00:19:52 +08:00
}
}
}
}
return 0 ;
2014-03-16 17:14:31 +08:00
} /* }}} */
2008-03-15 00:19:52 +08:00
/* {{{ proto DateTime::__set_state()
*/
PHP_METHOD ( DateTime , __set_state )
{
php_date_obj * dateobj ;
zval * array ;
HashTable * myht ;
2014-12-14 06:06:14 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " a " , & array ) = = FAILURE ) {
2008-03-15 00:19:52 +08:00
RETURN_FALSE ;
}
2015-09-25 03:39:59 +08:00
myht = Z_ARRVAL_P ( array ) ;
2008-03-15 00:19:52 +08:00
2014-12-14 06:06:14 +08:00
php_date_instantiate ( date_ce_date , return_value ) ;
2014-03-16 17:14:31 +08:00
dateobj = Z_PHPDATE_P ( return_value ) ;
2014-12-14 06:06:14 +08:00
if ( ! php_date_initialize_from_hash ( & dateobj , myht ) ) {
2013-03-16 04:22:35 +08:00
php_error ( E_ERROR , " Invalid serialization data for DateTime object " ) ;
}
2008-03-15 00:19:52 +08:00
}
/* }}} */
2012-12-20 00:24:38 +08:00
/* {{{ proto DateTimeImmutable::__set_state()
2012-12-17 23:31:23 +08:00
*/
2012-12-20 00:24:38 +08:00
PHP_METHOD ( DateTimeImmutable , __set_state )
2012-12-17 23:31:23 +08:00
{
php_date_obj * dateobj ;
zval * array ;
HashTable * myht ;
2014-12-14 06:06:14 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " a " , & array ) = = FAILURE ) {
2012-12-17 23:31:23 +08:00
RETURN_FALSE ;
}
2015-09-25 03:39:59 +08:00
myht = Z_ARRVAL_P ( array ) ;
2012-12-17 23:31:23 +08:00
2014-12-14 06:06:14 +08:00
php_date_instantiate ( date_ce_immutable , return_value ) ;
2014-03-16 17:14:31 +08:00
dateobj = Z_PHPDATE_P ( return_value ) ;
2014-12-14 06:06:14 +08:00
if ( ! php_date_initialize_from_hash ( & dateobj , myht ) ) {
2013-03-16 04:22:35 +08:00
php_error ( E_ERROR , " Invalid serialization data for DateTimeImmutable object " ) ;
}
2012-12-17 23:31:23 +08:00
}
/* }}} */
2008-03-15 00:19:52 +08:00
/* {{{ proto DateTime::__wakeup()
*/
PHP_METHOD ( DateTime , __wakeup )
{
zval * object = getThis ( ) ;
php_date_obj * dateobj ;
HashTable * myht ;
2014-03-16 17:14:31 +08:00
dateobj = Z_PHPDATE_P ( object ) ;
2008-03-15 00:19:52 +08:00
myht = Z_OBJPROP_P ( object ) ;
2014-12-14 06:06:14 +08:00
if ( ! php_date_initialize_from_hash ( & dateobj , myht ) ) {
2013-03-31 20:07:14 +08:00
php_error ( E_ERROR , " Invalid serialization data for DateTime object " ) ;
2013-03-16 04:22:35 +08:00
}
2008-03-15 00:19:52 +08:00
}
/* }}} */
2008-01-13 23:16:02 +08:00
/* Helper function used to add an associative array of warnings and errors to a zval */
2014-03-16 17:14:31 +08:00
static void zval_from_error_container ( zval * z , timelib_error_container * error ) /* { { { */
2008-01-13 23:16:02 +08:00
{
int i ;
2014-02-10 14:04:30 +08:00
zval element ;
2008-01-13 23:16:02 +08:00
2014-08-26 01:24:55 +08:00
add_assoc_long ( z , " warning_count " , error - > warning_count ) ;
2014-02-10 14:04:30 +08:00
array_init ( & element ) ;
2008-01-13 23:16:02 +08:00
for ( i = 0 ; i < error - > warning_count ; i + + ) {
2014-04-15 19:40:40 +08:00
add_index_string ( & element , error - > warning_messages [ i ] . position , error - > warning_messages [ i ] . message ) ;
2008-01-13 23:16:02 +08:00
}
2014-02-10 14:04:30 +08:00
add_assoc_zval ( z , " warnings " , & element ) ;
2008-01-13 23:16:02 +08:00
2014-08-26 01:24:55 +08:00
add_assoc_long ( z , " error_count " , error - > error_count ) ;
2014-02-10 14:04:30 +08:00
array_init ( & element ) ;
2008-01-13 23:16:02 +08:00
for ( i = 0 ; i < error - > error_count ; i + + ) {
2014-04-15 19:40:40 +08:00
add_index_string ( & element , error - > error_messages [ i ] . position , error - > error_messages [ i ] . message ) ;
2008-01-13 23:16:02 +08:00
}
2014-02-10 14:04:30 +08:00
add_assoc_zval ( z , " errors " , & element ) ;
2014-03-16 17:14:31 +08:00
} /* }}} */
2008-01-13 23:16:02 +08:00
2008-07-09 20:50:57 +08:00
/* {{{ proto array date_get_last_errors()
2008-01-13 23:16:02 +08:00
Returns the warnings and errors found while parsing a date / time string .
2006-09-11 01:01:51 +08:00
*/
2008-01-13 23:16:02 +08:00
PHP_FUNCTION ( date_get_last_errors )
2006-04-12 02:03:52 +08:00
{
2008-01-13 23:16:02 +08:00
if ( DATEG ( last_errors ) ) {
2008-03-07 10:04:40 +08:00
array_init ( return_value ) ;
2008-01-13 23:16:02 +08:00
zval_from_error_container ( return_value , DATEG ( last_errors ) ) ;
} else {
2006-04-12 02:03:52 +08:00
RETURN_FALSE ;
}
2008-01-13 23:16:02 +08:00
}
/* }}} */
2014-03-16 17:14:31 +08:00
void php_date_do_return_parsed_time ( INTERNAL_FUNCTION_PARAMETERS , timelib_time * parsed_time , struct timelib_error_container * error ) /* { { { */
2008-01-13 23:16:02 +08:00
{
2014-02-10 14:04:30 +08:00
zval element ;
2006-04-12 02:03:52 +08:00
array_init ( return_value ) ;
# define PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT(name, elem) \
2007-07-13 02:59:05 +08:00
if ( parsed_time - > elem = = - 99999 ) { \
2006-04-12 02:03:52 +08:00
add_assoc_bool ( return_value , # name , 0 ) ; \
} else { \
2014-08-26 01:24:55 +08:00
add_assoc_long ( return_value , # name , parsed_time - > elem ) ; \
2006-04-12 02:03:52 +08:00
}
PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT ( year , y ) ;
PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT ( month , m ) ;
PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT ( day , d ) ;
PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT ( hour , h ) ;
PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT ( minute , i ) ;
PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT ( second , s ) ;
2015-01-03 17:22:58 +08:00
2017-08-16 22:19:18 +08:00
if ( parsed_time - > f = = - 99999 ) {
2006-04-12 02:03:52 +08:00
add_assoc_bool ( return_value , " fraction " , 0 ) ;
} else {
2017-08-16 22:19:18 +08:00
add_assoc_double ( return_value , " fraction " , parsed_time - > f ) ;
2006-04-12 02:03:52 +08:00
}
2008-01-13 23:16:02 +08:00
zval_from_error_container ( return_value , error ) ;
2006-04-12 02:03:52 +08:00
timelib_error_container_dtor ( error ) ;
add_assoc_bool ( return_value , " is_localtime " , parsed_time - > is_localtime ) ;
if ( parsed_time - > is_localtime ) {
PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT ( zone_type , zone_type ) ;
switch ( parsed_time - > zone_type ) {
case TIMELIB_ZONETYPE_OFFSET :
PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT ( zone , z ) ;
add_assoc_bool ( return_value , " is_dst " , parsed_time - > dst ) ;
break ;
case TIMELIB_ZONETYPE_ID :
if ( parsed_time - > tz_abbr ) {
2014-04-15 19:40:40 +08:00
add_assoc_string ( return_value , " tz_abbr " , parsed_time - > tz_abbr ) ;
2006-04-12 02:03:52 +08:00
}
if ( parsed_time - > tz_info ) {
2014-04-15 19:40:40 +08:00
add_assoc_string ( return_value , " tz_id " , parsed_time - > tz_info - > name ) ;
2006-04-12 02:03:52 +08:00
}
break ;
case TIMELIB_ZONETYPE_ABBR :
PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT ( zone , z ) ;
add_assoc_bool ( return_value , " is_dst " , parsed_time - > dst ) ;
2014-04-15 19:40:40 +08:00
add_assoc_string ( return_value , " tz_abbr " , parsed_time - > tz_abbr ) ;
2006-04-12 02:03:52 +08:00
break ;
}
}
2008-05-02 00:15:45 +08:00
if ( parsed_time - > have_relative ) {
2014-02-10 14:04:30 +08:00
array_init ( & element ) ;
2014-08-26 01:24:55 +08:00
add_assoc_long ( & element , " year " , parsed_time - > relative . y ) ;
add_assoc_long ( & element , " month " , parsed_time - > relative . m ) ;
add_assoc_long ( & element , " day " , parsed_time - > relative . d ) ;
add_assoc_long ( & element , " hour " , parsed_time - > relative . h ) ;
add_assoc_long ( & element , " minute " , parsed_time - > relative . i ) ;
add_assoc_long ( & element , " second " , parsed_time - > relative . s ) ;
2008-05-02 00:15:45 +08:00
if ( parsed_time - > relative . have_weekday_relative ) {
2014-08-26 01:24:55 +08:00
add_assoc_long ( & element , " weekday " , parsed_time - > relative . weekday ) ;
2008-05-02 00:15:45 +08:00
}
if ( parsed_time - > relative . have_special_relative & & ( parsed_time - > relative . special . type = = TIMELIB_SPECIAL_WEEKDAY ) ) {
2014-08-26 01:24:55 +08:00
add_assoc_long ( & element , " weekdays " , parsed_time - > relative . special . amount ) ;
2008-05-02 00:15:45 +08:00
}
if ( parsed_time - > relative . first_last_day_of ) {
2015-03-31 23:36:51 +08:00
add_assoc_bool ( & element , parsed_time - > relative . first_last_day_of = = TIMELIB_SPECIAL_FIRST_DAY_OF_MONTH ? " first_day_of_month " : " last_day_of_month " , 1 ) ;
2008-05-02 00:15:45 +08:00
}
2014-02-10 14:04:30 +08:00
add_assoc_zval ( return_value , " relative " , & element ) ;
2006-04-12 02:03:52 +08:00
}
timelib_time_dtor ( parsed_time ) ;
2014-03-16 17:14:31 +08:00
} /* }}} */
2008-01-13 23:16:02 +08:00
/* {{{ proto array date_parse(string date)
Returns associative array with detailed info about given date
*/
PHP_FUNCTION ( date_parse )
{
char * date ;
2014-08-27 23:31:24 +08:00
size_t date_len ;
2008-01-13 23:16:02 +08:00
struct timelib_error_container * error ;
timelib_time * parsed_time ;
2015-01-03 17:22:58 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " s " , & date , & date_len ) = = FAILURE ) {
2008-01-13 23:16:02 +08:00
RETURN_FALSE ;
}
2011-12-06 14:21:08 +08:00
parsed_time = timelib_strtotime ( date , date_len , & error , DATE_TIMEZONEDB , php_date_parse_tzfile_wrapper ) ;
2008-01-13 23:16:02 +08:00
php_date_do_return_parsed_time ( INTERNAL_FUNCTION_PARAM_PASSTHRU , parsed_time , error ) ;
}
2006-06-11 09:42:17 +08:00
/* }}} */
2006-04-12 02:03:52 +08:00
2008-07-09 20:50:57 +08:00
/* {{{ proto array date_parse_from_format(string format, string date)
2008-01-13 23:16:02 +08:00
Returns associative array with detailed info about given date
*/
PHP_FUNCTION ( date_parse_from_format )
{
char * date , * format ;
2014-08-27 23:31:24 +08:00
size_t date_len , format_len ;
2008-01-13 23:16:02 +08:00
struct timelib_error_container * error ;
timelib_time * parsed_time ;
2015-01-03 17:22:58 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " ss " , & format , & format_len , & date , & date_len ) = = FAILURE ) {
2008-01-13 23:16:02 +08:00
RETURN_FALSE ;
}
2011-12-06 14:21:08 +08:00
parsed_time = timelib_parse_from_format ( format , date , date_len , & error , DATE_TIMEZONEDB , php_date_parse_tzfile_wrapper ) ;
2008-01-13 23:16:02 +08:00
php_date_do_return_parsed_time ( INTERNAL_FUNCTION_PARAM_PASSTHRU , parsed_time , error ) ;
}
2008-01-29 04:35:17 +08:00
/* }}} */
2008-01-13 23:16:02 +08:00
2013-03-31 17:37:16 +08:00
/* {{{ proto string date_format(DateTimeInterface object, string format)
2006-11-03 22:38:45 +08:00
Returns date formatted according to given format
2006-09-11 01:01:51 +08:00
*/
2005-07-20 16:31:02 +08:00
PHP_FUNCTION ( date_format )
{
zval * object ;
php_date_obj * dateobj ;
char * format ;
2014-08-27 23:31:24 +08:00
size_t format_len ;
2005-07-20 16:31:02 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_method_parameters ( ZEND_NUM_ARGS ( ) , getThis ( ) , " Os " , & object , date_ce_interface , & format , & format_len ) = = FAILURE ) {
2005-07-20 16:31:02 +08:00
RETURN_FALSE ;
}
2014-03-16 17:14:31 +08:00
dateobj = Z_PHPDATE_P ( object ) ;
2006-08-01 21:28:28 +08:00
DATE_CHECK_INITIALIZED ( dateobj - > time , DateTime ) ;
2014-12-14 06:06:14 +08:00
RETURN_STR ( date_format ( format , format_len , dateobj - > time , dateobj - > time - > is_localtime ) ) ;
2005-07-20 16:31:02 +08:00
}
2006-09-11 01:01:51 +08:00
/* }}} */
2005-07-20 16:31:02 +08:00
2014-12-14 06:06:14 +08:00
static int php_date_modify ( zval * object , char * modify , size_t modify_len ) /* { { { */
2005-07-20 16:31:02 +08:00
{
php_date_obj * dateobj ;
timelib_time * tmp_time ;
2010-02-11 00:23:30 +08:00
timelib_error_container * err = NULL ;
2005-07-20 16:31:02 +08:00
2014-03-16 17:14:31 +08:00
dateobj = Z_PHPDATE_P ( object ) ;
2013-01-18 15:49:36 +08:00
if ( ! ( dateobj - > time ) ) {
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , E_WARNING , " The DateTime object has not been correctly initialized by its constructor " ) ;
2013-01-18 15:49:36 +08:00
return 0 ;
}
2005-07-20 16:31:02 +08:00
2011-12-06 14:21:08 +08:00
tmp_time = timelib_strtotime ( modify , modify_len , & err , DATE_TIMEZONEDB , php_date_parse_tzfile_wrapper ) ;
2010-02-11 00:23:30 +08:00
/* update last errors and warnings */
2014-12-14 06:06:14 +08:00
update_errors_warnings ( err ) ;
2010-02-11 00:23:30 +08:00
if ( err & & err - > error_count ) {
/* spit out the first library error message, at least */
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , E_WARNING , " Failed to parse time string (%s) at position %d (%c): %s " , modify ,
2010-02-11 00:23:30 +08:00
err - > error_messages [ 0 ] . position , err - > error_messages [ 0 ] . character , err - > error_messages [ 0 ] . message ) ;
timelib_time_dtor ( tmp_time ) ;
2013-01-18 15:49:36 +08:00
return 0 ;
2010-02-11 00:23:30 +08:00
}
2008-07-31 02:00:44 +08:00
memcpy ( & dateobj - > time - > relative , & tmp_time - > relative , sizeof ( struct timelib_rel_time ) ) ;
2005-07-20 16:31:02 +08:00
dateobj - > time - > have_relative = tmp_time - > have_relative ;
dateobj - > time - > sse_uptodate = 0 ;
2010-12-16 05:45:25 +08:00
if ( tmp_time - > y ! = - 99999 ) {
dateobj - > time - > y = tmp_time - > y ;
}
if ( tmp_time - > m ! = - 99999 ) {
dateobj - > time - > m = tmp_time - > m ;
}
if ( tmp_time - > d ! = - 99999 ) {
dateobj - > time - > d = tmp_time - > d ;
}
if ( tmp_time - > h ! = - 99999 ) {
dateobj - > time - > h = tmp_time - > h ;
if ( tmp_time - > i ! = - 99999 ) {
dateobj - > time - > i = tmp_time - > i ;
if ( tmp_time - > s ! = - 99999 ) {
dateobj - > time - > s = tmp_time - > s ;
} else {
dateobj - > time - > s = 0 ;
}
} else {
dateobj - > time - > i = 0 ;
dateobj - > time - > s = 0 ;
}
}
2005-07-20 16:31:02 +08:00
timelib_time_dtor ( tmp_time ) ;
timelib_update_ts ( dateobj - > time , NULL ) ;
timelib_update_from_sse ( dateobj - > time ) ;
2008-12-19 04:32:23 +08:00
dateobj - > time - > have_relative = 0 ;
2016-02-05 05:13:57 +08:00
memset ( & dateobj - > time - > relative , 0 , sizeof ( dateobj - > time - > relative ) ) ;
2015-01-03 17:22:58 +08:00
2013-01-18 15:49:36 +08:00
return 1 ;
2014-03-16 17:14:31 +08:00
} /* }}} */
2008-07-31 02:00:44 +08:00
2012-12-17 23:31:23 +08:00
/* {{{ proto DateTime date_modify(DateTime object, string modify)
Alters the timestamp .
*/
PHP_FUNCTION ( date_modify )
{
zval * object ;
char * modify ;
2014-08-27 23:31:24 +08:00
size_t modify_len ;
2012-12-17 23:31:23 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_method_parameters ( ZEND_NUM_ARGS ( ) , getThis ( ) , " Os " , & object , date_ce_date , & modify , & modify_len ) = = FAILURE ) {
2012-12-17 23:31:23 +08:00
RETURN_FALSE ;
}
2015-06-12 17:33:23 +08:00
if ( ! php_date_modify ( object , modify , modify_len ) ) {
RETURN_FALSE ;
2013-01-18 15:49:36 +08:00
}
2012-12-17 23:31:23 +08:00
2015-06-12 18:33:14 +08:00
Z_ADDREF_P ( object ) ;
ZVAL_COPY_VALUE ( return_value , object ) ;
2005-07-20 16:31:02 +08:00
}
2006-09-11 01:01:51 +08:00
/* }}} */
2005-07-20 16:31:02 +08:00
2012-12-20 00:24:38 +08:00
/* {{{ proto DateTimeImmutable::modify()
2008-04-25 20:35:58 +08:00
*/
2012-12-20 00:24:38 +08:00
PHP_METHOD ( DateTimeImmutable , modify )
2008-04-25 20:35:58 +08:00
{
2014-02-10 14:04:30 +08:00
zval * object , new_object ;
2012-12-17 23:31:23 +08:00
char * modify ;
2014-08-27 23:31:24 +08:00
size_t modify_len ;
2008-04-25 20:35:58 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_method_parameters ( ZEND_NUM_ARGS ( ) , getThis ( ) , " Os " , & object , date_ce_immutable , & modify , & modify_len ) = = FAILURE ) {
2008-04-25 20:35:58 +08:00
RETURN_FALSE ;
}
2015-01-03 17:22:58 +08:00
2014-12-14 06:06:14 +08:00
date_clone_immutable ( object , & new_object ) ;
2015-06-12 17:33:23 +08:00
if ( ! php_date_modify ( & new_object , modify , modify_len ) ) {
RETURN_FALSE ;
2013-01-18 15:49:36 +08:00
}
2012-12-17 23:31:23 +08:00
2015-06-12 17:33:23 +08:00
ZVAL_COPY_VALUE ( return_value , & new_object ) ;
2012-12-17 23:31:23 +08:00
}
/* }}} */
2014-12-14 06:06:14 +08:00
static void php_date_add ( zval * object , zval * interval , zval * return_value ) /* { { { */
2012-12-17 23:31:23 +08:00
{
php_date_obj * dateobj ;
php_interval_obj * intobj ;
2014-01-02 20:45:48 +08:00
timelib_time * new_time ;
2012-12-17 23:31:23 +08:00
2014-03-16 17:14:31 +08:00
dateobj = Z_PHPDATE_P ( object ) ;
2008-04-25 20:35:58 +08:00
DATE_CHECK_INITIALIZED ( dateobj - > time , DateTime ) ;
2014-03-16 17:14:31 +08:00
intobj = Z_PHPINTERVAL_P ( interval ) ;
2008-04-25 20:35:58 +08:00
DATE_CHECK_INITIALIZED ( intobj - > initialized , DateInterval ) ;
2014-01-02 20:45:48 +08:00
new_time = timelib_add ( dateobj - > time , intobj - > diff ) ;
timelib_time_dtor ( dateobj - > time ) ;
dateobj - > time = new_time ;
2014-03-16 17:14:31 +08:00
} /* }}} */
2012-12-17 23:31:23 +08:00
/* {{{ proto DateTime date_add(DateTime object, DateInterval interval)
Adds an interval to the current date in object .
*/
PHP_FUNCTION ( date_add )
{
zval * object , * interval ;
2014-12-14 06:06:14 +08:00
if ( zend_parse_method_parameters ( ZEND_NUM_ARGS ( ) , getThis ( ) , " OO " , & object , date_ce_date , & interval , date_ce_interval ) = = FAILURE ) {
2012-12-17 23:31:23 +08:00
RETURN_FALSE ;
}
2014-12-14 06:06:14 +08:00
php_date_add ( object , interval , return_value ) ;
2008-08-04 00:45:15 +08:00
2015-06-12 18:33:14 +08:00
Z_ADDREF_P ( object ) ;
ZVAL_COPY_VALUE ( return_value , object ) ;
2008-04-25 20:35:58 +08:00
}
/* }}} */
2012-12-20 00:24:38 +08:00
/* {{{ proto DateTimeImmutable::add()
2008-04-25 20:35:58 +08:00
*/
2012-12-20 00:24:38 +08:00
PHP_METHOD ( DateTimeImmutable , add )
2008-04-25 20:35:58 +08:00
{
2014-02-10 14:04:30 +08:00
zval * object , * interval , new_object ;
2008-04-25 20:35:58 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_method_parameters ( ZEND_NUM_ARGS ( ) , getThis ( ) , " OO " , & object , date_ce_immutable , & interval , date_ce_interval ) = = FAILURE ) {
2008-04-25 20:35:58 +08:00
RETURN_FALSE ;
}
2012-12-17 23:31:23 +08:00
2014-12-14 06:06:14 +08:00
date_clone_immutable ( object , & new_object ) ;
php_date_add ( & new_object , interval , return_value ) ;
2012-12-17 23:31:23 +08:00
2015-06-12 17:33:23 +08:00
ZVAL_COPY_VALUE ( return_value , & new_object ) ;
2012-12-17 23:31:23 +08:00
}
/* }}} */
2014-12-14 06:06:14 +08:00
static void php_date_sub ( zval * object , zval * interval , zval * return_value ) /* { { { */
2012-12-17 23:31:23 +08:00
{
php_date_obj * dateobj ;
php_interval_obj * intobj ;
2014-01-02 20:45:48 +08:00
timelib_time * new_time ;
2012-12-17 23:31:23 +08:00
2014-03-16 17:14:31 +08:00
dateobj = Z_PHPDATE_P ( object ) ;
2008-04-25 20:35:58 +08:00
DATE_CHECK_INITIALIZED ( dateobj - > time , DateTime ) ;
2014-03-16 17:14:31 +08:00
intobj = Z_PHPINTERVAL_P ( interval ) ;
2008-04-25 20:35:58 +08:00
DATE_CHECK_INITIALIZED ( intobj - > initialized , DateInterval ) ;
2010-03-07 21:54:46 +08:00
if ( intobj - > diff - > have_special_relative ) {
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , E_WARNING , " Only non-special relative time specifications are supported for subtraction " ) ;
2010-03-07 21:54:46 +08:00
return ;
}
2014-01-02 20:45:48 +08:00
new_time = timelib_sub ( dateobj - > time , intobj - > diff ) ;
timelib_time_dtor ( dateobj - > time ) ;
dateobj - > time = new_time ;
2014-03-16 17:14:31 +08:00
} /* }}} */
2012-12-17 23:31:23 +08:00
/* {{{ proto DateTime date_sub(DateTime object, DateInterval interval)
Subtracts an interval to the current date in object .
*/
PHP_FUNCTION ( date_sub )
{
zval * object , * interval ;
2014-12-14 06:06:14 +08:00
if ( zend_parse_method_parameters ( ZEND_NUM_ARGS ( ) , getThis ( ) , " OO " , & object , date_ce_date , & interval , date_ce_interval ) = = FAILURE ) {
2012-12-17 23:31:23 +08:00
RETURN_FALSE ;
}
2014-12-14 06:06:14 +08:00
php_date_sub ( object , interval , return_value ) ;
2010-03-08 01:25:16 +08:00
2015-06-12 18:33:14 +08:00
Z_ADDREF_P ( object ) ;
ZVAL_COPY_VALUE ( return_value , object ) ;
2008-04-25 20:35:58 +08:00
}
/* }}} */
2012-12-20 00:24:38 +08:00
/* {{{ proto DateTimeImmutable::sub()
2012-12-17 23:31:23 +08:00
*/
2012-12-20 00:24:38 +08:00
PHP_METHOD ( DateTimeImmutable , sub )
2012-12-17 23:31:23 +08:00
{
2014-02-10 14:04:30 +08:00
zval * object , * interval , new_object ;
2012-12-17 23:31:23 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_method_parameters ( ZEND_NUM_ARGS ( ) , getThis ( ) , " OO " , & object , date_ce_immutable , & interval , date_ce_interval ) = = FAILURE ) {
2012-12-17 23:31:23 +08:00
RETURN_FALSE ;
}
2014-12-14 06:06:14 +08:00
date_clone_immutable ( object , & new_object ) ;
php_date_sub ( & new_object , interval , return_value ) ;
2012-12-17 23:31:23 +08:00
2015-06-12 17:33:23 +08:00
ZVAL_COPY_VALUE ( return_value , & new_object ) ;
2012-12-17 23:31:23 +08:00
}
/* }}} */
2014-02-06 10:00:13 +08:00
static void set_timezone_from_timelib_time ( php_timezone_obj * tzobj , timelib_time * t )
{
tzobj - > initialized = 1 ;
tzobj - > type = t - > zone_type ;
switch ( t - > zone_type ) {
case TIMELIB_ZONETYPE_ID :
tzobj - > tzi . tz = t - > tz_info ;
break ;
case TIMELIB_ZONETYPE_OFFSET :
tzobj - > tzi . utc_offset = t - > z ;
break ;
case TIMELIB_ZONETYPE_ABBR :
tzobj - > tzi . z . utc_offset = t - > z ;
tzobj - > tzi . z . dst = t - > dst ;
2015-09-22 16:17:50 +08:00
tzobj - > tzi . z . abbr = timelib_strdup ( t - > tz_abbr ) ;
2014-02-06 10:00:13 +08:00
break ;
}
}
2013-03-31 17:37:16 +08:00
/* {{{ proto DateTimeZone date_timezone_get(DateTimeInterface object)
2006-11-03 22:38:45 +08:00
Return new DateTimeZone object relative to give DateTime
2006-09-11 01:01:51 +08:00
*/
2005-07-20 16:31:02 +08:00
PHP_FUNCTION ( date_timezone_get )
{
zval * object ;
php_date_obj * dateobj ;
php_timezone_obj * tzobj ;
2014-12-14 06:06:14 +08:00
if ( zend_parse_method_parameters ( ZEND_NUM_ARGS ( ) , getThis ( ) , " O " , & object , date_ce_interface ) = = FAILURE ) {
2005-07-20 16:31:02 +08:00
RETURN_FALSE ;
}
2014-03-16 17:14:31 +08:00
dateobj = Z_PHPDATE_P ( object ) ;
2006-08-01 21:28:28 +08:00
DATE_CHECK_INITIALIZED ( dateobj - > time , DateTime ) ;
2008-01-18 02:49:45 +08:00
if ( dateobj - > time - > is_localtime /* && dateobj->time->tz_info*/ ) {
2014-12-14 06:06:14 +08:00
php_date_instantiate ( date_ce_timezone , return_value ) ;
2014-03-16 17:14:31 +08:00
tzobj = Z_PHPTIMEZONE_P ( return_value ) ;
2014-02-06 10:00:13 +08:00
set_timezone_from_timelib_time ( tzobj , dateobj - > time ) ;
2005-07-20 16:31:02 +08:00
} else {
RETURN_FALSE ;
}
}
2006-09-11 01:01:51 +08:00
/* }}} */
2005-07-20 16:31:02 +08:00
2014-12-14 06:06:14 +08:00
static void php_date_timezone_set ( zval * object , zval * timezone_object , zval * return_value ) /* { { { */
2005-07-20 16:31:02 +08:00
{
php_date_obj * dateobj ;
php_timezone_obj * tzobj ;
2014-03-16 17:14:31 +08:00
dateobj = Z_PHPDATE_P ( object ) ;
2006-08-01 21:28:28 +08:00
DATE_CHECK_INITIALIZED ( dateobj - > time , DateTime ) ;
2014-03-16 17:14:31 +08:00
tzobj = Z_PHPTIMEZONE_P ( timezone_object ) ;
2014-01-26 20:58:13 +08:00
switch ( tzobj - > type ) {
case TIMELIB_ZONETYPE_OFFSET :
timelib_set_timezone_from_offset ( dateobj - > time , tzobj - > tzi . utc_offset ) ;
break ;
case TIMELIB_ZONETYPE_ABBR :
timelib_set_timezone_from_abbr ( dateobj - > time , tzobj - > tzi . z ) ;
break ;
case TIMELIB_ZONETYPE_ID :
timelib_set_timezone ( dateobj - > time , tzobj - > tzi . tz ) ;
break ;
2008-01-18 02:49:45 +08:00
}
2005-12-19 21:00:37 +08:00
timelib_unixtime2local ( dateobj - > time , dateobj - > time - > sse ) ;
2014-03-16 17:14:31 +08:00
} /* }}} */
2012-12-17 23:31:23 +08:00
/* {{{ proto DateTime date_timezone_set(DateTime object, DateTimeZone object)
Sets the timezone for the DateTime object .
*/
PHP_FUNCTION ( date_timezone_set )
{
zval * object ;
zval * timezone_object ;
2014-12-14 06:06:14 +08:00
if ( zend_parse_method_parameters ( ZEND_NUM_ARGS ( ) , getThis ( ) , " OO " , & object , date_ce_date , & timezone_object , date_ce_timezone ) = = FAILURE ) {
2012-12-17 23:31:23 +08:00
RETURN_FALSE ;
}
2014-12-14 06:06:14 +08:00
php_date_timezone_set ( object , timezone_object , return_value ) ;
2008-07-31 02:00:44 +08:00
2015-06-12 18:33:14 +08:00
Z_ADDREF_P ( object ) ;
ZVAL_COPY_VALUE ( return_value , object ) ;
2005-07-20 16:31:02 +08:00
}
2006-09-11 01:01:51 +08:00
/* }}} */
2005-07-05 05:27:26 +08:00
2012-12-20 00:24:38 +08:00
/* {{{ proto DateTimeImmutable::setTimezone()
2012-12-17 23:31:23 +08:00
*/
2012-12-20 00:24:38 +08:00
PHP_METHOD ( DateTimeImmutable , setTimezone )
2012-12-17 23:31:23 +08:00
{
2014-02-10 14:04:30 +08:00
zval * object , new_object ;
2012-12-17 23:31:23 +08:00
zval * timezone_object ;
2014-12-14 06:06:14 +08:00
if ( zend_parse_method_parameters ( ZEND_NUM_ARGS ( ) , getThis ( ) , " OO " , & object , date_ce_immutable , & timezone_object , date_ce_timezone ) = = FAILURE ) {
2012-12-17 23:31:23 +08:00
RETURN_FALSE ;
}
2014-12-14 06:06:14 +08:00
date_clone_immutable ( object , & new_object ) ;
php_date_timezone_set ( & new_object , timezone_object , return_value ) ;
2012-12-17 23:31:23 +08:00
2015-06-12 17:33:23 +08:00
ZVAL_COPY_VALUE ( return_value , & new_object ) ;
2012-12-17 23:31:23 +08:00
}
/* }}} */
2013-03-31 17:37:16 +08:00
/* {{{ proto long date_offset_get(DateTimeInterface object)
2006-11-03 22:38:45 +08:00
Returns the DST offset .
2006-09-11 01:01:51 +08:00
*/
2005-07-20 16:31:02 +08:00
PHP_FUNCTION ( date_offset_get )
{
zval * object ;
php_date_obj * dateobj ;
timelib_time_offset * offset ;
2014-12-14 06:06:14 +08:00
if ( zend_parse_method_parameters ( ZEND_NUM_ARGS ( ) , getThis ( ) , " O " , & object , date_ce_interface ) = = FAILURE ) {
2005-07-20 16:31:02 +08:00
RETURN_FALSE ;
}
2014-03-16 17:14:31 +08:00
dateobj = Z_PHPDATE_P ( object ) ;
2006-08-01 21:28:28 +08:00
DATE_CHECK_INITIALIZED ( dateobj - > time , DateTime ) ;
2008-01-18 02:49:45 +08:00
if ( dateobj - > time - > is_localtime /* && dateobj->time->tz_info*/ ) {
switch ( dateobj - > time - > zone_type ) {
case TIMELIB_ZONETYPE_ID :
offset = timelib_get_time_zone_info ( dateobj - > time - > sse , dateobj - > time - > tz_info ) ;
2014-08-26 01:24:55 +08:00
RETVAL_LONG ( offset - > offset ) ;
2008-01-18 02:49:45 +08:00
timelib_time_offset_dtor ( offset ) ;
break ;
case TIMELIB_ZONETYPE_OFFSET :
2017-08-16 22:19:18 +08:00
RETVAL_LONG ( dateobj - > time - > z * - 60 ) ;
2008-01-18 02:49:45 +08:00
break ;
case TIMELIB_ZONETYPE_ABBR :
2017-08-16 22:19:18 +08:00
RETVAL_LONG ( ( dateobj - > time - > z - ( 60 * dateobj - > time - > dst ) ) * - 60 ) ;
2008-01-18 02:49:45 +08:00
break ;
}
2005-07-20 16:31:02 +08:00
return ;
} else {
2014-08-26 01:24:55 +08:00
RETURN_LONG ( 0 ) ;
2005-07-20 16:31:02 +08:00
}
}
2006-09-11 01:01:51 +08:00
/* }}} */
2005-07-20 16:31:02 +08:00
2014-12-14 06:06:14 +08:00
static void php_date_time_set ( zval * object , zend_long h , zend_long i , zend_long s , zval * return_value ) /* { { { */
2005-09-02 22:58:01 +08:00
{
php_date_obj * dateobj ;
2014-03-16 17:14:31 +08:00
dateobj = Z_PHPDATE_P ( object ) ;
2006-08-01 21:28:28 +08:00
DATE_CHECK_INITIALIZED ( dateobj - > time , DateTime ) ;
2005-09-02 22:58:01 +08:00
dateobj - > time - > h = h ;
dateobj - > time - > i = i ;
dateobj - > time - > s = s ;
timelib_update_ts ( dateobj - > time , NULL ) ;
2014-03-16 17:14:31 +08:00
} /* }}} */
2012-12-17 23:31:23 +08:00
/* {{{ proto DateTime date_time_set(DateTime object, long hour, long minute[, long second])
Sets the time .
*/
PHP_FUNCTION ( date_time_set )
{
zval * object ;
2014-08-26 01:24:55 +08:00
zend_long h , i , s = 0 ;
2012-12-17 23:31:23 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_method_parameters ( ZEND_NUM_ARGS ( ) , getThis ( ) , " Oll|l " , & object , date_ce_date , & h , & i , & s ) = = FAILURE ) {
2012-12-17 23:31:23 +08:00
RETURN_FALSE ;
}
2014-12-14 06:06:14 +08:00
php_date_time_set ( object , h , i , s , return_value ) ;
2008-07-31 02:00:44 +08:00
2015-06-12 18:33:14 +08:00
Z_ADDREF_P ( object ) ;
ZVAL_COPY_VALUE ( return_value , object ) ;
2005-09-02 22:58:01 +08:00
}
2006-09-11 01:01:51 +08:00
/* }}} */
2005-09-02 22:58:01 +08:00
2012-12-20 00:24:38 +08:00
/* {{{ proto DateTimeImmutable::setTime()
2006-09-11 01:01:51 +08:00
*/
2012-12-20 00:24:38 +08:00
PHP_METHOD ( DateTimeImmutable , setTime )
2005-09-02 22:58:01 +08:00
{
2014-02-10 14:04:30 +08:00
zval * object , new_object ;
2014-08-26 01:24:55 +08:00
zend_long h , i , s = 0 ;
2005-09-02 22:58:01 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_method_parameters ( ZEND_NUM_ARGS ( ) , getThis ( ) , " Oll|l " , & object , date_ce_immutable , & h , & i , & s ) = = FAILURE ) {
2005-09-02 22:58:01 +08:00
RETURN_FALSE ;
}
2012-12-17 23:31:23 +08:00
2014-12-14 06:06:14 +08:00
date_clone_immutable ( object , & new_object ) ;
php_date_time_set ( & new_object , h , i , s , return_value ) ;
2012-12-17 23:31:23 +08:00
2015-06-12 17:33:23 +08:00
ZVAL_COPY_VALUE ( return_value , & new_object ) ;
2012-12-17 23:31:23 +08:00
}
/* }}} */
2014-12-14 06:06:14 +08:00
static void php_date_date_set ( zval * object , zend_long y , zend_long m , zend_long d , zval * return_value ) /* { { { */
2012-12-17 23:31:23 +08:00
{
php_date_obj * dateobj ;
2014-03-16 17:14:31 +08:00
dateobj = Z_PHPDATE_P ( object ) ;
2006-08-01 21:28:28 +08:00
DATE_CHECK_INITIALIZED ( dateobj - > time , DateTime ) ;
2005-09-02 22:58:01 +08:00
dateobj - > time - > y = y ;
dateobj - > time - > m = m ;
dateobj - > time - > d = d ;
timelib_update_ts ( dateobj - > time , NULL ) ;
2014-03-16 17:14:31 +08:00
} /* }}} */
2012-12-17 23:31:23 +08:00
/* {{{ proto DateTime date_date_set(DateTime object, long year, long month, long day)
Sets the date .
*/
PHP_FUNCTION ( date_date_set )
{
zval * object ;
2014-08-26 01:24:55 +08:00
zend_long y , m , d ;
2012-12-17 23:31:23 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_method_parameters ( ZEND_NUM_ARGS ( ) , getThis ( ) , " Olll " , & object , date_ce_date , & y , & m , & d ) = = FAILURE ) {
2012-12-17 23:31:23 +08:00
RETURN_FALSE ;
}
2014-12-14 06:06:14 +08:00
php_date_date_set ( object , y , m , d , return_value ) ;
2008-07-31 02:00:44 +08:00
2015-06-12 18:33:14 +08:00
Z_ADDREF_P ( object ) ;
ZVAL_COPY_VALUE ( return_value , object ) ;
2005-09-02 22:58:01 +08:00
}
2006-09-11 01:01:51 +08:00
/* }}} */
2005-09-02 22:58:01 +08:00
2012-12-20 00:24:38 +08:00
/* {{{ proto DateTimeImmutable::setDate()
2006-09-11 01:01:51 +08:00
*/
2012-12-20 00:24:38 +08:00
PHP_METHOD ( DateTimeImmutable , setDate )
2005-09-02 22:58:01 +08:00
{
2014-02-10 14:04:30 +08:00
zval * object , new_object ;
2014-08-26 01:24:55 +08:00
zend_long y , m , d ;
2005-09-02 22:58:01 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_method_parameters ( ZEND_NUM_ARGS ( ) , getThis ( ) , " Olll " , & object , date_ce_immutable , & y , & m , & d ) = = FAILURE ) {
2005-09-02 22:58:01 +08:00
RETURN_FALSE ;
}
2012-12-17 23:31:23 +08:00
2014-12-14 06:06:14 +08:00
date_clone_immutable ( object , & new_object ) ;
php_date_date_set ( & new_object , y , m , d , return_value ) ;
2012-12-17 23:31:23 +08:00
2015-06-12 17:33:23 +08:00
ZVAL_COPY_VALUE ( return_value , & new_object ) ;
2012-12-17 23:31:23 +08:00
}
/* }}} */
2014-12-14 06:06:14 +08:00
static void php_date_isodate_set ( zval * object , zend_long y , zend_long w , zend_long d , zval * return_value ) /* { { { */
2012-12-17 23:31:23 +08:00
{
php_date_obj * dateobj ;
2014-03-16 17:14:31 +08:00
dateobj = Z_PHPDATE_P ( object ) ;
2006-08-01 21:28:28 +08:00
DATE_CHECK_INITIALIZED ( dateobj - > time , DateTime ) ;
2005-09-02 22:58:01 +08:00
dateobj - > time - > y = y ;
dateobj - > time - > m = 1 ;
dateobj - > time - > d = 1 ;
2011-01-30 18:18:12 +08:00
memset ( & dateobj - > time - > relative , 0 , sizeof ( dateobj - > time - > relative ) ) ;
2005-09-02 22:58:01 +08:00
dateobj - > time - > relative . d = timelib_daynr_from_weeknr ( y , w , d ) ;
dateobj - > time - > have_relative = 1 ;
2015-01-03 17:22:58 +08:00
2005-09-02 22:58:01 +08:00
timelib_update_ts ( dateobj - > time , NULL ) ;
2014-03-16 17:14:31 +08:00
} /* }}} */
2012-12-17 23:31:23 +08:00
/* {{{ proto DateTime date_isodate_set(DateTime object, long year, long week[, long day])
Sets the ISO date .
*/
PHP_FUNCTION ( date_isodate_set )
{
zval * object ;
2014-08-26 01:24:55 +08:00
zend_long y , w , d = 1 ;
2012-12-17 23:31:23 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_method_parameters ( ZEND_NUM_ARGS ( ) , getThis ( ) , " Oll|l " , & object , date_ce_date , & y , & w , & d ) = = FAILURE ) {
2012-12-17 23:31:23 +08:00
RETURN_FALSE ;
}
2014-12-14 06:06:14 +08:00
php_date_isodate_set ( object , y , w , d , return_value ) ;
2008-07-31 02:00:44 +08:00
2015-06-12 18:33:14 +08:00
Z_ADDREF_P ( object ) ;
ZVAL_COPY_VALUE ( return_value , object ) ;
2005-09-02 22:58:01 +08:00
}
2006-09-11 01:01:51 +08:00
/* }}} */
2005-07-20 16:31:02 +08:00
2012-12-20 00:24:38 +08:00
/* {{{ proto DateTimeImmutable::setISODate()
2007-12-14 22:28:36 +08:00
*/
2012-12-20 00:24:38 +08:00
PHP_METHOD ( DateTimeImmutable , setISODate )
2007-12-14 22:28:36 +08:00
{
2014-02-10 14:04:30 +08:00
zval * object , new_object ;
2014-08-26 01:24:55 +08:00
zend_long y , w , d = 1 ;
2007-12-14 22:28:36 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_method_parameters ( ZEND_NUM_ARGS ( ) , getThis ( ) , " Oll|l " , & object , date_ce_immutable , & y , & w , & d ) = = FAILURE ) {
2007-12-14 22:28:36 +08:00
RETURN_FALSE ;
}
2012-12-17 23:31:23 +08:00
2014-12-14 06:06:14 +08:00
date_clone_immutable ( object , & new_object ) ;
php_date_isodate_set ( & new_object , y , w , d , return_value ) ;
2012-12-17 23:31:23 +08:00
2015-06-12 17:33:23 +08:00
ZVAL_COPY_VALUE ( return_value , & new_object ) ;
2012-12-17 23:31:23 +08:00
}
/* }}} */
2014-12-14 06:06:14 +08:00
static void php_date_timestamp_set ( zval * object , zend_long timestamp , zval * return_value ) /* { { { */
2012-12-17 23:31:23 +08:00
{
php_date_obj * dateobj ;
2014-03-16 17:14:31 +08:00
dateobj = Z_PHPDATE_P ( object ) ;
2007-12-14 22:28:36 +08:00
DATE_CHECK_INITIALIZED ( dateobj - > time , DateTime ) ;
2008-07-28 03:10:23 +08:00
timelib_unixtime2local ( dateobj - > time , ( timelib_sll ) timestamp ) ;
2007-12-14 22:28:36 +08:00
timelib_update_ts ( dateobj - > time , NULL ) ;
2014-03-16 17:14:31 +08:00
} /* }}} */
2012-12-17 23:31:23 +08:00
/* {{{ proto DateTime date_timestamp_set(DateTime object, long unixTimestamp)
Sets the date and time based on an Unix timestamp .
*/
PHP_FUNCTION ( date_timestamp_set )
{
zval * object ;
2014-08-26 01:24:55 +08:00
zend_long timestamp ;
2012-12-17 23:31:23 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_method_parameters ( ZEND_NUM_ARGS ( ) , getThis ( ) , " Ol " , & object , date_ce_date , & timestamp ) = = FAILURE ) {
2012-12-17 23:31:23 +08:00
RETURN_FALSE ;
}
2014-12-14 06:06:14 +08:00
php_date_timestamp_set ( object , timestamp , return_value ) ;
2008-07-31 02:00:44 +08:00
2015-06-12 18:33:14 +08:00
Z_ADDREF_P ( object ) ;
ZVAL_COPY_VALUE ( return_value , object ) ;
2007-12-14 22:28:36 +08:00
}
/* }}} */
2012-12-20 00:24:38 +08:00
/* {{{ proto DateTimeImmutable::setTimestamp()
2012-12-17 23:31:23 +08:00
*/
2012-12-20 00:24:38 +08:00
PHP_METHOD ( DateTimeImmutable , setTimestamp )
2012-12-17 23:31:23 +08:00
{
2014-02-10 14:04:30 +08:00
zval * object , new_object ;
2014-08-26 01:24:55 +08:00
zend_long timestamp ;
2012-12-17 23:31:23 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_method_parameters ( ZEND_NUM_ARGS ( ) , getThis ( ) , " Ol " , & object , date_ce_immutable , & timestamp ) = = FAILURE ) {
2012-12-17 23:31:23 +08:00
RETURN_FALSE ;
}
2014-12-14 06:06:14 +08:00
date_clone_immutable ( object , & new_object ) ;
php_date_timestamp_set ( & new_object , timestamp , return_value ) ;
2012-12-17 23:31:23 +08:00
2015-06-12 17:33:23 +08:00
ZVAL_COPY_VALUE ( return_value , & new_object ) ;
2012-12-17 23:31:23 +08:00
}
/* }}} */
2013-03-31 17:37:16 +08:00
/* {{{ proto long date_timestamp_get(DateTimeInterface object)
2008-01-29 04:30:51 +08:00
Gets the Unix timestamp .
*/
PHP_FUNCTION ( date_timestamp_get )
{
zval * object ;
php_date_obj * dateobj ;
2014-08-26 01:24:55 +08:00
zend_long timestamp ;
2008-01-29 04:30:51 +08:00
int error ;
2014-12-14 06:06:14 +08:00
if ( zend_parse_method_parameters ( ZEND_NUM_ARGS ( ) , getThis ( ) , " O " , & object , date_ce_interface ) = = FAILURE ) {
2008-01-29 04:30:51 +08:00
RETURN_FALSE ;
}
2014-03-16 17:14:31 +08:00
dateobj = Z_PHPDATE_P ( object ) ;
2008-01-29 04:30:51 +08:00
DATE_CHECK_INITIALIZED ( dateobj - > time , DateTime ) ;
timelib_update_ts ( dateobj - > time , NULL ) ;
timestamp = timelib_date_to_int ( dateobj - > time , & error ) ;
if ( error ) {
RETURN_FALSE ;
} else {
2014-08-26 01:24:55 +08:00
RETVAL_LONG ( timestamp ) ;
2008-01-29 04:30:51 +08:00
}
}
/* }}} */
2008-04-25 20:35:58 +08:00
/* {{{ proto DateInterval date_diff(DateTime object [, bool absolute])
Returns the difference between two DateTime objects .
*/
PHP_FUNCTION ( date_diff )
{
zval * object1 , * object2 ;
php_date_obj * dateobj1 , * dateobj2 ;
php_interval_obj * interval ;
2015-12-13 14:52:37 +08:00
zend_bool absolute = 0 ;
2008-04-25 20:35:58 +08:00
2015-12-13 14:52:37 +08:00
if ( zend_parse_method_parameters ( ZEND_NUM_ARGS ( ) , getThis ( ) , " OO|b " , & object1 , date_ce_interface , & object2 , date_ce_interface , & absolute ) = = FAILURE ) {
2008-04-25 20:35:58 +08:00
RETURN_FALSE ;
}
2014-04-09 21:51:28 +08:00
dateobj1 = Z_PHPDATE_P ( object1 ) ;
dateobj2 = Z_PHPDATE_P ( object2 ) ;
2013-10-29 23:40:17 +08:00
DATE_CHECK_INITIALIZED ( dateobj1 - > time , DateTimeInterface ) ;
DATE_CHECK_INITIALIZED ( dateobj2 - > time , DateTimeInterface ) ;
2008-04-25 20:35:58 +08:00
timelib_update_ts ( dateobj1 - > time , NULL ) ;
timelib_update_ts ( dateobj2 - > time , NULL ) ;
2014-12-14 06:06:14 +08:00
php_date_instantiate ( date_ce_interval , return_value ) ;
2014-04-09 21:51:28 +08:00
interval = Z_PHPINTERVAL_P ( return_value ) ;
2008-04-25 20:35:58 +08:00
interval - > diff = timelib_diff ( dateobj1 - > time , dateobj2 - > time ) ;
if ( absolute ) {
interval - > diff - > invert = 0 ;
}
interval - > initialized = 1 ;
}
/* }}} */
2015-08-18 01:28:46 +08:00
static int timezone_initialize ( php_timezone_obj * tzobj , /*const*/ char * tz , size_t tz_len ) /* { { { */
2006-08-01 21:28:28 +08:00
{
2014-02-06 10:00:13 +08:00
timelib_time * dummy_t = ecalloc ( 1 , sizeof ( timelib_time ) ) ;
int dst , not_found ;
char * orig_tz = tz ;
2015-08-17 21:58:37 +08:00
if ( strlen ( tz ) ! = tz_len ) {
2015-08-18 01:28:46 +08:00
php_error_docref ( NULL , E_WARNING , " Timezone must not contain null bytes " ) ;
2016-07-14 23:43:29 +08:00
efree ( dummy_t ) ;
2015-08-17 21:58:37 +08:00
return FAILURE ;
}
2014-02-06 10:00:13 +08:00
dummy_t - > z = timelib_parse_zone ( & tz , & dst , dummy_t , & not_found , DATE_TIMEZONEDB , php_date_parse_tzfile_wrapper ) ;
if ( not_found ) {
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , E_WARNING , " Unknown or bad timezone (%s) " , orig_tz ) ;
2014-02-06 10:00:13 +08:00
efree ( dummy_t ) ;
return FAILURE ;
2006-08-01 21:28:28 +08:00
} else {
2014-02-11 19:27:01 +08:00
set_timezone_from_timelib_time ( tzobj , dummy_t ) ;
2015-09-22 16:17:50 +08:00
timelib_free ( dummy_t - > tz_abbr ) ;
2014-02-06 10:00:13 +08:00
efree ( dummy_t ) ;
2006-08-01 21:28:28 +08:00
return SUCCESS ;
}
2014-03-16 17:14:31 +08:00
} /* }}} */
2006-08-01 21:28:28 +08:00
2006-09-11 01:01:51 +08:00
/* {{{ proto DateTimeZone timezone_open(string timezone)
2006-11-03 22:38:45 +08:00
Returns new DateTimeZone object
2006-09-11 01:01:51 +08:00
*/
2005-07-20 16:31:02 +08:00
PHP_FUNCTION ( timezone_open )
{
char * tz ;
2014-08-27 23:31:24 +08:00
size_t tz_len ;
2008-01-18 02:49:45 +08:00
php_timezone_obj * tzobj ;
2005-07-20 16:31:02 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " s " , & tz , & tz_len ) = = FAILURE ) {
2005-07-20 16:31:02 +08:00
RETURN_FALSE ;
}
2014-12-14 06:06:14 +08:00
tzobj = Z_PHPTIMEZONE_P ( php_date_instantiate ( date_ce_timezone , return_value ) ) ;
2015-08-18 01:28:46 +08:00
if ( SUCCESS ! = timezone_initialize ( tzobj , tz , tz_len ) ) {
2015-04-15 03:43:43 +08:00
zval_ptr_dtor ( return_value ) ;
2005-07-20 16:31:02 +08:00
RETURN_FALSE ;
}
2006-08-01 21:28:28 +08:00
}
2006-09-11 01:01:51 +08:00
/* }}} */
2006-08-01 21:28:28 +08:00
2006-09-11 01:01:51 +08:00
/* {{{ proto DateTimeZone::__construct(string timezone)
2006-11-03 22:38:45 +08:00
Creates new DateTimeZone object .
2006-09-11 01:01:51 +08:00
*/
2006-08-01 21:28:28 +08:00
PHP_METHOD ( DateTimeZone , __construct )
{
char * tz ;
2014-08-27 23:31:24 +08:00
size_t tz_len ;
2008-01-18 02:49:45 +08:00
php_timezone_obj * tzobj ;
2008-11-19 10:00:53 +08:00
zend_error_handling error_handling ;
2015-01-03 17:22:58 +08:00
2015-04-03 00:52:32 +08:00
if ( FAILURE = = zend_parse_parameters_throw ( ZEND_NUM_ARGS ( ) , " s " , & tz , & tz_len ) ) {
return ;
2006-08-01 21:28:28 +08:00
}
2015-04-03 00:52:32 +08:00
zend_replace_error_handling ( EH_THROW , NULL , & error_handling ) ;
tzobj = Z_PHPTIMEZONE_P ( getThis ( ) ) ;
2015-08-18 01:28:46 +08:00
timezone_initialize ( tzobj , tz , tz_len ) ;
2014-12-14 06:06:14 +08:00
zend_restore_error_handling ( & error_handling ) ;
2005-07-20 16:31:02 +08:00
}
2006-09-11 01:01:51 +08:00
/* }}} */
2005-07-20 16:31:02 +08:00
2014-12-14 06:06:14 +08:00
static int php_date_timezone_initialize_from_hash ( zval * * return_value , php_timezone_obj * * tzobj , HashTable * myht ) /* { { { */
2012-09-28 20:15:20 +08:00
{
2014-02-10 14:04:30 +08:00
zval * z_timezone ;
zval * z_timezone_type ;
2012-09-28 20:15:20 +08:00
2015-02-27 11:13:07 +08:00
if ( ( z_timezone_type = zend_hash_str_find ( myht , " timezone_type " , sizeof ( " timezone_type " ) - 1 ) ) ! = NULL ) {
if ( ( z_timezone = zend_hash_str_find ( myht , " timezone " , sizeof ( " timezone " ) - 1 ) ) ! = NULL ) {
if ( Z_TYPE_P ( z_timezone_type ) ! = IS_LONG ) {
return FAILURE ;
}
if ( Z_TYPE_P ( z_timezone ) ! = IS_STRING ) {
2015-02-17 14:02:20 +08:00
return FAILURE ;
}
2015-08-18 01:28:46 +08:00
if ( SUCCESS = = timezone_initialize ( * tzobj , Z_STRVAL_P ( z_timezone ) , Z_STRLEN_P ( z_timezone ) ) ) {
2014-02-06 10:00:13 +08:00
return SUCCESS ;
2012-09-28 20:15:20 +08:00
}
}
}
2012-11-14 13:04:46 +08:00
return FAILURE ;
2014-03-16 17:14:31 +08:00
} /* }}} */
2012-09-28 20:15:20 +08:00
/* {{{ proto DateTimeZone::__set_state()
* */
PHP_METHOD ( DateTimeZone , __set_state )
{
php_timezone_obj * tzobj ;
zval * array ;
HashTable * myht ;
2014-12-14 06:06:14 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " a " , & array ) = = FAILURE ) {
2012-09-28 20:15:20 +08:00
RETURN_FALSE ;
}
2015-09-25 03:39:59 +08:00
myht = Z_ARRVAL_P ( array ) ;
2012-09-28 20:15:20 +08:00
2014-12-14 06:06:14 +08:00
php_date_instantiate ( date_ce_timezone , return_value ) ;
2014-03-16 17:14:31 +08:00
tzobj = Z_PHPTIMEZONE_P ( return_value ) ;
2015-02-17 14:02:20 +08:00
if ( php_date_timezone_initialize_from_hash ( & return_value , & tzobj , myht ) ! = SUCCESS ) {
php_error_docref ( NULL , E_ERROR , " Timezone initialization failed " ) ;
}
2012-09-28 20:15:20 +08:00
}
/* }}} */
/* {{{ proto DateTimeZone::__wakeup()
* */
PHP_METHOD ( DateTimeZone , __wakeup )
{
zval * object = getThis ( ) ;
php_timezone_obj * tzobj ;
HashTable * myht ;
2014-03-16 17:14:31 +08:00
tzobj = Z_PHPTIMEZONE_P ( object ) ;
2012-09-28 20:15:20 +08:00
myht = Z_OBJPROP_P ( object ) ;
2015-01-03 17:22:58 +08:00
2015-02-17 14:02:20 +08:00
if ( php_date_timezone_initialize_from_hash ( & return_value , & tzobj , myht ) ! = SUCCESS ) {
php_error_docref ( NULL , E_ERROR , " Timezone initialization failed " ) ;
}
2012-09-28 20:15:20 +08:00
}
/* }}} */
2006-09-11 01:01:51 +08:00
/* {{{ proto string timezone_name_get(DateTimeZone object)
2006-11-03 22:38:45 +08:00
Returns the name of the timezone .
2006-09-11 01:01:51 +08:00
*/
2005-07-20 16:31:02 +08:00
PHP_FUNCTION ( timezone_name_get )
{
zval * object ;
php_timezone_obj * tzobj ;
2014-12-14 06:06:14 +08:00
if ( zend_parse_method_parameters ( ZEND_NUM_ARGS ( ) , getThis ( ) , " O " , & object , date_ce_timezone ) = = FAILURE ) {
2005-07-20 16:31:02 +08:00
RETURN_FALSE ;
}
2014-03-16 17:14:31 +08:00
tzobj = Z_PHPTIMEZONE_P ( object ) ;
2008-01-18 03:59:00 +08:00
DATE_CHECK_INITIALIZED ( tzobj - > initialized , DateTimeZone ) ;
2008-01-18 02:49:45 +08:00
switch ( tzobj - > type ) {
case TIMELIB_ZONETYPE_ID :
2014-02-10 14:04:30 +08:00
RETURN_STRING ( tzobj - > tzi . tz - > name ) ;
2008-01-18 02:49:45 +08:00
break ;
case TIMELIB_ZONETYPE_OFFSET : {
2014-08-26 01:24:55 +08:00
zend_string * tmpstr = zend_string_alloc ( sizeof ( " UTC+05:00 " ) - 1 , 0 ) ;
2008-01-18 02:49:45 +08:00
timelib_sll utc_offset = tzobj - > tzi . utc_offset ;
2015-06-30 09:05:24 +08:00
ZSTR_LEN ( tmpstr ) = snprintf ( ZSTR_VAL ( tmpstr ) , sizeof ( " +05:00 " ) , " %c%02d:%02d " ,
2017-08-16 22:19:18 +08:00
utc_offset > 0 ? ' - ' : ' + ' ,
abs ( utc_offset / 60 ) ,
abs ( ( utc_offset % 60 ) ) ) ;
2005-07-20 16:31:02 +08:00
2015-03-12 21:53:51 +08:00
RETURN_NEW_STR ( tmpstr ) ;
2008-01-18 02:49:45 +08:00
}
break ;
case TIMELIB_ZONETYPE_ABBR :
2014-02-10 14:04:30 +08:00
RETURN_STRING ( tzobj - > tzi . z . abbr ) ;
2008-01-18 02:49:45 +08:00
break ;
}
2005-07-20 16:31:02 +08:00
}
2006-09-11 01:01:51 +08:00
/* }}} */
2005-07-20 16:31:02 +08:00
2006-09-11 01:01:51 +08:00
/* {{{ proto string timezone_name_from_abbr(string abbr[, long gmtOffset[, long isdst]])
2006-11-03 22:38:45 +08:00
Returns the timezone name from abbrevation
2006-09-11 01:01:51 +08:00
*/
2006-04-12 02:03:52 +08:00
PHP_FUNCTION ( timezone_name_from_abbr )
{
char * abbr ;
2007-01-03 22:46:23 +08:00
char * tzid ;
2014-08-27 21:31:48 +08:00
size_t abbr_len ;
2014-08-26 01:24:55 +08:00
zend_long gmtoffset = - 1 ;
zend_long isdst = - 1 ;
2006-04-12 02:03:52 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " s|ll " , & abbr , & abbr_len , & gmtoffset , & isdst ) = = FAILURE ) {
2006-04-12 02:03:52 +08:00
RETURN_FALSE ;
}
2007-01-03 22:46:23 +08:00
tzid = timelib_timezone_id_from_abbr ( abbr , gmtoffset , isdst ) ;
2006-04-12 02:03:52 +08:00
2007-01-03 22:46:23 +08:00
if ( tzid ) {
2014-02-10 14:04:30 +08:00
RETURN_STRING ( tzid ) ;
2006-04-12 02:03:52 +08:00
} else {
RETURN_FALSE ;
}
}
2006-09-11 01:01:51 +08:00
/* }}} */
2006-04-12 02:03:52 +08:00
2014-09-21 05:16:39 +08:00
/* {{{ proto long timezone_offset_get(DateTimeZone object, DateTimeInterface datetime)
2006-11-03 22:38:45 +08:00
Returns the timezone offset .
2006-09-11 01:01:51 +08:00
*/
2005-07-20 16:31:02 +08:00
PHP_FUNCTION ( timezone_offset_get )
{
zval * object , * dateobject ;
php_timezone_obj * tzobj ;
php_date_obj * dateobj ;
timelib_time_offset * offset ;
2014-12-14 06:06:14 +08:00
if ( zend_parse_method_parameters ( ZEND_NUM_ARGS ( ) , getThis ( ) , " OO " , & object , date_ce_timezone , & dateobject , date_ce_interface ) = = FAILURE ) {
2005-07-20 16:31:02 +08:00
RETURN_FALSE ;
}
2014-03-16 17:14:31 +08:00
tzobj = Z_PHPTIMEZONE_P ( object ) ;
2008-01-18 03:59:00 +08:00
DATE_CHECK_INITIALIZED ( tzobj - > initialized , DateTimeZone ) ;
2014-03-16 17:14:31 +08:00
dateobj = Z_PHPDATE_P ( dateobject ) ;
2014-09-21 05:16:39 +08:00
DATE_CHECK_INITIALIZED ( dateobj - > time , DateTimeInterface ) ;
2005-07-20 16:31:02 +08:00
2008-04-25 20:35:58 +08:00
switch ( tzobj - > type ) {
case TIMELIB_ZONETYPE_ID :
offset = timelib_get_time_zone_info ( dateobj - > time - > sse , tzobj - > tzi . tz ) ;
2014-08-26 01:24:55 +08:00
RETVAL_LONG ( offset - > offset ) ;
2008-04-25 20:35:58 +08:00
timelib_time_offset_dtor ( offset ) ;
break ;
case TIMELIB_ZONETYPE_OFFSET :
2017-08-16 22:19:18 +08:00
RETURN_LONG ( tzobj - > tzi . utc_offset * - 60 ) ;
2008-04-25 20:35:58 +08:00
break ;
case TIMELIB_ZONETYPE_ABBR :
2017-08-16 22:19:18 +08:00
RETURN_LONG ( ( tzobj - > tzi . z . utc_offset - ( tzobj - > tzi . z . dst * 60 ) ) * - 60 ) ;
2008-04-25 20:35:58 +08:00
break ;
}
2005-07-20 16:31:02 +08:00
}
2006-09-11 01:01:51 +08:00
/* }}} */
2005-07-20 16:31:02 +08:00
2008-01-29 05:12:41 +08:00
/* {{{ proto array timezone_transitions_get(DateTimeZone object [, long timestamp_begin [, long timestamp_end ]])
Returns numerically indexed array containing associative array for all transitions in the specified range for the timezone .
2006-09-11 01:01:51 +08:00
*/
2006-08-01 21:28:28 +08:00
PHP_FUNCTION ( timezone_transitions_get )
2005-07-20 16:31:02 +08:00
{
2014-02-10 14:04:30 +08:00
zval * object , element ;
2005-07-20 16:31:02 +08:00
php_timezone_obj * tzobj ;
2009-08-06 05:25:39 +08:00
unsigned int i , begin = 0 , found ;
2014-08-26 02:22:49 +08:00
zend_long timestamp_begin = ZEND_LONG_MIN , timestamp_end = ZEND_LONG_MAX ;
2005-07-20 16:31:02 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_method_parameters ( ZEND_NUM_ARGS ( ) , getThis ( ) , " O|ll " , & object , date_ce_timezone , & timestamp_begin , & timestamp_end ) = = FAILURE ) {
2005-07-20 16:31:02 +08:00
RETURN_FALSE ;
}
2014-03-16 17:14:31 +08:00
tzobj = Z_PHPTIMEZONE_P ( object ) ;
2008-01-18 03:59:00 +08:00
DATE_CHECK_INITIALIZED ( tzobj - > initialized , DateTimeZone ) ;
2008-01-18 02:49:45 +08:00
if ( tzobj - > type ! = TIMELIB_ZONETYPE_ID ) {
RETURN_FALSE ;
}
2005-07-20 16:31:02 +08:00
2008-03-21 03:43:36 +08:00
# define add_nominal() \
2014-02-10 14:04:30 +08:00
array_init ( & element ) ; \
2014-08-26 01:24:55 +08:00
add_assoc_long ( & element , " ts " , timestamp_begin ) ; \
2014-12-14 06:06:14 +08:00
add_assoc_str ( & element , " time " , php_format_date ( DATE_FORMAT_ISO8601 , 13 , timestamp_begin , 0 ) ) ; \
2014-08-26 01:24:55 +08:00
add_assoc_long ( & element , " offset " , tzobj - > tzi . tz - > type [ 0 ] . offset ) ; \
2014-02-10 14:04:30 +08:00
add_assoc_bool ( & element , " isdst " , tzobj - > tzi . tz - > type [ 0 ] . isdst ) ; \
2014-04-15 19:40:40 +08:00
add_assoc_string ( & element , " abbr " , & tzobj - > tzi . tz - > timezone_abbr [ tzobj - > tzi . tz - > type [ 0 ] . abbr_idx ] ) ; \
2014-02-10 14:04:30 +08:00
add_next_index_zval ( return_value , & element ) ;
2008-03-21 03:43:36 +08:00
# define add(i,ts) \
2014-02-10 14:04:30 +08:00
array_init ( & element ) ; \
2014-08-26 01:24:55 +08:00
add_assoc_long ( & element , " ts " , ts ) ; \
2014-12-14 06:06:14 +08:00
add_assoc_str ( & element , " time " , php_format_date ( DATE_FORMAT_ISO8601 , 13 , ts , 0 ) ) ; \
2014-08-26 01:24:55 +08:00
add_assoc_long ( & element , " offset " , tzobj - > tzi . tz - > type [ tzobj - > tzi . tz - > trans_idx [ i ] ] . offset ) ; \
2014-02-10 14:04:30 +08:00
add_assoc_bool ( & element , " isdst " , tzobj - > tzi . tz - > type [ tzobj - > tzi . tz - > trans_idx [ i ] ] . isdst ) ; \
2014-04-15 19:40:40 +08:00
add_assoc_string ( & element , " abbr " , & tzobj - > tzi . tz - > timezone_abbr [ tzobj - > tzi . tz - > type [ tzobj - > tzi . tz - > trans_idx [ i ] ] . abbr_idx ] ) ; \
2014-02-10 14:04:30 +08:00
add_next_index_zval ( return_value , & element ) ;
2008-03-21 03:43:36 +08:00
2015-04-29 07:28:50 +08:00
# define add_last() add(tzobj->tzi.tz->bit32.timecnt - 1, timestamp_begin)
2008-03-21 03:43:36 +08:00
2005-07-20 16:31:02 +08:00
array_init ( return_value ) ;
2008-03-21 03:43:36 +08:00
2014-08-26 02:22:49 +08:00
if ( timestamp_begin = = ZEND_LONG_MIN ) {
2008-03-21 03:43:36 +08:00
add_nominal ( ) ;
begin = 0 ;
found = 1 ;
} else {
begin = 0 ;
found = 0 ;
2015-04-29 07:28:50 +08:00
if ( tzobj - > tzi . tz - > bit32 . timecnt > 0 ) {
2008-03-21 03:43:36 +08:00
do {
if ( tzobj - > tzi . tz - > trans [ begin ] > timestamp_begin ) {
if ( begin > 0 ) {
add ( begin - 1 , timestamp_begin ) ;
} else {
add_nominal ( ) ;
}
found = 1 ;
break ;
}
begin + + ;
2015-04-29 07:28:50 +08:00
} while ( begin < tzobj - > tzi . tz - > bit32 . timecnt ) ;
2008-03-21 03:43:36 +08:00
}
}
if ( ! found ) {
2015-04-29 07:28:50 +08:00
if ( tzobj - > tzi . tz - > bit32 . timecnt > 0 ) {
2008-03-21 03:43:36 +08:00
add_last ( ) ;
} else {
add_nominal ( ) ;
}
} else {
2015-04-29 07:28:50 +08:00
for ( i = begin ; i < tzobj - > tzi . tz - > bit32 . timecnt ; + + i ) {
2008-03-21 03:43:36 +08:00
if ( tzobj - > tzi . tz - > trans [ i ] < timestamp_end ) {
add ( i , tzobj - > tzi . tz - > trans [ i ] ) ;
2008-01-29 05:12:41 +08:00
}
}
2005-07-20 16:31:02 +08:00
}
}
2006-09-11 01:01:51 +08:00
/* }}} */
2005-07-20 16:31:02 +08:00
2008-07-18 22:33:53 +08:00
/* {{{ proto array timezone_location_get()
Returns location information for a timezone , including country code , latitude / longitude and comments
*/
PHP_FUNCTION ( timezone_location_get )
{
zval * object ;
php_timezone_obj * tzobj ;
2014-12-14 06:06:14 +08:00
if ( zend_parse_method_parameters ( ZEND_NUM_ARGS ( ) , getThis ( ) , " O " , & object , date_ce_timezone ) = = FAILURE ) {
2008-07-18 22:33:53 +08:00
RETURN_FALSE ;
}
2014-03-16 17:14:31 +08:00
tzobj = Z_PHPTIMEZONE_P ( object ) ;
2008-07-18 22:33:53 +08:00
DATE_CHECK_INITIALIZED ( tzobj - > initialized , DateTimeZone ) ;
if ( tzobj - > type ! = TIMELIB_ZONETYPE_ID ) {
RETURN_FALSE ;
}
array_init ( return_value ) ;
2014-04-15 19:40:40 +08:00
add_assoc_string ( return_value , " country_code " , tzobj - > tzi . tz - > location . country_code ) ;
2008-07-18 22:33:53 +08:00
add_assoc_double ( return_value , " latitude " , tzobj - > tzi . tz - > location . latitude ) ;
add_assoc_double ( return_value , " longitude " , tzobj - > tzi . tz - > location . longitude ) ;
2014-04-15 19:40:40 +08:00
add_assoc_string ( return_value , " comments " , tzobj - > tzi . tz - > location . comments ) ;
2008-07-18 22:33:53 +08:00
}
/* }}} */
2014-12-14 06:06:14 +08:00
static int date_interval_initialize ( timelib_rel_time * * rt , /*const*/ char * format , size_t format_length ) /* { { { */
2008-05-01 08:12:24 +08:00
{
timelib_time * b = NULL , * e = NULL ;
timelib_rel_time * p = NULL ;
int r = 0 ;
int retval = 0 ;
struct timelib_error_container * errors ;
timelib_strtointerval ( format , format_length , & b , & e , & p , & r , & errors ) ;
2015-01-03 17:22:58 +08:00
2008-05-01 08:12:24 +08:00
if ( errors - > error_count > 0 ) {
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , E_WARNING , " Unknown or bad format (%s) " , format ) ;
2008-05-01 08:12:24 +08:00
retval = FAILURE ;
} else {
2011-01-30 16:54:53 +08:00
if ( p ) {
* rt = p ;
retval = SUCCESS ;
} else {
if ( b & & e ) {
timelib_update_ts ( b , NULL ) ;
timelib_update_ts ( e , NULL ) ;
* rt = timelib_diff ( b , e ) ;
retval = SUCCESS ;
} else {
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , E_WARNING , " Failed to parse interval (%s) " , format ) ;
2011-01-30 16:54:53 +08:00
retval = FAILURE ;
}
}
2008-05-01 08:12:24 +08:00
}
timelib_error_container_dtor ( errors ) ;
2015-09-22 16:17:50 +08:00
timelib_free ( b ) ;
timelib_free ( e ) ;
2008-05-01 08:12:24 +08:00
return retval ;
2014-03-16 17:14:31 +08:00
} /* }}} */
2008-05-01 08:12:24 +08:00
/* {{{ date_interval_read_property */
2014-12-14 06:06:14 +08:00
zval * date_interval_read_property ( zval * object , zval * member , int type , void * * cache_slot , zval * rv )
2008-05-01 08:12:24 +08:00
{
php_interval_obj * obj ;
zval * retval ;
zval tmp_member ;
timelib_sll value = - 1 ;
2014-04-02 18:34:44 +08:00
if ( Z_TYPE_P ( member ) ! = IS_STRING ) {
2008-05-01 08:12:24 +08:00
tmp_member = * member ;
zval_copy_ctor ( & tmp_member ) ;
convert_to_string ( & tmp_member ) ;
member = & tmp_member ;
2014-07-08 00:54:31 +08:00
cache_slot = NULL ;
2008-05-01 08:12:24 +08:00
}
2014-03-16 17:14:31 +08:00
obj = Z_PHPINTERVAL_P ( object ) ;
2008-05-01 08:12:24 +08:00
2012-07-09 00:25:48 +08:00
if ( ! obj - > initialized ) {
2014-12-14 06:06:14 +08:00
retval = ( zend_get_std_object_handlers ( ) ) - > read_property ( object , member , type , cache_slot , rv ) ;
2012-07-09 00:25:48 +08:00
if ( member = = & tmp_member ) {
zval_dtor ( member ) ;
}
return retval ;
}
2008-05-01 08:12:24 +08:00
# define GET_VALUE_FROM_STRUCT(n,m) \
if ( strcmp ( Z_STRVAL_P ( member ) , m ) = = 0 ) { \
value = obj - > diff - > n ; \
2011-01-24 10:31:48 +08:00
break ; \
}
do {
GET_VALUE_FROM_STRUCT ( y , " y " ) ;
GET_VALUE_FROM_STRUCT ( m , " m " ) ;
GET_VALUE_FROM_STRUCT ( d , " d " ) ;
GET_VALUE_FROM_STRUCT ( h , " h " ) ;
GET_VALUE_FROM_STRUCT ( i , " i " ) ;
GET_VALUE_FROM_STRUCT ( s , " s " ) ;
GET_VALUE_FROM_STRUCT ( invert , " invert " ) ;
GET_VALUE_FROM_STRUCT ( days , " days " ) ;
/* didn't find any */
2014-12-14 06:06:14 +08:00
retval = ( zend_get_std_object_handlers ( ) ) - > read_property ( object , member , type , cache_slot , rv ) ;
2011-01-24 10:31:48 +08:00
if ( member = = & tmp_member ) {
zval_dtor ( member ) ;
}
return retval ;
} while ( 0 ) ;
2008-05-01 08:12:24 +08:00
2014-03-06 20:09:00 +08:00
retval = rv ;
2008-07-09 03:29:18 +08:00
2013-04-10 04:12:39 +08:00
if ( value ! = - 99999 ) {
2014-08-26 01:24:55 +08:00
ZVAL_LONG ( retval , value ) ;
2013-04-10 04:12:39 +08:00
} else {
ZVAL_FALSE ( retval ) ;
}
2008-05-01 08:12:24 +08:00
if ( member = = & tmp_member ) {
zval_dtor ( member ) ;
}
return retval ;
}
/* }}} */
/* {{{ date_interval_write_property */
2014-12-14 06:06:14 +08:00
void date_interval_write_property ( zval * object , zval * member , zval * value , void * * cache_slot )
2008-05-01 08:12:24 +08:00
{
php_interval_obj * obj ;
2014-04-22 21:46:34 +08:00
zval tmp_member ;
2008-05-01 08:12:24 +08:00
2014-04-02 18:34:44 +08:00
if ( Z_TYPE_P ( member ) ! = IS_STRING ) {
2008-05-01 08:12:24 +08:00
tmp_member = * member ;
zval_copy_ctor ( & tmp_member ) ;
convert_to_string ( & tmp_member ) ;
member = & tmp_member ;
2014-07-08 00:54:31 +08:00
cache_slot = NULL ;
2008-05-01 08:12:24 +08:00
}
2012-07-09 00:25:48 +08:00
2014-03-16 17:14:31 +08:00
obj = Z_PHPINTERVAL_P ( object ) ;
2008-05-01 08:12:24 +08:00
2012-07-09 00:25:48 +08:00
if ( ! obj - > initialized ) {
2014-12-14 06:06:14 +08:00
( zend_get_std_object_handlers ( ) ) - > write_property ( object , member , value , cache_slot ) ;
2012-07-09 00:25:48 +08:00
if ( member = = & tmp_member ) {
zval_dtor ( member ) ;
}
return ;
}
2008-05-01 08:12:24 +08:00
# define SET_VALUE_FROM_STRUCT(n,m) \
if ( strcmp ( Z_STRVAL_P ( member ) , m ) = = 0 ) { \
2014-08-26 01:24:55 +08:00
obj - > diff - > n = zval_get_long ( value ) ; \
2011-01-24 10:31:48 +08:00
break ; \
}
do {
SET_VALUE_FROM_STRUCT ( y , " y " ) ;
SET_VALUE_FROM_STRUCT ( m , " m " ) ;
SET_VALUE_FROM_STRUCT ( d , " d " ) ;
SET_VALUE_FROM_STRUCT ( h , " h " ) ;
SET_VALUE_FROM_STRUCT ( i , " i " ) ;
SET_VALUE_FROM_STRUCT ( s , " s " ) ;
SET_VALUE_FROM_STRUCT ( invert , " invert " ) ;
/* didn't find any */
2014-12-14 06:06:14 +08:00
( zend_get_std_object_handlers ( ) ) - > write_property ( object , member , value , cache_slot ) ;
2011-01-24 10:31:48 +08:00
} while ( 0 ) ;
2008-05-01 08:12:24 +08:00
if ( member = = & tmp_member ) {
zval_dtor ( member ) ;
}
}
/* }}} */
2017-10-09 21:35:38 +08:00
/* {{{ date_interval_get_property_ptr_ptr */
static zval * date_interval_get_property_ptr_ptr ( zval * object , zval * member , int type , void * * cache_slot )
{
zval tmp_member , * ret ;
if ( Z_TYPE_P ( member ) ! = IS_STRING ) {
tmp_member = * member ;
zval_copy_ctor ( & tmp_member ) ;
convert_to_string ( & tmp_member ) ;
member = & tmp_member ;
cache_slot = NULL ;
}
if ( zend_binary_strcmp ( " y " , sizeof ( " y " ) - 1 , Z_STRVAL_P ( member ) , Z_STRLEN_P ( member ) ) = = 0 | |
zend_binary_strcmp ( " m " , sizeof ( " m " ) - 1 , Z_STRVAL_P ( member ) , Z_STRLEN_P ( member ) ) = = 0 | |
zend_binary_strcmp ( " d " , sizeof ( " d " ) - 1 , Z_STRVAL_P ( member ) , Z_STRLEN_P ( member ) ) = = 0 | |
zend_binary_strcmp ( " h " , sizeof ( " h " ) - 1 , Z_STRVAL_P ( member ) , Z_STRLEN_P ( member ) ) = = 0 | |
zend_binary_strcmp ( " i " , sizeof ( " i " ) - 1 , Z_STRVAL_P ( member ) , Z_STRLEN_P ( member ) ) = = 0 | |
zend_binary_strcmp ( " s " , sizeof ( " s " ) - 1 , Z_STRVAL_P ( member ) , Z_STRLEN_P ( member ) ) = = 0 | |
zend_binary_strcmp ( " days " , sizeof ( " days " ) - 1 , Z_STRVAL_P ( member ) , Z_STRLEN_P ( member ) ) = = 0 | |
zend_binary_strcmp ( " invert " , sizeof ( " invert " ) - 1 , Z_STRVAL_P ( member ) , Z_STRLEN_P ( member ) ) = = 0 ) {
/* Fallback to read_property. */
ret = NULL ;
} else {
ret = ( zend_get_std_object_handlers ( ) ) - > get_property_ptr_ptr ( object , member , type , cache_slot ) ;
}
if ( member = = & tmp_member ) {
zval_dtor ( member ) ;
}
return ret ;
}
/* }}} */
2008-05-01 08:12:24 +08:00
2008-04-25 20:35:58 +08:00
/* {{{ proto DateInterval::__construct([string interval_spec])
Creates new DateInterval object .
*/
PHP_METHOD ( DateInterval , __construct )
{
char * interval_string = NULL ;
2014-08-27 23:31:24 +08:00
size_t interval_string_length ;
2008-04-25 20:35:58 +08:00
php_interval_obj * diobj ;
timelib_rel_time * reltime ;
2008-11-19 10:00:53 +08:00
zend_error_handling error_handling ;
2015-01-03 17:22:58 +08:00
2015-04-03 00:52:32 +08:00
if ( zend_parse_parameters_throw ( ZEND_NUM_ARGS ( ) , " s " , & interval_string , & interval_string_length ) = = FAILURE ) {
return ;
}
2014-12-14 06:06:14 +08:00
zend_replace_error_handling ( EH_THROW , NULL , & error_handling ) ;
2015-04-03 00:52:32 +08:00
if ( date_interval_initialize ( & reltime , interval_string , interval_string_length ) = = SUCCESS ) {
diobj = Z_PHPINTERVAL_P ( getThis ( ) ) ;
diobj - > diff = reltime ;
diobj - > initialized = 1 ;
2008-04-25 20:35:58 +08:00
}
2014-12-14 06:06:14 +08:00
zend_restore_error_handling ( & error_handling ) ;
2008-04-25 20:35:58 +08:00
}
/* }}} */
2011-12-06 14:21:08 +08:00
2014-12-14 06:06:14 +08:00
static int php_date_interval_initialize_from_hash ( zval * * return_value , php_interval_obj * * intobj , HashTable * myht ) /* { { { */
2011-12-06 14:21:08 +08:00
{
( * intobj ) - > diff = timelib_rel_time_ctor ( ) ;
2013-03-17 01:07:21 +08:00
# define PHP_DATE_INTERVAL_READ_PROPERTY(element, member, itype, def) \
2013-03-15 23:59:54 +08:00
do { \
2014-02-10 14:04:30 +08:00
zval * z_arg = zend_hash_str_find ( myht , element , sizeof ( element ) - 1 ) ; \
2016-09-26 07:43:24 +08:00
if ( z_arg & & Z_TYPE_P ( z_arg ) < = IS_STRING ) { \
2014-08-26 01:24:55 +08:00
( * intobj ) - > diff - > member = ( itype ) zval_get_long ( z_arg ) ; \
2013-03-15 23:59:54 +08:00
} else { \
2013-03-17 01:07:21 +08:00
( * intobj ) - > diff - > member = ( itype ) def ; \
2013-03-15 23:59:54 +08:00
} \
} while ( 0 ) ;
# define PHP_DATE_INTERVAL_READ_PROPERTY_I64(element, member) \
do { \
2014-02-10 14:04:30 +08:00
zval * z_arg = zend_hash_str_find ( myht , element , sizeof ( element ) - 1 ) ; \
2016-09-26 07:43:24 +08:00
if ( z_arg & & Z_TYPE_P ( z_arg ) < = IS_STRING ) { \
2014-05-28 05:29:37 +08:00
zend_string * str = zval_get_string ( z_arg ) ; \
2015-06-30 09:05:24 +08:00
DATE_A64I ( ( * intobj ) - > diff - > member , ZSTR_VAL ( str ) ) ; \
2014-08-26 01:24:55 +08:00
zend_string_release ( str ) ; \
2013-03-15 23:59:54 +08:00
} else { \
( * intobj ) - > diff - > member = - 1LL ; \
} \
} while ( 0 ) ;
2013-03-17 01:07:21 +08:00
PHP_DATE_INTERVAL_READ_PROPERTY ( " y " , y , timelib_sll , - 1 )
PHP_DATE_INTERVAL_READ_PROPERTY ( " m " , m , timelib_sll , - 1 )
PHP_DATE_INTERVAL_READ_PROPERTY ( " d " , d , timelib_sll , - 1 )
PHP_DATE_INTERVAL_READ_PROPERTY ( " h " , h , timelib_sll , - 1 )
PHP_DATE_INTERVAL_READ_PROPERTY ( " i " , i , timelib_sll , - 1 )
PHP_DATE_INTERVAL_READ_PROPERTY ( " s " , s , timelib_sll , - 1 )
PHP_DATE_INTERVAL_READ_PROPERTY ( " weekday " , weekday , int , - 1 )
PHP_DATE_INTERVAL_READ_PROPERTY ( " weekday_behavior " , weekday_behavior , int , - 1 )
PHP_DATE_INTERVAL_READ_PROPERTY ( " first_last_day_of " , first_last_day_of , int , - 1 )
PHP_DATE_INTERVAL_READ_PROPERTY ( " invert " , invert , int , 0 ) ;
2013-03-15 23:59:54 +08:00
PHP_DATE_INTERVAL_READ_PROPERTY_I64 ( " days " , days ) ;
2013-03-17 01:07:21 +08:00
PHP_DATE_INTERVAL_READ_PROPERTY ( " special_type " , special . type , unsigned int , 0 ) ;
2013-03-15 23:59:54 +08:00
PHP_DATE_INTERVAL_READ_PROPERTY_I64 ( " special_amount " , special . amount ) ;
2013-03-17 01:07:21 +08:00
PHP_DATE_INTERVAL_READ_PROPERTY ( " have_weekday_relative " , have_weekday_relative , unsigned int , 0 ) ;
PHP_DATE_INTERVAL_READ_PROPERTY ( " have_special_relative " , have_special_relative , unsigned int , 0 ) ;
2011-12-06 14:21:08 +08:00
( * intobj ) - > initialized = 1 ;
return 0 ;
2014-03-16 17:14:31 +08:00
} /* }}} */
2011-12-06 14:21:08 +08:00
/* {{{ proto DateInterval::__set_state()
*/
PHP_METHOD ( DateInterval , __set_state )
{
php_interval_obj * intobj ;
zval * array ;
HashTable * myht ;
2014-12-14 06:06:14 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " a " , & array ) = = FAILURE ) {
2011-12-06 14:21:08 +08:00
RETURN_FALSE ;
}
2015-09-25 03:39:59 +08:00
myht = Z_ARRVAL_P ( array ) ;
2011-12-06 14:21:08 +08:00
2014-12-14 06:06:14 +08:00
php_date_instantiate ( date_ce_interval , return_value ) ;
2014-03-16 17:14:31 +08:00
intobj = Z_PHPINTERVAL_P ( return_value ) ;
2014-12-14 06:06:14 +08:00
php_date_interval_initialize_from_hash ( & return_value , & intobj , myht ) ;
2011-12-06 14:21:08 +08:00
}
/* }}} */
/* {{{ proto DateInterval::__wakeup()
*/
PHP_METHOD ( DateInterval , __wakeup )
{
zval * object = getThis ( ) ;
php_interval_obj * intobj ;
HashTable * myht ;
2014-03-16 17:14:31 +08:00
intobj = Z_PHPINTERVAL_P ( object ) ;
2011-12-06 14:21:08 +08:00
myht = Z_OBJPROP_P ( object ) ;
2014-12-14 06:06:14 +08:00
php_date_interval_initialize_from_hash ( & return_value , & intobj , myht ) ;
2011-12-06 14:21:08 +08:00
}
/* }}} */
2014-03-16 17:14:31 +08:00
2008-05-02 20:49:16 +08:00
/* {{{ proto DateInterval date_interval_create_from_date_string(string time)
Uses the normal date parsers and sets up a DateInterval from the relative parts of the parsed string
*/
PHP_FUNCTION ( date_interval_create_from_date_string )
{
char * time_str = NULL ;
2014-08-27 23:31:24 +08:00
size_t time_str_len = 0 ;
2008-05-02 20:49:16 +08:00
timelib_time * time ;
timelib_error_container * err = NULL ;
php_interval_obj * diobj ;
2014-12-14 06:06:14 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " s " , & time_str , & time_str_len ) = = FAILURE ) {
2008-05-02 20:49:16 +08:00
RETURN_FALSE ;
}
2014-12-14 06:06:14 +08:00
php_date_instantiate ( date_ce_interval , return_value ) ;
2008-05-02 20:49:16 +08:00
2011-12-06 14:21:08 +08:00
time = timelib_strtotime ( time_str , time_str_len , & err , DATE_TIMEZONEDB , php_date_parse_tzfile_wrapper ) ;
2014-03-16 17:14:31 +08:00
diobj = Z_PHPINTERVAL_P ( return_value ) ;
2008-05-02 20:49:16 +08:00
diobj - > diff = timelib_rel_time_clone ( & time - > relative ) ;
2008-07-21 04:58:51 +08:00
diobj - > initialized = 1 ;
2008-05-02 20:49:16 +08:00
timelib_time_dtor ( time ) ;
timelib_error_container_dtor ( err ) ;
}
/* }}} */
2008-04-25 20:35:58 +08:00
/* {{{ date_interval_format - */
2014-12-14 06:06:14 +08:00
static zend_string * date_interval_format ( char * format , size_t format_len , timelib_rel_time * t )
2008-04-25 20:35:58 +08:00
{
smart_str string = { 0 } ;
int i , length , have_format_spec = 0 ;
char buffer [ 33 ] ;
if ( ! format_len ) {
2015-06-29 21:44:54 +08:00
return ZSTR_EMPTY_ALLOC ( ) ;
2008-04-25 20:35:58 +08:00
}
for ( i = 0 ; i < format_len ; i + + ) {
if ( have_format_spec ) {
switch ( format [ i ] ) {
case ' Y ' : length = slprintf ( buffer , 32 , " %02d " , ( int ) t - > y ) ; break ;
case ' y ' : length = slprintf ( buffer , 32 , " %d " , ( int ) t - > y ) ; break ;
case ' M ' : length = slprintf ( buffer , 32 , " %02d " , ( int ) t - > m ) ; break ;
case ' m ' : length = slprintf ( buffer , 32 , " %d " , ( int ) t - > m ) ; break ;
case ' D ' : length = slprintf ( buffer , 32 , " %02d " , ( int ) t - > d ) ; break ;
case ' d ' : length = slprintf ( buffer , 32 , " %d " , ( int ) t - > d ) ; break ;
case ' H ' : length = slprintf ( buffer , 32 , " %02d " , ( int ) t - > h ) ; break ;
case ' h ' : length = slprintf ( buffer , 32 , " %d " , ( int ) t - > h ) ; break ;
case ' I ' : length = slprintf ( buffer , 32 , " %02d " , ( int ) t - > i ) ; break ;
case ' i ' : length = slprintf ( buffer , 32 , " %d " , ( int ) t - > i ) ; break ;
2014-08-26 02:22:49 +08:00
case ' S ' : length = slprintf ( buffer , 32 , " %02 " ZEND_LONG_FMT_SPEC , ( zend_long ) t - > s ) ; break ;
case ' s ' : length = slprintf ( buffer , 32 , ZEND_LONG_FMT , ( zend_long ) t - > s ) ; break ;
2008-04-25 20:35:58 +08:00
2010-03-07 23:26:39 +08:00
case ' a ' : {
if ( ( int ) t - > days ! = - 99999 ) {
length = slprintf ( buffer , 32 , " %d " , ( int ) t - > days ) ;
} else {
length = slprintf ( buffer , 32 , " (unknown) " ) ;
}
} break ;
2008-04-25 20:35:58 +08:00
case ' r ' : length = slprintf ( buffer , 32 , " %s " , t - > invert ? " - " : " " ) ; break ;
case ' R ' : length = slprintf ( buffer , 32 , " %c " , t - > invert ? ' - ' : ' + ' ) ; break ;
case ' % ' : length = slprintf ( buffer , 32 , " %% " ) ; break ;
default : buffer [ 0 ] = ' % ' ; buffer [ 1 ] = format [ i ] ; buffer [ 2 ] = ' \0 ' ; length = 2 ; break ;
}
smart_str_appendl ( & string , buffer , length ) ;
have_format_spec = 0 ;
} else {
if ( format [ i ] = = ' % ' ) {
have_format_spec = 1 ;
} else {
smart_str_appendc ( & string , format [ i ] ) ;
}
}
}
smart_str_0 ( & string ) ;
2016-04-05 17:24:23 +08:00
if ( string . s = = NULL ) {
return ZSTR_EMPTY_ALLOC ( ) ;
2016-03-24 07:57:50 +08:00
}
2014-02-18 17:42:46 +08:00
return string . s ;
2008-04-25 20:35:58 +08:00
}
/* }}} */
2009-05-20 03:23:33 +08:00
/* {{{ proto string date_interval_format(DateInterval object, string format)
2008-04-25 20:35:58 +08:00
Formats the interval .
*/
PHP_FUNCTION ( date_interval_format )
{
zval * object ;
php_interval_obj * diobj ;
char * format ;
2014-08-27 23:31:24 +08:00
size_t format_len ;
2008-04-25 20:35:58 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_method_parameters ( ZEND_NUM_ARGS ( ) , getThis ( ) , " Os " , & object , date_ce_interval , & format , & format_len ) = = FAILURE ) {
2008-04-25 20:35:58 +08:00
RETURN_FALSE ;
}
2014-03-16 17:14:31 +08:00
diobj = Z_PHPINTERVAL_P ( object ) ;
2008-04-25 20:35:58 +08:00
DATE_CHECK_INITIALIZED ( diobj - > initialized , DateInterval ) ;
2014-12-14 06:06:14 +08:00
RETURN_STR ( date_interval_format ( format , format_len , diobj - > diff ) ) ;
2008-04-25 20:35:58 +08:00
}
/* }}} */
2008-05-01 08:12:24 +08:00
2014-12-14 06:06:14 +08:00
static int date_period_initialize ( timelib_time * * st , timelib_time * * et , timelib_rel_time * * d , zend_long * recurrences , /*const*/ char * format , size_t format_length ) /* { { { */
2008-05-04 18:00:01 +08:00
{
timelib_time * b = NULL , * e = NULL ;
timelib_rel_time * p = NULL ;
int r = 0 ;
int retval = 0 ;
struct timelib_error_container * errors ;
timelib_strtointerval ( format , format_length , & b , & e , & p , & r , & errors ) ;
2015-01-03 17:22:58 +08:00
2008-05-04 18:00:01 +08:00
if ( errors - > error_count > 0 ) {
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , E_WARNING , " Unknown or bad format (%s) " , format ) ;
2008-05-04 18:00:01 +08:00
retval = FAILURE ;
} else {
* st = b ;
* et = e ;
* d = p ;
* recurrences = r ;
retval = SUCCESS ;
}
timelib_error_container_dtor ( errors ) ;
return retval ;
2014-03-16 17:14:31 +08:00
} /* }}} */
2008-05-04 18:00:01 +08:00
2008-05-03 18:59:36 +08:00
/* {{{ proto DatePeriod::__construct(DateTime $start, DateInterval $interval, int recurrences|DateTime $end)
2008-05-01 08:12:24 +08:00
Creates new DatePeriod object .
*/
PHP_METHOD ( DatePeriod , __construct )
{
php_period_obj * dpobj ;
php_date_obj * dateobj ;
php_interval_obj * intobj ;
2008-05-03 18:59:36 +08:00
zval * start , * end = NULL , * interval ;
2014-08-26 01:24:55 +08:00
zend_long recurrences = 0 , options = 0 ;
2008-05-04 18:00:01 +08:00
char * isostr = NULL ;
2014-08-27 21:31:48 +08:00
size_t isostr_len = 0 ;
2008-05-01 08:12:24 +08:00
timelib_time * clone ;
2008-11-19 10:00:53 +08:00
zend_error_handling error_handling ;
2015-01-03 17:22:58 +08:00
2014-12-14 06:06:14 +08:00
zend_replace_error_handling ( EH_THROW , NULL , & error_handling ) ;
if ( zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET , ZEND_NUM_ARGS ( ) , " OOl|l " , & start , date_ce_interface , & interval , date_ce_interval , & recurrences , & options ) = = FAILURE ) {
if ( zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET , ZEND_NUM_ARGS ( ) , " OOO|l " , & start , date_ce_interface , & interval , date_ce_interval , & end , date_ce_interface , & options ) = = FAILURE ) {
if ( zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET , ZEND_NUM_ARGS ( ) , " s|l " , & isostr , & isostr_len , & options ) = = FAILURE ) {
php_error_docref ( NULL , E_WARNING , " This constructor accepts either (DateTimeInterface, DateInterval, int) OR (DateTimeInterface, DateInterval, DateTime) OR (string) as arguments. " ) ;
zend_restore_error_handling ( & error_handling ) ;
2008-05-04 18:00:01 +08:00
return ;
}
2008-05-03 18:59:36 +08:00
}
2008-05-01 08:12:24 +08:00
}
2014-03-16 17:14:31 +08:00
dpobj = Z_PHPPERIOD_P ( getThis ( ) ) ;
2010-08-30 23:32:09 +08:00
dpobj - > current = NULL ;
2008-05-01 08:12:24 +08:00
2011-03-23 09:22:18 +08:00
if ( isostr ) {
2014-12-14 06:06:14 +08:00
date_period_initialize ( & ( dpobj - > start ) , & ( dpobj - > end ) , & ( dpobj - > interval ) , & recurrences , isostr , isostr_len ) ;
2008-05-04 18:00:01 +08:00
if ( dpobj - > start = = NULL ) {
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , E_WARNING , " The ISO interval '%s' did not contain a start date. " , isostr ) ;
2008-05-04 18:00:01 +08:00
}
if ( dpobj - > interval = = NULL ) {
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , E_WARNING , " The ISO interval '%s' did not contain an interval. " , isostr ) ;
2008-05-04 18:00:01 +08:00
}
if ( dpobj - > end = = NULL & & recurrences = = 0 ) {
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , E_WARNING , " The ISO interval '%s' did not contain an end date or a recurrence count. " , isostr ) ;
2008-05-04 18:00:01 +08:00
}
2008-05-01 08:12:24 +08:00
2008-07-21 04:58:51 +08:00
if ( dpobj - > start ) {
timelib_update_ts ( dpobj - > start , NULL ) ;
}
2008-05-04 18:00:01 +08:00
if ( dpobj - > end ) {
timelib_update_ts ( dpobj - > end , NULL ) ;
}
2012-12-20 21:22:18 +08:00
dpobj - > start_ce = date_ce_date ;
2008-05-04 18:00:01 +08:00
} else {
/* init */
2014-03-16 17:14:31 +08:00
intobj = Z_PHPINTERVAL_P ( interval ) ;
2008-05-03 18:59:36 +08:00
2008-05-04 18:00:01 +08:00
/* start date */
2014-03-16 17:14:31 +08:00
dateobj = Z_PHPDATE_P ( start ) ;
2008-05-03 18:59:36 +08:00
clone = timelib_time_ctor ( ) ;
memcpy ( clone , dateobj - > time , sizeof ( timelib_time ) ) ;
if ( dateobj - > time - > tz_abbr ) {
2015-09-22 16:17:50 +08:00
clone - > tz_abbr = timelib_strdup ( dateobj - > time - > tz_abbr ) ;
2008-05-03 18:59:36 +08:00
}
if ( dateobj - > time - > tz_info ) {
2008-07-09 01:41:51 +08:00
clone - > tz_info = dateobj - > time - > tz_info ;
2008-05-03 18:59:36 +08:00
}
2008-05-04 18:00:01 +08:00
dpobj - > start = clone ;
2012-12-20 21:22:18 +08:00
dpobj - > start_ce = Z_OBJCE_P ( start ) ;
2008-05-04 18:00:01 +08:00
/* interval */
dpobj - > interval = timelib_rel_time_clone ( intobj - > diff ) ;
/* end date */
if ( end ) {
2014-03-16 17:14:31 +08:00
dateobj = Z_PHPDATE_P ( end ) ;
2010-08-30 23:32:09 +08:00
clone = timelib_time_clone ( dateobj - > time ) ;
2008-05-04 18:00:01 +08:00
dpobj - > end = clone ;
}
2008-05-03 18:59:36 +08:00
}
/* options */
2008-05-01 21:31:22 +08:00
dpobj - > include_start_date = ! ( options & PHP_DATE_PERIOD_EXCLUDE_START_DATE ) ;
2008-05-03 18:59:36 +08:00
/* recurrrences */
2008-05-01 21:31:22 +08:00
dpobj - > recurrences = recurrences + dpobj - > include_start_date ;
2008-05-01 08:12:24 +08:00
2008-05-03 18:59:36 +08:00
dpobj - > initialized = 1 ;
2008-11-19 10:00:53 +08:00
2014-12-14 06:06:14 +08:00
zend_restore_error_handling ( & error_handling ) ;
2008-05-01 08:12:24 +08:00
}
/* }}} */
2014-10-20 16:27:56 +08:00
/* {{{ proto DatePeriod::getStartDate()
Get start date .
*/
PHP_METHOD ( DatePeriod , getStartDate )
{
php_period_obj * dpobj ;
php_date_obj * dateobj ;
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
}
dpobj = Z_PHPPERIOD_P ( getThis ( ) ) ;
2014-12-14 06:06:14 +08:00
php_date_instantiate ( dpobj - > start_ce , return_value ) ;
2014-10-20 16:27:56 +08:00
dateobj = Z_PHPDATE_P ( return_value ) ;
dateobj - > time = timelib_time_ctor ( ) ;
* dateobj - > time = * dpobj - > start ;
if ( dpobj - > start - > tz_abbr ) {
2015-09-22 16:17:50 +08:00
dateobj - > time - > tz_abbr = timelib_strdup ( dpobj - > start - > tz_abbr ) ;
2014-10-20 16:27:56 +08:00
}
if ( dpobj - > start - > tz_info ) {
dateobj - > time - > tz_info = dpobj - > start - > tz_info ;
}
}
/* }}} */
/* {{{ proto DatePeriod::getEndDate()
Get end date .
*/
PHP_METHOD ( DatePeriod , getEndDate )
{
php_period_obj * dpobj ;
php_date_obj * dateobj ;
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
}
dpobj = Z_PHPPERIOD_P ( getThis ( ) ) ;
2016-03-07 17:40:22 +08:00
if ( ! dpobj - > end ) {
return ;
}
2014-12-14 06:06:14 +08:00
php_date_instantiate ( dpobj - > start_ce , return_value ) ;
2014-10-20 16:27:56 +08:00
dateobj = Z_PHPDATE_P ( return_value ) ;
dateobj - > time = timelib_time_ctor ( ) ;
* dateobj - > time = * dpobj - > end ;
if ( dpobj - > end - > tz_abbr ) {
2015-09-22 16:17:50 +08:00
dateobj - > time - > tz_abbr = timelib_strdup ( dpobj - > end - > tz_abbr ) ;
2014-10-20 16:27:56 +08:00
}
if ( dpobj - > end - > tz_info ) {
dateobj - > time - > tz_info = dpobj - > end - > tz_info ;
}
}
/* }}} */
/* {{{ proto DatePeriod::getDateInterval()
Get date interval .
2015-01-03 17:22:58 +08:00
*/
2014-10-20 16:27:56 +08:00
PHP_METHOD ( DatePeriod , getDateInterval )
{
php_period_obj * dpobj ;
php_interval_obj * diobj ;
2015-01-03 17:22:58 +08:00
2014-10-20 16:27:56 +08:00
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
}
dpobj = Z_PHPPERIOD_P ( getThis ( ) ) ;
2014-12-14 06:06:14 +08:00
php_date_instantiate ( date_ce_interval , return_value ) ;
2014-10-20 16:27:56 +08:00
diobj = Z_PHPINTERVAL_P ( return_value ) ;
diobj - > diff = timelib_rel_time_clone ( dpobj - > interval ) ;
diobj - > initialized = 1 ;
}
/* }}} */
2014-08-26 01:24:55 +08:00
static int check_id_allowed ( char * id , zend_long what ) /* { { { */
2008-01-28 01:29:14 +08:00
{
2008-02-27 17:47:35 +08:00
if ( what & PHP_DATE_TIMEZONE_GROUP_AFRICA & & strncasecmp ( id , " Africa/ " , 7 ) = = 0 ) return 1 ;
2008-01-28 01:29:14 +08:00
if ( what & PHP_DATE_TIMEZONE_GROUP_AMERICA & & strncasecmp ( id , " America/ " , 8 ) = = 0 ) return 1 ;
if ( what & PHP_DATE_TIMEZONE_GROUP_ANTARCTICA & & strncasecmp ( id , " Antarctica/ " , 11 ) = = 0 ) return 1 ;
if ( what & PHP_DATE_TIMEZONE_GROUP_ARCTIC & & strncasecmp ( id , " Arctic/ " , 7 ) = = 0 ) return 1 ;
if ( what & PHP_DATE_TIMEZONE_GROUP_ASIA & & strncasecmp ( id , " Asia/ " , 5 ) = = 0 ) return 1 ;
if ( what & PHP_DATE_TIMEZONE_GROUP_ATLANTIC & & strncasecmp ( id , " Atlantic/ " , 9 ) = = 0 ) return 1 ;
if ( what & PHP_DATE_TIMEZONE_GROUP_AUSTRALIA & & strncasecmp ( id , " Australia/ " , 10 ) = = 0 ) return 1 ;
if ( what & PHP_DATE_TIMEZONE_GROUP_EUROPE & & strncasecmp ( id , " Europe/ " , 7 ) = = 0 ) return 1 ;
if ( what & PHP_DATE_TIMEZONE_GROUP_INDIAN & & strncasecmp ( id , " Indian/ " , 7 ) = = 0 ) return 1 ;
if ( what & PHP_DATE_TIMEZONE_GROUP_PACIFIC & & strncasecmp ( id , " Pacific/ " , 8 ) = = 0 ) return 1 ;
if ( what & PHP_DATE_TIMEZONE_GROUP_UTC & & strncasecmp ( id , " UTC " , 3 ) = = 0 ) return 1 ;
return 0 ;
2014-03-16 17:14:31 +08:00
} /* }}} */
2008-01-28 01:29:14 +08:00
2009-06-22 04:40:53 +08:00
/* {{{ proto array timezone_identifiers_list([long what[, string country]])
2006-11-03 22:38:45 +08:00
Returns numerically index array with all timezone identifiers .
2006-09-11 01:01:51 +08:00
*/
2005-07-20 16:31:02 +08:00
PHP_FUNCTION ( timezone_identifiers_list )
{
2006-05-15 01:36:05 +08:00
const timelib_tzdb * tzdb ;
const timelib_tzdb_index_entry * table ;
int i , item_count ;
2014-08-26 01:24:55 +08:00
zend_long what = PHP_DATE_TIMEZONE_GROUP_ALL ;
2008-10-22 07:39:15 +08:00
char * option = NULL ;
2014-08-27 21:31:48 +08:00
size_t option_len = 0 ;
2008-01-28 01:29:14 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " |ls " , & what , & option , & option_len ) = = FAILURE ) {
2008-07-18 22:33:53 +08:00
RETURN_FALSE ;
}
/* Extra validation */
if ( what = = PHP_DATE_TIMEZONE_PER_COUNTRY & & option_len ! = 2 ) {
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , E_NOTICE , " A two-letter ISO 3166-1 compatible country code is expected " ) ;
2008-01-28 01:29:14 +08:00
RETURN_FALSE ;
}
2005-10-03 19:17:28 +08:00
tzdb = DATE_TIMEZONEDB ;
item_count = tzdb - > index_size ;
table = tzdb - > index ;
2015-01-03 17:22:58 +08:00
2005-07-20 16:31:02 +08:00
array_init ( return_value ) ;
for ( i = 0 ; i < item_count ; + + i ) {
2008-07-18 22:33:53 +08:00
if ( what = = PHP_DATE_TIMEZONE_PER_COUNTRY ) {
if ( tzdb - > data [ table [ i ] . pos + 5 ] = = option [ 0 ] & & tzdb - > data [ table [ i ] . pos + 6 ] = = option [ 1 ] ) {
2014-04-15 19:40:40 +08:00
add_next_index_string ( return_value , table [ i ] . id ) ;
2008-07-18 22:33:53 +08:00
}
} else if ( what = = PHP_DATE_TIMEZONE_GROUP_ALL_W_BC | | ( check_id_allowed ( table [ i ] . id , what ) & & ( tzdb - > data [ table [ i ] . pos + 4 ] = = ' \1 ' ) ) ) {
2014-04-15 19:40:40 +08:00
add_next_index_string ( return_value , table [ i ] . id ) ;
2008-01-28 01:29:14 +08:00
}
2005-07-20 16:31:02 +08:00
} ;
}
2006-09-11 01:01:51 +08:00
/* }}} */
2005-07-20 16:31:02 +08:00
2009-05-04 03:58:49 +08:00
/* {{{ proto array timezone_version_get()
Returns the Olson database version number .
*/
PHP_FUNCTION ( timezone_version_get )
{
const timelib_tzdb * tzdb ;
tzdb = DATE_TIMEZONEDB ;
2014-02-10 14:04:30 +08:00
RETURN_STRING ( tzdb - > version ) ;
2009-05-04 03:58:49 +08:00
}
/* }}} */
2006-11-03 22:38:45 +08:00
/* {{{ proto array timezone_abbreviations_list()
Returns associative array containing dst , offset and the timezone name
2006-09-11 01:01:51 +08:00
*/
2005-07-20 16:31:02 +08:00
PHP_FUNCTION ( timezone_abbreviations_list )
{
2006-05-15 01:36:05 +08:00
const timelib_tz_lookup_table * table , * entry ;
2014-02-10 14:04:30 +08:00
zval element , * abbr_array_p , abbr_array ;
2015-01-03 17:22:58 +08:00
2005-07-20 16:31:02 +08:00
table = timelib_timezone_abbreviations_list ( ) ;
array_init ( return_value ) ;
entry = table ;
2005-10-03 19:17:28 +08:00
2005-07-20 16:31:02 +08:00
do {
2014-02-10 14:04:30 +08:00
array_init ( & element ) ;
2014-09-21 02:05:27 +08:00
add_assoc_bool_ex ( & element , " dst " , sizeof ( " dst " ) - 1 , entry - > type ) ;
add_assoc_long_ex ( & element , " offset " , sizeof ( " offset " ) - 1 , entry - > gmtoffset ) ;
2005-07-20 16:31:02 +08:00
if ( entry - > full_tz_name ) {
2014-09-21 02:05:27 +08:00
add_assoc_string_ex ( & element , " timezone_id " , sizeof ( " timezone_id " ) - 1 , entry - > full_tz_name ) ;
2005-07-20 16:31:02 +08:00
} else {
2014-09-21 02:05:27 +08:00
add_assoc_null_ex ( & element , " timezone_id " , sizeof ( " timezone_id " ) - 1 ) ;
2005-07-20 16:31:02 +08:00
}
2015-09-25 03:39:59 +08:00
abbr_array_p = zend_hash_str_find ( Z_ARRVAL_P ( return_value ) , entry - > name , strlen ( entry - > name ) ) ;
2014-02-10 14:04:30 +08:00
if ( ! abbr_array_p ) {
array_init ( & abbr_array ) ;
add_assoc_zval ( return_value , entry - > name , & abbr_array ) ;
2005-10-03 19:17:28 +08:00
} else {
2014-02-10 14:04:30 +08:00
ZVAL_COPY_VALUE ( & abbr_array , abbr_array_p ) ;
2005-10-03 19:17:28 +08:00
}
2014-02-10 14:04:30 +08:00
add_next_index_zval ( & abbr_array , & element ) ;
2005-07-20 16:31:02 +08:00
entry + + ;
} while ( entry - > name ) ;
}
2006-09-11 01:01:51 +08:00
/* }}} */
2005-07-20 16:31:02 +08:00
/* {{{ proto bool date_default_timezone_set(string timezone_identifier)
2005-07-05 05:27:26 +08:00
Sets the default timezone used by all date / time functions in a script */
PHP_FUNCTION ( date_default_timezone_set )
2005-07-03 05:19:25 +08:00
{
char * zone ;
2014-08-27 21:31:48 +08:00
size_t zone_len ;
2005-07-03 05:19:25 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " s " , & zone , & zone_len ) = = FAILURE ) {
2005-07-03 05:19:25 +08:00
RETURN_FALSE ;
}
2005-12-21 03:54:10 +08:00
if ( ! timelib_timezone_id_is_valid ( zone , DATE_TIMEZONEDB ) ) {
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , E_NOTICE , " Timezone ID '%s' is invalid " , zone ) ;
2005-12-21 03:54:10 +08:00
RETURN_FALSE ;
}
2005-07-03 05:19:25 +08:00
if ( DATEG ( timezone ) ) {
efree ( DATEG ( timezone ) ) ;
2005-07-05 02:13:15 +08:00
DATEG ( timezone ) = NULL ;
2005-07-03 05:19:25 +08:00
}
2005-07-04 02:56:57 +08:00
DATEG ( timezone ) = estrndup ( zone , zone_len ) ;
2005-07-03 05:19:25 +08:00
RETURN_TRUE ;
}
2005-07-05 05:27:26 +08:00
/* }}} */
2005-07-03 05:19:25 +08:00
2005-07-20 16:31:02 +08:00
/* {{{ proto string date_default_timezone_get()
2005-07-05 05:27:26 +08:00
Gets the default timezone used by all date / time functions in a script */
PHP_FUNCTION ( date_default_timezone_get )
2005-07-03 05:19:25 +08:00
{
2005-07-20 16:31:02 +08:00
timelib_tzinfo * default_tz ;
2014-12-14 06:06:14 +08:00
default_tz = get_timezone_info ( ) ;
2014-02-10 14:04:30 +08:00
RETVAL_STRING ( default_tz - > name ) ;
2005-07-03 05:19:25 +08:00
}
2005-07-05 05:27:26 +08:00
/* }}} */
2005-07-03 05:19:25 +08:00
2006-01-05 05:31:35 +08:00
/* {{{ php_do_date_sunrise_sunset
* Common for date_sunrise ( ) and date_sunset ( ) functions
*/
static void php_do_date_sunrise_sunset ( INTERNAL_FUNCTION_PARAMETERS , int calc_sunset )
{
2008-10-22 07:39:15 +08:00
double latitude = 0.0 , longitude = 0.0 , zenith = 0.0 , gmt_offset = 0 , altitude ;
2006-01-05 05:31:35 +08:00
double h_rise , h_set , N ;
timelib_sll rise , set , transit ;
2014-08-26 01:24:55 +08:00
zend_long time , retformat = 0 ;
2006-01-05 05:31:35 +08:00
int rs ;
timelib_time * t ;
timelib_tzinfo * tzi ;
2014-08-13 23:43:34 +08:00
zend_string * retstr ;
2015-01-03 17:22:58 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " l|ldddd " , & time , & retformat , & latitude , & longitude , & zenith , & gmt_offset ) = = FAILURE ) {
2006-01-05 05:31:35 +08:00
RETURN_FALSE ;
}
2015-01-03 17:22:58 +08:00
2006-01-05 05:31:35 +08:00
switch ( ZEND_NUM_ARGS ( ) ) {
case 1 :
retformat = SUNFUNCS_RET_STRING ;
case 2 :
latitude = INI_FLT ( " date.default_latitude " ) ;
case 3 :
longitude = INI_FLT ( " date.default_longitude " ) ;
case 4 :
if ( calc_sunset ) {
zenith = INI_FLT ( " date.sunset_zenith " ) ;
} else {
zenith = INI_FLT ( " date.sunrise_zenith " ) ;
}
case 5 :
case 6 :
break ;
default :
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , E_WARNING , " invalid format " ) ;
2006-01-05 05:31:35 +08:00
RETURN_FALSE ;
break ;
}
if ( retformat ! = SUNFUNCS_RET_TIMESTAMP & &
retformat ! = SUNFUNCS_RET_STRING & &
retformat ! = SUNFUNCS_RET_DOUBLE )
{
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , E_WARNING , " Wrong return format given, pick one of SUNFUNCS_RET_TIMESTAMP, SUNFUNCS_RET_STRING or SUNFUNCS_RET_DOUBLE " ) ;
2006-01-05 05:31:35 +08:00
RETURN_FALSE ;
}
altitude = 90 - zenith ;
/* Initialize time struct */
t = timelib_time_ctor ( ) ;
2014-12-14 06:06:14 +08:00
tzi = get_timezone_info ( ) ;
2006-01-05 05:31:35 +08:00
t - > tz_info = tzi ;
t - > zone_type = TIMELIB_ZONETYPE_ID ;
if ( ZEND_NUM_ARGS ( ) < = 5 ) {
gmt_offset = timelib_get_current_offset ( t ) / 3600 ;
}
timelib_unixtime2local ( t , time ) ;
2009-09-26 08:53:59 +08:00
rs = timelib_astro_rise_set_altitude ( t , longitude , latitude , altitude , 1 , & h_rise , & h_set , & rise , & set , & transit ) ;
2006-03-19 07:43:48 +08:00
timelib_time_dtor ( t ) ;
2015-01-03 17:22:58 +08:00
2006-01-05 05:31:35 +08:00
if ( rs ! = 0 ) {
RETURN_FALSE ;
}
if ( retformat = = SUNFUNCS_RET_TIMESTAMP ) {
2014-08-26 01:24:55 +08:00
RETURN_LONG ( calc_sunset ? set : rise ) ;
2006-01-05 05:31:35 +08:00
}
N = ( calc_sunset ? h_set : h_rise ) + gmt_offset ;
2007-06-07 06:58:42 +08:00
2007-06-08 07:16:04 +08:00
if ( N > 24 | | N < 0 ) {
2007-06-07 10:21:26 +08:00
N - = floor ( N / 24 ) * 24 ;
2006-01-05 05:31:35 +08:00
}
2007-06-07 06:58:42 +08:00
2006-01-05 05:31:35 +08:00
switch ( retformat ) {
case SUNFUNCS_RET_STRING :
2014-08-13 23:43:34 +08:00
retstr = strpprintf ( 0 , " %02d:%02d " , ( int ) N , ( int ) ( 60 * ( N - ( int ) N ) ) ) ;
2015-03-12 21:53:51 +08:00
RETURN_NEW_STR ( retstr ) ;
2006-01-05 05:31:35 +08:00
break ;
case SUNFUNCS_RET_DOUBLE :
RETURN_DOUBLE ( N ) ;
break ;
}
}
/* }}} */
/* {{{ proto mixed date_sunrise(mixed time [, int format [, float latitude [, float longitude [, float zenith [, float gmt_offset]]]]])
Returns time of sunrise for a given day and location */
PHP_FUNCTION ( date_sunrise )
{
php_do_date_sunrise_sunset ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 0 ) ;
}
/* }}} */
/* {{{ proto mixed date_sunset(mixed time [, int format [, float latitude [, float longitude [, float zenith [, float gmt_offset]]]]])
Returns time of sunset for a given day and location */
PHP_FUNCTION ( date_sunset )
{
php_do_date_sunrise_sunset ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 1 ) ;
}
/* }}} */
/* {{{ proto array date_sun_info(long time, float latitude, float longitude)
Returns an array with information about sun set / rise and twilight begin / end */
PHP_FUNCTION ( date_sun_info )
{
2014-08-26 01:24:55 +08:00
zend_long time ;
2006-01-05 05:31:35 +08:00
double latitude , longitude ;
timelib_time * t , * t2 ;
timelib_tzinfo * tzi ;
int rs ;
timelib_sll rise , set , transit ;
int dummy ;
double ddummy ;
2015-01-03 17:22:58 +08:00
2014-12-14 06:06:14 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " ldd " , & time , & latitude , & longitude ) = = FAILURE ) {
2006-01-05 05:31:35 +08:00
RETURN_FALSE ;
}
/* Initialize time struct */
t = timelib_time_ctor ( ) ;
2014-12-14 06:06:14 +08:00
tzi = get_timezone_info ( ) ;
2006-01-05 05:31:35 +08:00
t - > tz_info = tzi ;
t - > zone_type = TIMELIB_ZONETYPE_ID ;
timelib_unixtime2local ( t , time ) ;
/* Setup */
t2 = timelib_time_ctor ( ) ;
array_init ( return_value ) ;
2015-01-03 17:22:58 +08:00
2006-01-05 05:31:35 +08:00
/* Get sun up/down and transit */
2007-04-13 16:33:48 +08:00
rs = timelib_astro_rise_set_altitude ( t , longitude , latitude , - 35.0 / 60 , 1 , & ddummy , & ddummy , & rise , & set , & transit ) ;
2006-01-05 05:31:35 +08:00
switch ( rs ) {
case - 1 : /* always below */
add_assoc_bool ( return_value , " sunrise " , 0 ) ;
add_assoc_bool ( return_value , " sunset " , 0 ) ;
break ;
case 1 : /* always above */
add_assoc_bool ( return_value , " sunrise " , 1 ) ;
add_assoc_bool ( return_value , " sunset " , 1 ) ;
break ;
default :
t2 - > sse = rise ;
2014-08-26 01:24:55 +08:00
add_assoc_long ( return_value , " sunrise " , timelib_date_to_int ( t2 , & dummy ) ) ;
2006-01-05 05:31:35 +08:00
t2 - > sse = set ;
2014-08-26 01:24:55 +08:00
add_assoc_long ( return_value , " sunset " , timelib_date_to_int ( t2 , & dummy ) ) ;
2006-01-05 05:31:35 +08:00
}
t2 - > sse = transit ;
2014-08-26 01:24:55 +08:00
add_assoc_long ( return_value , " transit " , timelib_date_to_int ( t2 , & dummy ) ) ;
2006-01-05 05:31:35 +08:00
/* Get civil twilight */
2007-04-13 16:33:48 +08:00
rs = timelib_astro_rise_set_altitude ( t , longitude , latitude , - 6.0 , 0 , & ddummy , & ddummy , & rise , & set , & transit ) ;
2006-01-05 05:31:35 +08:00
switch ( rs ) {
case - 1 : /* always below */
add_assoc_bool ( return_value , " civil_twilight_begin " , 0 ) ;
add_assoc_bool ( return_value , " civil_twilight_end " , 0 ) ;
break ;
case 1 : /* always above */
add_assoc_bool ( return_value , " civil_twilight_begin " , 1 ) ;
add_assoc_bool ( return_value , " civil_twilight_end " , 1 ) ;
break ;
default :
t2 - > sse = rise ;
2014-08-26 01:24:55 +08:00
add_assoc_long ( return_value , " civil_twilight_begin " , timelib_date_to_int ( t2 , & dummy ) ) ;
2006-01-05 05:31:35 +08:00
t2 - > sse = set ;
2014-08-26 01:24:55 +08:00
add_assoc_long ( return_value , " civil_twilight_end " , timelib_date_to_int ( t2 , & dummy ) ) ;
2006-01-05 05:31:35 +08:00
}
/* Get nautical twilight */
2007-04-13 16:33:48 +08:00
rs = timelib_astro_rise_set_altitude ( t , longitude , latitude , - 12.0 , 0 , & ddummy , & ddummy , & rise , & set , & transit ) ;
2006-01-05 05:31:35 +08:00
switch ( rs ) {
case - 1 : /* always below */
add_assoc_bool ( return_value , " nautical_twilight_begin " , 0 ) ;
add_assoc_bool ( return_value , " nautical_twilight_end " , 0 ) ;
break ;
case 1 : /* always above */
add_assoc_bool ( return_value , " nautical_twilight_begin " , 1 ) ;
add_assoc_bool ( return_value , " nautical_twilight_end " , 1 ) ;
break ;
default :
t2 - > sse = rise ;
2014-08-26 01:24:55 +08:00
add_assoc_long ( return_value , " nautical_twilight_begin " , timelib_date_to_int ( t2 , & dummy ) ) ;
2006-01-05 05:31:35 +08:00
t2 - > sse = set ;
2014-08-26 01:24:55 +08:00
add_assoc_long ( return_value , " nautical_twilight_end " , timelib_date_to_int ( t2 , & dummy ) ) ;
2006-01-05 05:31:35 +08:00
}
/* Get astronomical twilight */
2007-04-13 16:33:48 +08:00
rs = timelib_astro_rise_set_altitude ( t , longitude , latitude , - 18.0 , 0 , & ddummy , & ddummy , & rise , & set , & transit ) ;
2006-01-05 05:31:35 +08:00
switch ( rs ) {
case - 1 : /* always below */
add_assoc_bool ( return_value , " astronomical_twilight_begin " , 0 ) ;
add_assoc_bool ( return_value , " astronomical_twilight_end " , 0 ) ;
break ;
case 1 : /* always above */
add_assoc_bool ( return_value , " astronomical_twilight_begin " , 1 ) ;
add_assoc_bool ( return_value , " astronomical_twilight_end " , 1 ) ;
break ;
default :
t2 - > sse = rise ;
2014-08-26 01:24:55 +08:00
add_assoc_long ( return_value , " astronomical_twilight_begin " , timelib_date_to_int ( t2 , & dummy ) ) ;
2006-01-05 05:31:35 +08:00
t2 - > sse = set ;
2014-08-26 01:24:55 +08:00
add_assoc_long ( return_value , " astronomical_twilight_end " , timelib_date_to_int ( t2 , & dummy ) ) ;
2006-01-05 05:31:35 +08:00
}
2006-03-19 07:43:48 +08:00
timelib_time_dtor ( t ) ;
timelib_time_dtor ( t2 ) ;
2006-01-05 05:31:35 +08:00
}
/* }}} */
2013-03-15 23:59:54 +08:00
2014-12-14 06:06:14 +08:00
static HashTable * date_object_get_gc_period ( zval * object , zval * * table , int * n ) /* { { { */
2013-03-15 23:59:54 +08:00
{
* table = NULL ;
* n = 0 ;
2014-12-14 06:06:14 +08:00
return zend_std_get_properties ( object ) ;
2014-03-16 17:14:31 +08:00
} /* }}} */
2013-03-15 23:59:54 +08:00
2014-12-14 06:06:14 +08:00
static HashTable * date_object_get_properties_period ( zval * object ) /* { { { */
2013-03-15 23:59:54 +08:00
{
HashTable * props ;
2014-02-10 14:04:30 +08:00
zval zv ;
2013-03-15 23:59:54 +08:00
php_period_obj * period_obj ;
2014-03-16 17:14:31 +08:00
period_obj = Z_PHPPERIOD_P ( object ) ;
2013-03-15 23:59:54 +08:00
2014-12-14 06:06:14 +08:00
props = zend_std_get_properties ( object ) ;
2013-03-15 23:59:54 +08:00
2016-06-15 04:36:09 +08:00
if ( ! period_obj - > start ) {
2013-03-15 23:59:54 +08:00
return props ;
}
if ( period_obj - > start ) {
php_date_obj * date_obj ;
2014-02-10 14:04:30 +08:00
object_init_ex ( & zv , date_ce_date ) ;
2014-03-16 17:14:31 +08:00
date_obj = Z_PHPDATE_P ( & zv ) ;
2013-03-15 23:59:54 +08:00
date_obj - > time = timelib_time_clone ( period_obj - > start ) ;
} else {
2014-02-10 14:04:30 +08:00
ZVAL_NULL ( & zv ) ;
2013-03-15 23:59:54 +08:00
}
2014-02-10 14:04:30 +08:00
zend_hash_str_update ( props , " start " , sizeof ( " start " ) - 1 , & zv ) ;
2013-03-15 23:59:54 +08:00
if ( period_obj - > current ) {
php_date_obj * date_obj ;
2014-02-10 14:04:30 +08:00
object_init_ex ( & zv , date_ce_date ) ;
2014-03-16 17:14:31 +08:00
date_obj = Z_PHPDATE_P ( & zv ) ;
2013-03-15 23:59:54 +08:00
date_obj - > time = timelib_time_clone ( period_obj - > current ) ;
} else {
2014-02-10 14:04:30 +08:00
ZVAL_NULL ( & zv ) ;
2013-03-15 23:59:54 +08:00
}
2014-02-10 14:04:30 +08:00
zend_hash_str_update ( props , " current " , sizeof ( " current " ) - 1 , & zv ) ;
2013-03-15 23:59:54 +08:00
if ( period_obj - > end ) {
php_date_obj * date_obj ;
2014-02-10 14:04:30 +08:00
object_init_ex ( & zv , date_ce_date ) ;
2014-03-16 17:14:31 +08:00
date_obj = Z_PHPDATE_P ( & zv ) ;
2013-03-15 23:59:54 +08:00
date_obj - > time = timelib_time_clone ( period_obj - > end ) ;
} else {
2014-02-10 14:04:30 +08:00
ZVAL_NULL ( & zv ) ;
2013-03-15 23:59:54 +08:00
}
2014-02-10 14:04:30 +08:00
zend_hash_str_update ( props , " end " , sizeof ( " end " ) - 1 , & zv ) ;
2013-03-15 23:59:54 +08:00
if ( period_obj - > interval ) {
php_interval_obj * interval_obj ;
2014-02-10 14:04:30 +08:00
object_init_ex ( & zv , date_ce_interval ) ;
2014-03-16 17:14:31 +08:00
interval_obj = Z_PHPINTERVAL_P ( & zv ) ;
2013-03-15 23:59:54 +08:00
interval_obj - > diff = timelib_rel_time_clone ( period_obj - > interval ) ;
interval_obj - > initialized = 1 ;
} else {
2014-02-10 14:04:30 +08:00
ZVAL_NULL ( & zv ) ;
2013-03-15 23:59:54 +08:00
}
2014-02-10 14:04:30 +08:00
zend_hash_str_update ( props , " interval " , sizeof ( " interval " ) - 1 , & zv ) ;
2015-01-03 17:22:58 +08:00
2013-03-15 23:59:54 +08:00
/* converted to larger type (int->long); must check when unserializing */
2014-08-26 17:23:25 +08:00
ZVAL_LONG ( & zv , ( zend_long ) period_obj - > recurrences ) ;
2014-02-10 14:04:30 +08:00
zend_hash_str_update ( props , " recurrences " , sizeof ( " recurrences " ) - 1 , & zv ) ;
2013-03-15 23:59:54 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_BOOL ( & zv , period_obj - > include_start_date ) ;
zend_hash_str_update ( props , " include_start_date " , sizeof ( " include_start_date " ) - 1 , & zv ) ;
2013-03-15 23:59:54 +08:00
return props ;
2014-03-16 17:14:31 +08:00
} /* }}} */
2013-03-15 23:59:54 +08:00
2014-12-14 06:06:14 +08:00
static int php_date_period_initialize_from_hash ( php_period_obj * period_obj , HashTable * myht ) /* { { { */
2013-03-15 23:59:54 +08:00
{
2014-02-10 14:04:30 +08:00
zval * ht_entry ;
2013-03-15 23:59:54 +08:00
/* this function does no rollback on error */
2014-02-10 14:04:30 +08:00
ht_entry = zend_hash_str_find ( myht , " start " , sizeof ( " start " ) - 1 ) ;
if ( ht_entry ) {
if ( Z_TYPE_P ( ht_entry ) = = IS_OBJECT & & Z_OBJCE_P ( ht_entry ) = = date_ce_date ) {
2013-03-15 23:59:54 +08:00
php_date_obj * date_obj ;
2014-03-16 17:14:31 +08:00
date_obj = Z_PHPDATE_P ( ht_entry ) ;
2013-03-15 23:59:54 +08:00
period_obj - > start = timelib_time_clone ( date_obj - > time ) ;
2014-02-10 14:04:30 +08:00
period_obj - > start_ce = Z_OBJCE_P ( ht_entry ) ;
} else if ( Z_TYPE_P ( ht_entry ) ! = IS_NULL ) {
2013-03-15 23:59:54 +08:00
return 0 ;
}
} else {
return 0 ;
}
2014-02-10 14:04:30 +08:00
ht_entry = zend_hash_str_find ( myht , " end " , sizeof ( " end " ) - 1 ) ;
if ( ht_entry ) {
if ( Z_TYPE_P ( ht_entry ) = = IS_OBJECT & & Z_OBJCE_P ( ht_entry ) = = date_ce_date ) {
2013-03-15 23:59:54 +08:00
php_date_obj * date_obj ;
2014-03-16 17:14:31 +08:00
date_obj = Z_PHPDATE_P ( ht_entry ) ;
2013-03-15 23:59:54 +08:00
period_obj - > end = timelib_time_clone ( date_obj - > time ) ;
2014-02-10 14:04:30 +08:00
} else if ( Z_TYPE_P ( ht_entry ) ! = IS_NULL ) {
2013-03-15 23:59:54 +08:00
return 0 ;
}
} else {
return 0 ;
}
2014-02-10 14:04:30 +08:00
ht_entry = zend_hash_str_find ( myht , " current " , sizeof ( " current " ) - 1 ) ;
if ( ht_entry ) {
if ( Z_TYPE_P ( ht_entry ) = = IS_OBJECT & & Z_OBJCE_P ( ht_entry ) = = date_ce_date ) {
2013-03-15 23:59:54 +08:00
php_date_obj * date_obj ;
2014-03-16 17:14:31 +08:00
date_obj = Z_PHPDATE_P ( ht_entry ) ;
2013-03-15 23:59:54 +08:00
period_obj - > current = timelib_time_clone ( date_obj - > time ) ;
2014-02-10 14:04:30 +08:00
} else if ( Z_TYPE_P ( ht_entry ) ! = IS_NULL ) {
2013-03-15 23:59:54 +08:00
return 0 ;
}
} else {
return 0 ;
}
2014-02-10 14:04:30 +08:00
ht_entry = zend_hash_str_find ( myht , " interval " , sizeof ( " interval " ) - 1 ) ;
if ( ht_entry ) {
if ( Z_TYPE_P ( ht_entry ) = = IS_OBJECT & & Z_OBJCE_P ( ht_entry ) = = date_ce_interval ) {
2013-03-15 23:59:54 +08:00
php_interval_obj * interval_obj ;
2014-03-16 17:14:31 +08:00
interval_obj = Z_PHPINTERVAL_P ( ht_entry ) ;
2013-03-15 23:59:54 +08:00
period_obj - > interval = timelib_rel_time_clone ( interval_obj - > diff ) ;
} else { /* interval is required */
return 0 ;
}
} else {
return 0 ;
}
2014-02-10 14:04:30 +08:00
ht_entry = zend_hash_str_find ( myht , " recurrences " , sizeof ( " recurrences " ) - 1 ) ;
if ( ht_entry & &
2014-08-26 01:24:55 +08:00
Z_TYPE_P ( ht_entry ) = = IS_LONG & & Z_LVAL_P ( ht_entry ) > = 0 & & Z_LVAL_P ( ht_entry ) < = INT_MAX ) {
period_obj - > recurrences = Z_LVAL_P ( ht_entry ) ;
2013-03-15 23:59:54 +08:00
} else {
return 0 ;
}
2014-02-10 14:04:30 +08:00
ht_entry = zend_hash_str_find ( myht , " include_start_date " , sizeof ( " include_start_date " ) - 1 ) ;
if ( ht_entry & &
2014-04-30 22:32:42 +08:00
( Z_TYPE_P ( ht_entry ) = = IS_FALSE | | Z_TYPE_P ( ht_entry ) = = IS_TRUE ) ) {
period_obj - > include_start_date = ( Z_TYPE_P ( ht_entry ) = = IS_TRUE ) ;
2013-03-15 23:59:54 +08:00
} else {
return 0 ;
}
period_obj - > initialized = 1 ;
2015-01-03 17:22:58 +08:00
2013-03-15 23:59:54 +08:00
return 1 ;
2014-03-16 17:14:31 +08:00
} /* }}} */
2013-03-15 23:59:54 +08:00
/* {{{ proto DatePeriod::__set_state()
*/
PHP_METHOD ( DatePeriod , __set_state )
{
php_period_obj * period_obj ;
zval * array ;
HashTable * myht ;
2014-12-14 06:06:14 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) , " a " , & array ) = = FAILURE ) {
2013-03-15 23:59:54 +08:00
RETURN_FALSE ;
}
myht = Z_ARRVAL_P ( array ) ;
2015-01-03 17:22:58 +08:00
2013-03-15 23:59:54 +08:00
object_init_ex ( return_value , date_ce_period ) ;
2014-03-16 17:14:31 +08:00
period_obj = Z_PHPPERIOD_P ( return_value ) ;
2014-12-14 06:06:14 +08:00
if ( ! php_date_period_initialize_from_hash ( period_obj , myht ) ) {
2013-03-15 23:59:54 +08:00
php_error ( E_ERROR , " Invalid serialization data for DatePeriod object " ) ;
}
}
/* }}} */
/* {{{ proto DatePeriod::__wakeup()
*/
PHP_METHOD ( DatePeriod , __wakeup )
{
zval * object = getThis ( ) ;
php_period_obj * period_obj ;
HashTable * myht ;
2014-03-16 17:14:31 +08:00
period_obj = Z_PHPPERIOD_P ( object ) ;
2013-03-15 23:59:54 +08:00
myht = Z_OBJPROP_P ( object ) ;
2014-12-14 06:06:14 +08:00
if ( ! php_date_period_initialize_from_hash ( period_obj , myht ) ) {
2013-03-15 23:59:54 +08:00
php_error ( E_ERROR , " Invalid serialization data for DatePeriod object " ) ;
}
}
/* }}} */
/* {{{ date_period_read_property */
2014-12-14 06:06:14 +08:00
static zval * date_period_read_property ( zval * object , zval * member , int type , void * * cache_slot , zval * rv )
2013-03-15 23:59:54 +08:00
{
zval * zv ;
if ( type ! = BP_VAR_IS & & type ! = BP_VAR_R ) {
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , E_ERROR , " Retrieval of DatePeriod properties for modification is unsupported " ) ;
2013-03-15 23:59:54 +08:00
}
Z_OBJPROP_P ( object ) ; /* build properties hash table */
2014-12-14 06:06:14 +08:00
zv = std_object_handlers . read_property ( object , member , type , cache_slot , rv ) ;
2013-03-15 23:59:54 +08:00
if ( Z_TYPE_P ( zv ) = = IS_OBJECT & & Z_OBJ_HANDLER_P ( zv , clone_obj ) ) {
/* defensive copy */
2014-12-14 06:06:14 +08:00
ZVAL_OBJ ( zv , Z_OBJ_HANDLER_P ( zv , clone_obj ) ( zv ) ) ;
2013-03-15 23:59:54 +08:00
}
return zv ;
}
/* }}} */
/* {{{ date_period_write_property */
2014-12-14 06:06:14 +08:00
static void date_period_write_property ( zval * object , zval * member , zval * value , void * * cache_slot )
2013-03-15 23:59:54 +08:00
{
2014-12-14 06:06:14 +08:00
php_error_docref ( NULL , E_ERROR , " Writing to DatePeriod properties is unsupported " ) ;
2013-03-15 23:59:54 +08:00
}
/* }}} */
2005-06-15 05:32:29 +08:00
/*
* Local variables :
* tab - width : 4
* c - basic - offset : 4
* End :
* vim600 : fdm = marker
* vim : noet sw = 4 ts = 4
*/