Annotation of embedaddon/php/ext/date/php_date.c, revision 1.1
1.1 ! misho 1: /*
! 2: +----------------------------------------------------------------------+
! 3: | PHP Version 5 |
! 4: +----------------------------------------------------------------------+
! 5: | Copyright (c) 1997-2012 The PHP Group |
! 6: +----------------------------------------------------------------------+
! 7: | This source file is subject to version 3.01 of the PHP license, |
! 8: | that is bundled with this package in the file LICENSE, and is |
! 9: | available through the world-wide-web at the following url: |
! 10: | http://www.php.net/license/3_01.txt |
! 11: | If you did not receive a copy of the PHP license and are unable to |
! 12: | obtain it through the world-wide-web, please send a note to |
! 13: | license@php.net so we can mail you a copy immediately. |
! 14: +----------------------------------------------------------------------+
! 15: | Authors: Derick Rethans <derick@derickrethans.nl> |
! 16: +----------------------------------------------------------------------+
! 17: */
! 18:
! 19: /* $Id: php_date.c 321634 2012-01-01 13:15:04Z felipe $ */
! 20:
! 21: #include "php.h"
! 22: #include "php_streams.h"
! 23: #include "php_main.h"
! 24: #include "php_globals.h"
! 25: #include "php_ini.h"
! 26: #include "ext/standard/info.h"
! 27: #include "ext/standard/php_versioning.h"
! 28: #include "ext/standard/php_math.h"
! 29: #include "php_date.h"
! 30: #include "zend_interfaces.h"
! 31: #include "lib/timelib.h"
! 32: #include <time.h>
! 33:
! 34: #ifdef PHP_WIN32
! 35: static __inline __int64 php_date_llabs( __int64 i ) { return i >= 0? i: -i; }
! 36: #elif defined(__GNUC__) && __GNUC__ < 3
! 37: static __inline __int64_t php_date_llabs( __int64_t i ) { return i >= 0 ? i : -i; }
! 38: #else
! 39: static inline long long php_date_llabs( long long i ) { return i >= 0 ? i : -i; }
! 40: #endif
! 41:
! 42: /* {{{ arginfo */
! 43: ZEND_BEGIN_ARG_INFO_EX(arginfo_date, 0, 0, 1)
! 44: ZEND_ARG_INFO(0, format)
! 45: ZEND_ARG_INFO(0, timestamp)
! 46: ZEND_END_ARG_INFO()
! 47:
! 48: ZEND_BEGIN_ARG_INFO_EX(arginfo_gmdate, 0, 0, 1)
! 49: ZEND_ARG_INFO(0, format)
! 50: ZEND_ARG_INFO(0, timestamp)
! 51: ZEND_END_ARG_INFO()
! 52:
! 53: ZEND_BEGIN_ARG_INFO_EX(arginfo_idate, 0, 0, 1)
! 54: ZEND_ARG_INFO(0, format)
! 55: ZEND_ARG_INFO(0, timestamp)
! 56: ZEND_END_ARG_INFO()
! 57:
! 58: ZEND_BEGIN_ARG_INFO_EX(arginfo_strtotime, 0, 0, 1)
! 59: ZEND_ARG_INFO(0, time)
! 60: ZEND_ARG_INFO(0, now)
! 61: ZEND_END_ARG_INFO()
! 62:
! 63: ZEND_BEGIN_ARG_INFO_EX(arginfo_mktime, 0, 0, 0)
! 64: ZEND_ARG_INFO(0, hour)
! 65: ZEND_ARG_INFO(0, min)
! 66: ZEND_ARG_INFO(0, sec)
! 67: ZEND_ARG_INFO(0, mon)
! 68: ZEND_ARG_INFO(0, day)
! 69: ZEND_ARG_INFO(0, year)
! 70: ZEND_END_ARG_INFO()
! 71:
! 72: ZEND_BEGIN_ARG_INFO_EX(arginfo_gmmktime, 0, 0, 0)
! 73: ZEND_ARG_INFO(0, hour)
! 74: ZEND_ARG_INFO(0, min)
! 75: ZEND_ARG_INFO(0, sec)
! 76: ZEND_ARG_INFO(0, mon)
! 77: ZEND_ARG_INFO(0, day)
! 78: ZEND_ARG_INFO(0, year)
! 79: ZEND_END_ARG_INFO()
! 80:
! 81: ZEND_BEGIN_ARG_INFO(arginfo_checkdate, 0)
! 82: ZEND_ARG_INFO(0, month)
! 83: ZEND_ARG_INFO(0, day)
! 84: ZEND_ARG_INFO(0, year)
! 85: ZEND_END_ARG_INFO()
! 86:
! 87: ZEND_BEGIN_ARG_INFO_EX(arginfo_strftime, 0, 0, 1)
! 88: ZEND_ARG_INFO(0, format)
! 89: ZEND_ARG_INFO(0, timestamp)
! 90: ZEND_END_ARG_INFO()
! 91:
! 92: ZEND_BEGIN_ARG_INFO_EX(arginfo_gmstrftime, 0, 0, 1)
! 93: ZEND_ARG_INFO(0, format)
! 94: ZEND_ARG_INFO(0, timestamp)
! 95: ZEND_END_ARG_INFO()
! 96:
! 97: ZEND_BEGIN_ARG_INFO(arginfo_time, 0)
! 98: ZEND_END_ARG_INFO()
! 99:
! 100: ZEND_BEGIN_ARG_INFO_EX(arginfo_localtime, 0, 0, 0)
! 101: ZEND_ARG_INFO(0, timestamp)
! 102: ZEND_ARG_INFO(0, associative_array)
! 103: ZEND_END_ARG_INFO()
! 104:
! 105: ZEND_BEGIN_ARG_INFO_EX(arginfo_getdate, 0, 0, 0)
! 106: ZEND_ARG_INFO(0, timestamp)
! 107: ZEND_END_ARG_INFO()
! 108:
! 109: ZEND_BEGIN_ARG_INFO(arginfo_date_default_timezone_set, 0)
! 110: ZEND_ARG_INFO(0, timezone_identifier)
! 111: ZEND_END_ARG_INFO()
! 112:
! 113: ZEND_BEGIN_ARG_INFO(arginfo_date_default_timezone_get, 0)
! 114: ZEND_END_ARG_INFO()
! 115:
! 116: ZEND_BEGIN_ARG_INFO_EX(arginfo_date_sunrise, 0, 0, 1)
! 117: ZEND_ARG_INFO(0, time)
! 118: ZEND_ARG_INFO(0, format)
! 119: ZEND_ARG_INFO(0, latitude)
! 120: ZEND_ARG_INFO(0, longitude)
! 121: ZEND_ARG_INFO(0, zenith)
! 122: ZEND_ARG_INFO(0, gmt_offset)
! 123: ZEND_END_ARG_INFO()
! 124:
! 125: ZEND_BEGIN_ARG_INFO_EX(arginfo_date_sunset, 0, 0, 1)
! 126: ZEND_ARG_INFO(0, time)
! 127: ZEND_ARG_INFO(0, format)
! 128: ZEND_ARG_INFO(0, latitude)
! 129: ZEND_ARG_INFO(0, longitude)
! 130: ZEND_ARG_INFO(0, zenith)
! 131: ZEND_ARG_INFO(0, gmt_offset)
! 132: ZEND_END_ARG_INFO()
! 133:
! 134: ZEND_BEGIN_ARG_INFO(arginfo_date_sun_info, 0)
! 135: ZEND_ARG_INFO(0, time)
! 136: ZEND_ARG_INFO(0, latitude)
! 137: ZEND_ARG_INFO(0, longitude)
! 138: ZEND_END_ARG_INFO()
! 139:
! 140: ZEND_BEGIN_ARG_INFO_EX(arginfo_date_create, 0, 0, 0)
! 141: ZEND_ARG_INFO(0, time)
! 142: ZEND_ARG_INFO(0, object)
! 143: ZEND_END_ARG_INFO()
! 144:
! 145: ZEND_BEGIN_ARG_INFO_EX(arginfo_date_create_from_format, 0, 0, 2)
! 146: ZEND_ARG_INFO(0, format)
! 147: ZEND_ARG_INFO(0, time)
! 148: ZEND_ARG_INFO(0, object)
! 149: ZEND_END_ARG_INFO()
! 150:
! 151: ZEND_BEGIN_ARG_INFO_EX(arginfo_date_parse, 0, 0, 1)
! 152: ZEND_ARG_INFO(0, date)
! 153: ZEND_END_ARG_INFO()
! 154:
! 155: ZEND_BEGIN_ARG_INFO_EX(arginfo_date_parse_from_format, 0, 0, 2)
! 156: ZEND_ARG_INFO(0, format)
! 157: ZEND_ARG_INFO(0, date)
! 158: ZEND_END_ARG_INFO()
! 159:
! 160: ZEND_BEGIN_ARG_INFO(arginfo_date_get_last_errors, 0)
! 161: ZEND_END_ARG_INFO()
! 162:
! 163: ZEND_BEGIN_ARG_INFO_EX(arginfo_date_format, 0, 0, 2)
! 164: ZEND_ARG_INFO(0, object)
! 165: ZEND_ARG_INFO(0, format)
! 166: ZEND_END_ARG_INFO()
! 167:
! 168: ZEND_BEGIN_ARG_INFO_EX(arginfo_date_method_format, 0, 0, 1)
! 169: ZEND_ARG_INFO(0, format)
! 170: ZEND_END_ARG_INFO()
! 171:
! 172: ZEND_BEGIN_ARG_INFO_EX(arginfo_date_modify, 0, 0, 2)
! 173: ZEND_ARG_INFO(0, object)
! 174: ZEND_ARG_INFO(0, modify)
! 175: ZEND_END_ARG_INFO()
! 176:
! 177: ZEND_BEGIN_ARG_INFO_EX(arginfo_date_method_modify, 0, 0, 1)
! 178: ZEND_ARG_INFO(0, modify)
! 179: ZEND_END_ARG_INFO()
! 180:
! 181: ZEND_BEGIN_ARG_INFO_EX(arginfo_date_add, 0, 0, 2)
! 182: ZEND_ARG_INFO(0, object)
! 183: ZEND_ARG_INFO(0, interval)
! 184: ZEND_END_ARG_INFO()
! 185:
! 186: ZEND_BEGIN_ARG_INFO_EX(arginfo_date_method_add, 0, 0, 1)
! 187: ZEND_ARG_INFO(0, interval)
! 188: ZEND_END_ARG_INFO()
! 189:
! 190: ZEND_BEGIN_ARG_INFO_EX(arginfo_date_sub, 0, 0, 2)
! 191: ZEND_ARG_INFO(0, object)
! 192: ZEND_ARG_INFO(0, interval)
! 193: ZEND_END_ARG_INFO()
! 194:
! 195: ZEND_BEGIN_ARG_INFO_EX(arginfo_date_method_sub, 0, 0, 1)
! 196: ZEND_ARG_INFO(0, interval)
! 197: ZEND_END_ARG_INFO()
! 198:
! 199: ZEND_BEGIN_ARG_INFO_EX(arginfo_date_timezone_get, 0, 0, 1)
! 200: ZEND_ARG_INFO(0, object)
! 201: ZEND_END_ARG_INFO()
! 202:
! 203: ZEND_BEGIN_ARG_INFO(arginfo_date_method_timezone_get, 0)
! 204: ZEND_END_ARG_INFO()
! 205:
! 206: ZEND_BEGIN_ARG_INFO_EX(arginfo_date_timezone_set, 0, 0, 2)
! 207: ZEND_ARG_INFO(0, object)
! 208: ZEND_ARG_INFO(0, timezone)
! 209: ZEND_END_ARG_INFO()
! 210:
! 211: ZEND_BEGIN_ARG_INFO_EX(arginfo_date_method_timezone_set, 0, 0, 1)
! 212: ZEND_ARG_INFO(0, timezone)
! 213: ZEND_END_ARG_INFO()
! 214:
! 215: ZEND_BEGIN_ARG_INFO_EX(arginfo_date_offset_get, 0, 0, 1)
! 216: ZEND_ARG_INFO(0, object)
! 217: ZEND_END_ARG_INFO()
! 218:
! 219: ZEND_BEGIN_ARG_INFO(arginfo_date_method_offset_get, 0)
! 220: ZEND_END_ARG_INFO()
! 221:
! 222: ZEND_BEGIN_ARG_INFO_EX(arginfo_date_diff, 0, 0, 2)
! 223: ZEND_ARG_INFO(0, object)
! 224: ZEND_ARG_INFO(0, object2)
! 225: ZEND_ARG_INFO(0, absolute)
! 226: ZEND_END_ARG_INFO()
! 227:
! 228: ZEND_BEGIN_ARG_INFO_EX(arginfo_date_method_diff, 0, 0, 1)
! 229: ZEND_ARG_INFO(0, object)
! 230: ZEND_ARG_INFO(0, absolute)
! 231: ZEND_END_ARG_INFO()
! 232:
! 233: ZEND_BEGIN_ARG_INFO_EX(arginfo_date_time_set, 0, 0, 3)
! 234: ZEND_ARG_INFO(0, object)
! 235: ZEND_ARG_INFO(0, hour)
! 236: ZEND_ARG_INFO(0, minute)
! 237: ZEND_ARG_INFO(0, second)
! 238: ZEND_END_ARG_INFO()
! 239:
! 240: ZEND_BEGIN_ARG_INFO_EX(arginfo_date_method_time_set, 0, 0, 2)
! 241: ZEND_ARG_INFO(0, hour)
! 242: ZEND_ARG_INFO(0, minute)
! 243: ZEND_ARG_INFO(0, second)
! 244: ZEND_END_ARG_INFO()
! 245:
! 246: ZEND_BEGIN_ARG_INFO_EX(arginfo_date_date_set, 0, 0, 4)
! 247: ZEND_ARG_INFO(0, object)
! 248: ZEND_ARG_INFO(0, year)
! 249: ZEND_ARG_INFO(0, month)
! 250: ZEND_ARG_INFO(0, day)
! 251: ZEND_END_ARG_INFO()
! 252:
! 253: ZEND_BEGIN_ARG_INFO_EX(arginfo_date_method_date_set, 0, 0, 3)
! 254: ZEND_ARG_INFO(0, year)
! 255: ZEND_ARG_INFO(0, month)
! 256: ZEND_ARG_INFO(0, day)
! 257: ZEND_END_ARG_INFO()
! 258:
! 259: ZEND_BEGIN_ARG_INFO_EX(arginfo_date_isodate_set, 0, 0, 3)
! 260: ZEND_ARG_INFO(0, object)
! 261: ZEND_ARG_INFO(0, year)
! 262: ZEND_ARG_INFO(0, week)
! 263: ZEND_ARG_INFO(0, day)
! 264: ZEND_END_ARG_INFO()
! 265:
! 266: ZEND_BEGIN_ARG_INFO_EX(arginfo_date_method_isodate_set, 0, 0, 2)
! 267: ZEND_ARG_INFO(0, year)
! 268: ZEND_ARG_INFO(0, week)
! 269: ZEND_ARG_INFO(0, day)
! 270: ZEND_END_ARG_INFO()
! 271:
! 272: ZEND_BEGIN_ARG_INFO_EX(arginfo_date_timestamp_set, 0, 0, 2)
! 273: ZEND_ARG_INFO(0, object)
! 274: ZEND_ARG_INFO(0, unixtimestamp)
! 275: ZEND_END_ARG_INFO()
! 276:
! 277: ZEND_BEGIN_ARG_INFO_EX(arginfo_date_method_timestamp_set, 0, 0, 1)
! 278: ZEND_ARG_INFO(0, unixtimestamp)
! 279: ZEND_END_ARG_INFO()
! 280:
! 281: ZEND_BEGIN_ARG_INFO_EX(arginfo_date_timestamp_get, 0, 0, 1)
! 282: ZEND_ARG_INFO(0, object)
! 283: ZEND_END_ARG_INFO()
! 284:
! 285: ZEND_BEGIN_ARG_INFO(arginfo_date_method_timestamp_get, 0)
! 286: ZEND_END_ARG_INFO()
! 287:
! 288: ZEND_BEGIN_ARG_INFO_EX(arginfo_timezone_open, 0, 0, 1)
! 289: ZEND_ARG_INFO(0, timezone)
! 290: ZEND_END_ARG_INFO()
! 291:
! 292: ZEND_BEGIN_ARG_INFO_EX(arginfo_timezone_name_get, 0, 0, 1)
! 293: ZEND_ARG_INFO(0, object)
! 294: ZEND_END_ARG_INFO()
! 295:
! 296: ZEND_BEGIN_ARG_INFO(arginfo_timezone_method_name_get, 0)
! 297: ZEND_END_ARG_INFO()
! 298:
! 299: ZEND_BEGIN_ARG_INFO_EX(arginfo_timezone_name_from_abbr, 0, 0, 1)
! 300: ZEND_ARG_INFO(0, abbr)
! 301: ZEND_ARG_INFO(0, gmtoffset)
! 302: ZEND_ARG_INFO(0, isdst)
! 303: ZEND_END_ARG_INFO()
! 304:
! 305: ZEND_BEGIN_ARG_INFO_EX(arginfo_timezone_offset_get, 0, 0, 2)
! 306: ZEND_ARG_INFO(0, object)
! 307: ZEND_ARG_INFO(0, datetime)
! 308: ZEND_END_ARG_INFO()
! 309:
! 310: ZEND_BEGIN_ARG_INFO_EX(arginfo_timezone_method_offset_get, 0, 0, 1)
! 311: ZEND_ARG_INFO(0, datetime)
! 312: ZEND_END_ARG_INFO()
! 313:
! 314: ZEND_BEGIN_ARG_INFO_EX(arginfo_timezone_transitions_get, 0, 0, 1)
! 315: ZEND_ARG_INFO(0, object)
! 316: ZEND_ARG_INFO(0, timestamp_begin)
! 317: ZEND_ARG_INFO(0, timestamp_end)
! 318: ZEND_END_ARG_INFO()
! 319:
! 320: ZEND_BEGIN_ARG_INFO(arginfo_timezone_method_transitions_get, 0)
! 321: ZEND_ARG_INFO(0, timestamp_begin)
! 322: ZEND_ARG_INFO(0, timestamp_end)
! 323: ZEND_END_ARG_INFO()
! 324:
! 325: ZEND_BEGIN_ARG_INFO_EX(arginfo_timezone_location_get, 0, 0, 1)
! 326: ZEND_ARG_INFO(0, object)
! 327: ZEND_END_ARG_INFO()
! 328:
! 329: ZEND_BEGIN_ARG_INFO(arginfo_timezone_method_location_get, 0)
! 330: ZEND_END_ARG_INFO()
! 331:
! 332: ZEND_BEGIN_ARG_INFO_EX(arginfo_timezone_identifiers_list, 0, 0, 0)
! 333: ZEND_ARG_INFO(0, what)
! 334: ZEND_ARG_INFO(0, country)
! 335: ZEND_END_ARG_INFO()
! 336:
! 337: ZEND_BEGIN_ARG_INFO(arginfo_timezone_abbreviations_list, 0)
! 338: ZEND_END_ARG_INFO()
! 339:
! 340: ZEND_BEGIN_ARG_INFO(arginfo_timezone_version_get, 0)
! 341: ZEND_END_ARG_INFO()
! 342:
! 343: ZEND_BEGIN_ARG_INFO_EX(arginfo_date_interval_create_from_date_string, 0, 0, 1)
! 344: ZEND_ARG_INFO(0, time)
! 345: ZEND_END_ARG_INFO()
! 346:
! 347: ZEND_BEGIN_ARG_INFO_EX(arginfo_date_interval_format, 0, 0, 2)
! 348: ZEND_ARG_INFO(0, object)
! 349: ZEND_ARG_INFO(0, format)
! 350: ZEND_END_ARG_INFO()
! 351:
! 352: ZEND_BEGIN_ARG_INFO(arginfo_date_method_interval_format, 0)
! 353: ZEND_ARG_INFO(0, format)
! 354: ZEND_END_ARG_INFO()
! 355:
! 356: ZEND_BEGIN_ARG_INFO_EX(arginfo_date_period_construct, 0, 0, 3)
! 357: ZEND_ARG_INFO(0, start)
! 358: ZEND_ARG_INFO(0, interval)
! 359: ZEND_ARG_INFO(0, end)
! 360: ZEND_END_ARG_INFO()
! 361:
! 362: ZEND_BEGIN_ARG_INFO_EX(arginfo_date_interval_construct, 0, 0, 0)
! 363: ZEND_ARG_INFO(0, interval_spec)
! 364: ZEND_END_ARG_INFO()
! 365: /* }}} */
! 366:
! 367: /* {{{ Function table */
! 368: const zend_function_entry date_functions[] = {
! 369: PHP_FE(strtotime, arginfo_strtotime)
! 370: PHP_FE(date, arginfo_date)
! 371: PHP_FE(idate, arginfo_idate)
! 372: PHP_FE(gmdate, arginfo_gmdate)
! 373: PHP_FE(mktime, arginfo_mktime)
! 374: PHP_FE(gmmktime, arginfo_gmmktime)
! 375: PHP_FE(checkdate, arginfo_checkdate)
! 376:
! 377: #ifdef HAVE_STRFTIME
! 378: PHP_FE(strftime, arginfo_strftime)
! 379: PHP_FE(gmstrftime, arginfo_gmstrftime)
! 380: #endif
! 381:
! 382: PHP_FE(time, arginfo_time)
! 383: PHP_FE(localtime, arginfo_localtime)
! 384: PHP_FE(getdate, arginfo_getdate)
! 385:
! 386: /* Advanced Interface */
! 387: PHP_FE(date_create, arginfo_date_create)
! 388: PHP_FE(date_create_from_format, arginfo_date_create_from_format)
! 389: PHP_FE(date_parse, arginfo_date_parse)
! 390: PHP_FE(date_parse_from_format, arginfo_date_parse_from_format)
! 391: PHP_FE(date_get_last_errors, arginfo_date_get_last_errors)
! 392: PHP_FE(date_format, arginfo_date_format)
! 393: PHP_FE(date_modify, arginfo_date_modify)
! 394: PHP_FE(date_add, arginfo_date_add)
! 395: PHP_FE(date_sub, arginfo_date_sub)
! 396: PHP_FE(date_timezone_get, arginfo_date_timezone_get)
! 397: PHP_FE(date_timezone_set, arginfo_date_timezone_set)
! 398: PHP_FE(date_offset_get, arginfo_date_offset_get)
! 399: PHP_FE(date_diff, arginfo_date_diff)
! 400:
! 401: PHP_FE(date_time_set, arginfo_date_time_set)
! 402: PHP_FE(date_date_set, arginfo_date_date_set)
! 403: PHP_FE(date_isodate_set, arginfo_date_isodate_set)
! 404: PHP_FE(date_timestamp_set, arginfo_date_timestamp_set)
! 405: PHP_FE(date_timestamp_get, arginfo_date_timestamp_get)
! 406:
! 407: PHP_FE(timezone_open, arginfo_timezone_open)
! 408: PHP_FE(timezone_name_get, arginfo_timezone_name_get)
! 409: PHP_FE(timezone_name_from_abbr, arginfo_timezone_name_from_abbr)
! 410: PHP_FE(timezone_offset_get, arginfo_timezone_offset_get)
! 411: PHP_FE(timezone_transitions_get, arginfo_timezone_transitions_get)
! 412: PHP_FE(timezone_location_get, arginfo_timezone_location_get)
! 413: PHP_FE(timezone_identifiers_list, arginfo_timezone_identifiers_list)
! 414: PHP_FE(timezone_abbreviations_list, arginfo_timezone_abbreviations_list)
! 415: PHP_FE(timezone_version_get, arginfo_timezone_version_get)
! 416:
! 417: PHP_FE(date_interval_create_from_date_string, arginfo_date_interval_create_from_date_string)
! 418: PHP_FE(date_interval_format, arginfo_date_interval_format)
! 419:
! 420: /* Options and Configuration */
! 421: PHP_FE(date_default_timezone_set, arginfo_date_default_timezone_set)
! 422: PHP_FE(date_default_timezone_get, arginfo_date_default_timezone_get)
! 423:
! 424: /* Astronomical functions */
! 425: PHP_FE(date_sunrise, arginfo_date_sunrise)
! 426: PHP_FE(date_sunset, arginfo_date_sunset)
! 427: PHP_FE(date_sun_info, arginfo_date_sun_info)
! 428: PHP_FE_END
! 429: };
! 430:
! 431: const zend_function_entry date_funcs_date[] = {
! 432: PHP_ME(DateTime, __construct, arginfo_date_create, ZEND_ACC_CTOR|ZEND_ACC_PUBLIC)
! 433: PHP_ME(DateTime, __wakeup, NULL, ZEND_ACC_PUBLIC)
! 434: PHP_ME(DateTime, __set_state, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
! 435: PHP_ME_MAPPING(createFromFormat, date_create_from_format, arginfo_date_create_from_format, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
! 436: PHP_ME_MAPPING(getLastErrors, date_get_last_errors, arginfo_date_get_last_errors, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
! 437: PHP_ME_MAPPING(format, date_format, arginfo_date_method_format, 0)
! 438: PHP_ME_MAPPING(modify, date_modify, arginfo_date_method_modify, 0)
! 439: PHP_ME_MAPPING(add, date_add, arginfo_date_method_add, 0)
! 440: PHP_ME_MAPPING(sub, date_sub, arginfo_date_method_sub, 0)
! 441: PHP_ME_MAPPING(getTimezone, date_timezone_get, arginfo_date_method_timezone_get, 0)
! 442: PHP_ME_MAPPING(setTimezone, date_timezone_set, arginfo_date_method_timezone_set, 0)
! 443: PHP_ME_MAPPING(getOffset, date_offset_get, arginfo_date_method_offset_get, 0)
! 444: PHP_ME_MAPPING(setTime, date_time_set, arginfo_date_method_time_set, 0)
! 445: PHP_ME_MAPPING(setDate, date_date_set, arginfo_date_method_date_set, 0)
! 446: PHP_ME_MAPPING(setISODate, date_isodate_set, arginfo_date_method_isodate_set, 0)
! 447: PHP_ME_MAPPING(setTimestamp, date_timestamp_set, arginfo_date_method_timestamp_set, 0)
! 448: PHP_ME_MAPPING(getTimestamp, date_timestamp_get, arginfo_date_method_timestamp_get, 0)
! 449: PHP_ME_MAPPING(diff, date_diff, arginfo_date_method_diff, 0)
! 450: PHP_FE_END
! 451: };
! 452:
! 453: const zend_function_entry date_funcs_timezone[] = {
! 454: PHP_ME(DateTimeZone, __construct, arginfo_timezone_open, ZEND_ACC_CTOR|ZEND_ACC_PUBLIC)
! 455: PHP_ME_MAPPING(getName, timezone_name_get, arginfo_timezone_method_name_get, 0)
! 456: PHP_ME_MAPPING(getOffset, timezone_offset_get, arginfo_timezone_method_offset_get, 0)
! 457: PHP_ME_MAPPING(getTransitions, timezone_transitions_get, arginfo_timezone_method_transitions_get, 0)
! 458: PHP_ME_MAPPING(getLocation, timezone_location_get, arginfo_timezone_method_location_get, 0)
! 459: PHP_ME_MAPPING(listAbbreviations, timezone_abbreviations_list, arginfo_timezone_abbreviations_list, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
! 460: PHP_ME_MAPPING(listIdentifiers, timezone_identifiers_list, arginfo_timezone_identifiers_list, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
! 461: PHP_FE_END
! 462: };
! 463:
! 464: const zend_function_entry date_funcs_interval[] = {
! 465: PHP_ME(DateInterval, __construct, arginfo_date_interval_construct, ZEND_ACC_CTOR|ZEND_ACC_PUBLIC)
! 466: PHP_ME(DateInterval, __wakeup, NULL, ZEND_ACC_PUBLIC)
! 467: PHP_ME(DateInterval, __set_state, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
! 468: PHP_ME_MAPPING(format, date_interval_format, arginfo_date_method_interval_format, 0)
! 469: PHP_ME_MAPPING(createFromDateString, date_interval_create_from_date_string, arginfo_date_interval_create_from_date_string, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
! 470: PHP_FE_END
! 471: };
! 472:
! 473: const zend_function_entry date_funcs_period[] = {
! 474: PHP_ME(DatePeriod, __construct, arginfo_date_period_construct, ZEND_ACC_CTOR|ZEND_ACC_PUBLIC)
! 475: PHP_FE_END
! 476: };
! 477:
! 478: static char* guess_timezone(const timelib_tzdb *tzdb TSRMLS_DC);
! 479: static void date_register_classes(TSRMLS_D);
! 480: /* }}} */
! 481:
! 482: ZEND_DECLARE_MODULE_GLOBALS(date)
! 483: static PHP_GINIT_FUNCTION(date);
! 484:
! 485: /* True global */
! 486: timelib_tzdb *php_date_global_timezone_db;
! 487: int php_date_global_timezone_db_enabled;
! 488:
! 489: #define DATE_DEFAULT_LATITUDE "31.7667"
! 490: #define DATE_DEFAULT_LONGITUDE "35.2333"
! 491:
! 492: /* on 90'35; common sunset declaration (start of sun body appear) */
! 493: #define DATE_SUNSET_ZENITH "90.583333"
! 494:
! 495: /* on 90'35; common sunrise declaration (sun body disappeared) */
! 496: #define DATE_SUNRISE_ZENITH "90.583333"
! 497:
! 498: /* {{{ INI Settings */
! 499: PHP_INI_BEGIN()
! 500: STD_PHP_INI_ENTRY("date.timezone", "", PHP_INI_ALL, OnUpdateString, default_timezone, zend_date_globals, date_globals)
! 501: PHP_INI_ENTRY("date.default_latitude", DATE_DEFAULT_LATITUDE, PHP_INI_ALL, NULL)
! 502: PHP_INI_ENTRY("date.default_longitude", DATE_DEFAULT_LONGITUDE, PHP_INI_ALL, NULL)
! 503: PHP_INI_ENTRY("date.sunset_zenith", DATE_SUNSET_ZENITH, PHP_INI_ALL, NULL)
! 504: PHP_INI_ENTRY("date.sunrise_zenith", DATE_SUNRISE_ZENITH, PHP_INI_ALL, NULL)
! 505: PHP_INI_END()
! 506: /* }}} */
! 507:
! 508: zend_class_entry *date_ce_date, *date_ce_timezone, *date_ce_interval, *date_ce_period;
! 509:
! 510:
! 511: PHPAPI zend_class_entry *php_date_get_date_ce(void)
! 512: {
! 513: return date_ce_date;
! 514: }
! 515:
! 516: PHPAPI zend_class_entry *php_date_get_timezone_ce(void)
! 517: {
! 518: return date_ce_timezone;
! 519: }
! 520:
! 521: static zend_object_handlers date_object_handlers_date;
! 522: static zend_object_handlers date_object_handlers_timezone;
! 523: static zend_object_handlers date_object_handlers_interval;
! 524: static zend_object_handlers date_object_handlers_period;
! 525:
! 526: #define DATE_SET_CONTEXT \
! 527: zval *object; \
! 528: object = getThis(); \
! 529:
! 530: #define DATE_FETCH_OBJECT \
! 531: php_date_obj *obj; \
! 532: DATE_SET_CONTEXT; \
! 533: if (object) { \
! 534: if (zend_parse_parameters_none() == FAILURE) { \
! 535: return; \
! 536: } \
! 537: } else { \
! 538: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, NULL, "O", &object, date_ce_date) == FAILURE) { \
! 539: RETURN_FALSE; \
! 540: } \
! 541: } \
! 542: obj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC); \
! 543:
! 544: #define DATE_CHECK_INITIALIZED(member, class_name) \
! 545: if (!(member)) { \
! 546: php_error_docref(NULL TSRMLS_CC, E_WARNING, "The " #class_name " object has not been correctly initialized by its constructor"); \
! 547: RETURN_FALSE; \
! 548: }
! 549:
! 550: static void date_object_free_storage_date(void *object TSRMLS_DC);
! 551: static void date_object_free_storage_timezone(void *object TSRMLS_DC);
! 552: static void date_object_free_storage_interval(void *object TSRMLS_DC);
! 553: static void date_object_free_storage_period(void *object TSRMLS_DC);
! 554:
! 555: static zend_object_value date_object_new_date(zend_class_entry *class_type TSRMLS_DC);
! 556: static zend_object_value date_object_new_timezone(zend_class_entry *class_type TSRMLS_DC);
! 557: static zend_object_value date_object_new_interval(zend_class_entry *class_type TSRMLS_DC);
! 558: static zend_object_value date_object_new_period(zend_class_entry *class_type TSRMLS_DC);
! 559:
! 560: static zend_object_value date_object_clone_date(zval *this_ptr TSRMLS_DC);
! 561: static zend_object_value date_object_clone_timezone(zval *this_ptr TSRMLS_DC);
! 562: static zend_object_value date_object_clone_interval(zval *this_ptr TSRMLS_DC);
! 563: static zend_object_value date_object_clone_period(zval *this_ptr TSRMLS_DC);
! 564:
! 565: static int date_object_compare_date(zval *d1, zval *d2 TSRMLS_DC);
! 566: static HashTable *date_object_get_properties(zval *object TSRMLS_DC);
! 567: static HashTable *date_object_get_properties_interval(zval *object TSRMLS_DC);
! 568:
! 569: zval *date_interval_read_property(zval *object, zval *member, int type TSRMLS_DC);
! 570: void date_interval_write_property(zval *object, zval *member, zval *value TSRMLS_DC);
! 571:
! 572: /* {{{ Module struct */
! 573: zend_module_entry date_module_entry = {
! 574: STANDARD_MODULE_HEADER_EX,
! 575: NULL,
! 576: NULL,
! 577: "date", /* extension name */
! 578: date_functions, /* function list */
! 579: PHP_MINIT(date), /* process startup */
! 580: PHP_MSHUTDOWN(date), /* process shutdown */
! 581: PHP_RINIT(date), /* request startup */
! 582: PHP_RSHUTDOWN(date), /* request shutdown */
! 583: PHP_MINFO(date), /* extension info */
! 584: PHP_VERSION, /* extension version */
! 585: PHP_MODULE_GLOBALS(date), /* globals descriptor */
! 586: PHP_GINIT(date), /* globals ctor */
! 587: NULL, /* globals dtor */
! 588: NULL, /* post deactivate */
! 589: STANDARD_MODULE_PROPERTIES_EX
! 590: };
! 591: /* }}} */
! 592:
! 593:
! 594: /* {{{ PHP_GINIT_FUNCTION */
! 595: static PHP_GINIT_FUNCTION(date)
! 596: {
! 597: date_globals->default_timezone = NULL;
! 598: date_globals->timezone = NULL;
! 599: date_globals->tzcache = NULL;
! 600: }
! 601: /* }}} */
! 602:
! 603:
! 604: static void _php_date_tzinfo_dtor(void *tzinfo)
! 605: {
! 606: timelib_tzinfo **tzi = (timelib_tzinfo **)tzinfo;
! 607:
! 608: timelib_tzinfo_dtor(*tzi);
! 609: }
! 610:
! 611: /* {{{ PHP_RINIT_FUNCTION */
! 612: PHP_RINIT_FUNCTION(date)
! 613: {
! 614: if (DATEG(timezone)) {
! 615: efree(DATEG(timezone));
! 616: }
! 617: DATEG(timezone) = NULL;
! 618: DATEG(tzcache) = NULL;
! 619: DATEG(last_errors) = NULL;
! 620:
! 621: return SUCCESS;
! 622: }
! 623: /* }}} */
! 624:
! 625: /* {{{ PHP_RSHUTDOWN_FUNCTION */
! 626: PHP_RSHUTDOWN_FUNCTION(date)
! 627: {
! 628: if (DATEG(timezone)) {
! 629: efree(DATEG(timezone));
! 630: }
! 631: DATEG(timezone) = NULL;
! 632: if(DATEG(tzcache)) {
! 633: zend_hash_destroy(DATEG(tzcache));
! 634: FREE_HASHTABLE(DATEG(tzcache));
! 635: DATEG(tzcache) = NULL;
! 636: }
! 637: if (DATEG(last_errors)) {
! 638: timelib_error_container_dtor(DATEG(last_errors));
! 639: DATEG(last_errors) = NULL;
! 640: }
! 641:
! 642: return SUCCESS;
! 643: }
! 644: /* }}} */
! 645:
! 646: #define DATE_TIMEZONEDB php_date_global_timezone_db ? php_date_global_timezone_db : timelib_builtin_db()
! 647:
! 648: /*
! 649: * RFC822, Section 5.1: http://www.ietf.org/rfc/rfc822.txt
! 650: * date-time = [ day "," ] date time ; dd mm yy hh:mm:ss zzz
! 651: * day = "Mon" / "Tue" / "Wed" / "Thu" / "Fri" / "Sat" / "Sun"
! 652: * date = 1*2DIGIT month 2DIGIT ; day month year e.g. 20 Jun 82
! 653: * month = "Jan" / "Feb" / "Mar" / "Apr" / "May" / "Jun" / "Jul" / "Aug" / "Sep" / "Oct" / "Nov" / "Dec"
! 654: * time = hour zone ; ANSI and Military
! 655: * hour = 2DIGIT ":" 2DIGIT [":" 2DIGIT] ; 00:00:00 - 23:59:59
! 656: * zone = "UT" / "GMT" / "EST" / "EDT" / "CST" / "CDT" / "MST" / "MDT" / "PST" / "PDT" / 1ALPHA / ( ("+" / "-") 4DIGIT )
! 657: */
! 658: #define DATE_FORMAT_RFC822 "D, d M y H:i:s O"
! 659:
! 660: /*
! 661: * RFC850, Section 2.1.4: http://www.ietf.org/rfc/rfc850.txt
! 662: * Format must be acceptable both to the ARPANET and to the getdate routine.
! 663: * One format that is acceptable to both is Weekday, DD-Mon-YY HH:MM:SS TIMEZONE
! 664: * TIMEZONE can be any timezone name (3 or more letters)
! 665: */
! 666: #define DATE_FORMAT_RFC850 "l, d-M-y H:i:s T"
! 667:
! 668: /*
! 669: * RFC1036, Section 2.1.2: http://www.ietf.org/rfc/rfc1036.txt
! 670: * Its format must be acceptable both in RFC-822 and to the getdate(3)
! 671: * Wdy, DD Mon YY HH:MM:SS TIMEZONE
! 672: * There is no hope of having a complete list of timezones. Universal
! 673: * Time (GMT), the North American timezones (PST, PDT, MST, MDT, CST,
! 674: * CDT, EST, EDT) and the +/-hhmm offset specifed in RFC-822 should be supported.
! 675: */
! 676: #define DATE_FORMAT_RFC1036 "D, d M y H:i:s O"
! 677:
! 678: /*
! 679: * RFC1123, Section 5.2.14: http://www.ietf.org/rfc/rfc1123.txt
! 680: * RFC-822 Date and Time Specification: RFC-822 Section 5
! 681: * The syntax for the date is hereby changed to: date = 1*2DIGIT month 2*4DIGIT
! 682: */
! 683: #define DATE_FORMAT_RFC1123 "D, d M Y H:i:s O"
! 684:
! 685: /*
! 686: * RFC2822, Section 3.3: http://www.ietf.org/rfc/rfc2822.txt
! 687: * FWS = ([*WSP CRLF] 1*WSP) / ; Folding white space
! 688: * CFWS = *([FWS] comment) (([FWS] comment) / FWS)
! 689: *
! 690: * date-time = [ day-of-week "," ] date FWS time [CFWS]
! 691: * day-of-week = ([FWS] day-name)
! 692: * day-name = "Mon" / "Tue" / "Wed" / "Thu" / "Fri" / "Sat" / "Sun"
! 693: * date = day month year
! 694: * year = 4*DIGIT
! 695: * month = (FWS month-name FWS)
! 696: * month-name = "Jan" / "Feb" / "Mar" / "Apr" / "May" / "Jun" / "Jul" / "Aug" / "Sep" / "Oct" / "Nov" / "Dec"
! 697: * day = ([FWS] 1*2DIGIT)
! 698: * time = time-of-day FWS zone
! 699: * time-of-day = hour ":" minute [ ":" second ]
! 700: * hour = 2DIGIT
! 701: * minute = 2DIGIT
! 702: * second = 2DIGIT
! 703: * zone = (( "+" / "-" ) 4DIGIT)
! 704: */
! 705: #define DATE_FORMAT_RFC2822 "D, d M Y H:i:s O"
! 706: /*
! 707: * RFC3339, Section 5.6: http://www.ietf.org/rfc/rfc3339.txt
! 708: * date-fullyear = 4DIGIT
! 709: * date-month = 2DIGIT ; 01-12
! 710: * date-mday = 2DIGIT ; 01-28, 01-29, 01-30, 01-31 based on month/year
! 711: *
! 712: * time-hour = 2DIGIT ; 00-23
! 713: * time-minute = 2DIGIT ; 00-59
! 714: * time-second = 2DIGIT ; 00-58, 00-59, 00-60 based on leap second rules
! 715: *
! 716: * time-secfrac = "." 1*DIGIT
! 717: * time-numoffset = ("+" / "-") time-hour ":" time-minute
! 718: * time-offset = "Z" / time-numoffset
! 719: *
! 720: * partial-time = time-hour ":" time-minute ":" time-second [time-secfrac]
! 721: * full-date = date-fullyear "-" date-month "-" date-mday
! 722: * full-time = partial-time time-offset
! 723: *
! 724: * date-time = full-date "T" full-time
! 725: */
! 726: #define DATE_FORMAT_RFC3339 "Y-m-d\\TH:i:sP"
! 727:
! 728: #define DATE_FORMAT_ISO8601 "Y-m-d\\TH:i:sO"
! 729:
! 730: #define DATE_TZ_ERRMSG \
! 731: "It is not safe to rely on the system's timezone settings. You are " \
! 732: "*required* to use the date.timezone setting or the " \
! 733: "date_default_timezone_set() function. In case you used any of those " \
! 734: "methods and you are still getting this warning, you most likely " \
! 735: "misspelled the timezone identifier. "
! 736:
! 737: #define SUNFUNCS_RET_TIMESTAMP 0
! 738: #define SUNFUNCS_RET_STRING 1
! 739: #define SUNFUNCS_RET_DOUBLE 2
! 740:
! 741:
! 742: /* {{{ PHP_MINIT_FUNCTION */
! 743: PHP_MINIT_FUNCTION(date)
! 744: {
! 745: REGISTER_INI_ENTRIES();
! 746: date_register_classes(TSRMLS_C);
! 747: /*
! 748: * RFC4287, Section 3.3: http://www.ietf.org/rfc/rfc4287.txt
! 749: * A Date construct is an element whose content MUST conform to the
! 750: * "date-time" production in [RFC3339]. In addition, an uppercase "T"
! 751: * character MUST be used to separate date and time, and an uppercase
! 752: * "Z" character MUST be present in the absence of a numeric time zone offset.
! 753: */
! 754: REGISTER_STRING_CONSTANT("DATE_ATOM", DATE_FORMAT_RFC3339, CONST_CS | CONST_PERSISTENT);
! 755: /*
! 756: * Preliminary specification: http://wp.netscape.com/newsref/std/cookie_spec.html
! 757: * "This is based on RFC 822, RFC 850, RFC 1036, and RFC 1123,
! 758: * with the variations that the only legal time zone is GMT
! 759: * and the separators between the elements of the date must be dashes."
! 760: */
! 761: REGISTER_STRING_CONSTANT("DATE_COOKIE", DATE_FORMAT_RFC850, CONST_CS | CONST_PERSISTENT);
! 762: REGISTER_STRING_CONSTANT("DATE_ISO8601", DATE_FORMAT_ISO8601, CONST_CS | CONST_PERSISTENT);
! 763: REGISTER_STRING_CONSTANT("DATE_RFC822", DATE_FORMAT_RFC822, CONST_CS | CONST_PERSISTENT);
! 764: REGISTER_STRING_CONSTANT("DATE_RFC850", DATE_FORMAT_RFC850, CONST_CS | CONST_PERSISTENT);
! 765: REGISTER_STRING_CONSTANT("DATE_RFC1036", DATE_FORMAT_RFC1036, CONST_CS | CONST_PERSISTENT);
! 766: REGISTER_STRING_CONSTANT("DATE_RFC1123", DATE_FORMAT_RFC1123, CONST_CS | CONST_PERSISTENT);
! 767: REGISTER_STRING_CONSTANT("DATE_RFC2822", DATE_FORMAT_RFC2822, CONST_CS | CONST_PERSISTENT);
! 768: REGISTER_STRING_CONSTANT("DATE_RFC3339", DATE_FORMAT_RFC3339, CONST_CS | CONST_PERSISTENT);
! 769: /*
! 770: * RSS 2.0 Specification: http://blogs.law.harvard.edu/tech/rss
! 771: * "All date-times in RSS conform to the Date and Time Specification of RFC 822,
! 772: * with the exception that the year may be expressed with two characters or four characters (four preferred)"
! 773: */
! 774: REGISTER_STRING_CONSTANT("DATE_RSS", DATE_FORMAT_RFC1123, CONST_CS | CONST_PERSISTENT);
! 775: REGISTER_STRING_CONSTANT("DATE_W3C", DATE_FORMAT_RFC3339, CONST_CS | CONST_PERSISTENT);
! 776:
! 777: REGISTER_LONG_CONSTANT("SUNFUNCS_RET_TIMESTAMP", SUNFUNCS_RET_TIMESTAMP, CONST_CS | CONST_PERSISTENT);
! 778: REGISTER_LONG_CONSTANT("SUNFUNCS_RET_STRING", SUNFUNCS_RET_STRING, CONST_CS | CONST_PERSISTENT);
! 779: REGISTER_LONG_CONSTANT("SUNFUNCS_RET_DOUBLE", SUNFUNCS_RET_DOUBLE, CONST_CS | CONST_PERSISTENT);
! 780:
! 781: php_date_global_timezone_db = NULL;
! 782: php_date_global_timezone_db_enabled = 0;
! 783: DATEG(last_errors) = NULL;
! 784: return SUCCESS;
! 785: }
! 786: /* }}} */
! 787:
! 788: /* {{{ PHP_MSHUTDOWN_FUNCTION */
! 789: PHP_MSHUTDOWN_FUNCTION(date)
! 790: {
! 791: UNREGISTER_INI_ENTRIES();
! 792:
! 793: if (DATEG(last_errors)) {
! 794: timelib_error_container_dtor(DATEG(last_errors));
! 795: }
! 796:
! 797: return SUCCESS;
! 798: }
! 799: /* }}} */
! 800:
! 801: /* {{{ PHP_MINFO_FUNCTION */
! 802: PHP_MINFO_FUNCTION(date)
! 803: {
! 804: const timelib_tzdb *tzdb = DATE_TIMEZONEDB;
! 805:
! 806: php_info_print_table_start();
! 807: php_info_print_table_row(2, "date/time support", "enabled");
! 808: php_info_print_table_row(2, "\"Olson\" Timezone Database Version", tzdb->version);
! 809: php_info_print_table_row(2, "Timezone Database", php_date_global_timezone_db_enabled ? "external" : "internal");
! 810: php_info_print_table_row(2, "Default timezone", guess_timezone(tzdb TSRMLS_CC));
! 811: php_info_print_table_end();
! 812:
! 813: DISPLAY_INI_ENTRIES();
! 814: }
! 815: /* }}} */
! 816:
! 817: /* {{{ Timezone Cache functions */
! 818: static timelib_tzinfo *php_date_parse_tzfile(char *formal_tzname, const timelib_tzdb *tzdb TSRMLS_DC)
! 819: {
! 820: timelib_tzinfo *tzi, **ptzi;
! 821:
! 822: if(!DATEG(tzcache)) {
! 823: ALLOC_HASHTABLE(DATEG(tzcache));
! 824: zend_hash_init(DATEG(tzcache), 4, NULL, _php_date_tzinfo_dtor, 0);
! 825: }
! 826:
! 827: if (zend_hash_find(DATEG(tzcache), formal_tzname, strlen(formal_tzname) + 1, (void **) &ptzi) == SUCCESS) {
! 828: return *ptzi;
! 829: }
! 830:
! 831: tzi = timelib_parse_tzfile(formal_tzname, tzdb);
! 832: if (tzi) {
! 833: zend_hash_add(DATEG(tzcache), formal_tzname, strlen(formal_tzname) + 1, (void *) &tzi, sizeof(timelib_tzinfo*), NULL);
! 834: }
! 835: return tzi;
! 836: }
! 837:
! 838: timelib_tzinfo *php_date_parse_tzfile_wrapper(char *formal_tzname, const timelib_tzdb *tzdb)
! 839: {
! 840: TSRMLS_FETCH();
! 841: return php_date_parse_tzfile(formal_tzname, tzdb TSRMLS_CC);
! 842: }
! 843: /* }}} */
! 844:
! 845: /* {{{ Helper functions */
! 846: static char* guess_timezone(const timelib_tzdb *tzdb TSRMLS_DC)
! 847: {
! 848: char *env;
! 849:
! 850: /* Checking configure timezone */
! 851: if (DATEG(timezone) && (strlen(DATEG(timezone)) > 0)) {
! 852: return DATEG(timezone);
! 853: }
! 854: /* Check environment variable */
! 855: env = getenv("TZ");
! 856: if (env && *env && timelib_timezone_id_is_valid(env, tzdb)) {
! 857: return env;
! 858: }
! 859: /* Check config setting for default timezone */
! 860: if (!DATEG(default_timezone)) {
! 861: /* Special case: ext/date wasn't initialized yet */
! 862: zval ztz;
! 863:
! 864: if (SUCCESS == zend_get_configuration_directive("date.timezone", sizeof("date.timezone"), &ztz) &&
! 865: Z_TYPE(ztz) == IS_STRING &&
! 866: Z_STRLEN(ztz) > 0 &&
! 867: timelib_timezone_id_is_valid(Z_STRVAL(ztz), tzdb)) {
! 868: return Z_STRVAL(ztz);
! 869: }
! 870: } else if (*DATEG(default_timezone) && timelib_timezone_id_is_valid(DATEG(default_timezone), tzdb)) {
! 871: return DATEG(default_timezone);
! 872: }
! 873: #if HAVE_TM_ZONE
! 874: /* Try to guess timezone from system information */
! 875: {
! 876: struct tm *ta, tmbuf;
! 877: time_t the_time;
! 878: char *tzid = NULL;
! 879:
! 880: the_time = time(NULL);
! 881: ta = php_localtime_r(&the_time, &tmbuf);
! 882: if (ta) {
! 883: tzid = timelib_timezone_id_from_abbr(ta->tm_zone, ta->tm_gmtoff, ta->tm_isdst);
! 884: }
! 885: if (! tzid) {
! 886: tzid = "UTC";
! 887: }
! 888:
! 889: php_error_docref(NULL TSRMLS_CC, E_WARNING, DATE_TZ_ERRMSG "We selected '%s' for '%s/%.1f/%s' instead", tzid, ta ? ta->tm_zone : "Unknown", ta ? (float) (ta->tm_gmtoff / 3600) : 0, ta ? (ta->tm_isdst ? "DST" : "no DST") : "Unknown");
! 890: return tzid;
! 891: }
! 892: #endif
! 893: #ifdef PHP_WIN32
! 894: {
! 895: char *tzid;
! 896: TIME_ZONE_INFORMATION tzi;
! 897:
! 898: switch (GetTimeZoneInformation(&tzi))
! 899: {
! 900: /* DST in effect */
! 901: case TIME_ZONE_ID_DAYLIGHT:
! 902: /* If user has disabled DST in the control panel, Windows returns 0 here */
! 903: if (tzi.DaylightBias == 0) {
! 904: goto php_win_std_time;
! 905: }
! 906:
! 907: tzid = timelib_timezone_id_from_abbr("", (tzi.Bias + tzi.DaylightBias) * -60, 1);
! 908: if (! tzid) {
! 909: tzid = "UTC";
! 910: }
! 911: php_error_docref(NULL TSRMLS_CC, E_WARNING, DATE_TZ_ERRMSG "We selected '%s' for '%.1f/DST' instead", tzid, ((tzi.Bias + tzi.DaylightBias) / -60.0));
! 912: break;
! 913:
! 914: /* no DST or not in effect */
! 915: case TIME_ZONE_ID_UNKNOWN:
! 916: case TIME_ZONE_ID_STANDARD:
! 917: default:
! 918: php_win_std_time:
! 919: tzid = timelib_timezone_id_from_abbr("", (tzi.Bias + tzi.StandardBias) * -60, 0);
! 920: if (! tzid) {
! 921: tzid = "UTC";
! 922: }
! 923: php_error_docref(NULL TSRMLS_CC, E_WARNING, DATE_TZ_ERRMSG "We selected '%s' for '%.1f/no DST' instead", tzid, ((tzi.Bias + tzi.StandardBias) / -60.0));
! 924: break;
! 925:
! 926: }
! 927: return tzid;
! 928: }
! 929: #elif defined(NETWARE)
! 930: /* Try to guess timezone from system information */
! 931: {
! 932: char *tzid = timelib_timezone_id_from_abbr("", ((_timezone * -1) + (daylightOffset * daylightOnOff)), daylightOnOff);
! 933: if (tzid) {
! 934: return tzid;
! 935: }
! 936: }
! 937: #endif
! 938: /* Fallback to UTC */
! 939: php_error_docref(NULL TSRMLS_CC, E_WARNING, DATE_TZ_ERRMSG "We had to select 'UTC' because your platform doesn't provide functionality for the guessing algorithm");
! 940: return "UTC";
! 941: }
! 942:
! 943: PHPAPI timelib_tzinfo *get_timezone_info(TSRMLS_D)
! 944: {
! 945: char *tz;
! 946: timelib_tzinfo *tzi;
! 947:
! 948: tz = guess_timezone(DATE_TIMEZONEDB TSRMLS_CC);
! 949: tzi = php_date_parse_tzfile(tz, DATE_TIMEZONEDB TSRMLS_CC);
! 950: if (! tzi) {
! 951: php_error_docref(NULL TSRMLS_CC, E_ERROR, "Timezone database is corrupt - this should *never* happen!");
! 952: }
! 953: return tzi;
! 954: }
! 955: /* }}} */
! 956:
! 957:
! 958: /* {{{ date() and gmdate() data */
! 959: #include "ext/standard/php_smart_str.h"
! 960:
! 961: static char *mon_full_names[] = {
! 962: "January", "February", "March", "April",
! 963: "May", "June", "July", "August",
! 964: "September", "October", "November", "December"
! 965: };
! 966:
! 967: static char *mon_short_names[] = {
! 968: "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
! 969: };
! 970:
! 971: static char *day_full_names[] = {
! 972: "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
! 973: };
! 974:
! 975: static char *day_short_names[] = {
! 976: "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
! 977: };
! 978:
! 979: static char *english_suffix(timelib_sll number)
! 980: {
! 981: if (number >= 10 && number <= 19) {
! 982: return "th";
! 983: } else {
! 984: switch (number % 10) {
! 985: case 1: return "st";
! 986: case 2: return "nd";
! 987: case 3: return "rd";
! 988: }
! 989: }
! 990: return "th";
! 991: }
! 992: /* }}} */
! 993:
! 994: /* {{{ day of week helpers */
! 995: char *php_date_full_day_name(timelib_sll y, timelib_sll m, timelib_sll d)
! 996: {
! 997: timelib_sll day_of_week = timelib_day_of_week(y, m, d);
! 998: if (day_of_week < 0) {
! 999: return "Unknown";
! 1000: }
! 1001: return day_full_names[day_of_week];
! 1002: }
! 1003:
! 1004: char *php_date_short_day_name(timelib_sll y, timelib_sll m, timelib_sll d)
! 1005: {
! 1006: timelib_sll day_of_week = timelib_day_of_week(y, m, d);
! 1007: if (day_of_week < 0) {
! 1008: return "Unknown";
! 1009: }
! 1010: return day_short_names[day_of_week];
! 1011: }
! 1012: /* }}} */
! 1013:
! 1014: /* {{{ date_format - (gm)date helper */
! 1015: static char *date_format(char *format, int format_len, timelib_time *t, int localtime)
! 1016: {
! 1017: smart_str string = {0};
! 1018: int i, length;
! 1019: char buffer[97];
! 1020: timelib_time_offset *offset = NULL;
! 1021: timelib_sll isoweek, isoyear;
! 1022: int rfc_colon;
! 1023:
! 1024: if (!format_len) {
! 1025: return estrdup("");
! 1026: }
! 1027:
! 1028: if (localtime) {
! 1029: if (t->zone_type == TIMELIB_ZONETYPE_ABBR) {
! 1030: offset = timelib_time_offset_ctor();
! 1031: offset->offset = (t->z - (t->dst * 60)) * -60;
! 1032: offset->leap_secs = 0;
! 1033: offset->is_dst = t->dst;
! 1034: offset->abbr = strdup(t->tz_abbr);
! 1035: } else if (t->zone_type == TIMELIB_ZONETYPE_OFFSET) {
! 1036: offset = timelib_time_offset_ctor();
! 1037: offset->offset = (t->z) * -60;
! 1038: offset->leap_secs = 0;
! 1039: offset->is_dst = 0;
! 1040: offset->abbr = malloc(9); /* GMT�xxxx\0 */
! 1041: snprintf(offset->abbr, 9, "GMT%c%02d%02d",
! 1042: localtime ? ((offset->offset < 0) ? '-' : '+') : '+',
! 1043: localtime ? abs(offset->offset / 3600) : 0,
! 1044: localtime ? abs((offset->offset % 3600) / 60) : 0 );
! 1045: } else {
! 1046: offset = timelib_get_time_zone_info(t->sse, t->tz_info);
! 1047: }
! 1048: }
! 1049: timelib_isoweek_from_date(t->y, t->m, t->d, &isoweek, &isoyear);
! 1050:
! 1051: for (i = 0; i < format_len; i++) {
! 1052: rfc_colon = 0;
! 1053: switch (format[i]) {
! 1054: /* day */
! 1055: case 'd': length = slprintf(buffer, 32, "%02d", (int) t->d); break;
! 1056: case 'D': length = slprintf(buffer, 32, "%s", php_date_short_day_name(t->y, t->m, t->d)); break;
! 1057: case 'j': length = slprintf(buffer, 32, "%d", (int) t->d); break;
! 1058: case 'l': length = slprintf(buffer, 32, "%s", php_date_full_day_name(t->y, t->m, t->d)); break;
! 1059: case 'S': length = slprintf(buffer, 32, "%s", english_suffix(t->d)); break;
! 1060: case 'w': length = slprintf(buffer, 32, "%d", (int) timelib_day_of_week(t->y, t->m, t->d)); break;
! 1061: case 'N': length = slprintf(buffer, 32, "%d", (int) timelib_iso_day_of_week(t->y, t->m, t->d)); break;
! 1062: case 'z': length = slprintf(buffer, 32, "%d", (int) timelib_day_of_year(t->y, t->m, t->d)); break;
! 1063:
! 1064: /* week */
! 1065: case 'W': length = slprintf(buffer, 32, "%02d", (int) isoweek); break; /* iso weeknr */
! 1066: case 'o': length = slprintf(buffer, 32, "%d", (int) isoyear); break; /* iso year */
! 1067:
! 1068: /* month */
! 1069: case 'F': length = slprintf(buffer, 32, "%s", mon_full_names[t->m - 1]); break;
! 1070: case 'm': length = slprintf(buffer, 32, "%02d", (int) t->m); break;
! 1071: case 'M': length = slprintf(buffer, 32, "%s", mon_short_names[t->m - 1]); break;
! 1072: case 'n': length = slprintf(buffer, 32, "%d", (int) t->m); break;
! 1073: case 't': length = slprintf(buffer, 32, "%d", (int) timelib_days_in_month(t->y, t->m)); break;
! 1074:
! 1075: /* year */
! 1076: case 'L': length = slprintf(buffer, 32, "%d", timelib_is_leap((int) t->y)); break;
! 1077: case 'y': length = slprintf(buffer, 32, "%02d", (int) t->y % 100); break;
! 1078: case 'Y': length = slprintf(buffer, 32, "%s%04lld", t->y < 0 ? "-" : "", php_date_llabs((timelib_sll) t->y)); break;
! 1079:
! 1080: /* time */
! 1081: case 'a': length = slprintf(buffer, 32, "%s", t->h >= 12 ? "pm" : "am"); break;
! 1082: case 'A': length = slprintf(buffer, 32, "%s", t->h >= 12 ? "PM" : "AM"); break;
! 1083: case 'B': {
! 1084: int retval = (((((long)t->sse)-(((long)t->sse) - ((((long)t->sse) % 86400) + 3600))) * 10) / 864);
! 1085: while (retval < 0) {
! 1086: retval += 1000;
! 1087: }
! 1088: retval = retval % 1000;
! 1089: length = slprintf(buffer, 32, "%03d", retval);
! 1090: break;
! 1091: }
! 1092: case 'g': length = slprintf(buffer, 32, "%d", (t->h % 12) ? (int) t->h % 12 : 12); break;
! 1093: case 'G': length = slprintf(buffer, 32, "%d", (int) t->h); break;
! 1094: case 'h': length = slprintf(buffer, 32, "%02d", (t->h % 12) ? (int) t->h % 12 : 12); break;
! 1095: case 'H': length = slprintf(buffer, 32, "%02d", (int) t->h); break;
! 1096: case 'i': length = slprintf(buffer, 32, "%02d", (int) t->i); break;
! 1097: case 's': length = slprintf(buffer, 32, "%02d", (int) t->s); break;
! 1098: case 'u': length = slprintf(buffer, 32, "%06d", (int) floor(t->f * 1000000)); break;
! 1099:
! 1100: /* timezone */
! 1101: case 'I': length = slprintf(buffer, 32, "%d", localtime ? offset->is_dst : 0); break;
! 1102: case 'P': rfc_colon = 1; /* break intentionally missing */
! 1103: case 'O': length = slprintf(buffer, 32, "%c%02d%s%02d",
! 1104: localtime ? ((offset->offset < 0) ? '-' : '+') : '+',
! 1105: localtime ? abs(offset->offset / 3600) : 0,
! 1106: rfc_colon ? ":" : "",
! 1107: localtime ? abs((offset->offset % 3600) / 60) : 0
! 1108: );
! 1109: break;
! 1110: case 'T': length = slprintf(buffer, 32, "%s", localtime ? offset->abbr : "GMT"); break;
! 1111: case 'e': if (!localtime) {
! 1112: length = slprintf(buffer, 32, "%s", "UTC");
! 1113: } else {
! 1114: switch (t->zone_type) {
! 1115: case TIMELIB_ZONETYPE_ID:
! 1116: length = slprintf(buffer, 32, "%s", t->tz_info->name);
! 1117: break;
! 1118: case TIMELIB_ZONETYPE_ABBR:
! 1119: length = slprintf(buffer, 32, "%s", offset->abbr);
! 1120: break;
! 1121: case TIMELIB_ZONETYPE_OFFSET:
! 1122: length = slprintf(buffer, 32, "%c%02d:%02d",
! 1123: ((offset->offset < 0) ? '-' : '+'),
! 1124: abs(offset->offset / 3600),
! 1125: abs((offset->offset % 3600) / 60)
! 1126: );
! 1127: break;
! 1128: }
! 1129: }
! 1130: break;
! 1131: case 'Z': length = slprintf(buffer, 32, "%d", localtime ? offset->offset : 0); break;
! 1132:
! 1133: /* full date/time */
! 1134: case 'c': length = slprintf(buffer, 96, "%04d-%02d-%02dT%02d:%02d:%02d%c%02d:%02d",
! 1135: (int) t->y, (int) t->m, (int) t->d,
! 1136: (int) t->h, (int) t->i, (int) t->s,
! 1137: localtime ? ((offset->offset < 0) ? '-' : '+') : '+',
! 1138: localtime ? abs(offset->offset / 3600) : 0,
! 1139: localtime ? abs((offset->offset % 3600) / 60) : 0
! 1140: );
! 1141: break;
! 1142: case 'r': length = slprintf(buffer, 96, "%3s, %02d %3s %04d %02d:%02d:%02d %c%02d%02d",
! 1143: php_date_short_day_name(t->y, t->m, t->d),
! 1144: (int) t->d, mon_short_names[t->m - 1],
! 1145: (int) t->y, (int) t->h, (int) t->i, (int) t->s,
! 1146: localtime ? ((offset->offset < 0) ? '-' : '+') : '+',
! 1147: localtime ? abs(offset->offset / 3600) : 0,
! 1148: localtime ? abs((offset->offset % 3600) / 60) : 0
! 1149: );
! 1150: break;
! 1151: case 'U': length = slprintf(buffer, 32, "%lld", (timelib_sll) t->sse); break;
! 1152:
! 1153: case '\\': if (i < format_len) i++; /* break intentionally missing */
! 1154:
! 1155: default: buffer[0] = format[i]; buffer[1] = '\0'; length = 1; break;
! 1156: }
! 1157: smart_str_appendl(&string, buffer, length);
! 1158: }
! 1159:
! 1160: smart_str_0(&string);
! 1161:
! 1162: if (localtime) {
! 1163: timelib_time_offset_dtor(offset);
! 1164: }
! 1165:
! 1166: return string.c;
! 1167: }
! 1168:
! 1169: static void php_date(INTERNAL_FUNCTION_PARAMETERS, int localtime)
! 1170: {
! 1171: char *format;
! 1172: int format_len;
! 1173: long ts;
! 1174: char *string;
! 1175:
! 1176: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &format, &format_len, &ts) == FAILURE) {
! 1177: RETURN_FALSE;
! 1178: }
! 1179: if (ZEND_NUM_ARGS() == 1) {
! 1180: ts = time(NULL);
! 1181: }
! 1182:
! 1183: string = php_format_date(format, format_len, ts, localtime TSRMLS_CC);
! 1184:
! 1185: RETVAL_STRING(string, 0);
! 1186: }
! 1187: /* }}} */
! 1188:
! 1189: PHPAPI char *php_format_date(char *format, int format_len, time_t ts, int localtime TSRMLS_DC) /* {{{ */
! 1190: {
! 1191: timelib_time *t;
! 1192: timelib_tzinfo *tzi;
! 1193: char *string;
! 1194:
! 1195: t = timelib_time_ctor();
! 1196:
! 1197: if (localtime) {
! 1198: tzi = get_timezone_info(TSRMLS_C);
! 1199: t->tz_info = tzi;
! 1200: t->zone_type = TIMELIB_ZONETYPE_ID;
! 1201: timelib_unixtime2local(t, ts);
! 1202: } else {
! 1203: tzi = NULL;
! 1204: timelib_unixtime2gmt(t, ts);
! 1205: }
! 1206:
! 1207: string = date_format(format, format_len, t, localtime);
! 1208:
! 1209: timelib_time_dtor(t);
! 1210: return string;
! 1211: }
! 1212: /* }}} */
! 1213:
! 1214: /* {{{ php_idate
! 1215: */
! 1216: PHPAPI int php_idate(char format, time_t ts, int localtime)
! 1217: {
! 1218: timelib_time *t;
! 1219: timelib_tzinfo *tzi;
! 1220: int retval = -1;
! 1221: timelib_time_offset *offset = NULL;
! 1222: timelib_sll isoweek, isoyear;
! 1223: TSRMLS_FETCH();
! 1224:
! 1225: t = timelib_time_ctor();
! 1226:
! 1227: if (!localtime) {
! 1228: tzi = get_timezone_info(TSRMLS_C);
! 1229: t->tz_info = tzi;
! 1230: t->zone_type = TIMELIB_ZONETYPE_ID;
! 1231: timelib_unixtime2local(t, ts);
! 1232: } else {
! 1233: tzi = NULL;
! 1234: timelib_unixtime2gmt(t, ts);
! 1235: }
! 1236:
! 1237: if (!localtime) {
! 1238: if (t->zone_type == TIMELIB_ZONETYPE_ABBR) {
! 1239: offset = timelib_time_offset_ctor();
! 1240: offset->offset = (t->z - (t->dst * 60)) * -60;
! 1241: offset->leap_secs = 0;
! 1242: offset->is_dst = t->dst;
! 1243: offset->abbr = strdup(t->tz_abbr);
! 1244: } else if (t->zone_type == TIMELIB_ZONETYPE_OFFSET) {
! 1245: offset = timelib_time_offset_ctor();
! 1246: offset->offset = (t->z - (t->dst * 60)) * -60;
! 1247: offset->leap_secs = 0;
! 1248: offset->is_dst = t->dst;
! 1249: offset->abbr = malloc(9); /* GMT�xxxx\0 */
! 1250: snprintf(offset->abbr, 9, "GMT%c%02d%02d",
! 1251: !localtime ? ((offset->offset < 0) ? '-' : '+') : '+',
! 1252: !localtime ? abs(offset->offset / 3600) : 0,
! 1253: !localtime ? abs((offset->offset % 3600) / 60) : 0 );
! 1254: } else {
! 1255: offset = timelib_get_time_zone_info(t->sse, t->tz_info);
! 1256: }
! 1257: }
! 1258:
! 1259: timelib_isoweek_from_date(t->y, t->m, t->d, &isoweek, &isoyear);
! 1260:
! 1261: switch (format) {
! 1262: /* day */
! 1263: case 'd': case 'j': retval = (int) t->d; break;
! 1264:
! 1265: case 'w': retval = (int) timelib_day_of_week(t->y, t->m, t->d); break;
! 1266: case 'z': retval = (int) timelib_day_of_year(t->y, t->m, t->d); break;
! 1267:
! 1268: /* week */
! 1269: case 'W': retval = (int) isoweek; break; /* iso weeknr */
! 1270:
! 1271: /* month */
! 1272: case 'm': case 'n': retval = (int) t->m; break;
! 1273: case 't': retval = (int) timelib_days_in_month(t->y, t->m); break;
! 1274:
! 1275: /* year */
! 1276: case 'L': retval = (int) timelib_is_leap((int) t->y); break;
! 1277: case 'y': retval = (int) (t->y % 100); break;
! 1278: case 'Y': retval = (int) t->y; break;
! 1279:
! 1280: /* Swatch Beat a.k.a. Internet Time */
! 1281: case 'B':
! 1282: retval = (((((long)t->sse)-(((long)t->sse) - ((((long)t->sse) % 86400) + 3600))) * 10) / 864);
! 1283: while (retval < 0) {
! 1284: retval += 1000;
! 1285: }
! 1286: retval = retval % 1000;
! 1287: break;
! 1288:
! 1289: /* time */
! 1290: case 'g': case 'h': retval = (int) ((t->h % 12) ? (int) t->h % 12 : 12); break;
! 1291: case 'H': case 'G': retval = (int) t->h; break;
! 1292: case 'i': retval = (int) t->i; break;
! 1293: case 's': retval = (int) t->s; break;
! 1294:
! 1295: /* timezone */
! 1296: case 'I': retval = (int) (!localtime ? offset->is_dst : 0); break;
! 1297: case 'Z': retval = (int) (!localtime ? offset->offset : 0); break;
! 1298:
! 1299: case 'U': retval = (int) t->sse; break;
! 1300: }
! 1301:
! 1302: if (!localtime) {
! 1303: timelib_time_offset_dtor(offset);
! 1304: }
! 1305: timelib_time_dtor(t);
! 1306:
! 1307: return retval;
! 1308: }
! 1309: /* }}} */
! 1310:
! 1311: /* {{{ proto string date(string format [, long timestamp])
! 1312: Format a local date/time */
! 1313: PHP_FUNCTION(date)
! 1314: {
! 1315: php_date(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
! 1316: }
! 1317: /* }}} */
! 1318:
! 1319: /* {{{ proto string gmdate(string format [, long timestamp])
! 1320: Format a GMT date/time */
! 1321: PHP_FUNCTION(gmdate)
! 1322: {
! 1323: php_date(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
! 1324: }
! 1325: /* }}} */
! 1326:
! 1327: /* {{{ proto int idate(string format [, int timestamp])
! 1328: Format a local time/date as integer */
! 1329: PHP_FUNCTION(idate)
! 1330: {
! 1331: char *format;
! 1332: int format_len;
! 1333: long ts = 0;
! 1334: int ret;
! 1335:
! 1336: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &format, &format_len, &ts) == FAILURE) {
! 1337: RETURN_FALSE;
! 1338: }
! 1339:
! 1340: if (format_len != 1) {
! 1341: php_error_docref(NULL TSRMLS_CC, E_WARNING, "idate format is one char");
! 1342: RETURN_FALSE;
! 1343: }
! 1344:
! 1345: if (ZEND_NUM_ARGS() == 1) {
! 1346: ts = time(NULL);
! 1347: }
! 1348:
! 1349: ret = php_idate(format[0], ts, 0);
! 1350: if (ret == -1) {
! 1351: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unrecognized date format token.");
! 1352: RETURN_FALSE;
! 1353: }
! 1354: RETURN_LONG(ret);
! 1355: }
! 1356: /* }}} */
! 1357:
! 1358: /* {{{ php_date_set_tzdb - NOT THREADSAFE */
! 1359: PHPAPI void php_date_set_tzdb(timelib_tzdb *tzdb)
! 1360: {
! 1361: const timelib_tzdb *builtin = timelib_builtin_db();
! 1362:
! 1363: if (php_version_compare(tzdb->version, builtin->version) > 0) {
! 1364: php_date_global_timezone_db = tzdb;
! 1365: php_date_global_timezone_db_enabled = 1;
! 1366: }
! 1367: }
! 1368: /* }}} */
! 1369:
! 1370: /* {{{ php_parse_date: Backwards compability function */
! 1371: PHPAPI signed long php_parse_date(char *string, signed long *now)
! 1372: {
! 1373: timelib_time *parsed_time;
! 1374: timelib_error_container *error = NULL;
! 1375: int error2;
! 1376: signed long retval;
! 1377:
! 1378: parsed_time = timelib_strtotime(string, strlen(string), &error, DATE_TIMEZONEDB, php_date_parse_tzfile_wrapper);
! 1379: if (error->error_count) {
! 1380: timelib_error_container_dtor(error);
! 1381: return -1;
! 1382: }
! 1383: timelib_error_container_dtor(error);
! 1384: timelib_update_ts(parsed_time, NULL);
! 1385: retval = timelib_date_to_int(parsed_time, &error2);
! 1386: timelib_time_dtor(parsed_time);
! 1387: if (error2) {
! 1388: return -1;
! 1389: }
! 1390: return retval;
! 1391: }
! 1392: /* }}} */
! 1393:
! 1394:
! 1395: /* {{{ proto int strtotime(string time [, int now ])
! 1396: Convert string representation of date and time to a timestamp */
! 1397: PHP_FUNCTION(strtotime)
! 1398: {
! 1399: char *times, *initial_ts;
! 1400: int time_len, error1, error2;
! 1401: struct timelib_error_container *error;
! 1402: long preset_ts = 0, ts;
! 1403:
! 1404: timelib_time *t, *now;
! 1405: timelib_tzinfo *tzi;
! 1406:
! 1407: tzi = get_timezone_info(TSRMLS_C);
! 1408:
! 1409: if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "sl", ×, &time_len, &preset_ts) != FAILURE) {
! 1410: /* We have an initial timestamp */
! 1411: now = timelib_time_ctor();
! 1412:
! 1413: initial_ts = emalloc(25);
! 1414: snprintf(initial_ts, 24, "@%ld UTC", preset_ts);
! 1415: t = timelib_strtotime(initial_ts, strlen(initial_ts), NULL, DATE_TIMEZONEDB, php_date_parse_tzfile_wrapper); /* we ignore the error here, as this should never fail */
! 1416: timelib_update_ts(t, tzi);
! 1417: now->tz_info = tzi;
! 1418: now->zone_type = TIMELIB_ZONETYPE_ID;
! 1419: timelib_unixtime2local(now, t->sse);
! 1420: timelib_time_dtor(t);
! 1421: efree(initial_ts);
! 1422: } else if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", ×, &time_len, &preset_ts) != FAILURE) {
! 1423: /* We have no initial timestamp */
! 1424: now = timelib_time_ctor();
! 1425: now->tz_info = tzi;
! 1426: now->zone_type = TIMELIB_ZONETYPE_ID;
! 1427: timelib_unixtime2local(now, (timelib_sll) time(NULL));
! 1428: } else {
! 1429: RETURN_FALSE;
! 1430: }
! 1431:
! 1432: if (!time_len) {
! 1433: timelib_time_dtor(now);
! 1434: RETURN_FALSE;
! 1435: }
! 1436:
! 1437: t = timelib_strtotime(times, time_len, &error, DATE_TIMEZONEDB, php_date_parse_tzfile_wrapper);
! 1438: error1 = error->error_count;
! 1439: timelib_error_container_dtor(error);
! 1440: timelib_fill_holes(t, now, TIMELIB_NO_CLONE);
! 1441: timelib_update_ts(t, tzi);
! 1442: ts = timelib_date_to_int(t, &error2);
! 1443:
! 1444: timelib_time_dtor(now);
! 1445: timelib_time_dtor(t);
! 1446:
! 1447: if (error1 || error2) {
! 1448: RETURN_FALSE;
! 1449: } else {
! 1450: RETURN_LONG(ts);
! 1451: }
! 1452: }
! 1453: /* }}} */
! 1454:
! 1455:
! 1456: /* {{{ php_mktime - (gm)mktime helper */
! 1457: PHPAPI void php_mktime(INTERNAL_FUNCTION_PARAMETERS, int gmt)
! 1458: {
! 1459: long hou = 0, min = 0, sec = 0, mon = 0, day = 0, yea = 0, dst = -1;
! 1460: timelib_time *now;
! 1461: timelib_tzinfo *tzi = NULL;
! 1462: long ts, adjust_seconds = 0;
! 1463: int error;
! 1464:
! 1465: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|lllllll", &hou, &min, &sec, &mon, &day, &yea, &dst) == FAILURE) {
! 1466: RETURN_FALSE;
! 1467: }
! 1468: /* Initialize structure with current time */
! 1469: now = timelib_time_ctor();
! 1470: if (gmt) {
! 1471: timelib_unixtime2gmt(now, (timelib_sll) time(NULL));
! 1472: } else {
! 1473: tzi = get_timezone_info(TSRMLS_C);
! 1474: now->tz_info = tzi;
! 1475: now->zone_type = TIMELIB_ZONETYPE_ID;
! 1476: timelib_unixtime2local(now, (timelib_sll) time(NULL));
! 1477: }
! 1478: /* Fill in the new data */
! 1479: switch (ZEND_NUM_ARGS()) {
! 1480: case 7:
! 1481: /* break intentionally missing */
! 1482: case 6:
! 1483: if (yea >= 0 && yea < 70) {
! 1484: yea += 2000;
! 1485: } else if (yea >= 70 && yea <= 100) {
! 1486: yea += 1900;
! 1487: }
! 1488: now->y = yea;
! 1489: /* break intentionally missing again */
! 1490: case 5:
! 1491: now->d = day;
! 1492: /* break missing intentionally here too */
! 1493: case 4:
! 1494: now->m = mon;
! 1495: /* and here */
! 1496: case 3:
! 1497: now->s = sec;
! 1498: /* yup, this break isn't here on purpose too */
! 1499: case 2:
! 1500: now->i = min;
! 1501: /* last intentionally missing break */
! 1502: case 1:
! 1503: now->h = hou;
! 1504: break;
! 1505: default:
! 1506: php_error_docref(NULL TSRMLS_CC, E_STRICT, "You should be using the time() function instead");
! 1507: }
! 1508: /* Update the timestamp */
! 1509: if (gmt) {
! 1510: timelib_update_ts(now, NULL);
! 1511: } else {
! 1512: timelib_update_ts(now, tzi);
! 1513: }
! 1514: /* Support for the deprecated is_dst parameter */
! 1515: if (dst != -1) {
! 1516: php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "The is_dst parameter is deprecated");
! 1517: if (gmt) {
! 1518: /* GMT never uses DST */
! 1519: if (dst == 1) {
! 1520: adjust_seconds = -3600;
! 1521: }
! 1522: } else {
! 1523: /* Figure out is_dst for current TS */
! 1524: timelib_time_offset *tmp_offset;
! 1525: tmp_offset = timelib_get_time_zone_info(now->sse, tzi);
! 1526: if (dst == 1 && tmp_offset->is_dst == 0) {
! 1527: adjust_seconds = -3600;
! 1528: }
! 1529: if (dst == 0 && tmp_offset->is_dst == 1) {
! 1530: adjust_seconds = +3600;
! 1531: }
! 1532: timelib_time_offset_dtor(tmp_offset);
! 1533: }
! 1534: }
! 1535: /* Clean up and return */
! 1536: ts = timelib_date_to_int(now, &error);
! 1537: ts += adjust_seconds;
! 1538: timelib_time_dtor(now);
! 1539:
! 1540: if (error) {
! 1541: RETURN_FALSE;
! 1542: } else {
! 1543: RETURN_LONG(ts);
! 1544: }
! 1545: }
! 1546: /* }}} */
! 1547:
! 1548: /* {{{ proto int mktime([int hour [, int min [, int sec [, int mon [, int day [, int year]]]]]])
! 1549: Get UNIX timestamp for a date */
! 1550: PHP_FUNCTION(mktime)
! 1551: {
! 1552: php_mktime(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
! 1553: }
! 1554: /* }}} */
! 1555:
! 1556: /* {{{ proto int gmmktime([int hour [, int min [, int sec [, int mon [, int day [, int year]]]]]])
! 1557: Get UNIX timestamp for a GMT date */
! 1558: PHP_FUNCTION(gmmktime)
! 1559: {
! 1560: php_mktime(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
! 1561: }
! 1562: /* }}} */
! 1563:
! 1564:
! 1565: /* {{{ proto bool checkdate(int month, int day, int year)
! 1566: Returns true(1) if it is a valid date in gregorian calendar */
! 1567: PHP_FUNCTION(checkdate)
! 1568: {
! 1569: long m, d, y;
! 1570:
! 1571: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lll", &m, &d, &y) == FAILURE) {
! 1572: RETURN_FALSE;
! 1573: }
! 1574:
! 1575: if (y < 1 || y > 32767 || !timelib_valid_date(y, m, d)) {
! 1576: RETURN_FALSE;
! 1577: }
! 1578: RETURN_TRUE; /* True : This month, day, year arguments are valid */
! 1579: }
! 1580: /* }}} */
! 1581:
! 1582: #ifdef HAVE_STRFTIME
! 1583: /* {{{ php_strftime - (gm)strftime helper */
! 1584: PHPAPI void php_strftime(INTERNAL_FUNCTION_PARAMETERS, int gmt)
! 1585: {
! 1586: char *format, *buf;
! 1587: int format_len;
! 1588: long timestamp = 0;
! 1589: struct tm ta;
! 1590: int max_reallocs = 5;
! 1591: size_t buf_len = 64, real_len;
! 1592: timelib_time *ts;
! 1593: timelib_tzinfo *tzi;
! 1594: timelib_time_offset *offset = NULL;
! 1595:
! 1596: timestamp = (long) time(NULL);
! 1597:
! 1598: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &format, &format_len, ×tamp) == FAILURE) {
! 1599: RETURN_FALSE;
! 1600: }
! 1601:
! 1602: if (format_len == 0) {
! 1603: RETURN_FALSE;
! 1604: }
! 1605:
! 1606: ts = timelib_time_ctor();
! 1607: if (gmt) {
! 1608: tzi = NULL;
! 1609: timelib_unixtime2gmt(ts, (timelib_sll) timestamp);
! 1610: } else {
! 1611: tzi = get_timezone_info(TSRMLS_C);
! 1612: ts->tz_info = tzi;
! 1613: ts->zone_type = TIMELIB_ZONETYPE_ID;
! 1614: timelib_unixtime2local(ts, (timelib_sll) timestamp);
! 1615: }
! 1616: ta.tm_sec = ts->s;
! 1617: ta.tm_min = ts->i;
! 1618: ta.tm_hour = ts->h;
! 1619: ta.tm_mday = ts->d;
! 1620: ta.tm_mon = ts->m - 1;
! 1621: ta.tm_year = ts->y - 1900;
! 1622: ta.tm_wday = timelib_day_of_week(ts->y, ts->m, ts->d);
! 1623: ta.tm_yday = timelib_day_of_year(ts->y, ts->m, ts->d);
! 1624: if (gmt) {
! 1625: ta.tm_isdst = 0;
! 1626: #if HAVE_TM_GMTOFF
! 1627: ta.tm_gmtoff = 0;
! 1628: #endif
! 1629: #if HAVE_TM_ZONE
! 1630: ta.tm_zone = "GMT";
! 1631: #endif
! 1632: } else {
! 1633: offset = timelib_get_time_zone_info(timestamp, tzi);
! 1634:
! 1635: ta.tm_isdst = offset->is_dst;
! 1636: #if HAVE_TM_GMTOFF
! 1637: ta.tm_gmtoff = offset->offset;
! 1638: #endif
! 1639: #if HAVE_TM_ZONE
! 1640: ta.tm_zone = offset->abbr;
! 1641: #endif
! 1642: }
! 1643:
! 1644: buf = (char *) emalloc(buf_len);
! 1645: while ((real_len=strftime(buf, buf_len, format, &ta))==buf_len || real_len==0) {
! 1646: buf_len *= 2;
! 1647: buf = (char *) erealloc(buf, buf_len);
! 1648: if (!--max_reallocs) {
! 1649: break;
! 1650: }
! 1651: }
! 1652:
! 1653: timelib_time_dtor(ts);
! 1654: if (!gmt) {
! 1655: timelib_time_offset_dtor(offset);
! 1656: }
! 1657:
! 1658: if (real_len && real_len != buf_len) {
! 1659: buf = (char *) erealloc(buf, real_len + 1);
! 1660: RETURN_STRINGL(buf, real_len, 0);
! 1661: }
! 1662: efree(buf);
! 1663: RETURN_FALSE;
! 1664: }
! 1665: /* }}} */
! 1666:
! 1667: /* {{{ proto string strftime(string format [, int timestamp])
! 1668: Format a local time/date according to locale settings */
! 1669: PHP_FUNCTION(strftime)
! 1670: {
! 1671: php_strftime(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
! 1672: }
! 1673: /* }}} */
! 1674:
! 1675: /* {{{ proto string gmstrftime(string format [, int timestamp])
! 1676: Format a GMT/UCT time/date according to locale settings */
! 1677: PHP_FUNCTION(gmstrftime)
! 1678: {
! 1679: php_strftime(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
! 1680: }
! 1681: /* }}} */
! 1682: #endif
! 1683:
! 1684: /* {{{ proto int time(void)
! 1685: Return current UNIX timestamp */
! 1686: PHP_FUNCTION(time)
! 1687: {
! 1688: RETURN_LONG((long)time(NULL));
! 1689: }
! 1690: /* }}} */
! 1691:
! 1692: /* {{{ proto array localtime([int timestamp [, bool associative_array]])
! 1693: 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 */
! 1694: PHP_FUNCTION(localtime)
! 1695: {
! 1696: long timestamp = (long)time(NULL);
! 1697: zend_bool associative = 0;
! 1698: timelib_tzinfo *tzi;
! 1699: timelib_time *ts;
! 1700:
! 1701: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|lb", ×tamp, &associative) == FAILURE) {
! 1702: RETURN_FALSE;
! 1703: }
! 1704:
! 1705: tzi = get_timezone_info(TSRMLS_C);
! 1706: ts = timelib_time_ctor();
! 1707: ts->tz_info = tzi;
! 1708: ts->zone_type = TIMELIB_ZONETYPE_ID;
! 1709: timelib_unixtime2local(ts, (timelib_sll) timestamp);
! 1710:
! 1711: array_init(return_value);
! 1712:
! 1713: if (associative) {
! 1714: add_assoc_long(return_value, "tm_sec", ts->s);
! 1715: add_assoc_long(return_value, "tm_min", ts->i);
! 1716: add_assoc_long(return_value, "tm_hour", ts->h);
! 1717: add_assoc_long(return_value, "tm_mday", ts->d);
! 1718: add_assoc_long(return_value, "tm_mon", ts->m - 1);
! 1719: add_assoc_long(return_value, "tm_year", ts->y - 1900);
! 1720: add_assoc_long(return_value, "tm_wday", timelib_day_of_week(ts->y, ts->m, ts->d));
! 1721: add_assoc_long(return_value, "tm_yday", timelib_day_of_year(ts->y, ts->m, ts->d));
! 1722: add_assoc_long(return_value, "tm_isdst", ts->dst);
! 1723: } else {
! 1724: add_next_index_long(return_value, ts->s);
! 1725: add_next_index_long(return_value, ts->i);
! 1726: add_next_index_long(return_value, ts->h);
! 1727: add_next_index_long(return_value, ts->d);
! 1728: add_next_index_long(return_value, ts->m - 1);
! 1729: add_next_index_long(return_value, ts->y- 1900);
! 1730: add_next_index_long(return_value, timelib_day_of_week(ts->y, ts->m, ts->d));
! 1731: add_next_index_long(return_value, timelib_day_of_year(ts->y, ts->m, ts->d));
! 1732: add_next_index_long(return_value, ts->dst);
! 1733: }
! 1734:
! 1735: timelib_time_dtor(ts);
! 1736: }
! 1737: /* }}} */
! 1738:
! 1739: /* {{{ proto array getdate([int timestamp])
! 1740: Get date/time information */
! 1741: PHP_FUNCTION(getdate)
! 1742: {
! 1743: long timestamp = (long)time(NULL);
! 1744: timelib_tzinfo *tzi;
! 1745: timelib_time *ts;
! 1746:
! 1747: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", ×tamp) == FAILURE) {
! 1748: RETURN_FALSE;
! 1749: }
! 1750:
! 1751: tzi = get_timezone_info(TSRMLS_C);
! 1752: ts = timelib_time_ctor();
! 1753: ts->tz_info = tzi;
! 1754: ts->zone_type = TIMELIB_ZONETYPE_ID;
! 1755: timelib_unixtime2local(ts, (timelib_sll) timestamp);
! 1756:
! 1757: array_init(return_value);
! 1758:
! 1759: add_assoc_long(return_value, "seconds", ts->s);
! 1760: add_assoc_long(return_value, "minutes", ts->i);
! 1761: add_assoc_long(return_value, "hours", ts->h);
! 1762: add_assoc_long(return_value, "mday", ts->d);
! 1763: add_assoc_long(return_value, "wday", timelib_day_of_week(ts->y, ts->m, ts->d));
! 1764: add_assoc_long(return_value, "mon", ts->m);
! 1765: add_assoc_long(return_value, "year", ts->y);
! 1766: add_assoc_long(return_value, "yday", timelib_day_of_year(ts->y, ts->m, ts->d));
! 1767: add_assoc_string(return_value, "weekday", php_date_full_day_name(ts->y, ts->m, ts->d), 1);
! 1768: add_assoc_string(return_value, "month", mon_full_names[ts->m - 1], 1);
! 1769: add_index_long(return_value, 0, timestamp);
! 1770:
! 1771: timelib_time_dtor(ts);
! 1772: }
! 1773: /* }}} */
! 1774:
! 1775: #define PHP_DATE_TIMEZONE_GROUP_AFRICA 0x0001
! 1776: #define PHP_DATE_TIMEZONE_GROUP_AMERICA 0x0002
! 1777: #define PHP_DATE_TIMEZONE_GROUP_ANTARCTICA 0x0004
! 1778: #define PHP_DATE_TIMEZONE_GROUP_ARCTIC 0x0008
! 1779: #define PHP_DATE_TIMEZONE_GROUP_ASIA 0x0010
! 1780: #define PHP_DATE_TIMEZONE_GROUP_ATLANTIC 0x0020
! 1781: #define PHP_DATE_TIMEZONE_GROUP_AUSTRALIA 0x0040
! 1782: #define PHP_DATE_TIMEZONE_GROUP_EUROPE 0x0080
! 1783: #define PHP_DATE_TIMEZONE_GROUP_INDIAN 0x0100
! 1784: #define PHP_DATE_TIMEZONE_GROUP_PACIFIC 0x0200
! 1785: #define PHP_DATE_TIMEZONE_GROUP_UTC 0x0400
! 1786: #define PHP_DATE_TIMEZONE_GROUP_ALL 0x07FF
! 1787: #define PHP_DATE_TIMEZONE_GROUP_ALL_W_BC 0x0FFF
! 1788: #define PHP_DATE_TIMEZONE_PER_COUNTRY 0x1000
! 1789:
! 1790: #define PHP_DATE_PERIOD_EXCLUDE_START_DATE 0x0001
! 1791:
! 1792:
! 1793: /* define an overloaded iterator structure */
! 1794: typedef struct {
! 1795: zend_object_iterator intern;
! 1796: zval *date_period_zval;
! 1797: zval *current;
! 1798: php_period_obj *object;
! 1799: int current_index;
! 1800: } date_period_it;
! 1801:
! 1802: /* {{{ date_period_it_invalidate_current */
! 1803: static void date_period_it_invalidate_current(zend_object_iterator *iter TSRMLS_DC)
! 1804: {
! 1805: date_period_it *iterator = (date_period_it *)iter;
! 1806:
! 1807: if (iterator->current) {
! 1808: zval_ptr_dtor(&iterator->current);
! 1809: iterator->current = NULL;
! 1810: }
! 1811: }
! 1812: /* }}} */
! 1813:
! 1814:
! 1815: /* {{{ date_period_it_dtor */
! 1816: static void date_period_it_dtor(zend_object_iterator *iter TSRMLS_DC)
! 1817: {
! 1818: date_period_it *iterator = (date_period_it *)iter;
! 1819:
! 1820: date_period_it_invalidate_current(iter TSRMLS_CC);
! 1821:
! 1822: zval_ptr_dtor(&iterator->date_period_zval);
! 1823:
! 1824: efree(iterator);
! 1825: }
! 1826: /* }}} */
! 1827:
! 1828:
! 1829: /* {{{ date_period_it_has_more */
! 1830: static int date_period_it_has_more(zend_object_iterator *iter TSRMLS_DC)
! 1831: {
! 1832: date_period_it *iterator = (date_period_it *)iter;
! 1833: php_period_obj *object = iterator->object;
! 1834: timelib_time *it_time = object->current;
! 1835:
! 1836: /* apply modification if it's not the first iteration */
! 1837: if (!object->include_start_date || iterator->current_index > 0) {
! 1838: it_time->have_relative = 1;
! 1839: it_time->relative = *object->interval;
! 1840: it_time->sse_uptodate = 0;
! 1841: timelib_update_ts(it_time, NULL);
! 1842: timelib_update_from_sse(it_time);
! 1843: }
! 1844:
! 1845: if (object->end) {
! 1846: return object->current->sse < object->end->sse ? SUCCESS : FAILURE;
! 1847: } else {
! 1848: return (iterator->current_index < object->recurrences) ? SUCCESS : FAILURE;
! 1849: }
! 1850: }
! 1851: /* }}} */
! 1852:
! 1853:
! 1854: /* {{{ date_period_it_current_data */
! 1855: static void date_period_it_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC)
! 1856: {
! 1857: date_period_it *iterator = (date_period_it *)iter;
! 1858: php_period_obj *object = iterator->object;
! 1859: timelib_time *it_time = object->current;
! 1860: php_date_obj *newdateobj;
! 1861:
! 1862: /* Create new object */
! 1863: MAKE_STD_ZVAL(iterator->current);
! 1864: php_date_instantiate(date_ce_date, iterator->current TSRMLS_CC);
! 1865: newdateobj = (php_date_obj *) zend_object_store_get_object(iterator->current TSRMLS_CC);
! 1866: newdateobj->time = timelib_time_ctor();
! 1867: *newdateobj->time = *it_time;
! 1868: if (it_time->tz_abbr) {
! 1869: newdateobj->time->tz_abbr = strdup(it_time->tz_abbr);
! 1870: }
! 1871: if (it_time->tz_info) {
! 1872: newdateobj->time->tz_info = it_time->tz_info;
! 1873: }
! 1874:
! 1875: *data = &iterator->current;
! 1876: }
! 1877: /* }}} */
! 1878:
! 1879:
! 1880: /* {{{ date_period_it_current_key */
! 1881: static int date_period_it_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC)
! 1882: {
! 1883: date_period_it *iterator = (date_period_it *)iter;
! 1884: *int_key = iterator->current_index;
! 1885: return HASH_KEY_IS_LONG;
! 1886: }
! 1887: /* }}} */
! 1888:
! 1889:
! 1890: /* {{{ date_period_it_move_forward */
! 1891: static void date_period_it_move_forward(zend_object_iterator *iter TSRMLS_DC)
! 1892: {
! 1893: date_period_it *iterator = (date_period_it *)iter;
! 1894:
! 1895: iterator->current_index++;
! 1896: date_period_it_invalidate_current(iter TSRMLS_CC);
! 1897: }
! 1898: /* }}} */
! 1899:
! 1900:
! 1901: /* {{{ date_period_it_rewind */
! 1902: static void date_period_it_rewind(zend_object_iterator *iter TSRMLS_DC)
! 1903: {
! 1904: date_period_it *iterator = (date_period_it *)iter;
! 1905:
! 1906: iterator->current_index = 0;
! 1907: if (iterator->object->current) {
! 1908: timelib_time_dtor(iterator->object->current);
! 1909: }
! 1910: iterator->object->current = timelib_time_clone(iterator->object->start);
! 1911: date_period_it_invalidate_current(iter TSRMLS_CC);
! 1912: }
! 1913: /* }}} */
! 1914:
! 1915:
! 1916: /* iterator handler table */
! 1917: zend_object_iterator_funcs date_period_it_funcs = {
! 1918: date_period_it_dtor,
! 1919: date_period_it_has_more,
! 1920: date_period_it_current_data,
! 1921: date_period_it_current_key,
! 1922: date_period_it_move_forward,
! 1923: date_period_it_rewind,
! 1924: date_period_it_invalidate_current
! 1925: };
! 1926:
! 1927:
! 1928:
! 1929: zend_object_iterator *date_object_period_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC)
! 1930: {
! 1931: date_period_it *iterator = emalloc(sizeof(date_period_it));
! 1932: php_period_obj *dpobj = (php_period_obj *)zend_object_store_get_object(object TSRMLS_CC);
! 1933:
! 1934: if (by_ref) {
! 1935: zend_error(E_ERROR, "An iterator cannot be used with foreach by reference");
! 1936: }
! 1937:
! 1938: Z_ADDREF_P(object);
! 1939: iterator->intern.data = (void*) dpobj;
! 1940: iterator->intern.funcs = &date_period_it_funcs;
! 1941: iterator->date_period_zval = object;
! 1942: iterator->object = dpobj;
! 1943: iterator->current = NULL;
! 1944:
! 1945: return (zend_object_iterator*)iterator;
! 1946: }
! 1947:
! 1948: static void date_register_classes(TSRMLS_D)
! 1949: {
! 1950: zend_class_entry ce_date, ce_timezone, ce_interval, ce_period;
! 1951:
! 1952: INIT_CLASS_ENTRY(ce_date, "DateTime", date_funcs_date);
! 1953: ce_date.create_object = date_object_new_date;
! 1954: date_ce_date = zend_register_internal_class_ex(&ce_date, NULL, NULL TSRMLS_CC);
! 1955: memcpy(&date_object_handlers_date, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
! 1956: date_object_handlers_date.clone_obj = date_object_clone_date;
! 1957: date_object_handlers_date.compare_objects = date_object_compare_date;
! 1958: date_object_handlers_date.get_properties = date_object_get_properties;
! 1959:
! 1960: #define REGISTER_DATE_CLASS_CONST_STRING(const_name, value) \
! 1961: zend_declare_class_constant_stringl(date_ce_date, const_name, sizeof(const_name)-1, value, sizeof(value)-1 TSRMLS_CC);
! 1962:
! 1963: REGISTER_DATE_CLASS_CONST_STRING("ATOM", DATE_FORMAT_RFC3339);
! 1964: REGISTER_DATE_CLASS_CONST_STRING("COOKIE", DATE_FORMAT_RFC850);
! 1965: REGISTER_DATE_CLASS_CONST_STRING("ISO8601", DATE_FORMAT_ISO8601);
! 1966: REGISTER_DATE_CLASS_CONST_STRING("RFC822", DATE_FORMAT_RFC822);
! 1967: REGISTER_DATE_CLASS_CONST_STRING("RFC850", DATE_FORMAT_RFC850);
! 1968: REGISTER_DATE_CLASS_CONST_STRING("RFC1036", DATE_FORMAT_RFC1036);
! 1969: REGISTER_DATE_CLASS_CONST_STRING("RFC1123", DATE_FORMAT_RFC1123);
! 1970: REGISTER_DATE_CLASS_CONST_STRING("RFC2822", DATE_FORMAT_RFC2822);
! 1971: REGISTER_DATE_CLASS_CONST_STRING("RFC3339", DATE_FORMAT_RFC3339);
! 1972: REGISTER_DATE_CLASS_CONST_STRING("RSS", DATE_FORMAT_RFC1123);
! 1973: REGISTER_DATE_CLASS_CONST_STRING("W3C", DATE_FORMAT_RFC3339);
! 1974:
! 1975:
! 1976: INIT_CLASS_ENTRY(ce_timezone, "DateTimeZone", date_funcs_timezone);
! 1977: ce_timezone.create_object = date_object_new_timezone;
! 1978: date_ce_timezone = zend_register_internal_class_ex(&ce_timezone, NULL, NULL TSRMLS_CC);
! 1979: memcpy(&date_object_handlers_timezone, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
! 1980: date_object_handlers_timezone.clone_obj = date_object_clone_timezone;
! 1981:
! 1982: #define REGISTER_TIMEZONE_CLASS_CONST_STRING(const_name, value) \
! 1983: zend_declare_class_constant_long(date_ce_timezone, const_name, sizeof(const_name)-1, value TSRMLS_CC);
! 1984:
! 1985: REGISTER_TIMEZONE_CLASS_CONST_STRING("AFRICA", PHP_DATE_TIMEZONE_GROUP_AFRICA);
! 1986: REGISTER_TIMEZONE_CLASS_CONST_STRING("AMERICA", PHP_DATE_TIMEZONE_GROUP_AMERICA);
! 1987: REGISTER_TIMEZONE_CLASS_CONST_STRING("ANTARCTICA", PHP_DATE_TIMEZONE_GROUP_ANTARCTICA);
! 1988: REGISTER_TIMEZONE_CLASS_CONST_STRING("ARCTIC", PHP_DATE_TIMEZONE_GROUP_ARCTIC);
! 1989: REGISTER_TIMEZONE_CLASS_CONST_STRING("ASIA", PHP_DATE_TIMEZONE_GROUP_ASIA);
! 1990: REGISTER_TIMEZONE_CLASS_CONST_STRING("ATLANTIC", PHP_DATE_TIMEZONE_GROUP_ATLANTIC);
! 1991: REGISTER_TIMEZONE_CLASS_CONST_STRING("AUSTRALIA", PHP_DATE_TIMEZONE_GROUP_AUSTRALIA);
! 1992: REGISTER_TIMEZONE_CLASS_CONST_STRING("EUROPE", PHP_DATE_TIMEZONE_GROUP_EUROPE);
! 1993: REGISTER_TIMEZONE_CLASS_CONST_STRING("INDIAN", PHP_DATE_TIMEZONE_GROUP_INDIAN);
! 1994: REGISTER_TIMEZONE_CLASS_CONST_STRING("PACIFIC", PHP_DATE_TIMEZONE_GROUP_PACIFIC);
! 1995: REGISTER_TIMEZONE_CLASS_CONST_STRING("UTC", PHP_DATE_TIMEZONE_GROUP_UTC);
! 1996: REGISTER_TIMEZONE_CLASS_CONST_STRING("ALL", PHP_DATE_TIMEZONE_GROUP_ALL);
! 1997: REGISTER_TIMEZONE_CLASS_CONST_STRING("ALL_WITH_BC", PHP_DATE_TIMEZONE_GROUP_ALL_W_BC);
! 1998: REGISTER_TIMEZONE_CLASS_CONST_STRING("PER_COUNTRY", PHP_DATE_TIMEZONE_PER_COUNTRY);
! 1999:
! 2000: INIT_CLASS_ENTRY(ce_interval, "DateInterval", date_funcs_interval);
! 2001: ce_interval.create_object = date_object_new_interval;
! 2002: date_ce_interval = zend_register_internal_class_ex(&ce_interval, NULL, NULL TSRMLS_CC);
! 2003: memcpy(&date_object_handlers_interval, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
! 2004: date_object_handlers_interval.clone_obj = date_object_clone_interval;
! 2005: date_object_handlers_interval.read_property = date_interval_read_property;
! 2006: date_object_handlers_interval.write_property = date_interval_write_property;
! 2007: date_object_handlers_interval.get_properties = date_object_get_properties_interval;
! 2008: date_object_handlers_interval.get_property_ptr_ptr = NULL;
! 2009:
! 2010: INIT_CLASS_ENTRY(ce_period, "DatePeriod", date_funcs_period);
! 2011: ce_period.create_object = date_object_new_period;
! 2012: date_ce_period = zend_register_internal_class_ex(&ce_period, NULL, NULL TSRMLS_CC);
! 2013: date_ce_period->get_iterator = date_object_period_get_iterator;
! 2014: date_ce_period->iterator_funcs.funcs = &date_period_it_funcs;
! 2015: zend_class_implements(date_ce_period TSRMLS_CC, 1, zend_ce_traversable);
! 2016: memcpy(&date_object_handlers_period, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
! 2017: date_object_handlers_period.clone_obj = date_object_clone_period;
! 2018:
! 2019: #define REGISTER_PERIOD_CLASS_CONST_STRING(const_name, value) \
! 2020: zend_declare_class_constant_long(date_ce_period, const_name, sizeof(const_name)-1, value TSRMLS_CC);
! 2021:
! 2022: REGISTER_PERIOD_CLASS_CONST_STRING("EXCLUDE_START_DATE", PHP_DATE_PERIOD_EXCLUDE_START_DATE);
! 2023: }
! 2024:
! 2025: static inline zend_object_value date_object_new_date_ex(zend_class_entry *class_type, php_date_obj **ptr TSRMLS_DC)
! 2026: {
! 2027: php_date_obj *intern;
! 2028: zend_object_value retval;
! 2029: zval *tmp;
! 2030:
! 2031: intern = emalloc(sizeof(php_date_obj));
! 2032: memset(intern, 0, sizeof(php_date_obj));
! 2033: if (ptr) {
! 2034: *ptr = intern;
! 2035: }
! 2036:
! 2037: zend_object_std_init(&intern->std, class_type TSRMLS_CC);
! 2038: zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
! 2039:
! 2040: retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) date_object_free_storage_date, NULL TSRMLS_CC);
! 2041: retval.handlers = &date_object_handlers_date;
! 2042:
! 2043: return retval;
! 2044: }
! 2045:
! 2046: static zend_object_value date_object_new_date(zend_class_entry *class_type TSRMLS_DC)
! 2047: {
! 2048: return date_object_new_date_ex(class_type, NULL TSRMLS_CC);
! 2049: }
! 2050:
! 2051: static zend_object_value date_object_clone_date(zval *this_ptr TSRMLS_DC)
! 2052: {
! 2053: php_date_obj *new_obj = NULL;
! 2054: php_date_obj *old_obj = (php_date_obj *) zend_object_store_get_object(this_ptr TSRMLS_CC);
! 2055: zend_object_value new_ov = date_object_new_date_ex(old_obj->std.ce, &new_obj TSRMLS_CC);
! 2056:
! 2057: zend_objects_clone_members(&new_obj->std, new_ov, &old_obj->std, Z_OBJ_HANDLE_P(this_ptr) TSRMLS_CC);
! 2058: if (!old_obj->time) {
! 2059: return new_ov;
! 2060: }
! 2061:
! 2062: /* this should probably moved to a new `timelib_time *timelime_time_clone(timelib_time *)` */
! 2063: new_obj->time = timelib_time_ctor();
! 2064: *new_obj->time = *old_obj->time;
! 2065: if (old_obj->time->tz_abbr) {
! 2066: new_obj->time->tz_abbr = strdup(old_obj->time->tz_abbr);
! 2067: }
! 2068: if (old_obj->time->tz_info) {
! 2069: new_obj->time->tz_info = old_obj->time->tz_info;
! 2070: }
! 2071:
! 2072: return new_ov;
! 2073: }
! 2074:
! 2075: static int date_object_compare_date(zval *d1, zval *d2 TSRMLS_DC)
! 2076: {
! 2077: if (Z_TYPE_P(d1) == IS_OBJECT && Z_TYPE_P(d2) == IS_OBJECT &&
! 2078: instanceof_function(Z_OBJCE_P(d1), date_ce_date TSRMLS_CC) &&
! 2079: instanceof_function(Z_OBJCE_P(d2), date_ce_date TSRMLS_CC)) {
! 2080: php_date_obj *o1 = zend_object_store_get_object(d1 TSRMLS_CC);
! 2081: php_date_obj *o2 = zend_object_store_get_object(d2 TSRMLS_CC);
! 2082:
! 2083: if (!o1->time->sse_uptodate) {
! 2084: timelib_update_ts(o1->time, o1->time->tz_info);
! 2085: }
! 2086: if (!o2->time->sse_uptodate) {
! 2087: timelib_update_ts(o2->time, o2->time->tz_info);
! 2088: }
! 2089:
! 2090: return (o1->time->sse == o2->time->sse) ? 0 : ((o1->time->sse < o2->time->sse) ? -1 : 1);
! 2091: }
! 2092:
! 2093: return 1;
! 2094: }
! 2095:
! 2096: static HashTable *date_object_get_properties(zval *object TSRMLS_DC)
! 2097: {
! 2098: HashTable *props;
! 2099: zval *zv;
! 2100: php_date_obj *dateobj;
! 2101:
! 2102:
! 2103: dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC);
! 2104:
! 2105: props = zend_std_get_properties(object TSRMLS_CC);
! 2106:
! 2107: if (!dateobj->time || GC_G(gc_active)) {
! 2108: return props;
! 2109: }
! 2110:
! 2111: /* first we add the date and time in ISO format */
! 2112: MAKE_STD_ZVAL(zv);
! 2113: ZVAL_STRING(zv, date_format("Y-m-d H:i:s", 12, dateobj->time, 1), 0);
! 2114: zend_hash_update(props, "date", 5, &zv, sizeof(zval), NULL);
! 2115:
! 2116: /* then we add the timezone name (or similar) */
! 2117: if (dateobj->time->is_localtime) {
! 2118: MAKE_STD_ZVAL(zv);
! 2119: ZVAL_LONG(zv, dateobj->time->zone_type);
! 2120: zend_hash_update(props, "timezone_type", 14, &zv, sizeof(zval), NULL);
! 2121:
! 2122: MAKE_STD_ZVAL(zv);
! 2123: switch (dateobj->time->zone_type) {
! 2124: case TIMELIB_ZONETYPE_ID:
! 2125: ZVAL_STRING(zv, dateobj->time->tz_info->name, 1);
! 2126: break;
! 2127: case TIMELIB_ZONETYPE_OFFSET: {
! 2128: char *tmpstr = emalloc(sizeof("UTC+05:00"));
! 2129: timelib_sll utc_offset = dateobj->time->z;
! 2130:
! 2131: snprintf(tmpstr, sizeof("+05:00"), "%c%02d:%02d",
! 2132: utc_offset > 0 ? '-' : '+',
! 2133: abs(utc_offset / 60),
! 2134: abs((utc_offset % 60)));
! 2135:
! 2136: ZVAL_STRING(zv, tmpstr, 0);
! 2137: }
! 2138: break;
! 2139: case TIMELIB_ZONETYPE_ABBR:
! 2140: ZVAL_STRING(zv, dateobj->time->tz_abbr, 1);
! 2141: break;
! 2142: }
! 2143: zend_hash_update(props, "timezone", 9, &zv, sizeof(zval), NULL);
! 2144: }
! 2145:
! 2146: return props;
! 2147: }
! 2148:
! 2149: static inline zend_object_value date_object_new_timezone_ex(zend_class_entry *class_type, php_timezone_obj **ptr TSRMLS_DC)
! 2150: {
! 2151: php_timezone_obj *intern;
! 2152: zend_object_value retval;
! 2153: zval *tmp;
! 2154:
! 2155: intern = emalloc(sizeof(php_timezone_obj));
! 2156: memset(intern, 0, sizeof(php_timezone_obj));
! 2157: if (ptr) {
! 2158: *ptr = intern;
! 2159: }
! 2160:
! 2161: zend_object_std_init(&intern->std, class_type TSRMLS_CC);
! 2162: zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
! 2163:
! 2164: retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) date_object_free_storage_timezone, NULL TSRMLS_CC);
! 2165: retval.handlers = &date_object_handlers_timezone;
! 2166:
! 2167: return retval;
! 2168: }
! 2169:
! 2170: static zend_object_value date_object_new_timezone(zend_class_entry *class_type TSRMLS_DC)
! 2171: {
! 2172: return date_object_new_timezone_ex(class_type, NULL TSRMLS_CC);
! 2173: }
! 2174:
! 2175: static zend_object_value date_object_clone_timezone(zval *this_ptr TSRMLS_DC)
! 2176: {
! 2177: php_timezone_obj *new_obj = NULL;
! 2178: php_timezone_obj *old_obj = (php_timezone_obj *) zend_object_store_get_object(this_ptr TSRMLS_CC);
! 2179: zend_object_value new_ov = date_object_new_timezone_ex(old_obj->std.ce, &new_obj TSRMLS_CC);
! 2180:
! 2181: zend_objects_clone_members(&new_obj->std, new_ov, &old_obj->std, Z_OBJ_HANDLE_P(this_ptr) TSRMLS_CC);
! 2182: if (!old_obj->initialized) {
! 2183: return new_ov;
! 2184: }
! 2185:
! 2186: new_obj->type = old_obj->type;
! 2187: new_obj->initialized = 1;
! 2188: switch (new_obj->type) {
! 2189: case TIMELIB_ZONETYPE_ID:
! 2190: new_obj->tzi.tz = old_obj->tzi.tz;
! 2191: break;
! 2192: case TIMELIB_ZONETYPE_OFFSET:
! 2193: new_obj->tzi.utc_offset = old_obj->tzi.utc_offset;
! 2194: break;
! 2195: case TIMELIB_ZONETYPE_ABBR:
! 2196: new_obj->tzi.z.utc_offset = old_obj->tzi.z.utc_offset;
! 2197: new_obj->tzi.z.dst = old_obj->tzi.z.dst;
! 2198: new_obj->tzi.z.abbr = old_obj->tzi.z.abbr;
! 2199: break;
! 2200: }
! 2201:
! 2202: return new_ov;
! 2203: }
! 2204:
! 2205: static inline zend_object_value date_object_new_interval_ex(zend_class_entry *class_type, php_interval_obj **ptr TSRMLS_DC)
! 2206: {
! 2207: php_interval_obj *intern;
! 2208: zend_object_value retval;
! 2209: zval *tmp;
! 2210:
! 2211: intern = emalloc(sizeof(php_interval_obj));
! 2212: memset(intern, 0, sizeof(php_interval_obj));
! 2213: if (ptr) {
! 2214: *ptr = intern;
! 2215: }
! 2216:
! 2217: zend_object_std_init(&intern->std, class_type TSRMLS_CC);
! 2218: zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
! 2219:
! 2220: retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) date_object_free_storage_interval, NULL TSRMLS_CC);
! 2221: retval.handlers = &date_object_handlers_interval;
! 2222:
! 2223: return retval;
! 2224: }
! 2225:
! 2226: static zend_object_value date_object_new_interval(zend_class_entry *class_type TSRMLS_DC)
! 2227: {
! 2228: return date_object_new_interval_ex(class_type, NULL TSRMLS_CC);
! 2229: }
! 2230:
! 2231: static zend_object_value date_object_clone_interval(zval *this_ptr TSRMLS_DC)
! 2232: {
! 2233: php_interval_obj *new_obj = NULL;
! 2234: php_interval_obj *old_obj = (php_interval_obj *) zend_object_store_get_object(this_ptr TSRMLS_CC);
! 2235: zend_object_value new_ov = date_object_new_interval_ex(old_obj->std.ce, &new_obj TSRMLS_CC);
! 2236:
! 2237: zend_objects_clone_members(&new_obj->std, new_ov, &old_obj->std, Z_OBJ_HANDLE_P(this_ptr) TSRMLS_CC);
! 2238:
! 2239: /** FIX ME ADD CLONE STUFF **/
! 2240: return new_ov;
! 2241: }
! 2242:
! 2243: static HashTable *date_object_get_properties_interval(zval *object TSRMLS_DC)
! 2244: {
! 2245: HashTable *props;
! 2246: zval *zv;
! 2247: php_interval_obj *intervalobj;
! 2248:
! 2249:
! 2250: intervalobj = (php_interval_obj *) zend_object_store_get_object(object TSRMLS_CC);
! 2251:
! 2252: props = zend_std_get_properties(object TSRMLS_CC);
! 2253:
! 2254: if (!intervalobj->initialized || GC_G(gc_active)) {
! 2255: return props;
! 2256: }
! 2257:
! 2258: #define PHP_DATE_INTERVAL_ADD_PROPERTY(n,f) \
! 2259: MAKE_STD_ZVAL(zv); \
! 2260: ZVAL_LONG(zv, intervalobj->diff->f); \
! 2261: zend_hash_update(props, n, strlen(n) + 1, &zv, sizeof(zval), NULL);
! 2262:
! 2263: PHP_DATE_INTERVAL_ADD_PROPERTY("y", y);
! 2264: PHP_DATE_INTERVAL_ADD_PROPERTY("m", m);
! 2265: PHP_DATE_INTERVAL_ADD_PROPERTY("d", d);
! 2266: PHP_DATE_INTERVAL_ADD_PROPERTY("h", h);
! 2267: PHP_DATE_INTERVAL_ADD_PROPERTY("i", i);
! 2268: PHP_DATE_INTERVAL_ADD_PROPERTY("s", s);
! 2269: PHP_DATE_INTERVAL_ADD_PROPERTY("invert", invert);
! 2270: if (intervalobj->diff->days != -99999) {
! 2271: PHP_DATE_INTERVAL_ADD_PROPERTY("days", days);
! 2272: } else {
! 2273: MAKE_STD_ZVAL(zv);
! 2274: ZVAL_FALSE(zv);
! 2275: zend_hash_update(props, "days", 5, &zv, sizeof(zval), NULL);
! 2276: }
! 2277:
! 2278: return props;
! 2279: }
! 2280:
! 2281: static inline zend_object_value date_object_new_period_ex(zend_class_entry *class_type, php_period_obj **ptr TSRMLS_DC)
! 2282: {
! 2283: php_period_obj *intern;
! 2284: zend_object_value retval;
! 2285: zval *tmp;
! 2286:
! 2287: intern = emalloc(sizeof(php_period_obj));
! 2288: memset(intern, 0, sizeof(php_period_obj));
! 2289: if (ptr) {
! 2290: *ptr = intern;
! 2291: }
! 2292:
! 2293: zend_object_std_init(&intern->std, class_type TSRMLS_CC);
! 2294: zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
! 2295:
! 2296: retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) date_object_free_storage_period, NULL TSRMLS_CC);
! 2297: retval.handlers = &date_object_handlers_period;
! 2298:
! 2299: return retval;
! 2300: }
! 2301:
! 2302: static zend_object_value date_object_new_period(zend_class_entry *class_type TSRMLS_DC)
! 2303: {
! 2304: return date_object_new_period_ex(class_type, NULL TSRMLS_CC);
! 2305: }
! 2306:
! 2307: static zend_object_value date_object_clone_period(zval *this_ptr TSRMLS_DC)
! 2308: {
! 2309: php_period_obj *new_obj = NULL;
! 2310: php_period_obj *old_obj = (php_period_obj *) zend_object_store_get_object(this_ptr TSRMLS_CC);
! 2311: zend_object_value new_ov = date_object_new_period_ex(old_obj->std.ce, &new_obj TSRMLS_CC);
! 2312:
! 2313: zend_objects_clone_members(&new_obj->std, new_ov, &old_obj->std, Z_OBJ_HANDLE_P(this_ptr) TSRMLS_CC);
! 2314:
! 2315: /** FIX ME ADD CLONE STUFF **/
! 2316: return new_ov;
! 2317: }
! 2318:
! 2319: static void date_object_free_storage_date(void *object TSRMLS_DC)
! 2320: {
! 2321: php_date_obj *intern = (php_date_obj *)object;
! 2322:
! 2323: if (intern->time) {
! 2324: timelib_time_dtor(intern->time);
! 2325: }
! 2326:
! 2327: zend_object_std_dtor(&intern->std TSRMLS_CC);
! 2328: efree(object);
! 2329: }
! 2330:
! 2331: static void date_object_free_storage_timezone(void *object TSRMLS_DC)
! 2332: {
! 2333: php_timezone_obj *intern = (php_timezone_obj *)object;
! 2334:
! 2335: if (intern->type == TIMELIB_ZONETYPE_ABBR) {
! 2336: free(intern->tzi.z.abbr);
! 2337: }
! 2338: zend_object_std_dtor(&intern->std TSRMLS_CC);
! 2339: efree(object);
! 2340: }
! 2341:
! 2342: static void date_object_free_storage_interval(void *object TSRMLS_DC)
! 2343: {
! 2344: php_interval_obj *intern = (php_interval_obj *)object;
! 2345:
! 2346: timelib_rel_time_dtor(intern->diff);
! 2347: zend_object_std_dtor(&intern->std TSRMLS_CC);
! 2348: efree(object);
! 2349: }
! 2350:
! 2351: static void date_object_free_storage_period(void *object TSRMLS_DC)
! 2352: {
! 2353: php_period_obj *intern = (php_period_obj *)object;
! 2354:
! 2355: if (intern->start) {
! 2356: timelib_time_dtor(intern->start);
! 2357: }
! 2358:
! 2359: if (intern->current) {
! 2360: timelib_time_dtor(intern->current);
! 2361: }
! 2362:
! 2363: if (intern->end) {
! 2364: timelib_time_dtor(intern->end);
! 2365: }
! 2366:
! 2367: timelib_rel_time_dtor(intern->interval);
! 2368: zend_object_std_dtor(&intern->std TSRMLS_CC);
! 2369: efree(object);
! 2370: }
! 2371:
! 2372: /* Advanced Interface */
! 2373: PHPAPI zval *php_date_instantiate(zend_class_entry *pce, zval *object TSRMLS_DC)
! 2374: {
! 2375: Z_TYPE_P(object) = IS_OBJECT;
! 2376: object_init_ex(object, pce);
! 2377: Z_SET_REFCOUNT_P(object, 1);
! 2378: Z_UNSET_ISREF_P(object);
! 2379: return object;
! 2380: }
! 2381:
! 2382: /* Helper function used to store the latest found warnings and errors while
! 2383: * parsing, from either strtotime or parse_from_format. */
! 2384: static void update_errors_warnings(timelib_error_container *last_errors TSRMLS_DC)
! 2385: {
! 2386: if (DATEG(last_errors)) {
! 2387: timelib_error_container_dtor(DATEG(last_errors));
! 2388: DATEG(last_errors) = NULL;
! 2389: }
! 2390: DATEG(last_errors) = last_errors;
! 2391: }
! 2392:
! 2393: PHPAPI int php_date_initialize(php_date_obj *dateobj, /*const*/ char *time_str, int time_str_len, char *format, zval *timezone_object, int ctor TSRMLS_DC)
! 2394: {
! 2395: timelib_time *now;
! 2396: timelib_tzinfo *tzi = NULL;
! 2397: timelib_error_container *err = NULL;
! 2398: int type = TIMELIB_ZONETYPE_ID, new_dst;
! 2399: char *new_abbr;
! 2400: timelib_sll new_offset;
! 2401:
! 2402: if (dateobj->time) {
! 2403: timelib_time_dtor(dateobj->time);
! 2404: }
! 2405: if (format) {
! 2406: 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);
! 2407: } else {
! 2408: 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);
! 2409: }
! 2410:
! 2411: /* update last errors and warnings */
! 2412: update_errors_warnings(err TSRMLS_CC);
! 2413:
! 2414:
! 2415: if (ctor && err && err->error_count) {
! 2416: /* spit out the first library error message, at least */
! 2417: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to parse time string (%s) at position %d (%c): %s", time_str,
! 2418: err->error_messages[0].position, err->error_messages[0].character, err->error_messages[0].message);
! 2419: }
! 2420: if (err && err->error_count) {
! 2421: return 0;
! 2422: }
! 2423:
! 2424: if (timezone_object) {
! 2425: php_timezone_obj *tzobj;
! 2426:
! 2427: tzobj = (php_timezone_obj *) zend_object_store_get_object(timezone_object TSRMLS_CC);
! 2428: switch (tzobj->type) {
! 2429: case TIMELIB_ZONETYPE_ID:
! 2430: tzi = tzobj->tzi.tz;
! 2431: break;
! 2432: case TIMELIB_ZONETYPE_OFFSET:
! 2433: new_offset = tzobj->tzi.utc_offset;
! 2434: break;
! 2435: case TIMELIB_ZONETYPE_ABBR:
! 2436: new_offset = tzobj->tzi.z.utc_offset;
! 2437: new_dst = tzobj->tzi.z.dst;
! 2438: new_abbr = strdup(tzobj->tzi.z.abbr);
! 2439: break;
! 2440: }
! 2441: type = tzobj->type;
! 2442: } else if (dateobj->time->tz_info) {
! 2443: tzi = dateobj->time->tz_info;
! 2444: } else {
! 2445: tzi = get_timezone_info(TSRMLS_C);
! 2446: }
! 2447:
! 2448: now = timelib_time_ctor();
! 2449: now->zone_type = type;
! 2450: switch (type) {
! 2451: case TIMELIB_ZONETYPE_ID:
! 2452: now->tz_info = tzi;
! 2453: break;
! 2454: case TIMELIB_ZONETYPE_OFFSET:
! 2455: now->z = new_offset;
! 2456: break;
! 2457: case TIMELIB_ZONETYPE_ABBR:
! 2458: now->z = new_offset;
! 2459: now->dst = new_dst;
! 2460: now->tz_abbr = new_abbr;
! 2461: break;
! 2462: }
! 2463: timelib_unixtime2local(now, (timelib_sll) time(NULL));
! 2464:
! 2465: timelib_fill_holes(dateobj->time, now, TIMELIB_NO_CLONE);
! 2466: timelib_update_ts(dateobj->time, tzi);
! 2467:
! 2468: dateobj->time->have_relative = 0;
! 2469:
! 2470: timelib_time_dtor(now);
! 2471:
! 2472: return 1;
! 2473: }
! 2474:
! 2475: /* {{{ proto DateTime date_create([string time[, DateTimeZone object]])
! 2476: Returns new DateTime object
! 2477: */
! 2478: PHP_FUNCTION(date_create)
! 2479: {
! 2480: zval *timezone_object = NULL;
! 2481: char *time_str = NULL;
! 2482: int time_str_len = 0;
! 2483:
! 2484: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sO!", &time_str, &time_str_len, &timezone_object, date_ce_timezone) == FAILURE) {
! 2485: RETURN_FALSE;
! 2486: }
! 2487:
! 2488: php_date_instantiate(date_ce_date, return_value TSRMLS_CC);
! 2489: if (!php_date_initialize(zend_object_store_get_object(return_value TSRMLS_CC), time_str, time_str_len, NULL, timezone_object, 0 TSRMLS_CC)) {
! 2490: RETURN_FALSE;
! 2491: }
! 2492: }
! 2493: /* }}} */
! 2494:
! 2495: /* {{{ proto DateTime date_create_from_format(string format, string time[, DateTimeZone object])
! 2496: Returns new DateTime object formatted according to the specified format
! 2497: */
! 2498: PHP_FUNCTION(date_create_from_format)
! 2499: {
! 2500: zval *timezone_object = NULL;
! 2501: char *time_str = NULL, *format_str = NULL;
! 2502: int time_str_len = 0, format_str_len = 0;
! 2503:
! 2504: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|O", &format_str, &format_str_len, &time_str, &time_str_len, &timezone_object, date_ce_timezone) == FAILURE) {
! 2505: RETURN_FALSE;
! 2506: }
! 2507:
! 2508: php_date_instantiate(date_ce_date, return_value TSRMLS_CC);
! 2509: if (!php_date_initialize(zend_object_store_get_object(return_value TSRMLS_CC), time_str, time_str_len, format_str, timezone_object, 0 TSRMLS_CC)) {
! 2510: RETURN_FALSE;
! 2511: }
! 2512: }
! 2513: /* }}} */
! 2514:
! 2515: /* {{{ proto DateTime::__construct([string time[, DateTimeZone object]])
! 2516: Creates new DateTime object
! 2517: */
! 2518: PHP_METHOD(DateTime, __construct)
! 2519: {
! 2520: zval *timezone_object = NULL;
! 2521: char *time_str = NULL;
! 2522: int time_str_len = 0;
! 2523: zend_error_handling error_handling;
! 2524:
! 2525: zend_replace_error_handling(EH_THROW, NULL, &error_handling TSRMLS_CC);
! 2526: if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sO!", &time_str, &time_str_len, &timezone_object, date_ce_timezone)) {
! 2527: php_date_initialize(zend_object_store_get_object(getThis() TSRMLS_CC), time_str, time_str_len, NULL, timezone_object, 1 TSRMLS_CC);
! 2528: }
! 2529: zend_restore_error_handling(&error_handling TSRMLS_CC);
! 2530: }
! 2531: /* }}} */
! 2532:
! 2533: static int php_date_initialize_from_hash(zval **return_value, php_date_obj **dateobj, HashTable *myht TSRMLS_DC)
! 2534: {
! 2535: zval **z_date = NULL;
! 2536: zval **z_timezone = NULL;
! 2537: zval **z_timezone_type = NULL;
! 2538: zval *tmp_obj = NULL;
! 2539: timelib_tzinfo *tzi;
! 2540: php_timezone_obj *tzobj;
! 2541:
! 2542: if (zend_hash_find(myht, "date", 5, (void**) &z_date) == SUCCESS) {
! 2543: convert_to_string(*z_date);
! 2544: if (zend_hash_find(myht, "timezone_type", 14, (void**) &z_timezone_type) == SUCCESS) {
! 2545: convert_to_long(*z_timezone_type);
! 2546: if (zend_hash_find(myht, "timezone", 9, (void**) &z_timezone) == SUCCESS) {
! 2547: convert_to_string(*z_timezone);
! 2548:
! 2549: switch (Z_LVAL_PP(z_timezone_type)) {
! 2550: case TIMELIB_ZONETYPE_OFFSET:
! 2551: case TIMELIB_ZONETYPE_ABBR: {
! 2552: char *tmp = emalloc(Z_STRLEN_PP(z_date) + Z_STRLEN_PP(z_timezone) + 2);
! 2553: snprintf(tmp, Z_STRLEN_PP(z_date) + Z_STRLEN_PP(z_timezone) + 2, "%s %s", Z_STRVAL_PP(z_date), Z_STRVAL_PP(z_timezone));
! 2554: php_date_initialize(*dateobj, tmp, Z_STRLEN_PP(z_date) + Z_STRLEN_PP(z_timezone) + 1, NULL, NULL, 0 TSRMLS_CC);
! 2555: efree(tmp);
! 2556: return 1;
! 2557: }
! 2558:
! 2559: case TIMELIB_ZONETYPE_ID:
! 2560: convert_to_string(*z_timezone);
! 2561:
! 2562: tzi = php_date_parse_tzfile(Z_STRVAL_PP(z_timezone), DATE_TIMEZONEDB TSRMLS_CC);
! 2563:
! 2564: ALLOC_INIT_ZVAL(tmp_obj);
! 2565: tzobj = zend_object_store_get_object(php_date_instantiate(date_ce_timezone, tmp_obj TSRMLS_CC) TSRMLS_CC);
! 2566: tzobj->type = TIMELIB_ZONETYPE_ID;
! 2567: tzobj->tzi.tz = tzi;
! 2568: tzobj->initialized = 1;
! 2569:
! 2570: php_date_initialize(*dateobj, Z_STRVAL_PP(z_date), Z_STRLEN_PP(z_date), NULL, tmp_obj, 0 TSRMLS_CC);
! 2571: zval_ptr_dtor(&tmp_obj);
! 2572: return 1;
! 2573: }
! 2574: }
! 2575: }
! 2576: }
! 2577: return 0;
! 2578: }
! 2579:
! 2580: /* {{{ proto DateTime::__set_state()
! 2581: */
! 2582: PHP_METHOD(DateTime, __set_state)
! 2583: {
! 2584: php_date_obj *dateobj;
! 2585: zval *array;
! 2586: HashTable *myht;
! 2587:
! 2588: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == FAILURE) {
! 2589: RETURN_FALSE;
! 2590: }
! 2591:
! 2592: myht = HASH_OF(array);
! 2593:
! 2594: php_date_instantiate(date_ce_date, return_value TSRMLS_CC);
! 2595: dateobj = (php_date_obj *) zend_object_store_get_object(return_value TSRMLS_CC);
! 2596: php_date_initialize_from_hash(&return_value, &dateobj, myht TSRMLS_CC);
! 2597: }
! 2598: /* }}} */
! 2599:
! 2600: /* {{{ proto DateTime::__wakeup()
! 2601: */
! 2602: PHP_METHOD(DateTime, __wakeup)
! 2603: {
! 2604: zval *object = getThis();
! 2605: php_date_obj *dateobj;
! 2606: HashTable *myht;
! 2607:
! 2608: dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC);
! 2609:
! 2610: myht = Z_OBJPROP_P(object);
! 2611:
! 2612: php_date_initialize_from_hash(&return_value, &dateobj, myht TSRMLS_CC);
! 2613: }
! 2614: /* }}} */
! 2615:
! 2616: /* Helper function used to add an associative array of warnings and errors to a zval */
! 2617: static void zval_from_error_container(zval *z, timelib_error_container *error)
! 2618: {
! 2619: int i;
! 2620: zval *element;
! 2621:
! 2622: add_assoc_long(z, "warning_count", error->warning_count);
! 2623: MAKE_STD_ZVAL(element);
! 2624: array_init(element);
! 2625: for (i = 0; i < error->warning_count; i++) {
! 2626: add_index_string(element, error->warning_messages[i].position, error->warning_messages[i].message, 1);
! 2627: }
! 2628: add_assoc_zval(z, "warnings", element);
! 2629:
! 2630: add_assoc_long(z, "error_count", error->error_count);
! 2631: MAKE_STD_ZVAL(element);
! 2632: array_init(element);
! 2633: for (i = 0; i < error->error_count; i++) {
! 2634: add_index_string(element, error->error_messages[i].position, error->error_messages[i].message, 1);
! 2635: }
! 2636: add_assoc_zval(z, "errors", element);
! 2637: }
! 2638:
! 2639: /* {{{ proto array date_get_last_errors()
! 2640: Returns the warnings and errors found while parsing a date/time string.
! 2641: */
! 2642: PHP_FUNCTION(date_get_last_errors)
! 2643: {
! 2644: if (DATEG(last_errors)) {
! 2645: array_init(return_value);
! 2646: zval_from_error_container(return_value, DATEG(last_errors));
! 2647: } else {
! 2648: RETURN_FALSE;
! 2649: }
! 2650: }
! 2651: /* }}} */
! 2652:
! 2653: void php_date_do_return_parsed_time(INTERNAL_FUNCTION_PARAMETERS, timelib_time *parsed_time, struct timelib_error_container *error)
! 2654: {
! 2655: zval *element;
! 2656:
! 2657: array_init(return_value);
! 2658: #define PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT(name, elem) \
! 2659: if (parsed_time->elem == -99999) { \
! 2660: add_assoc_bool(return_value, #name, 0); \
! 2661: } else { \
! 2662: add_assoc_long(return_value, #name, parsed_time->elem); \
! 2663: }
! 2664: PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT(year, y);
! 2665: PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT(month, m);
! 2666: PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT(day, d);
! 2667: PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT(hour, h);
! 2668: PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT(minute, i);
! 2669: PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT(second, s);
! 2670:
! 2671: if (parsed_time->f == -99999) {
! 2672: add_assoc_bool(return_value, "fraction", 0);
! 2673: } else {
! 2674: add_assoc_double(return_value, "fraction", parsed_time->f);
! 2675: }
! 2676:
! 2677: zval_from_error_container(return_value, error);
! 2678:
! 2679: timelib_error_container_dtor(error);
! 2680:
! 2681: add_assoc_bool(return_value, "is_localtime", parsed_time->is_localtime);
! 2682:
! 2683: if (parsed_time->is_localtime) {
! 2684: PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT(zone_type, zone_type);
! 2685: switch (parsed_time->zone_type) {
! 2686: case TIMELIB_ZONETYPE_OFFSET:
! 2687: PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT(zone, z);
! 2688: add_assoc_bool(return_value, "is_dst", parsed_time->dst);
! 2689: break;
! 2690: case TIMELIB_ZONETYPE_ID:
! 2691: if (parsed_time->tz_abbr) {
! 2692: add_assoc_string(return_value, "tz_abbr", parsed_time->tz_abbr, 1);
! 2693: }
! 2694: if (parsed_time->tz_info) {
! 2695: add_assoc_string(return_value, "tz_id", parsed_time->tz_info->name, 1);
! 2696: }
! 2697: break;
! 2698: case TIMELIB_ZONETYPE_ABBR:
! 2699: PHP_DATE_PARSE_DATE_SET_TIME_ELEMENT(zone, z);
! 2700: add_assoc_bool(return_value, "is_dst", parsed_time->dst);
! 2701: add_assoc_string(return_value, "tz_abbr", parsed_time->tz_abbr, 1);
! 2702: break;
! 2703: }
! 2704: }
! 2705: if (parsed_time->have_relative) {
! 2706: MAKE_STD_ZVAL(element);
! 2707: array_init(element);
! 2708: add_assoc_long(element, "year", parsed_time->relative.y);
! 2709: add_assoc_long(element, "month", parsed_time->relative.m);
! 2710: add_assoc_long(element, "day", parsed_time->relative.d);
! 2711: add_assoc_long(element, "hour", parsed_time->relative.h);
! 2712: add_assoc_long(element, "minute", parsed_time->relative.i);
! 2713: add_assoc_long(element, "second", parsed_time->relative.s);
! 2714: if (parsed_time->relative.have_weekday_relative) {
! 2715: add_assoc_long(element, "weekday", parsed_time->relative.weekday);
! 2716: }
! 2717: if (parsed_time->relative.have_special_relative && (parsed_time->relative.special.type == TIMELIB_SPECIAL_WEEKDAY)) {
! 2718: add_assoc_long(element, "weekdays", parsed_time->relative.special.amount);
! 2719: }
! 2720: if (parsed_time->relative.first_last_day_of) {
! 2721: add_assoc_bool(element, parsed_time->relative.first_last_day_of == 1 ? "first_day_of_month" : "last_day_of_month", 1);
! 2722: }
! 2723: add_assoc_zval(return_value, "relative", element);
! 2724: }
! 2725: timelib_time_dtor(parsed_time);
! 2726: }
! 2727:
! 2728: /* {{{ proto array date_parse(string date)
! 2729: Returns associative array with detailed info about given date
! 2730: */
! 2731: PHP_FUNCTION(date_parse)
! 2732: {
! 2733: char *date;
! 2734: int date_len;
! 2735: struct timelib_error_container *error;
! 2736: timelib_time *parsed_time;
! 2737:
! 2738: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &date, &date_len) == FAILURE) {
! 2739: RETURN_FALSE;
! 2740: }
! 2741:
! 2742: parsed_time = timelib_strtotime(date, date_len, &error, DATE_TIMEZONEDB, php_date_parse_tzfile_wrapper);
! 2743: php_date_do_return_parsed_time(INTERNAL_FUNCTION_PARAM_PASSTHRU, parsed_time, error);
! 2744: }
! 2745: /* }}} */
! 2746:
! 2747: /* {{{ proto array date_parse_from_format(string format, string date)
! 2748: Returns associative array with detailed info about given date
! 2749: */
! 2750: PHP_FUNCTION(date_parse_from_format)
! 2751: {
! 2752: char *date, *format;
! 2753: int date_len, format_len;
! 2754: struct timelib_error_container *error;
! 2755: timelib_time *parsed_time;
! 2756:
! 2757: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &format, &format_len, &date, &date_len) == FAILURE) {
! 2758: RETURN_FALSE;
! 2759: }
! 2760:
! 2761: parsed_time = timelib_parse_from_format(format, date, date_len, &error, DATE_TIMEZONEDB, php_date_parse_tzfile_wrapper);
! 2762: php_date_do_return_parsed_time(INTERNAL_FUNCTION_PARAM_PASSTHRU, parsed_time, error);
! 2763: }
! 2764: /* }}} */
! 2765:
! 2766: /* {{{ proto string date_format(DateTime object, string format)
! 2767: Returns date formatted according to given format
! 2768: */
! 2769: PHP_FUNCTION(date_format)
! 2770: {
! 2771: zval *object;
! 2772: php_date_obj *dateobj;
! 2773: char *format;
! 2774: int format_len;
! 2775:
! 2776: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &object, date_ce_date, &format, &format_len) == FAILURE) {
! 2777: RETURN_FALSE;
! 2778: }
! 2779: dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC);
! 2780: DATE_CHECK_INITIALIZED(dateobj->time, DateTime);
! 2781: RETURN_STRING(date_format(format, format_len, dateobj->time, dateobj->time->is_localtime), 0);
! 2782: }
! 2783: /* }}} */
! 2784:
! 2785: /* {{{ proto DateTime date_modify(DateTime object, string modify)
! 2786: Alters the timestamp.
! 2787: */
! 2788: PHP_FUNCTION(date_modify)
! 2789: {
! 2790: zval *object;
! 2791: php_date_obj *dateobj;
! 2792: char *modify;
! 2793: int modify_len;
! 2794: timelib_time *tmp_time;
! 2795: timelib_error_container *err = NULL;
! 2796:
! 2797: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &object, date_ce_date, &modify, &modify_len) == FAILURE) {
! 2798: RETURN_FALSE;
! 2799: }
! 2800: dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC);
! 2801: DATE_CHECK_INITIALIZED(dateobj->time, DateTime);
! 2802:
! 2803: tmp_time = timelib_strtotime(modify, modify_len, &err, DATE_TIMEZONEDB, php_date_parse_tzfile_wrapper);
! 2804:
! 2805: /* update last errors and warnings */
! 2806: update_errors_warnings(err TSRMLS_CC);
! 2807: if (err && err->error_count) {
! 2808: /* spit out the first library error message, at least */
! 2809: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to parse time string (%s) at position %d (%c): %s", modify,
! 2810: err->error_messages[0].position, err->error_messages[0].character, err->error_messages[0].message);
! 2811: timelib_time_dtor(tmp_time);
! 2812: RETURN_FALSE;
! 2813: }
! 2814:
! 2815: memcpy(&dateobj->time->relative, &tmp_time->relative, sizeof(struct timelib_rel_time));
! 2816: dateobj->time->have_relative = tmp_time->have_relative;
! 2817: dateobj->time->sse_uptodate = 0;
! 2818:
! 2819: if (tmp_time->y != -99999) {
! 2820: dateobj->time->y = tmp_time->y;
! 2821: }
! 2822: if (tmp_time->m != -99999) {
! 2823: dateobj->time->m = tmp_time->m;
! 2824: }
! 2825: if (tmp_time->d != -99999) {
! 2826: dateobj->time->d = tmp_time->d;
! 2827: }
! 2828:
! 2829: if (tmp_time->h != -99999) {
! 2830: dateobj->time->h = tmp_time->h;
! 2831: if (tmp_time->i != -99999) {
! 2832: dateobj->time->i = tmp_time->i;
! 2833: if (tmp_time->s != -99999) {
! 2834: dateobj->time->s = tmp_time->s;
! 2835: } else {
! 2836: dateobj->time->s = 0;
! 2837: }
! 2838: } else {
! 2839: dateobj->time->i = 0;
! 2840: dateobj->time->s = 0;
! 2841: }
! 2842: }
! 2843: timelib_time_dtor(tmp_time);
! 2844:
! 2845: timelib_update_ts(dateobj->time, NULL);
! 2846: timelib_update_from_sse(dateobj->time);
! 2847: dateobj->time->have_relative = 0;
! 2848:
! 2849: RETURN_ZVAL(object, 1, 0);
! 2850: }
! 2851: /* }}} */
! 2852:
! 2853: /* {{{ proto DateTime date_add(DateTime object, DateInterval interval)
! 2854: Adds an interval to the current date in object.
! 2855: */
! 2856: PHP_FUNCTION(date_add)
! 2857: {
! 2858: zval *object, *interval;
! 2859: php_date_obj *dateobj;
! 2860: php_interval_obj *intobj;
! 2861: int bias = 1;
! 2862:
! 2863: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &object, date_ce_date, &interval, date_ce_interval) == FAILURE) {
! 2864: RETURN_FALSE;
! 2865: }
! 2866: dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC);
! 2867: DATE_CHECK_INITIALIZED(dateobj->time, DateTime);
! 2868: intobj = (php_interval_obj *) zend_object_store_get_object(interval TSRMLS_CC);
! 2869: DATE_CHECK_INITIALIZED(intobj->initialized, DateInterval);
! 2870:
! 2871:
! 2872: if (intobj->diff->have_weekday_relative || intobj->diff->have_special_relative) {
! 2873: memcpy(&dateobj->time->relative, intobj->diff, sizeof(struct timelib_rel_time));
! 2874: } else {
! 2875: if (intobj->diff->invert) {
! 2876: bias = -1;
! 2877: }
! 2878: memset(&dateobj->time->relative, 0, sizeof(struct timelib_rel_time));
! 2879: dateobj->time->relative.y = intobj->diff->y * bias;
! 2880: dateobj->time->relative.m = intobj->diff->m * bias;
! 2881: dateobj->time->relative.d = intobj->diff->d * bias;
! 2882: dateobj->time->relative.h = intobj->diff->h * bias;
! 2883: dateobj->time->relative.i = intobj->diff->i * bias;
! 2884: dateobj->time->relative.s = intobj->diff->s * bias;
! 2885: }
! 2886: dateobj->time->have_relative = 1;
! 2887: dateobj->time->sse_uptodate = 0;
! 2888:
! 2889: timelib_update_ts(dateobj->time, NULL);
! 2890: timelib_update_from_sse(dateobj->time);
! 2891: dateobj->time->have_relative = 0;
! 2892:
! 2893: RETURN_ZVAL(object, 1, 0);
! 2894: }
! 2895: /* }}} */
! 2896:
! 2897: /* {{{ proto DateTime date_sub(DateTime object, DateInterval interval)
! 2898: Subtracts an interval to the current date in object.
! 2899: */
! 2900: PHP_FUNCTION(date_sub)
! 2901: {
! 2902: zval *object, *interval;
! 2903: php_date_obj *dateobj;
! 2904: php_interval_obj *intobj;
! 2905: int bias = 1;
! 2906:
! 2907: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &object, date_ce_date, &interval, date_ce_interval) == FAILURE) {
! 2908: RETURN_FALSE;
! 2909: }
! 2910: dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC);
! 2911: DATE_CHECK_INITIALIZED(dateobj->time, DateTime);
! 2912: intobj = (php_interval_obj *) zend_object_store_get_object(interval TSRMLS_CC);
! 2913: DATE_CHECK_INITIALIZED(intobj->initialized, DateInterval);
! 2914:
! 2915: if (intobj->diff->have_special_relative) {
! 2916: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Only non-special relative time specifications are supported for subtraction");
! 2917: return;
! 2918: }
! 2919:
! 2920: if (intobj->diff->invert) {
! 2921: bias = -1;
! 2922: }
! 2923:
! 2924: memset(&dateobj->time->relative, 0, sizeof(struct timelib_rel_time));
! 2925: dateobj->time->relative.y = 0 - (intobj->diff->y * bias);
! 2926: dateobj->time->relative.m = 0 - (intobj->diff->m * bias);
! 2927: dateobj->time->relative.d = 0 - (intobj->diff->d * bias);
! 2928: dateobj->time->relative.h = 0 - (intobj->diff->h * bias);
! 2929: dateobj->time->relative.i = 0 - (intobj->diff->i * bias);
! 2930: dateobj->time->relative.s = 0 - (intobj->diff->s * bias);
! 2931: dateobj->time->have_relative = 1;
! 2932: dateobj->time->sse_uptodate = 0;
! 2933:
! 2934: timelib_update_ts(dateobj->time, NULL);
! 2935: timelib_update_from_sse(dateobj->time);
! 2936:
! 2937: dateobj->time->have_relative = 0;
! 2938:
! 2939: RETURN_ZVAL(object, 1, 0);
! 2940: }
! 2941: /* }}} */
! 2942:
! 2943: /* {{{ proto DateTimeZone date_timezone_get(DateTime object)
! 2944: Return new DateTimeZone object relative to give DateTime
! 2945: */
! 2946: PHP_FUNCTION(date_timezone_get)
! 2947: {
! 2948: zval *object;
! 2949: php_date_obj *dateobj;
! 2950: php_timezone_obj *tzobj;
! 2951:
! 2952: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, date_ce_date) == FAILURE) {
! 2953: RETURN_FALSE;
! 2954: }
! 2955: dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC);
! 2956: DATE_CHECK_INITIALIZED(dateobj->time, DateTime);
! 2957: if (dateobj->time->is_localtime/* && dateobj->time->tz_info*/) {
! 2958: php_date_instantiate(date_ce_timezone, return_value TSRMLS_CC);
! 2959: tzobj = (php_timezone_obj *) zend_object_store_get_object(return_value TSRMLS_CC);
! 2960: tzobj->initialized = 1;
! 2961: tzobj->type = dateobj->time->zone_type;
! 2962: switch (dateobj->time->zone_type) {
! 2963: case TIMELIB_ZONETYPE_ID:
! 2964: tzobj->tzi.tz = dateobj->time->tz_info;
! 2965: break;
! 2966: case TIMELIB_ZONETYPE_OFFSET:
! 2967: tzobj->tzi.utc_offset = dateobj->time->z;
! 2968: break;
! 2969: case TIMELIB_ZONETYPE_ABBR:
! 2970: tzobj->tzi.z.utc_offset = dateobj->time->z;
! 2971: tzobj->tzi.z.dst = dateobj->time->dst;
! 2972: tzobj->tzi.z.abbr = strdup(dateobj->time->tz_abbr);
! 2973: break;
! 2974: }
! 2975: } else {
! 2976: RETURN_FALSE;
! 2977: }
! 2978: }
! 2979: /* }}} */
! 2980:
! 2981: /* {{{ proto DateTime date_timezone_set(DateTime object, DateTimeZone object)
! 2982: Sets the timezone for the DateTime object.
! 2983: */
! 2984: PHP_FUNCTION(date_timezone_set)
! 2985: {
! 2986: zval *object;
! 2987: zval *timezone_object;
! 2988: php_date_obj *dateobj;
! 2989: php_timezone_obj *tzobj;
! 2990:
! 2991: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &object, date_ce_date, &timezone_object, date_ce_timezone) == FAILURE) {
! 2992: RETURN_FALSE;
! 2993: }
! 2994: dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC);
! 2995: DATE_CHECK_INITIALIZED(dateobj->time, DateTime);
! 2996: tzobj = (php_timezone_obj *) zend_object_store_get_object(timezone_object TSRMLS_CC);
! 2997: if (tzobj->type != TIMELIB_ZONETYPE_ID) {
! 2998: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can only do this for zones with ID for now");
! 2999: return;
! 3000: }
! 3001: timelib_set_timezone(dateobj->time, tzobj->tzi.tz);
! 3002: timelib_unixtime2local(dateobj->time, dateobj->time->sse);
! 3003:
! 3004: RETURN_ZVAL(object, 1, 0);
! 3005: }
! 3006: /* }}} */
! 3007:
! 3008: /* {{{ proto long date_offset_get(DateTime object)
! 3009: Returns the DST offset.
! 3010: */
! 3011: PHP_FUNCTION(date_offset_get)
! 3012: {
! 3013: zval *object;
! 3014: php_date_obj *dateobj;
! 3015: timelib_time_offset *offset;
! 3016:
! 3017: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, date_ce_date) == FAILURE) {
! 3018: RETURN_FALSE;
! 3019: }
! 3020: dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC);
! 3021: DATE_CHECK_INITIALIZED(dateobj->time, DateTime);
! 3022: if (dateobj->time->is_localtime/* && dateobj->time->tz_info*/) {
! 3023: switch (dateobj->time->zone_type) {
! 3024: case TIMELIB_ZONETYPE_ID:
! 3025: offset = timelib_get_time_zone_info(dateobj->time->sse, dateobj->time->tz_info);
! 3026: RETVAL_LONG(offset->offset);
! 3027: timelib_time_offset_dtor(offset);
! 3028: break;
! 3029: case TIMELIB_ZONETYPE_OFFSET:
! 3030: RETVAL_LONG(dateobj->time->z * -60);
! 3031: break;
! 3032: case TIMELIB_ZONETYPE_ABBR:
! 3033: RETVAL_LONG((dateobj->time->z - (60 * dateobj->time->dst)) * -60);
! 3034: break;
! 3035: }
! 3036: return;
! 3037: } else {
! 3038: RETURN_LONG(0);
! 3039: }
! 3040: }
! 3041: /* }}} */
! 3042:
! 3043: /* {{{ proto DateTime date_time_set(DateTime object, long hour, long minute[, long second])
! 3044: Sets the time.
! 3045: */
! 3046: PHP_FUNCTION(date_time_set)
! 3047: {
! 3048: zval *object;
! 3049: php_date_obj *dateobj;
! 3050: long h, i, s = 0;
! 3051:
! 3052: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oll|l", &object, date_ce_date, &h, &i, &s) == FAILURE) {
! 3053: RETURN_FALSE;
! 3054: }
! 3055: dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC);
! 3056: DATE_CHECK_INITIALIZED(dateobj->time, DateTime);
! 3057: dateobj->time->h = h;
! 3058: dateobj->time->i = i;
! 3059: dateobj->time->s = s;
! 3060: timelib_update_ts(dateobj->time, NULL);
! 3061:
! 3062: RETURN_ZVAL(object, 1, 0);
! 3063: }
! 3064: /* }}} */
! 3065:
! 3066: /* {{{ proto DateTime date_date_set(DateTime object, long year, long month, long day)
! 3067: Sets the date.
! 3068: */
! 3069: PHP_FUNCTION(date_date_set)
! 3070: {
! 3071: zval *object;
! 3072: php_date_obj *dateobj;
! 3073: long y, m, d;
! 3074:
! 3075: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Olll", &object, date_ce_date, &y, &m, &d) == FAILURE) {
! 3076: RETURN_FALSE;
! 3077: }
! 3078: dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC);
! 3079: DATE_CHECK_INITIALIZED(dateobj->time, DateTime);
! 3080: dateobj->time->y = y;
! 3081: dateobj->time->m = m;
! 3082: dateobj->time->d = d;
! 3083: timelib_update_ts(dateobj->time, NULL);
! 3084:
! 3085: RETURN_ZVAL(object, 1, 0);
! 3086: }
! 3087: /* }}} */
! 3088:
! 3089: /* {{{ proto DateTime date_isodate_set(DateTime object, long year, long week[, long day])
! 3090: Sets the ISO date.
! 3091: */
! 3092: PHP_FUNCTION(date_isodate_set)
! 3093: {
! 3094: zval *object;
! 3095: php_date_obj *dateobj;
! 3096: long y, w, d = 1;
! 3097:
! 3098: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oll|l", &object, date_ce_date, &y, &w, &d) == FAILURE) {
! 3099: RETURN_FALSE;
! 3100: }
! 3101: dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC);
! 3102: DATE_CHECK_INITIALIZED(dateobj->time, DateTime);
! 3103: dateobj->time->y = y;
! 3104: dateobj->time->m = 1;
! 3105: dateobj->time->d = 1;
! 3106: memset(&dateobj->time->relative, 0, sizeof(dateobj->time->relative));
! 3107: dateobj->time->relative.d = timelib_daynr_from_weeknr(y, w, d);
! 3108: dateobj->time->have_relative = 1;
! 3109:
! 3110: timelib_update_ts(dateobj->time, NULL);
! 3111:
! 3112: RETURN_ZVAL(object, 1, 0);
! 3113: }
! 3114: /* }}} */
! 3115:
! 3116: /* {{{ proto DateTime date_timestamp_set(DateTime object, long unixTimestamp)
! 3117: Sets the date and time based on an Unix timestamp.
! 3118: */
! 3119: PHP_FUNCTION(date_timestamp_set)
! 3120: {
! 3121: zval *object;
! 3122: php_date_obj *dateobj;
! 3123: long timestamp;
! 3124:
! 3125: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &object, date_ce_date, ×tamp) == FAILURE) {
! 3126: RETURN_FALSE;
! 3127: }
! 3128: dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC);
! 3129: DATE_CHECK_INITIALIZED(dateobj->time, DateTime);
! 3130: timelib_unixtime2local(dateobj->time, (timelib_sll)timestamp);
! 3131: timelib_update_ts(dateobj->time, NULL);
! 3132:
! 3133: RETURN_ZVAL(object, 1, 0);
! 3134: }
! 3135: /* }}} */
! 3136:
! 3137: /* {{{ proto long date_timestamp_get(DateTime object)
! 3138: Gets the Unix timestamp.
! 3139: */
! 3140: PHP_FUNCTION(date_timestamp_get)
! 3141: {
! 3142: zval *object;
! 3143: php_date_obj *dateobj;
! 3144: long timestamp;
! 3145: int error;
! 3146:
! 3147: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, date_ce_date) == FAILURE) {
! 3148: RETURN_FALSE;
! 3149: }
! 3150: dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC);
! 3151: DATE_CHECK_INITIALIZED(dateobj->time, DateTime);
! 3152: timelib_update_ts(dateobj->time, NULL);
! 3153:
! 3154: timestamp = timelib_date_to_int(dateobj->time, &error);
! 3155: if (error) {
! 3156: RETURN_FALSE;
! 3157: } else {
! 3158: RETVAL_LONG(timestamp);
! 3159: }
! 3160: }
! 3161: /* }}} */
! 3162:
! 3163: /* {{{ proto DateInterval date_diff(DateTime object [, bool absolute])
! 3164: Returns the difference between two DateTime objects.
! 3165: */
! 3166: PHP_FUNCTION(date_diff)
! 3167: {
! 3168: zval *object1, *object2;
! 3169: php_date_obj *dateobj1, *dateobj2;
! 3170: php_interval_obj *interval;
! 3171: long absolute = 0;
! 3172:
! 3173: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO|l", &object1, date_ce_date, &object2, date_ce_date, &absolute) == FAILURE) {
! 3174: RETURN_FALSE;
! 3175: }
! 3176: dateobj1 = (php_date_obj *) zend_object_store_get_object(object1 TSRMLS_CC);
! 3177: dateobj2 = (php_date_obj *) zend_object_store_get_object(object2 TSRMLS_CC);
! 3178: DATE_CHECK_INITIALIZED(dateobj1->time, DateTime);
! 3179: DATE_CHECK_INITIALIZED(dateobj2->time, DateTime);
! 3180: timelib_update_ts(dateobj1->time, NULL);
! 3181: timelib_update_ts(dateobj2->time, NULL);
! 3182:
! 3183: php_date_instantiate(date_ce_interval, return_value TSRMLS_CC);
! 3184: interval = zend_object_store_get_object(return_value TSRMLS_CC);
! 3185: interval->diff = timelib_diff(dateobj1->time, dateobj2->time);
! 3186: if (absolute) {
! 3187: interval->diff->invert = 0;
! 3188: }
! 3189: interval->initialized = 1;
! 3190: }
! 3191: /* }}} */
! 3192:
! 3193: static int timezone_initialize(timelib_tzinfo **tzi, /*const*/ char *tz TSRMLS_DC)
! 3194: {
! 3195: char *tzid;
! 3196:
! 3197: *tzi = NULL;
! 3198:
! 3199: if ((tzid = timelib_timezone_id_from_abbr(tz, -1, 0))) {
! 3200: *tzi = php_date_parse_tzfile(tzid, DATE_TIMEZONEDB TSRMLS_CC);
! 3201: } else {
! 3202: *tzi = php_date_parse_tzfile(tz, DATE_TIMEZONEDB TSRMLS_CC);
! 3203: }
! 3204:
! 3205: if (*tzi) {
! 3206: return SUCCESS;
! 3207: } else {
! 3208: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown or bad timezone (%s)", tz);
! 3209: return FAILURE;
! 3210: }
! 3211: }
! 3212:
! 3213: /* {{{ proto DateTimeZone timezone_open(string timezone)
! 3214: Returns new DateTimeZone object
! 3215: */
! 3216: PHP_FUNCTION(timezone_open)
! 3217: {
! 3218: char *tz;
! 3219: int tz_len;
! 3220: timelib_tzinfo *tzi = NULL;
! 3221: php_timezone_obj *tzobj;
! 3222:
! 3223: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &tz, &tz_len) == FAILURE) {
! 3224: RETURN_FALSE;
! 3225: }
! 3226: if (SUCCESS != timezone_initialize(&tzi, tz TSRMLS_CC)) {
! 3227: RETURN_FALSE;
! 3228: }
! 3229: tzobj = zend_object_store_get_object(php_date_instantiate(date_ce_timezone, return_value TSRMLS_CC) TSRMLS_CC);
! 3230: tzobj->type = TIMELIB_ZONETYPE_ID;
! 3231: tzobj->tzi.tz = tzi;
! 3232: tzobj->initialized = 1;
! 3233: }
! 3234: /* }}} */
! 3235:
! 3236: /* {{{ proto DateTimeZone::__construct(string timezone)
! 3237: Creates new DateTimeZone object.
! 3238: */
! 3239: PHP_METHOD(DateTimeZone, __construct)
! 3240: {
! 3241: char *tz;
! 3242: int tz_len;
! 3243: timelib_tzinfo *tzi = NULL;
! 3244: php_timezone_obj *tzobj;
! 3245: zend_error_handling error_handling;
! 3246:
! 3247: zend_replace_error_handling(EH_THROW, NULL, &error_handling TSRMLS_CC);
! 3248: if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &tz, &tz_len)) {
! 3249: if (SUCCESS == timezone_initialize(&tzi, tz TSRMLS_CC)) {
! 3250: tzobj = zend_object_store_get_object(getThis() TSRMLS_CC);
! 3251: tzobj->type = TIMELIB_ZONETYPE_ID;
! 3252: tzobj->tzi.tz = tzi;
! 3253: tzobj->initialized = 1;
! 3254: } else {
! 3255: ZVAL_NULL(getThis());
! 3256: }
! 3257: }
! 3258: zend_restore_error_handling(&error_handling TSRMLS_CC);
! 3259: }
! 3260: /* }}} */
! 3261:
! 3262: /* {{{ proto string timezone_name_get(DateTimeZone object)
! 3263: Returns the name of the timezone.
! 3264: */
! 3265: PHP_FUNCTION(timezone_name_get)
! 3266: {
! 3267: zval *object;
! 3268: php_timezone_obj *tzobj;
! 3269:
! 3270: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, date_ce_timezone) == FAILURE) {
! 3271: RETURN_FALSE;
! 3272: }
! 3273: tzobj = (php_timezone_obj *) zend_object_store_get_object(object TSRMLS_CC);
! 3274: DATE_CHECK_INITIALIZED(tzobj->initialized, DateTimeZone);
! 3275:
! 3276: switch (tzobj->type) {
! 3277: case TIMELIB_ZONETYPE_ID:
! 3278: RETURN_STRING(tzobj->tzi.tz->name, 1);
! 3279: break;
! 3280: case TIMELIB_ZONETYPE_OFFSET: {
! 3281: char *tmpstr = emalloc(sizeof("UTC+05:00"));
! 3282: timelib_sll utc_offset = tzobj->tzi.utc_offset;
! 3283:
! 3284: snprintf(tmpstr, sizeof("+05:00"), "%c%02d:%02d",
! 3285: utc_offset > 0 ? '-' : '+',
! 3286: abs(utc_offset / 60),
! 3287: abs((utc_offset % 60)));
! 3288:
! 3289: RETURN_STRING(tmpstr, 0);
! 3290: }
! 3291: break;
! 3292: case TIMELIB_ZONETYPE_ABBR:
! 3293: RETURN_STRING(tzobj->tzi.z.abbr, 1);
! 3294: break;
! 3295: }
! 3296: }
! 3297: /* }}} */
! 3298:
! 3299: /* {{{ proto string timezone_name_from_abbr(string abbr[, long gmtOffset[, long isdst]])
! 3300: Returns the timezone name from abbrevation
! 3301: */
! 3302: PHP_FUNCTION(timezone_name_from_abbr)
! 3303: {
! 3304: char *abbr;
! 3305: char *tzid;
! 3306: int abbr_len;
! 3307: long gmtoffset = -1;
! 3308: long isdst = -1;
! 3309:
! 3310: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ll", &abbr, &abbr_len, &gmtoffset, &isdst) == FAILURE) {
! 3311: RETURN_FALSE;
! 3312: }
! 3313: tzid = timelib_timezone_id_from_abbr(abbr, gmtoffset, isdst);
! 3314:
! 3315: if (tzid) {
! 3316: RETURN_STRING(tzid, 1);
! 3317: } else {
! 3318: RETURN_FALSE;
! 3319: }
! 3320: }
! 3321: /* }}} */
! 3322:
! 3323: /* {{{ proto long timezone_offset_get(DateTimeZone object, DateTime object)
! 3324: Returns the timezone offset.
! 3325: */
! 3326: PHP_FUNCTION(timezone_offset_get)
! 3327: {
! 3328: zval *object, *dateobject;
! 3329: php_timezone_obj *tzobj;
! 3330: php_date_obj *dateobj;
! 3331: timelib_time_offset *offset;
! 3332:
! 3333: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &object, date_ce_timezone, &dateobject, date_ce_date) == FAILURE) {
! 3334: RETURN_FALSE;
! 3335: }
! 3336: tzobj = (php_timezone_obj *) zend_object_store_get_object(object TSRMLS_CC);
! 3337: DATE_CHECK_INITIALIZED(tzobj->initialized, DateTimeZone);
! 3338: dateobj = (php_date_obj *) zend_object_store_get_object(dateobject TSRMLS_CC);
! 3339: DATE_CHECK_INITIALIZED(dateobj->time, DateTime);
! 3340:
! 3341: switch (tzobj->type) {
! 3342: case TIMELIB_ZONETYPE_ID:
! 3343: offset = timelib_get_time_zone_info(dateobj->time->sse, tzobj->tzi.tz);
! 3344: RETVAL_LONG(offset->offset);
! 3345: timelib_time_offset_dtor(offset);
! 3346: break;
! 3347: case TIMELIB_ZONETYPE_OFFSET:
! 3348: RETURN_LONG(tzobj->tzi.utc_offset * -60);
! 3349: break;
! 3350: case TIMELIB_ZONETYPE_ABBR:
! 3351: RETURN_LONG((tzobj->tzi.z.utc_offset - (tzobj->tzi.z.dst*60)) * -60);
! 3352: break;
! 3353: }
! 3354: }
! 3355: /* }}} */
! 3356:
! 3357: /* {{{ proto array timezone_transitions_get(DateTimeZone object [, long timestamp_begin [, long timestamp_end ]])
! 3358: Returns numerically indexed array containing associative array for all transitions in the specified range for the timezone.
! 3359: */
! 3360: PHP_FUNCTION(timezone_transitions_get)
! 3361: {
! 3362: zval *object, *element;
! 3363: php_timezone_obj *tzobj;
! 3364: unsigned int i, begin = 0, found;
! 3365: long timestamp_begin = LONG_MIN, timestamp_end = LONG_MAX;
! 3366:
! 3367: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|ll", &object, date_ce_timezone, ×tamp_begin, ×tamp_end) == FAILURE) {
! 3368: RETURN_FALSE;
! 3369: }
! 3370: tzobj = (php_timezone_obj *) zend_object_store_get_object(object TSRMLS_CC);
! 3371: DATE_CHECK_INITIALIZED(tzobj->initialized, DateTimeZone);
! 3372: if (tzobj->type != TIMELIB_ZONETYPE_ID) {
! 3373: RETURN_FALSE;
! 3374: }
! 3375:
! 3376: #define add_nominal() \
! 3377: MAKE_STD_ZVAL(element); \
! 3378: array_init(element); \
! 3379: add_assoc_long(element, "ts", timestamp_begin); \
! 3380: add_assoc_string(element, "time", php_format_date(DATE_FORMAT_ISO8601, 13, timestamp_begin, 0 TSRMLS_CC), 0); \
! 3381: add_assoc_long(element, "offset", tzobj->tzi.tz->type[0].offset); \
! 3382: add_assoc_bool(element, "isdst", tzobj->tzi.tz->type[0].isdst); \
! 3383: add_assoc_string(element, "abbr", &tzobj->tzi.tz->timezone_abbr[tzobj->tzi.tz->type[0].abbr_idx], 1); \
! 3384: add_next_index_zval(return_value, element);
! 3385:
! 3386: #define add(i,ts) \
! 3387: MAKE_STD_ZVAL(element); \
! 3388: array_init(element); \
! 3389: add_assoc_long(element, "ts", ts); \
! 3390: add_assoc_string(element, "time", php_format_date(DATE_FORMAT_ISO8601, 13, ts, 0 TSRMLS_CC), 0); \
! 3391: add_assoc_long(element, "offset", tzobj->tzi.tz->type[tzobj->tzi.tz->trans_idx[i]].offset); \
! 3392: add_assoc_bool(element, "isdst", tzobj->tzi.tz->type[tzobj->tzi.tz->trans_idx[i]].isdst); \
! 3393: add_assoc_string(element, "abbr", &tzobj->tzi.tz->timezone_abbr[tzobj->tzi.tz->type[tzobj->tzi.tz->trans_idx[i]].abbr_idx], 1); \
! 3394: add_next_index_zval(return_value, element);
! 3395:
! 3396: #define add_last() add(tzobj->tzi.tz->timecnt - 1, timestamp_begin)
! 3397:
! 3398: array_init(return_value);
! 3399:
! 3400: if (timestamp_begin == LONG_MIN) {
! 3401: add_nominal();
! 3402: begin = 0;
! 3403: found = 1;
! 3404: } else {
! 3405: begin = 0;
! 3406: found = 0;
! 3407: if (tzobj->tzi.tz->timecnt > 0) {
! 3408: do {
! 3409: if (tzobj->tzi.tz->trans[begin] > timestamp_begin) {
! 3410: if (begin > 0) {
! 3411: add(begin - 1, timestamp_begin);
! 3412: } else {
! 3413: add_nominal();
! 3414: }
! 3415: found = 1;
! 3416: break;
! 3417: }
! 3418: begin++;
! 3419: } while (begin < tzobj->tzi.tz->timecnt);
! 3420: }
! 3421: }
! 3422:
! 3423: if (!found) {
! 3424: if (tzobj->tzi.tz->timecnt > 0) {
! 3425: add_last();
! 3426: } else {
! 3427: add_nominal();
! 3428: }
! 3429: } else {
! 3430: for (i = begin; i < tzobj->tzi.tz->timecnt; ++i) {
! 3431: if (tzobj->tzi.tz->trans[i] < timestamp_end) {
! 3432: add(i, tzobj->tzi.tz->trans[i]);
! 3433: }
! 3434: }
! 3435: }
! 3436: }
! 3437: /* }}} */
! 3438:
! 3439: /* {{{ proto array timezone_location_get()
! 3440: Returns location information for a timezone, including country code, latitude/longitude and comments
! 3441: */
! 3442: PHP_FUNCTION(timezone_location_get)
! 3443: {
! 3444: zval *object;
! 3445: php_timezone_obj *tzobj;
! 3446:
! 3447: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, date_ce_timezone) == FAILURE) {
! 3448: RETURN_FALSE;
! 3449: }
! 3450: tzobj = (php_timezone_obj *) zend_object_store_get_object(object TSRMLS_CC);
! 3451: DATE_CHECK_INITIALIZED(tzobj->initialized, DateTimeZone);
! 3452: if (tzobj->type != TIMELIB_ZONETYPE_ID) {
! 3453: RETURN_FALSE;
! 3454: }
! 3455:
! 3456: array_init(return_value);
! 3457: add_assoc_string(return_value, "country_code", tzobj->tzi.tz->location.country_code, 1);
! 3458: add_assoc_double(return_value, "latitude", tzobj->tzi.tz->location.latitude);
! 3459: add_assoc_double(return_value, "longitude", tzobj->tzi.tz->location.longitude);
! 3460: add_assoc_string(return_value, "comments", tzobj->tzi.tz->location.comments, 1);
! 3461: }
! 3462: /* }}} */
! 3463:
! 3464: static int date_interval_initialize(timelib_rel_time **rt, /*const*/ char *format, int format_length TSRMLS_DC)
! 3465: {
! 3466: timelib_time *b = NULL, *e = NULL;
! 3467: timelib_rel_time *p = NULL;
! 3468: int r = 0;
! 3469: int retval = 0;
! 3470: struct timelib_error_container *errors;
! 3471:
! 3472: timelib_strtointerval(format, format_length, &b, &e, &p, &r, &errors);
! 3473:
! 3474: if (errors->error_count > 0) {
! 3475: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown or bad format (%s)", format);
! 3476: retval = FAILURE;
! 3477: } else {
! 3478: if(p) {
! 3479: *rt = p;
! 3480: retval = SUCCESS;
! 3481: } else {
! 3482: if(b && e) {
! 3483: timelib_update_ts(b, NULL);
! 3484: timelib_update_ts(e, NULL);
! 3485: *rt = timelib_diff(b, e);
! 3486: retval = SUCCESS;
! 3487: } else {
! 3488: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to parse interval (%s)", format);
! 3489: retval = FAILURE;
! 3490: }
! 3491: }
! 3492: }
! 3493: timelib_error_container_dtor(errors);
! 3494: return retval;
! 3495: }
! 3496:
! 3497: /* {{{ date_interval_read_property */
! 3498: zval *date_interval_read_property(zval *object, zval *member, int type TSRMLS_DC)
! 3499: {
! 3500: php_interval_obj *obj;
! 3501: zval *retval;
! 3502: zval tmp_member;
! 3503: timelib_sll value = -1;
! 3504:
! 3505: if (member->type != IS_STRING) {
! 3506: tmp_member = *member;
! 3507: zval_copy_ctor(&tmp_member);
! 3508: convert_to_string(&tmp_member);
! 3509: member = &tmp_member;
! 3510: }
! 3511:
! 3512: obj = (php_interval_obj *)zend_objects_get_address(object TSRMLS_CC);
! 3513:
! 3514: #define GET_VALUE_FROM_STRUCT(n,m) \
! 3515: if (strcmp(Z_STRVAL_P(member), m) == 0) { \
! 3516: value = obj->diff->n; \
! 3517: break; \
! 3518: }
! 3519: do {
! 3520: GET_VALUE_FROM_STRUCT(y, "y");
! 3521: GET_VALUE_FROM_STRUCT(m, "m");
! 3522: GET_VALUE_FROM_STRUCT(d, "d");
! 3523: GET_VALUE_FROM_STRUCT(h, "h");
! 3524: GET_VALUE_FROM_STRUCT(i, "i");
! 3525: GET_VALUE_FROM_STRUCT(s, "s");
! 3526: GET_VALUE_FROM_STRUCT(invert, "invert");
! 3527: GET_VALUE_FROM_STRUCT(days, "days");
! 3528: /* didn't find any */
! 3529: retval = (zend_get_std_object_handlers())->read_property(object, member, type TSRMLS_CC);
! 3530:
! 3531: if (member == &tmp_member) {
! 3532: zval_dtor(member);
! 3533: }
! 3534:
! 3535: return retval;
! 3536: } while(0);
! 3537:
! 3538: ALLOC_INIT_ZVAL(retval);
! 3539: Z_SET_REFCOUNT_P(retval, 0);
! 3540:
! 3541: ZVAL_LONG(retval, value);
! 3542:
! 3543: if (member == &tmp_member) {
! 3544: zval_dtor(member);
! 3545: }
! 3546:
! 3547: return retval;
! 3548: }
! 3549: /* }}} */
! 3550:
! 3551: /* {{{ date_interval_write_property */
! 3552: void date_interval_write_property(zval *object, zval *member, zval *value TSRMLS_DC)
! 3553: {
! 3554: php_interval_obj *obj;
! 3555: zval tmp_member, tmp_value;
! 3556:
! 3557: if (member->type != IS_STRING) {
! 3558: tmp_member = *member;
! 3559: zval_copy_ctor(&tmp_member);
! 3560: convert_to_string(&tmp_member);
! 3561: member = &tmp_member;
! 3562: }
! 3563: obj = (php_interval_obj *)zend_objects_get_address(object TSRMLS_CC);
! 3564:
! 3565: #define SET_VALUE_FROM_STRUCT(n,m) \
! 3566: if (strcmp(Z_STRVAL_P(member), m) == 0) { \
! 3567: if (value->type != IS_LONG) { \
! 3568: tmp_value = *value; \
! 3569: zval_copy_ctor(&tmp_value); \
! 3570: convert_to_long(&tmp_value); \
! 3571: value = &tmp_value; \
! 3572: } \
! 3573: obj->diff->n = Z_LVAL_P(value); \
! 3574: if (value == &tmp_value) { \
! 3575: zval_dtor(value); \
! 3576: } \
! 3577: break; \
! 3578: }
! 3579:
! 3580: do {
! 3581: SET_VALUE_FROM_STRUCT(y, "y");
! 3582: SET_VALUE_FROM_STRUCT(m, "m");
! 3583: SET_VALUE_FROM_STRUCT(d, "d");
! 3584: SET_VALUE_FROM_STRUCT(h, "h");
! 3585: SET_VALUE_FROM_STRUCT(i, "i");
! 3586: SET_VALUE_FROM_STRUCT(s, "s");
! 3587: SET_VALUE_FROM_STRUCT(invert, "invert");
! 3588: /* didn't find any */
! 3589: (zend_get_std_object_handlers())->write_property(object, member, value TSRMLS_CC);
! 3590: } while(0);
! 3591:
! 3592: if (member == &tmp_member) {
! 3593: zval_dtor(member);
! 3594: }
! 3595: }
! 3596: /* }}} */
! 3597:
! 3598:
! 3599: /* {{{ proto DateInterval::__construct([string interval_spec])
! 3600: Creates new DateInterval object.
! 3601: */
! 3602: PHP_METHOD(DateInterval, __construct)
! 3603: {
! 3604: char *interval_string = NULL;
! 3605: int interval_string_length;
! 3606: php_interval_obj *diobj;
! 3607: timelib_rel_time *reltime;
! 3608: zend_error_handling error_handling;
! 3609:
! 3610: zend_replace_error_handling(EH_THROW, NULL, &error_handling TSRMLS_CC);
! 3611: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &interval_string, &interval_string_length) == SUCCESS) {
! 3612: if (date_interval_initialize(&reltime, interval_string, interval_string_length TSRMLS_CC) == SUCCESS) {
! 3613: diobj = zend_object_store_get_object(getThis() TSRMLS_CC);
! 3614: diobj->diff = reltime;
! 3615: diobj->initialized = 1;
! 3616: } else {
! 3617: ZVAL_NULL(getThis());
! 3618: }
! 3619: }
! 3620: zend_restore_error_handling(&error_handling TSRMLS_CC);
! 3621: }
! 3622: /* }}} */
! 3623:
! 3624: static long php_date_long_from_hash_element(HashTable *myht, char *element, size_t size)
! 3625: {
! 3626: zval **z_arg = NULL;
! 3627:
! 3628: if (zend_hash_find(myht, element, size + 1, (void**) &z_arg) == SUCCESS) {
! 3629: convert_to_long(*z_arg);
! 3630: return Z_LVAL_PP(z_arg);
! 3631: } else {
! 3632: return -1;
! 3633: }
! 3634: }
! 3635:
! 3636: static int php_date_interval_initialize_from_hash(zval **return_value, php_interval_obj **intobj, HashTable *myht TSRMLS_DC)
! 3637: {
! 3638: (*intobj)->diff = timelib_rel_time_ctor();
! 3639:
! 3640: (*intobj)->diff->y = php_date_long_from_hash_element(myht, "y", 1);
! 3641: (*intobj)->diff->m = php_date_long_from_hash_element(myht, "m", 1);
! 3642: (*intobj)->diff->d = php_date_long_from_hash_element(myht, "d", 1);
! 3643: (*intobj)->diff->h = php_date_long_from_hash_element(myht, "h", 1);
! 3644: (*intobj)->diff->i = php_date_long_from_hash_element(myht, "i", 1);
! 3645: (*intobj)->diff->s = php_date_long_from_hash_element(myht, "s", 1);
! 3646: (*intobj)->diff->invert = php_date_long_from_hash_element(myht, "invert", 6);
! 3647: (*intobj)->diff->days = php_date_long_from_hash_element(myht, "days", 4);
! 3648: (*intobj)->initialized = 1;
! 3649:
! 3650: return 0;
! 3651: }
! 3652:
! 3653: /* {{{ proto DateInterval::__set_state()
! 3654: */
! 3655: PHP_METHOD(DateInterval, __set_state)
! 3656: {
! 3657: php_interval_obj *intobj;
! 3658: zval *array;
! 3659: HashTable *myht;
! 3660:
! 3661: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == FAILURE) {
! 3662: RETURN_FALSE;
! 3663: }
! 3664:
! 3665: myht = HASH_OF(array);
! 3666:
! 3667: php_date_instantiate(date_ce_interval, return_value TSRMLS_CC);
! 3668: intobj = (php_interval_obj *) zend_object_store_get_object(return_value TSRMLS_CC);
! 3669: php_date_interval_initialize_from_hash(&return_value, &intobj, myht TSRMLS_CC);
! 3670: }
! 3671: /* }}} */
! 3672:
! 3673: /* {{{ proto DateInterval::__wakeup()
! 3674: */
! 3675: PHP_METHOD(DateInterval, __wakeup)
! 3676: {
! 3677: zval *object = getThis();
! 3678: php_interval_obj *intobj;
! 3679: HashTable *myht;
! 3680:
! 3681: intobj = (php_interval_obj *) zend_object_store_get_object(object TSRMLS_CC);
! 3682:
! 3683: myht = Z_OBJPROP_P(object);
! 3684:
! 3685: php_date_interval_initialize_from_hash(&return_value, &intobj, myht TSRMLS_CC);
! 3686: }
! 3687: /* }}} */
! 3688: /* {{{ proto DateInterval date_interval_create_from_date_string(string time)
! 3689: Uses the normal date parsers and sets up a DateInterval from the relative parts of the parsed string
! 3690: */
! 3691: PHP_FUNCTION(date_interval_create_from_date_string)
! 3692: {
! 3693: char *time_str = NULL;
! 3694: int time_str_len = 0;
! 3695: timelib_time *time;
! 3696: timelib_error_container *err = NULL;
! 3697: php_interval_obj *diobj;
! 3698:
! 3699: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &time_str, &time_str_len) == FAILURE) {
! 3700: RETURN_FALSE;
! 3701: }
! 3702:
! 3703: php_date_instantiate(date_ce_interval, return_value TSRMLS_CC);
! 3704:
! 3705: time = timelib_strtotime(time_str, time_str_len, &err, DATE_TIMEZONEDB, php_date_parse_tzfile_wrapper);
! 3706: diobj = (php_interval_obj *) zend_object_store_get_object(return_value TSRMLS_CC);
! 3707: diobj->diff = timelib_rel_time_clone(&time->relative);
! 3708: diobj->initialized = 1;
! 3709: timelib_time_dtor(time);
! 3710: timelib_error_container_dtor(err);
! 3711: }
! 3712: /* }}} */
! 3713:
! 3714: /* {{{ date_interval_format - */
! 3715: static char *date_interval_format(char *format, int format_len, timelib_rel_time *t)
! 3716: {
! 3717: smart_str string = {0};
! 3718: int i, length, have_format_spec = 0;
! 3719: char buffer[33];
! 3720:
! 3721: if (!format_len) {
! 3722: return estrdup("");
! 3723: }
! 3724:
! 3725: for (i = 0; i < format_len; i++) {
! 3726: if (have_format_spec) {
! 3727: switch (format[i]) {
! 3728: case 'Y': length = slprintf(buffer, 32, "%02d", (int) t->y); break;
! 3729: case 'y': length = slprintf(buffer, 32, "%d", (int) t->y); break;
! 3730:
! 3731: case 'M': length = slprintf(buffer, 32, "%02d", (int) t->m); break;
! 3732: case 'm': length = slprintf(buffer, 32, "%d", (int) t->m); break;
! 3733:
! 3734: case 'D': length = slprintf(buffer, 32, "%02d", (int) t->d); break;
! 3735: case 'd': length = slprintf(buffer, 32, "%d", (int) t->d); break;
! 3736:
! 3737: case 'H': length = slprintf(buffer, 32, "%02d", (int) t->h); break;
! 3738: case 'h': length = slprintf(buffer, 32, "%d", (int) t->h); break;
! 3739:
! 3740: case 'I': length = slprintf(buffer, 32, "%02d", (int) t->i); break;
! 3741: case 'i': length = slprintf(buffer, 32, "%d", (int) t->i); break;
! 3742:
! 3743: case 'S': length = slprintf(buffer, 32, "%02ld", (long) t->s); break;
! 3744: case 's': length = slprintf(buffer, 32, "%ld", (long) t->s); break;
! 3745:
! 3746: case 'a': {
! 3747: if ((int) t->days != -99999) {
! 3748: length = slprintf(buffer, 32, "%d", (int) t->days);
! 3749: } else {
! 3750: length = slprintf(buffer, 32, "(unknown)");
! 3751: }
! 3752: } break;
! 3753: case 'r': length = slprintf(buffer, 32, "%s", t->invert ? "-" : ""); break;
! 3754: case 'R': length = slprintf(buffer, 32, "%c", t->invert ? '-' : '+'); break;
! 3755:
! 3756: case '%': length = slprintf(buffer, 32, "%%"); break;
! 3757: default: buffer[0] = '%'; buffer[1] = format[i]; buffer[2] = '\0'; length = 2; break;
! 3758: }
! 3759: smart_str_appendl(&string, buffer, length);
! 3760: have_format_spec = 0;
! 3761: } else {
! 3762: if (format[i] == '%') {
! 3763: have_format_spec = 1;
! 3764: } else {
! 3765: smart_str_appendc(&string, format[i]);
! 3766: }
! 3767: }
! 3768: }
! 3769:
! 3770: smart_str_0(&string);
! 3771:
! 3772: return string.c;
! 3773: }
! 3774: /* }}} */
! 3775:
! 3776: /* {{{ proto string date_interval_format(DateInterval object, string format)
! 3777: Formats the interval.
! 3778: */
! 3779: PHP_FUNCTION(date_interval_format)
! 3780: {
! 3781: zval *object;
! 3782: php_interval_obj *diobj;
! 3783: char *format;
! 3784: int format_len;
! 3785:
! 3786: if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &object, date_ce_interval, &format, &format_len) == FAILURE) {
! 3787: RETURN_FALSE;
! 3788: }
! 3789: diobj = (php_interval_obj *) zend_object_store_get_object(object TSRMLS_CC);
! 3790: DATE_CHECK_INITIALIZED(diobj->initialized, DateInterval);
! 3791:
! 3792: RETURN_STRING(date_interval_format(format, format_len, diobj->diff), 0);
! 3793: }
! 3794: /* }}} */
! 3795:
! 3796: static int date_period_initialize(timelib_time **st, timelib_time **et, timelib_rel_time **d, long *recurrences, /*const*/ char *format, int format_length TSRMLS_DC)
! 3797: {
! 3798: timelib_time *b = NULL, *e = NULL;
! 3799: timelib_rel_time *p = NULL;
! 3800: int r = 0;
! 3801: int retval = 0;
! 3802: struct timelib_error_container *errors;
! 3803:
! 3804: timelib_strtointerval(format, format_length, &b, &e, &p, &r, &errors);
! 3805:
! 3806: if (errors->error_count > 0) {
! 3807: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown or bad format (%s)", format);
! 3808: retval = FAILURE;
! 3809: } else {
! 3810: *st = b;
! 3811: *et = e;
! 3812: *d = p;
! 3813: *recurrences = r;
! 3814: retval = SUCCESS;
! 3815: }
! 3816: timelib_error_container_dtor(errors);
! 3817: return retval;
! 3818: }
! 3819:
! 3820: /* {{{ proto DatePeriod::__construct(DateTime $start, DateInterval $interval, int recurrences|DateTime $end)
! 3821: Creates new DatePeriod object.
! 3822: */
! 3823: PHP_METHOD(DatePeriod, __construct)
! 3824: {
! 3825: php_period_obj *dpobj;
! 3826: php_date_obj *dateobj;
! 3827: php_interval_obj *intobj;
! 3828: zval *start, *end = NULL, *interval;
! 3829: long recurrences = 0, options = 0;
! 3830: char *isostr = NULL;
! 3831: int isostr_len = 0;
! 3832: timelib_time *clone;
! 3833: zend_error_handling error_handling;
! 3834:
! 3835: zend_replace_error_handling(EH_THROW, NULL, &error_handling TSRMLS_CC);
! 3836: if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "OOl|l", &start, date_ce_date, &interval, date_ce_interval, &recurrences, &options) == FAILURE) {
! 3837: if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "OOO|l", &start, date_ce_date, &interval, date_ce_interval, &end, date_ce_date, &options) == FAILURE) {
! 3838: if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &isostr, &isostr_len, &options) == FAILURE) {
! 3839: php_error_docref(NULL TSRMLS_CC, E_WARNING, "This constructor accepts either (DateTime, DateInterval, int) OR (DateTime, DateInterval, DateTime) OR (string) as arguments.");
! 3840: zend_restore_error_handling(&error_handling TSRMLS_CC);
! 3841: return;
! 3842: }
! 3843: }
! 3844: }
! 3845:
! 3846: dpobj = zend_object_store_get_object(getThis() TSRMLS_CC);
! 3847: dpobj->current = NULL;
! 3848:
! 3849: if (isostr) {
! 3850: date_period_initialize(&(dpobj->start), &(dpobj->end), &(dpobj->interval), &recurrences, isostr, isostr_len TSRMLS_CC);
! 3851: if (dpobj->start == NULL) {
! 3852: php_error_docref(NULL TSRMLS_CC, E_WARNING, "The ISO interval '%s' did not contain a start date.", isostr);
! 3853: }
! 3854: if (dpobj->interval == NULL) {
! 3855: php_error_docref(NULL TSRMLS_CC, E_WARNING, "The ISO interval '%s' did not contain an interval.", isostr);
! 3856: }
! 3857: if (dpobj->end == NULL && recurrences == 0) {
! 3858: php_error_docref(NULL TSRMLS_CC, E_WARNING, "The ISO interval '%s' did not contain an end date or a recurrence count.", isostr);
! 3859: }
! 3860:
! 3861: if (dpobj->start) {
! 3862: timelib_update_ts(dpobj->start, NULL);
! 3863: }
! 3864: if (dpobj->end) {
! 3865: timelib_update_ts(dpobj->end, NULL);
! 3866: }
! 3867: } else {
! 3868: /* init */
! 3869: intobj = (php_interval_obj *) zend_object_store_get_object(interval TSRMLS_CC);
! 3870:
! 3871: /* start date */
! 3872: dateobj = (php_date_obj *) zend_object_store_get_object(start TSRMLS_CC);
! 3873: clone = timelib_time_ctor();
! 3874: memcpy(clone, dateobj->time, sizeof(timelib_time));
! 3875: if (dateobj->time->tz_abbr) {
! 3876: clone->tz_abbr = strdup(dateobj->time->tz_abbr);
! 3877: }
! 3878: if (dateobj->time->tz_info) {
! 3879: clone->tz_info = dateobj->time->tz_info;
! 3880: }
! 3881: dpobj->start = clone;
! 3882:
! 3883: /* interval */
! 3884: dpobj->interval = timelib_rel_time_clone(intobj->diff);
! 3885:
! 3886: /* end date */
! 3887: if (end) {
! 3888: dateobj = (php_date_obj *) zend_object_store_get_object(end TSRMLS_CC);
! 3889: clone = timelib_time_clone(dateobj->time);
! 3890: dpobj->end = clone;
! 3891: }
! 3892: }
! 3893:
! 3894: /* options */
! 3895: dpobj->include_start_date = !(options & PHP_DATE_PERIOD_EXCLUDE_START_DATE);
! 3896:
! 3897: /* recurrrences */
! 3898: dpobj->recurrences = recurrences + dpobj->include_start_date;
! 3899:
! 3900: dpobj->initialized = 1;
! 3901:
! 3902: zend_restore_error_handling(&error_handling TSRMLS_CC);
! 3903: }
! 3904: /* }}} */
! 3905:
! 3906: static int check_id_allowed(char *id, long what)
! 3907: {
! 3908: if (what & PHP_DATE_TIMEZONE_GROUP_AFRICA && strncasecmp(id, "Africa/", 7) == 0) return 1;
! 3909: if (what & PHP_DATE_TIMEZONE_GROUP_AMERICA && strncasecmp(id, "America/", 8) == 0) return 1;
! 3910: if (what & PHP_DATE_TIMEZONE_GROUP_ANTARCTICA && strncasecmp(id, "Antarctica/", 11) == 0) return 1;
! 3911: if (what & PHP_DATE_TIMEZONE_GROUP_ARCTIC && strncasecmp(id, "Arctic/", 7) == 0) return 1;
! 3912: if (what & PHP_DATE_TIMEZONE_GROUP_ASIA && strncasecmp(id, "Asia/", 5) == 0) return 1;
! 3913: if (what & PHP_DATE_TIMEZONE_GROUP_ATLANTIC && strncasecmp(id, "Atlantic/", 9) == 0) return 1;
! 3914: if (what & PHP_DATE_TIMEZONE_GROUP_AUSTRALIA && strncasecmp(id, "Australia/", 10) == 0) return 1;
! 3915: if (what & PHP_DATE_TIMEZONE_GROUP_EUROPE && strncasecmp(id, "Europe/", 7) == 0) return 1;
! 3916: if (what & PHP_DATE_TIMEZONE_GROUP_INDIAN && strncasecmp(id, "Indian/", 7) == 0) return 1;
! 3917: if (what & PHP_DATE_TIMEZONE_GROUP_PACIFIC && strncasecmp(id, "Pacific/", 8) == 0) return 1;
! 3918: if (what & PHP_DATE_TIMEZONE_GROUP_UTC && strncasecmp(id, "UTC", 3) == 0) return 1;
! 3919: return 0;
! 3920: }
! 3921:
! 3922: /* {{{ proto array timezone_identifiers_list([long what[, string country]])
! 3923: Returns numerically index array with all timezone identifiers.
! 3924: */
! 3925: PHP_FUNCTION(timezone_identifiers_list)
! 3926: {
! 3927: const timelib_tzdb *tzdb;
! 3928: const timelib_tzdb_index_entry *table;
! 3929: int i, item_count;
! 3930: long what = PHP_DATE_TIMEZONE_GROUP_ALL;
! 3931: char *option = NULL;
! 3932: int option_len = 0;
! 3933:
! 3934: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ls", &what, &option, &option_len) == FAILURE) {
! 3935: RETURN_FALSE;
! 3936: }
! 3937:
! 3938: /* Extra validation */
! 3939: if (what == PHP_DATE_TIMEZONE_PER_COUNTRY && option_len != 2) {
! 3940: php_error_docref(NULL TSRMLS_CC, E_NOTICE, "A two-letter ISO 3166-1 compatible country code is expected");
! 3941: RETURN_FALSE;
! 3942: }
! 3943:
! 3944: tzdb = DATE_TIMEZONEDB;
! 3945: item_count = tzdb->index_size;
! 3946: table = tzdb->index;
! 3947:
! 3948: array_init(return_value);
! 3949:
! 3950: for (i = 0; i < item_count; ++i) {
! 3951: if (what == PHP_DATE_TIMEZONE_PER_COUNTRY) {
! 3952: if (tzdb->data[table[i].pos + 5] == option[0] && tzdb->data[table[i].pos + 6] == option[1]) {
! 3953: add_next_index_string(return_value, table[i].id, 1);
! 3954: }
! 3955: } else if (what == PHP_DATE_TIMEZONE_GROUP_ALL_W_BC || (check_id_allowed(table[i].id, what) && (tzdb->data[table[i].pos + 4] == '\1'))) {
! 3956: add_next_index_string(return_value, table[i].id, 1);
! 3957: }
! 3958: };
! 3959: }
! 3960: /* }}} */
! 3961:
! 3962: /* {{{ proto array timezone_version_get()
! 3963: Returns the Olson database version number.
! 3964: */
! 3965: PHP_FUNCTION(timezone_version_get)
! 3966: {
! 3967: const timelib_tzdb *tzdb;
! 3968:
! 3969: tzdb = DATE_TIMEZONEDB;
! 3970: RETURN_STRING(tzdb->version, 1);
! 3971: }
! 3972: /* }}} */
! 3973:
! 3974: /* {{{ proto array timezone_abbreviations_list()
! 3975: Returns associative array containing dst, offset and the timezone name
! 3976: */
! 3977: PHP_FUNCTION(timezone_abbreviations_list)
! 3978: {
! 3979: const timelib_tz_lookup_table *table, *entry;
! 3980: zval *element, **abbr_array_pp, *abbr_array;
! 3981:
! 3982: table = timelib_timezone_abbreviations_list();
! 3983: array_init(return_value);
! 3984: entry = table;
! 3985:
! 3986: do {
! 3987: MAKE_STD_ZVAL(element);
! 3988: array_init(element);
! 3989: add_assoc_bool(element, "dst", entry->type);
! 3990: add_assoc_long(element, "offset", entry->gmtoffset);
! 3991: if (entry->full_tz_name) {
! 3992: add_assoc_string(element, "timezone_id", entry->full_tz_name, 1);
! 3993: } else {
! 3994: add_assoc_null(element, "timezone_id");
! 3995: }
! 3996:
! 3997: if (zend_hash_find(HASH_OF(return_value), entry->name, strlen(entry->name) + 1, (void **) &abbr_array_pp) == FAILURE) {
! 3998: MAKE_STD_ZVAL(abbr_array);
! 3999: array_init(abbr_array);
! 4000: add_assoc_zval(return_value, entry->name, abbr_array);
! 4001: } else {
! 4002: abbr_array = *abbr_array_pp;
! 4003: }
! 4004: add_next_index_zval(abbr_array, element);
! 4005: entry++;
! 4006: } while (entry->name);
! 4007: }
! 4008: /* }}} */
! 4009:
! 4010: /* {{{ proto bool date_default_timezone_set(string timezone_identifier)
! 4011: Sets the default timezone used by all date/time functions in a script */
! 4012: PHP_FUNCTION(date_default_timezone_set)
! 4013: {
! 4014: char *zone;
! 4015: int zone_len;
! 4016:
! 4017: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &zone, &zone_len) == FAILURE) {
! 4018: RETURN_FALSE;
! 4019: }
! 4020: if (!timelib_timezone_id_is_valid(zone, DATE_TIMEZONEDB)) {
! 4021: php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Timezone ID '%s' is invalid", zone);
! 4022: RETURN_FALSE;
! 4023: }
! 4024: if (DATEG(timezone)) {
! 4025: efree(DATEG(timezone));
! 4026: DATEG(timezone) = NULL;
! 4027: }
! 4028: DATEG(timezone) = estrndup(zone, zone_len);
! 4029: RETURN_TRUE;
! 4030: }
! 4031: /* }}} */
! 4032:
! 4033: /* {{{ proto string date_default_timezone_get()
! 4034: Gets the default timezone used by all date/time functions in a script */
! 4035: PHP_FUNCTION(date_default_timezone_get)
! 4036: {
! 4037: timelib_tzinfo *default_tz;
! 4038:
! 4039: default_tz = get_timezone_info(TSRMLS_C);
! 4040: RETVAL_STRING(default_tz->name, 1);
! 4041: }
! 4042: /* }}} */
! 4043:
! 4044: /* {{{ php_do_date_sunrise_sunset
! 4045: * Common for date_sunrise() and date_sunset() functions
! 4046: */
! 4047: static void php_do_date_sunrise_sunset(INTERNAL_FUNCTION_PARAMETERS, int calc_sunset)
! 4048: {
! 4049: double latitude = 0.0, longitude = 0.0, zenith = 0.0, gmt_offset = 0, altitude;
! 4050: double h_rise, h_set, N;
! 4051: timelib_sll rise, set, transit;
! 4052: long time, retformat = 0;
! 4053: int rs;
! 4054: timelib_time *t;
! 4055: timelib_tzinfo *tzi;
! 4056: char *retstr;
! 4057:
! 4058: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|ldddd", &time, &retformat, &latitude, &longitude, &zenith, &gmt_offset) == FAILURE) {
! 4059: RETURN_FALSE;
! 4060: }
! 4061:
! 4062: switch (ZEND_NUM_ARGS()) {
! 4063: case 1:
! 4064: retformat = SUNFUNCS_RET_STRING;
! 4065: case 2:
! 4066: latitude = INI_FLT("date.default_latitude");
! 4067: case 3:
! 4068: longitude = INI_FLT("date.default_longitude");
! 4069: case 4:
! 4070: if (calc_sunset) {
! 4071: zenith = INI_FLT("date.sunset_zenith");
! 4072: } else {
! 4073: zenith = INI_FLT("date.sunrise_zenith");
! 4074: }
! 4075: case 5:
! 4076: case 6:
! 4077: break;
! 4078: default:
! 4079: php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid format");
! 4080: RETURN_FALSE;
! 4081: break;
! 4082: }
! 4083: if (retformat != SUNFUNCS_RET_TIMESTAMP &&
! 4084: retformat != SUNFUNCS_RET_STRING &&
! 4085: retformat != SUNFUNCS_RET_DOUBLE)
! 4086: {
! 4087: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Wrong return format given, pick one of SUNFUNCS_RET_TIMESTAMP, SUNFUNCS_RET_STRING or SUNFUNCS_RET_DOUBLE");
! 4088: RETURN_FALSE;
! 4089: }
! 4090: altitude = 90 - zenith;
! 4091:
! 4092: /* Initialize time struct */
! 4093: t = timelib_time_ctor();
! 4094: tzi = get_timezone_info(TSRMLS_C);
! 4095: t->tz_info = tzi;
! 4096: t->zone_type = TIMELIB_ZONETYPE_ID;
! 4097:
! 4098: if (ZEND_NUM_ARGS() <= 5) {
! 4099: gmt_offset = timelib_get_current_offset(t) / 3600;
! 4100: }
! 4101:
! 4102: timelib_unixtime2local(t, time);
! 4103: rs = timelib_astro_rise_set_altitude(t, longitude, latitude, altitude, 1, &h_rise, &h_set, &rise, &set, &transit);
! 4104: timelib_time_dtor(t);
! 4105:
! 4106: if (rs != 0) {
! 4107: RETURN_FALSE;
! 4108: }
! 4109:
! 4110: if (retformat == SUNFUNCS_RET_TIMESTAMP) {
! 4111: RETURN_LONG(calc_sunset ? set : rise);
! 4112: }
! 4113: N = (calc_sunset ? h_set : h_rise) + gmt_offset;
! 4114:
! 4115: if (N > 24 || N < 0) {
! 4116: N -= floor(N / 24) * 24;
! 4117: }
! 4118:
! 4119: switch (retformat) {
! 4120: case SUNFUNCS_RET_STRING:
! 4121: spprintf(&retstr, 0, "%02d:%02d", (int) N, (int) (60 * (N - (int) N)));
! 4122: RETURN_STRINGL(retstr, 5, 0);
! 4123: break;
! 4124: case SUNFUNCS_RET_DOUBLE:
! 4125: RETURN_DOUBLE(N);
! 4126: break;
! 4127: }
! 4128: }
! 4129: /* }}} */
! 4130:
! 4131: /* {{{ proto mixed date_sunrise(mixed time [, int format [, float latitude [, float longitude [, float zenith [, float gmt_offset]]]]])
! 4132: Returns time of sunrise for a given day and location */
! 4133: PHP_FUNCTION(date_sunrise)
! 4134: {
! 4135: php_do_date_sunrise_sunset(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
! 4136: }
! 4137: /* }}} */
! 4138:
! 4139: /* {{{ proto mixed date_sunset(mixed time [, int format [, float latitude [, float longitude [, float zenith [, float gmt_offset]]]]])
! 4140: Returns time of sunset for a given day and location */
! 4141: PHP_FUNCTION(date_sunset)
! 4142: {
! 4143: php_do_date_sunrise_sunset(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
! 4144: }
! 4145: /* }}} */
! 4146:
! 4147: /* {{{ proto array date_sun_info(long time, float latitude, float longitude)
! 4148: Returns an array with information about sun set/rise and twilight begin/end */
! 4149: PHP_FUNCTION(date_sun_info)
! 4150: {
! 4151: long time;
! 4152: double latitude, longitude;
! 4153: timelib_time *t, *t2;
! 4154: timelib_tzinfo *tzi;
! 4155: int rs;
! 4156: timelib_sll rise, set, transit;
! 4157: int dummy;
! 4158: double ddummy;
! 4159:
! 4160: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ldd", &time, &latitude, &longitude) == FAILURE) {
! 4161: RETURN_FALSE;
! 4162: }
! 4163: /* Initialize time struct */
! 4164: t = timelib_time_ctor();
! 4165: tzi = get_timezone_info(TSRMLS_C);
! 4166: t->tz_info = tzi;
! 4167: t->zone_type = TIMELIB_ZONETYPE_ID;
! 4168: timelib_unixtime2local(t, time);
! 4169:
! 4170: /* Setup */
! 4171: t2 = timelib_time_ctor();
! 4172: array_init(return_value);
! 4173:
! 4174: /* Get sun up/down and transit */
! 4175: rs = timelib_astro_rise_set_altitude(t, longitude, latitude, -35.0/60, 1, &ddummy, &ddummy, &rise, &set, &transit);
! 4176: switch (rs) {
! 4177: case -1: /* always below */
! 4178: add_assoc_bool(return_value, "sunrise", 0);
! 4179: add_assoc_bool(return_value, "sunset", 0);
! 4180: break;
! 4181: case 1: /* always above */
! 4182: add_assoc_bool(return_value, "sunrise", 1);
! 4183: add_assoc_bool(return_value, "sunset", 1);
! 4184: break;
! 4185: default:
! 4186: t2->sse = rise;
! 4187: add_assoc_long(return_value, "sunrise", timelib_date_to_int(t2, &dummy));
! 4188: t2->sse = set;
! 4189: add_assoc_long(return_value, "sunset", timelib_date_to_int(t2, &dummy));
! 4190: }
! 4191: t2->sse = transit;
! 4192: add_assoc_long(return_value, "transit", timelib_date_to_int(t2, &dummy));
! 4193:
! 4194: /* Get civil twilight */
! 4195: rs = timelib_astro_rise_set_altitude(t, longitude, latitude, -6.0, 0, &ddummy, &ddummy, &rise, &set, &transit);
! 4196: switch (rs) {
! 4197: case -1: /* always below */
! 4198: add_assoc_bool(return_value, "civil_twilight_begin", 0);
! 4199: add_assoc_bool(return_value, "civil_twilight_end", 0);
! 4200: break;
! 4201: case 1: /* always above */
! 4202: add_assoc_bool(return_value, "civil_twilight_begin", 1);
! 4203: add_assoc_bool(return_value, "civil_twilight_end", 1);
! 4204: break;
! 4205: default:
! 4206: t2->sse = rise;
! 4207: add_assoc_long(return_value, "civil_twilight_begin", timelib_date_to_int(t2, &dummy));
! 4208: t2->sse = set;
! 4209: add_assoc_long(return_value, "civil_twilight_end", timelib_date_to_int(t2, &dummy));
! 4210: }
! 4211:
! 4212: /* Get nautical twilight */
! 4213: rs = timelib_astro_rise_set_altitude(t, longitude, latitude, -12.0, 0, &ddummy, &ddummy, &rise, &set, &transit);
! 4214: switch (rs) {
! 4215: case -1: /* always below */
! 4216: add_assoc_bool(return_value, "nautical_twilight_begin", 0);
! 4217: add_assoc_bool(return_value, "nautical_twilight_end", 0);
! 4218: break;
! 4219: case 1: /* always above */
! 4220: add_assoc_bool(return_value, "nautical_twilight_begin", 1);
! 4221: add_assoc_bool(return_value, "nautical_twilight_end", 1);
! 4222: break;
! 4223: default:
! 4224: t2->sse = rise;
! 4225: add_assoc_long(return_value, "nautical_twilight_begin", timelib_date_to_int(t2, &dummy));
! 4226: t2->sse = set;
! 4227: add_assoc_long(return_value, "nautical_twilight_end", timelib_date_to_int(t2, &dummy));
! 4228: }
! 4229:
! 4230: /* Get astronomical twilight */
! 4231: rs = timelib_astro_rise_set_altitude(t, longitude, latitude, -18.0, 0, &ddummy, &ddummy, &rise, &set, &transit);
! 4232: switch (rs) {
! 4233: case -1: /* always below */
! 4234: add_assoc_bool(return_value, "astronomical_twilight_begin", 0);
! 4235: add_assoc_bool(return_value, "astronomical_twilight_end", 0);
! 4236: break;
! 4237: case 1: /* always above */
! 4238: add_assoc_bool(return_value, "astronomical_twilight_begin", 1);
! 4239: add_assoc_bool(return_value, "astronomical_twilight_end", 1);
! 4240: break;
! 4241: default:
! 4242: t2->sse = rise;
! 4243: add_assoc_long(return_value, "astronomical_twilight_begin", timelib_date_to_int(t2, &dummy));
! 4244: t2->sse = set;
! 4245: add_assoc_long(return_value, "astronomical_twilight_end", timelib_date_to_int(t2, &dummy));
! 4246: }
! 4247: timelib_time_dtor(t);
! 4248: timelib_time_dtor(t2);
! 4249: }
! 4250: /* }}} */
! 4251: /*
! 4252: * Local variables:
! 4253: * tab-width: 4
! 4254: * c-basic-offset: 4
! 4255: * End:
! 4256: * vim600: fdm=marker
! 4257: * vim: noet sw=4 ts=4
! 4258: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>