Skip to content

Commit eb346ef

Browse files
committed
DateFormat plays nice with Calendar, TimeZone
The following changes were made: * The IntlDateFormatter constructor now accepts the usual values for its $timezone argument. This includes timezone identifiers, IntlTimeZone objects, DateTimeZone objects and NULL. An empty string is not accepted. An invalid time zone is no longer accepted (it used to use UTC in this case). * When NULL is passed to IntlDateFormatter, the time zone specified in date.timezone is used instead of the ICU default. * The IntlDateFormatter $calendar argument now accepts also an IntlCalendar. In this case, IntlDateFormatter::getCalendar() will return false. * The time zone passed to the IntlDateFormatter is ignored if it is NULL and if the calendar passed is an IntlCalendar object -- in this case, the IntlCalendar time zone will be used instead. Otherwise, the time zone specified in the $timezone argument is used instead. * Added IntlDateFormatter::getCalendarObject(), which always returns the IntlCalendar object that backs the DateFormat, even if a constant was passed to the constructor, i.e., if an IntlCalendar was not passed to the constructor. * Added IntlDateFormatter::setTimeZone(). It accepts the usual values for time zone arguments. If NULL is passed, the time zone of the IntlDateFormatter WILL be overridden with the default time zone, even if an IntlCalendar object was passed to the constructor. * Added IntlDateFormatter::getTimeZone(), which returns the time zone that's associated with the DateFormat. * Depreacated IntlDateFormatter::setTimeZoneId() and made it an alias for IntlDateFormatter::setTimeZone(), as the new ::setTimeZone() also accepts plain identifiers, besides other types. IntlDateFormatter::getTimeZoneId() is not deprecated however. * IntlDateFormatter::setCalendar() with a constant passed should now work correctly. This requires saving the requested locale to the constructor. * Centralized the hacks required to avoid compilation disasters on Windows due to some headers being included inside and outside of extern "C" blocks.
1 parent 72beff0 commit eb346ef

28 files changed

+768
-358
lines changed

ext/intl/calendar/calendar_class.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#include "config.h"
1919
#endif
2020

21+
#include "../intl_cppshims.h"
22+
2123
#include <unicode/calendar.h>
2224
#include <unicode/gregocal.h>
2325

@@ -55,6 +57,14 @@ U_CFUNC void calendar_object_create(zval *object,
5557
calendar_object_construct(object, calendar TSRMLS_CC);
5658
}
5759

