1 /*
2 +----------------------------------------------------------------------+
3 | This source file is subject to version 3.01 of the PHP license, |
4 | that is bundled with this package in the file LICENSE, and is |
5 | available through the world-wide-web at the following url: |
6 | https://www.php.net/license/3_01.txt |
7 | If you did not receive a copy of the PHP license and are unable to |
8 | obtain it through the world-wide-web, please send a note to |
9 | license@php.net so we can mail you a copy immediately. |
10 +----------------------------------------------------------------------+
11 | Authors: Gustavo Lopes <cataphract@php.net> |
12 +----------------------------------------------------------------------+
13 */
14
15 #ifdef HAVE_CONFIG_H
16 #include "config.h"
17 #endif
18
19 #include "../intl_cppshims.h"
20
21 #include <unicode/locid.h>
22 #include <unicode/timezone.h>
23 #include <unicode/ustring.h>
24 #include <unicode/calendar.h>
25 #include "intl_convertcpp.h"
26
27 #include "../common/common_date.h"
28
29 extern "C" {
30 #include "../php_intl.h"
31 #define USE_TIMEZONE_POINTER 1
32 #include "timezone_class.h"
33 #include "intl_convert.h"
34 #include <zend_exceptions.h>
35 #include <ext/date/php_date.h>
36 }
37 #include "common/common_enum.h"
38
39 using icu::Locale;
40 using icu::Calendar;
41
PHP_METHOD(IntlTimeZone,__construct)42 U_CFUNC PHP_METHOD(IntlTimeZone, __construct)
43 {
44 zend_throw_exception( NULL,
45 "An object of this type cannot be created with the new operator",
46 0 );
47 }
48
PHP_FUNCTION(intltz_create_time_zone)49 U_CFUNC PHP_FUNCTION(intltz_create_time_zone)
50 {
51 char *str_id;
52 size_t str_id_len;
53 intl_error_reset(NULL);
54
55 ZEND_PARSE_PARAMETERS_START(1, 1)
56 Z_PARAM_STRING(str_id, str_id_len)
57 ZEND_PARSE_PARAMETERS_END();
58
59 UErrorCode status = UErrorCode();
60 UnicodeString id = UnicodeString();
61 if (intl_stringFromChar(id, str_id, str_id_len, &status) == FAILURE) {
62 intl_error_set(NULL, status,
63 "could not convert time zone id to UTF-16", 0);
64 RETURN_NULL();
65 }
66
67 //guaranteed non-null; GMT if timezone cannot be understood
68 TimeZone *tz = TimeZone::createTimeZone(id);
69 timezone_object_construct(tz, return_value, 1);
70 }
71
PHP_FUNCTION(intltz_from_date_time_zone)72 U_CFUNC PHP_FUNCTION(intltz_from_date_time_zone)
73 {
74 zval *zv_timezone;
75 TimeZone *tz;
76 php_timezone_obj *tzobj;
77 intl_error_reset(NULL);
78
79 ZEND_PARSE_PARAMETERS_START(1, 1)
80 Z_PARAM_OBJECT_OF_CLASS(zv_timezone, php_date_get_timezone_ce())
81 ZEND_PARSE_PARAMETERS_END();
82
83 tzobj = Z_PHPTIMEZONE_P(zv_timezone);
84 if (!tzobj->initialized) {
85 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
86 "DateTimeZone object is unconstructed",
87 0);
88 RETURN_NULL();
89 }
90
91 tz = timezone_convert_datetimezone(tzobj->type, tzobj, false, NULL,
92 "intltz_from_date_time_zone");
93 if (tz == NULL) {
94 RETURN_NULL();
95 }
96
97 timezone_object_construct(tz, return_value, 1);
98 }
99
PHP_FUNCTION(intltz_create_default)100 U_CFUNC PHP_FUNCTION(intltz_create_default)
101 {
102 intl_error_reset(NULL);
103
104 ZEND_PARSE_PARAMETERS_NONE();
105
106 TimeZone *tz = TimeZone::createDefault();
107 timezone_object_construct(tz, return_value, 1);
108 }
109
PHP_FUNCTION(intltz_get_gmt)110 U_CFUNC PHP_FUNCTION(intltz_get_gmt)
111 {
112 intl_error_reset(NULL);
113
114 ZEND_PARSE_PARAMETERS_NONE();
115
116 timezone_object_construct(TimeZone::getGMT(), return_value, 0);
117 }
118
PHP_FUNCTION(intltz_get_unknown)119 U_CFUNC PHP_FUNCTION(intltz_get_unknown)
120 {
121 intl_error_reset(NULL);
122
123 ZEND_PARSE_PARAMETERS_NONE();
124
125 timezone_object_construct(&TimeZone::getUnknown(), return_value, 0);
126 }
127
PHP_FUNCTION(intltz_create_enumeration)128 U_CFUNC PHP_FUNCTION(intltz_create_enumeration)
129 {
130 zval *arg = NULL;
131 StringEnumeration *se = NULL;
132 intl_error_reset(NULL);
133
134 /* double indirection to have the zend engine destroy the new zval that
135 * results from separation */
136 ZEND_PARSE_PARAMETERS_START(0, 1)
137 Z_PARAM_OPTIONAL
138 Z_PARAM_ZVAL(arg)
139 ZEND_PARSE_PARAMETERS_END();
140
141 if (arg == NULL || Z_TYPE_P(arg) == IS_NULL) {
142 se = TimeZone::createEnumeration();
143 } else if (Z_TYPE_P(arg) == IS_LONG) {
144 int_offset:
145 if (UNEXPECTED(Z_LVAL_P(arg) < (zend_long)INT32_MIN ||
146 Z_LVAL_P(arg) > (zend_long)INT32_MAX)) {
147 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
148 "value is out of range", 0);
149 RETURN_FALSE;
150 } else {
151 se = TimeZone::createEnumeration((int32_t) Z_LVAL_P(arg));
152 }
153 } else if (Z_TYPE_P(arg) == IS_DOUBLE) {
154 double_offset:
155 convert_to_long(arg);
156 goto int_offset;
157 } else if (Z_TYPE_P(arg) == IS_OBJECT || Z_TYPE_P(arg) == IS_STRING) {
158 zend_long lval;
159 double dval;
160 if (!try_convert_to_string(arg)) {
161 RETURN_THROWS();
162 }
163 switch (is_numeric_string(Z_STRVAL_P(arg), Z_STRLEN_P(arg), &lval, &dval, 0)) {
164 case IS_DOUBLE:
165 zval_ptr_dtor(arg);
166 ZVAL_DOUBLE(arg, dval);
167 goto double_offset;
168 case IS_LONG:
169 zval_ptr_dtor(arg);
170 ZVAL_LONG(arg, lval);
171 goto int_offset;
172 }
173 /* else call string version */
174 se = TimeZone::createEnumeration(Z_STRVAL_P(arg));
175 } else {
176 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
177 "invalid argument type", 0);
178 RETURN_FALSE;
179 }
180
181 if (se) {
182 IntlIterator_from_StringEnumeration(se, return_value);
183 } else {
184 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
185 "error obtaining enumeration", 0);
186 RETVAL_FALSE;
187 }
188 }
189
PHP_FUNCTION(intltz_count_equivalent_ids)190 U_CFUNC PHP_FUNCTION(intltz_count_equivalent_ids)
191 {
192 char *str_id;
193 size_t str_id_len;
194 intl_error_reset(NULL);
195
196 ZEND_PARSE_PARAMETERS_START(1, 1)
197 Z_PARAM_STRING(str_id, str_id_len)
198 ZEND_PARSE_PARAMETERS_END();
199
200 UErrorCode status = UErrorCode();
201 UnicodeString id = UnicodeString();
202 if (intl_stringFromChar(id, str_id, str_id_len, &status) == FAILURE) {
203 intl_error_set(NULL, status,
204 "could not convert time zone id to UTF-16", 0);
205 RETURN_FALSE;
206 }
207
208 int32_t result = TimeZone::countEquivalentIDs(id);
209 RETURN_LONG((zend_long)result);
210 }
211
PHP_FUNCTION(intltz_create_time_zone_id_enumeration)212 U_CFUNC PHP_FUNCTION(intltz_create_time_zone_id_enumeration)
213 {
214 zend_long zoneType,
215 offset_arg;
216 char *region = NULL;
217 size_t region_len = 0;
218 int32_t offset,
219 *offsetp = NULL;
220 bool arg3isnull = 1;
221
222 intl_error_reset(NULL);
223
224 ZEND_PARSE_PARAMETERS_START(1, 3)
225 Z_PARAM_LONG(zoneType)
226 Z_PARAM_OPTIONAL
227 Z_PARAM_STRING_OR_NULL(region, region_len)
228 Z_PARAM_LONG_OR_NULL(offset_arg, arg3isnull)
229 ZEND_PARSE_PARAMETERS_END();
230
231 if (zoneType != UCAL_ZONE_TYPE_ANY && zoneType != UCAL_ZONE_TYPE_CANONICAL
232 && zoneType != UCAL_ZONE_TYPE_CANONICAL_LOCATION) {
233 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
234 "bad zone type", 0);
235 RETURN_FALSE;
236 }
237
238 if (!arg3isnull) {
239 if (UNEXPECTED(offset_arg < (zend_long)INT32_MIN || offset_arg > (zend_long)INT32_MAX)) {
240 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
241 "offset out of bounds", 0);
242 RETURN_FALSE;
243 }
244 offset = (int32_t)offset_arg;
245 offsetp = &offset;
246 } //else leave offsetp NULL
247
248 StringEnumeration *se;
249 UErrorCode uec = UErrorCode();
250 se = TimeZone::createTimeZoneIDEnumeration((USystemTimeZoneType)zoneType,
251 region, offsetp, uec);
252 INTL_CHECK_STATUS(uec, "error obtaining time zone id enumeration")
253
254 IntlIterator_from_StringEnumeration(se, return_value);
255 }
256
PHP_FUNCTION(intltz_get_canonical_id)257 U_CFUNC PHP_FUNCTION(intltz_get_canonical_id)
258 {
259 char *str_id;
260 size_t str_id_len;
261 zval *is_systemid = NULL;
262 intl_error_reset(NULL);
263
264 ZEND_PARSE_PARAMETERS_START(1, 2)
265 Z_PARAM_STRING(str_id, str_id_len)
266 Z_PARAM_OPTIONAL
267 Z_PARAM_ZVAL(is_systemid)
268 ZEND_PARSE_PARAMETERS_END();
269
270 UErrorCode status = UErrorCode();
271 UnicodeString id;
272 if (intl_stringFromChar(id, str_id, str_id_len, &status) == FAILURE) {
273 intl_error_set(NULL, status,
274 "could not convert time zone id to UTF-16", 0);
275 RETURN_FALSE;
276 }
277
278 UnicodeString result;
279 UBool isSystemID;
280 TimeZone::getCanonicalID(id, result, isSystemID, status);
281 INTL_CHECK_STATUS(status, "error obtaining canonical ID");
282
283 zend_string *u8str =intl_convert_utf16_to_utf8(result.getBuffer(), result.length(), &status);
284 INTL_CHECK_STATUS(status,
285 "could not convert time zone id to UTF-16");
286 RETVAL_NEW_STR(u8str);
287
288 if (is_systemid) { /* by-ref argument passed */
289 ZVAL_DEREF(is_systemid);
290 zval_ptr_dtor(is_systemid);
291 ZVAL_BOOL(is_systemid, isSystemID);
292 }
293 }
294
PHP_FUNCTION(intltz_get_region)295 U_CFUNC PHP_FUNCTION(intltz_get_region)
296 {
297 char *str_id;
298 size_t str_id_len;
299 char outbuf[3];
300 intl_error_reset(NULL);
301
302 ZEND_PARSE_PARAMETERS_START(1, 1)
303 Z_PARAM_STRING(str_id, str_id_len)
304 ZEND_PARSE_PARAMETERS_END();
305
306 UErrorCode status = UErrorCode();
307 UnicodeString id;
308 if (intl_stringFromChar(id, str_id, str_id_len, &status) == FAILURE) {
309 intl_error_set(NULL, status,
310 "could not convert time zone id to UTF-16", 0);
311 RETURN_FALSE;
312 }
313
314 int32_t region_len = TimeZone::getRegion(id, outbuf, sizeof(outbuf), status);
315 INTL_CHECK_STATUS(status, "error obtaining region");
316
317 RETURN_STRINGL(outbuf, region_len);
318 }
319
PHP_FUNCTION(intltz_get_tz_data_version)320 U_CFUNC PHP_FUNCTION(intltz_get_tz_data_version)
321 {
322 intl_error_reset(NULL);
323
324 ZEND_PARSE_PARAMETERS_NONE();
325
326 UErrorCode status = UErrorCode();
327 const char *res = TimeZone::getTZDataVersion(status);
328 INTL_CHECK_STATUS(status, "error obtaining time zone data version");
329
330 RETURN_STRING(res);
331 }
332
PHP_FUNCTION(intltz_get_equivalent_id)333 U_CFUNC PHP_FUNCTION(intltz_get_equivalent_id)
334 {
335 char *str_id;
336 size_t str_id_len;
337 zend_long index;
338 intl_error_reset(NULL);
339
340 ZEND_PARSE_PARAMETERS_START(2, 2)
341 Z_PARAM_STRING(str_id, str_id_len)
342 Z_PARAM_LONG(index)
343 ZEND_PARSE_PARAMETERS_END();
344
345 if (UNEXPECTED(index < (zend_long)INT32_MIN || index > (zend_long)INT32_MAX)) {
346 RETURN_FALSE;
347 }
348
349 UErrorCode status = UErrorCode();
350 UnicodeString id;
351 if (intl_stringFromChar(id, str_id, str_id_len, &status) == FAILURE) {
352 intl_error_set(NULL, status,
353 "could not convert time zone id to UTF-16", 0);
354 RETURN_FALSE;
355 }
356
357 const UnicodeString result = TimeZone::getEquivalentID(id, (int32_t)index);
358 zend_string *u8str;
359
360 u8str = intl_convert_utf16_to_utf8(result.getBuffer(), result.length(), &status);
361 INTL_CHECK_STATUS(status, "could not convert resulting time zone id to UTF-16");
362 RETVAL_NEW_STR(u8str);
363 }
364
365 #if U_ICU_VERSION_MAJOR_NUM >= 74
PHP_FUNCTION(intltz_get_iana_id)366 U_CFUNC PHP_FUNCTION(intltz_get_iana_id)
367 {
368 char *str_id;
369 size_t str_id_len;
370 intl_error_reset(NULL);
371
372 ZEND_PARSE_PARAMETERS_START(1, 1)
373 Z_PARAM_STRING(str_id, str_id_len)
374 ZEND_PARSE_PARAMETERS_END();
375
376 UErrorCode status = UErrorCode();
377 UnicodeString id;
378 if (intl_stringFromChar(id, str_id, str_id_len, &status) == FAILURE) {
379 intl_error_set(NULL, status,
380 "could not convert time zone id to UTF-16", 0);
381 RETURN_FALSE;
382 }
383
384 UnicodeString result;
385 TimeZone::getIanaID(id, result, status);
386 INTL_CHECK_STATUS(status, "error obtaining IANA ID");
387
388 zend_string *u8str = intl_convert_utf16_to_utf8(result.getBuffer(), result.length(), &status);
389 INTL_CHECK_STATUS(status,
390 "could not convert time zone id to UTF-16");
391 RETVAL_NEW_STR(u8str);
392 }
393 #endif
394
PHP_FUNCTION(intltz_get_id)395 U_CFUNC PHP_FUNCTION(intltz_get_id)
396 {
397 TIMEZONE_METHOD_INIT_VARS;
398
399 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O",
400 &object, TimeZone_ce_ptr) == FAILURE) {
401 RETURN_THROWS();
402 }
403
404 TIMEZONE_METHOD_FETCH_OBJECT;
405
406 UnicodeString id_us;
407 to->utimezone->getID(id_us);
408
409 zend_string *u8str;
410
411 u8str = intl_convert_utf16_to_utf8(
412 id_us.getBuffer(), id_us.length(), TIMEZONE_ERROR_CODE_P(to));
413 INTL_METHOD_CHECK_STATUS(to, "could not convert id to UTF-8");
414
415 RETVAL_NEW_STR(u8str);
416 }
417
PHP_FUNCTION(intltz_use_daylight_time)418 U_CFUNC PHP_FUNCTION(intltz_use_daylight_time)
419 {
420 TIMEZONE_METHOD_INIT_VARS;
421
422 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O",
423 &object, TimeZone_ce_ptr) == FAILURE) {
424 RETURN_THROWS();
425 }
426
427 TIMEZONE_METHOD_FETCH_OBJECT;
428
429 RETURN_BOOL(to->utimezone->useDaylightTime());
430 }
431
PHP_FUNCTION(intltz_get_offset)432 U_CFUNC PHP_FUNCTION(intltz_get_offset)
433 {
434 double date;
435 bool local;
436 zval *rawOffsetArg,
437 *dstOffsetArg;
438 int32_t rawOffset,
439 dstOffset;
440 TIMEZONE_METHOD_INIT_VARS;
441
442 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(),
443 "Odbz/z/", &object, TimeZone_ce_ptr, &date, &local, &rawOffsetArg,
444 &dstOffsetArg) == FAILURE) {
445 RETURN_THROWS();
446 }
447
448 TIMEZONE_METHOD_FETCH_OBJECT;
449
450 to->utimezone->getOffset((UDate) date, (UBool) local, rawOffset, dstOffset,
451 TIMEZONE_ERROR_CODE(to));
452
453 INTL_METHOD_CHECK_STATUS(to, "error obtaining offset");
454
455 zval_ptr_dtor(rawOffsetArg);
456 ZVAL_LONG(rawOffsetArg, rawOffset);
457 zval_ptr_dtor(dstOffsetArg);
458 ZVAL_LONG(dstOffsetArg, dstOffset);
459
460 RETURN_TRUE;
461 }
462
PHP_FUNCTION(intltz_get_raw_offset)463 U_CFUNC PHP_FUNCTION(intltz_get_raw_offset)
464 {
465 TIMEZONE_METHOD_INIT_VARS;
466
467 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(),
468 "O", &object, TimeZone_ce_ptr) == FAILURE) {
469 RETURN_THROWS();
470 }
471
472 TIMEZONE_METHOD_FETCH_OBJECT;
473
474 RETURN_LONG(to->utimezone->getRawOffset());
475 }
476
PHP_FUNCTION(intltz_has_same_rules)477 U_CFUNC PHP_FUNCTION(intltz_has_same_rules)
478 {
479 zval *other_object;
480 TimeZone_object *other_to;
481 TIMEZONE_METHOD_INIT_VARS;
482
483 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(),
484 "OO", &object, TimeZone_ce_ptr, &other_object, TimeZone_ce_ptr)
485 == FAILURE) {
486 RETURN_THROWS();
487 }
488 TIMEZONE_METHOD_FETCH_OBJECT;
489 other_to = Z_INTL_TIMEZONE_P(other_object);
490 if (other_to->utimezone == NULL) {
491 intl_errors_set(&to->err, U_ILLEGAL_ARGUMENT_ERROR,
492 "The second IntlTimeZone is unconstructed", 0);
493 RETURN_FALSE;
494 }
495
496 RETURN_BOOL(to->utimezone->hasSameRules(*other_to->utimezone));
497 }
498
499 static constexpr TimeZone::EDisplayType display_types[] = {
500 TimeZone::SHORT, TimeZone::LONG,
501 TimeZone::SHORT_GENERIC, TimeZone::LONG_GENERIC,
502 TimeZone::SHORT_GMT, TimeZone::LONG_GMT,
503 TimeZone::SHORT_COMMONLY_USED, TimeZone::GENERIC_LOCATION
504 };
505
PHP_FUNCTION(intltz_get_display_name)506 U_CFUNC PHP_FUNCTION(intltz_get_display_name)
507 {
508 bool daylight = 0;
509 zend_long display_type = TimeZone::LONG;
510 const char *locale_str = NULL;
511 size_t dummy = 0;
512 TIMEZONE_METHOD_INIT_VARS;
513
514 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(),
515 "O|bls!", &object, TimeZone_ce_ptr, &daylight, &display_type,
516 &locale_str, &dummy) == FAILURE) {
517 RETURN_THROWS();
518 }
519
520 bool found = false;
521 for (int i = 0; !found && i < sizeof(display_types)/sizeof(*display_types); i++) {
522 if (display_types[i] == display_type)
523 found = true;
524 }
525 if (!found) {
526 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
527 "wrong display type", 0);
528 RETURN_FALSE;
529 }
530
531 if (!locale_str) {
532 locale_str = intl_locale_get_default();
533 }
534
535 TIMEZONE_METHOD_FETCH_OBJECT;
536
537 UnicodeString result;
538 to->utimezone->getDisplayName((UBool)daylight, (TimeZone::EDisplayType)display_type,
539 Locale::createFromName(locale_str), result);
540
541 zend_string *u8str = intl_convert_utf16_to_utf8(result.getBuffer(), result.length(), TIMEZONE_ERROR_CODE_P(to));
542 INTL_METHOD_CHECK_STATUS(to, "could not convert resulting time zone id to UTF-16");
543
544 RETVAL_NEW_STR(u8str);
545 }
546
PHP_FUNCTION(intltz_get_dst_savings)547 U_CFUNC PHP_FUNCTION(intltz_get_dst_savings)
548 {
549 TIMEZONE_METHOD_INIT_VARS;
550
551 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(),
552 "O", &object, TimeZone_ce_ptr) == FAILURE) {
553 RETURN_THROWS();
554 }
555
556 TIMEZONE_METHOD_FETCH_OBJECT;
557
558 RETURN_LONG((zend_long)to->utimezone->getDSTSavings());
559 }
560
PHP_FUNCTION(intltz_to_date_time_zone)561 U_CFUNC PHP_FUNCTION(intltz_to_date_time_zone)
562 {
563 zval tmp;
564 TIMEZONE_METHOD_INIT_VARS;
565
566 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(),
567 "O", &object, TimeZone_ce_ptr) == FAILURE) {
568 RETURN_THROWS();
569 }
570
571 TIMEZONE_METHOD_FETCH_OBJECT;
572
573 zval *ret = timezone_convert_to_datetimezone(to->utimezone,
574 &TIMEZONE_ERROR(to), "intltz_to_date_time_zone", &tmp);
575
576 if (ret) {
577 ZVAL_COPY_VALUE(return_value, ret);
578 } else {
579 RETURN_FALSE;
580 }
581 }
582
PHP_FUNCTION(intltz_get_error_code)583 U_CFUNC PHP_FUNCTION(intltz_get_error_code)
584 {
585 TIMEZONE_METHOD_INIT_VARS
586
587 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O",
588 &object, TimeZone_ce_ptr) == FAILURE) {
589 RETURN_THROWS();
590 }
591
592 /* Fetch the object (without resetting its last error code ). */
593 to = Z_INTL_TIMEZONE_P(object);
594 if (to == NULL)
595 RETURN_FALSE;
596
597 RETURN_LONG((zend_long)TIMEZONE_ERROR_CODE(to));
598 }
599
PHP_FUNCTION(intltz_get_error_message)600 U_CFUNC PHP_FUNCTION(intltz_get_error_message)
601 {
602 zend_string* message = NULL;
603 TIMEZONE_METHOD_INIT_VARS
604
605 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O",
606 &object, TimeZone_ce_ptr) == FAILURE) {
607 RETURN_THROWS();
608 }
609
610
611 /* Fetch the object (without resetting its last error code ). */
612 to = Z_INTL_TIMEZONE_P(object);
613 if (to == NULL)
614 RETURN_FALSE;
615
616 /* Return last error message. */
617 message = intl_error_get_message(TIMEZONE_ERROR_P(to));
618 RETURN_STR(message);
619 }
620
621 #if U_ICU_VERSION_MAJOR_NUM >= 52
622 /* {{{ Translate a system timezone (e.g. "America/Los_Angeles" into a
623 Windows Timezone (e.g. "Pacific Standard Time")
624 */
PHP_FUNCTION(intltz_get_windows_id)625 U_CFUNC PHP_FUNCTION(intltz_get_windows_id)
626 {
627 zend_string *id, *winID;
628 UnicodeString uID, uWinID;
629 UErrorCode error;
630
631 ZEND_PARSE_PARAMETERS_START(1, 1)
632 Z_PARAM_STR(id)
633 ZEND_PARSE_PARAMETERS_END();
634
635 error = U_ZERO_ERROR;
636 if (intl_stringFromChar(uID, id->val, id->len, &error) == FAILURE) {
637 intl_error_set(NULL, error,
638 "could not convert time zone id to UTF-16", 0);
639 RETURN_FALSE;
640 }
641
642 error = U_ZERO_ERROR;
643 TimeZone::getWindowsID(uID, uWinID, error);
644 INTL_CHECK_STATUS(error, "intltz_get_windows_id: Unable to get timezone from windows ID");
645 if (uWinID.length() == 0) {
646 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
647 "unknown system timezone", 0);
648 RETURN_FALSE;
649 }
650
651 error = U_ZERO_ERROR;
652 winID = intl_convert_utf16_to_utf8(uWinID.getBuffer(), uWinID.length(), &error);
653 INTL_CHECK_STATUS(error, "could not convert time zone id to UTF-8");
654 RETURN_STR(winID);
655 }
656 /* }}} */
657
658 /* {{{ Translate a windows timezone (e.g. "Pacific Time Zone" into a
659 System Timezone (e.g. "America/Los_Angeles")
660 */
PHP_FUNCTION(intltz_get_id_for_windows_id)661 U_CFUNC PHP_FUNCTION(intltz_get_id_for_windows_id)
662 {
663 zend_string *winID, *region = NULL, *id;
664 UnicodeString uWinID, uID;
665 UErrorCode error;
666
667 ZEND_PARSE_PARAMETERS_START(1, 2)
668 Z_PARAM_STR(winID)
669 Z_PARAM_OPTIONAL
670 Z_PARAM_STR_OR_NULL(region)
671 ZEND_PARSE_PARAMETERS_END();
672
673 error = U_ZERO_ERROR;
674 if (intl_stringFromChar(uWinID, winID->val, winID->len, &error) == FAILURE) {
675 intl_error_set(NULL, error,
676 "could not convert time zone id to UTF-16", 0);
677 RETURN_FALSE;
678 }
679
680 error = U_ZERO_ERROR;
681 TimeZone::getIDForWindowsID(uWinID, region ? region->val : NULL, uID, error);
682 INTL_CHECK_STATUS(error, "unable to get windows ID for timezone");
683 if (uID.length() == 0) {
684 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
685 "unknown windows timezone", 0);
686 RETURN_FALSE;
687 }
688
689 error = U_ZERO_ERROR;
690 id = intl_convert_utf16_to_utf8(uID.getBuffer(), uID.length(), &error);
691 INTL_CHECK_STATUS(error, "could not convert time zone id to UTF-8");
692 RETURN_STR(id);
693 }
694 /* }}} */
695 #endif
696