60+
U_CFUNC Calendar *calendar_fetch_native_calendar(zval *object TSRMLS_DC)
61+
{
62+
Calendar_object *co = (Calendar_object*)
63+
zend_object_store_get_object(object TSRMLS_CC);
64+
65+
return co->ucal;
66+
}
67+
5868
U_CFUNC void calendar_object_construct(zval *object,
5969
Calendar *calendar TSRMLS_DC)
6070
{

ext/intl/calendar/calendar_class.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ typedef struct {
5656

5757
void calendar_object_create(zval *object, Calendar *calendar TSRMLS_DC);
5858

59+
Calendar *calendar_fetch_native_calendar(zval *object TSRMLS_DC);
60+
5961
void calendar_object_construct(zval *object, Calendar *calendar TSRMLS_DC);
6062

6163
void calendar_register_IntlCalendar_class(TSRMLS_D);

ext/intl/calendar/calendar_methods.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#include "config.h"
1919
#endif
2020

21+
#include "../intl_cppshims.h"
22+
2123
#include <unicode/locid.h>
2224
#include <unicode/calendar.h>
2325
#include <unicode/ustring.h>
@@ -31,7 +33,6 @@ extern "C" {
3133
#include "../locale/locale.h"
3234
#include <zend_exceptions.h>
3335
#include <zend_interfaces.h>
34-
#define _MSC_STDINT_H_ /* avoid redefinitions */
3536
#include <ext/date/php_date.h>
3637
}
3738
#include "../common/common_enum.h"

ext/intl/calendar/gregoriancalendar_methods.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#include "config.h"
1919
#endif
2020

21+
#include "../intl_cppshims.h"
22+
2123
#include <unicode/locid.h>
2224
#include <unicode/calendar.h>
2325
#include <unicode/gregocal.h>
@@ -27,8 +29,6 @@ extern "C" {
2729
#define USE_CALENDAR_POINTER 1
2830
#include "calendar_class.h"
2931
#include "../locale/locale.h"
30-
/* avoid redefinition of int8_t, already defined in unicode/pwin32.h */
31-
#define _MSC_STDINT_H_ 1
3232
#include <ext/date/php_date.h>
3333
}
3434

ext/intl/common/common_enum.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#include "config.h"
1919
#endif
2020

21+
#include "../intl_cppshims.h"
22+
2123
// Fix build on Windows/old versions of ICU
2224
#include <stdio.h>
2325

ext/intl/config.m4

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ if test "$PHP_INTL" != "no"; then
5252
dateformat/dateformat_data.c \
5353
dateformat/dateformat_format.c \
5454
dateformat/dateformat_parse.c \
55+
dateformat/dateformat_create.cpp \
56+
dateformat/dateformat_attrcpp.cpp \
57+
dateformat/dateformat_helpers.cpp \
5558
msgformat/msgformat.c \
5659
msgformat/msgformat_attr.c \
5760
msgformat/msgformat_class.c \
@@ -67,11 +70,11 @@ if test "$PHP_INTL" != "no"; then
6770
transliterator/transliterator.c \
6871
transliterator/transliterator_class.c \
6972
transliterator/transliterator_methods.c \
70-
timezone/timezone_class.cpp \
71-
timezone/timezone_methods.cpp \
72-
calendar/calendar_class.cpp \
73-
calendar/calendar_methods.cpp \
74-
calendar/gregoriancalendar_methods.cpp \
73+
timezone/timezone_class.cpp \
74+
timezone/timezone_methods.cpp \
75+
calendar/calendar_class.cpp \
76+
calendar/calendar_methods.cpp \
77+
calendar/gregoriancalendar_methods.cpp \
7578
idn/idn.c \
7679
$icu_spoof_src, $ext_shared,,$ICU_INCS -Wno-write-strings)
7780
PHP_ADD_BUILD_DIR($ext_builddir/collator)

ext/intl/config.w32

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ if (PHP_INTL != "no") {
6363
dateformat_format.c \
6464
dateformat_parse.c \
6565
dateformat_data.c \
66+
dateformat_attrcpp.cpp \
67+
dateformat_helpers.cpp \
68+
dateformat_create.cpp \
6669
", "intl");
6770
ADD_SOURCES(configure_module_dirname + "/idn", "\
6871
idn.c",

ext/intl/dateformat/dateformat.c

Lines changed: 0 additions & 154 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,9 @@
1717
#include "config.h"
1818
#endif
1919

20-
#include <unicode/ustring.h>
2120
#include <unicode/udat.h>
22-
#include <unicode/ucal.h>
2321

2422
#include "php_intl.h"
25-
#include "intl_convert.h"
2623
#include "dateformat_class.h"
2724
#include "dateformat.h"
2825

@@ -67,157 +64,6 @@ void dateformat_register_constants( INIT_FUNC_ARGS )
6764
}
6865
/* }}} */
6966

70-
/* {{{ */
71-
static void datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS)
72-
{
73-
char* locale;
74-
int locale_len = 0;
75-
zval* object;
76-
long date_type = 0;
77-
long time_type = 0;
78-
long calendar = UCAL_GREGORIAN;
79-
char* timezone_str = NULL;
80-
int timezone_str_len = 0;
81-
char* pattern_str = NULL;
82-
int pattern_str_len = 0;
83-
UChar* svalue = NULL; /* UTF-16 pattern_str */
84-
int slength = 0;
85-
UChar* timezone_utf16 = NULL; /* UTF-16 timezone_str */
86-
int timezone_utf16_len = 0;
87-
UCalendar ucal_obj = NULL;
88-
IntlDateFormatter_object* dfo;
89-
90-
intl_error_reset( NULL TSRMLS_CC );
91-
object = return_value;
92-
/* Parse parameters. */
93-
if( zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "sll|sls",
94-
&locale, &locale_len, &date_type, &time_type, &timezone_str, &timezone_str_len, &calendar,&pattern_str, &pattern_str_len ) == FAILURE )
95-
{
96-
intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_create: unable to parse input parameters", 0 TSRMLS_CC );
97-
zval_dtor(return_value);
98-
RETURN_NULL();
99-
}
100-
101-
INTL_CHECK_LOCALE_LEN_OBJ(locale_len, return_value);
102-
103-
if (calendar != UCAL_TRADITIONAL && calendar != UCAL_GREGORIAN) {
104-
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_create: "
105-
"invalid value for calendar type; it must be one of "
106-
"IntlDateFormatter::TRADITIONAL (locale's default calendar) "
107-
"or IntlDateFormatter::GREGORIAN", 0 TSRMLS_CC);
108-
goto error;
109-
}
110-
111-
DATE_FORMAT_METHOD_FETCH_OBJECT;
112-
113-
if (DATE_FORMAT_OBJECT(dfo) != NULL) {
114-
intl_errors_set(INTL_DATA_ERROR_P(dfo), U_ILLEGAL_ARGUMENT_ERROR,
115-
"datefmt_create: cannot call constructor twice", 0 TSRMLS_CC);
116-
return;
117-
}
118-
119-
/* Convert pattern (if specified) to UTF-16. */
120-
if( pattern_str && pattern_str_len>0 ){
121-
intl_convert_utf8_to_utf16(&svalue, &slength,
122-
pattern_str, pattern_str_len, &INTL_DATA_ERROR_CODE(dfo));
123-
if (U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) {
124-
/* object construction -> only set global error */
125-
intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create: "
126-
"error converting pattern to UTF-16", 0 TSRMLS_CC);
127-
goto error;
128-
}
129-
}
130-
131-
/* resources allocated from now on */
132-
133-
/* Convert pattern (if specified) to UTF-16. */
134-
if( timezone_str && timezone_str_len >0 ){
135-
intl_convert_utf8_to_utf16(&timezone_utf16, &timezone_utf16_len,
136-
timezone_str, timezone_str_len, &INTL_DATA_ERROR_CODE(dfo));
137-
if (U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) {
138-
intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create: "
139-
"error converting timezone_str to UTF-16", 0 TSRMLS_CC);
140-
goto error;
141-
}
142-
}
143-
144-
if(locale_len == 0) {
145-
locale = INTL_G(default_locale);
146-
}
147-
148-
if( pattern_str && pattern_str_len>0 ){
149-
DATE_FORMAT_OBJECT(dfo) = udat_open(UDAT_IGNORE, UDAT_IGNORE, locale, timezone_utf16, timezone_utf16_len, svalue, slength, &INTL_DATA_ERROR_CODE(dfo));
150-
} else {
151-
DATE_FORMAT_OBJECT(dfo) = udat_open(time_type, date_type, locale, timezone_utf16, timezone_utf16_len, svalue, slength, &INTL_DATA_ERROR_CODE(dfo));
152-
}
153-
154-
if (!U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) {
155-
if (calendar != UCAL_TRADITIONAL) {
156-
ucal_obj = ucal_open(timezone_utf16, timezone_utf16_len, locale,
157-
calendar, &INTL_DATA_ERROR_CODE(dfo));
158-
if (!U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) {
159-
udat_setCalendar(DATE_FORMAT_OBJECT(dfo), ucal_obj);
160-
ucal_close(ucal_obj);
161-
} else {
162-
intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create"
163-
": error opening calendar", 0 TSRMLS_CC);
164-
goto error;
165-
}
166-
}
167-
} else {
168-
intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create: date "
169-
"formatter creation failed", 0 TSRMLS_CC);
170-
goto error;
171-
}
172-
173-
/* Set the class variables */
174-
dfo->date_type = date_type;
175-
dfo->time_type = time_type;
176-
dfo->calendar = calendar;
177-
if( timezone_str && timezone_str_len > 0){
178-
dfo->timezone_id = estrndup( timezone_str, timezone_str_len);
179-
}
180-
181-
error:
182-
if (svalue) {
183-
efree(svalue);
184-
}
185-
if (timezone_utf16) {
186-
efree(timezone_utf16);
187-
}
188-
if (U_FAILURE(intl_error_get_code(NULL TSRMLS_CC))) {
189-
/* free_object handles partially constructed instances fine */
190-
zval_dtor(return_value);
191-
RETVAL_NULL();
192-
}
193-
}
194-
/* }}} */
195-
196-
/* {{{ proto IntlDateFormatter IntlDateFormatter::create(string $locale, long date_type, long time_type[, string $timezone_str, long $calendar, string $pattern] )
197-
* Create formatter. }}} */
198-
/* {{{ proto IntlDateFormatter datefmt_create(string $locale, long date_type, long time_type[, string $timezone_str, long $calendar, string $pattern] )
199-
200-
* Create formatter.
201-
*/
202-
PHP_FUNCTION( datefmt_create )
203-
{
204-
object_init_ex( return_value, IntlDateFormatter_ce_ptr );
205-
datefmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU);
206-
}
207-
/* }}} */
208-
209-
/* {{{ proto void IntlDateFormatter::__construct(string $locale, long date_type, long time_type[, string $timezone_str, long $calendar, string $pattern])
210-
* IntlDateFormatter object constructor.
211-
*/
212-
PHP_METHOD( IntlDateFormatter, __construct )
213-
{
214-
/* return_value param is being changed, therefore we will always return
215-
* NULL here */
216-
return_value = getThis();
217-
datefmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU);
218-
}
219-
/* }}} */
220-
22167
/* {{{ proto int IntlDateFormatter::getErrorCode()
22268
* Get formatter's last error code. }}} */
22369
/* {{{ proto int datefmt_get_error_code( IntlDateFormatter $nf )

0 commit comments

Comments
 (0)