|
27 | 27 | /* External libs */ |
28 | 28 | #include <bson.h> |
29 | 29 | #include <mongoc.h> |
| 30 | +#include <math.h> |
30 | 31 |
|
31 | 32 | /* PHP Core stuff */ |
32 | 33 | #include <php.h> |
@@ -77,11 +78,7 @@ static bool php_phongo_utcdatetime_init_from_string(php_phongo_utcdatetime_t *in |
77 | 78 |
|
78 | 79 | errno = 0; |
79 | 80 |
|
80 | | -#if defined(PHP_WIN32) |
81 | | - milliseconds = _atoi64(s_milliseconds); |
82 | | -#else |
83 | 81 | milliseconds = bson_ascii_strtoll(s_milliseconds, &endptr, 10); |
84 | | -#endif |
85 | 82 |
|
86 | 83 | /* errno will set errno if conversion fails; however, we do not need to |
87 | 84 | * specify the type of error. |
@@ -161,49 +158,64 @@ static bool php_phongo_utcdatetime_init_from_date(php_phongo_utcdatetime_t *inte |
161 | 158 | return true; |
162 | 159 | } |
163 | 160 |
|
164 | | -/* {{{ proto void UTCDateTime::__construct([string|DateTimeInterface $milliseconds = null]) |
| 161 | +/* {{{ proto void UTCDateTime::__construct([int|float|string|DateTimeInterface $milliseconds = null]) |
165 | 162 | Construct a new BSON UTCDateTime type from either the current time, |
166 | | - milliseconds since the epoch, or a DateTimeInterface object. */ |
| 163 | + milliseconds since the epoch, or a DateTimeInterface object. Defaults to the |
| 164 | + current time. */ |
167 | 165 | PHP_METHOD(UTCDateTime, __construct) |
168 | 166 | { |
169 | 167 | php_phongo_utcdatetime_t *intern; |
170 | 168 | zend_error_handling error_handling; |
171 | | - zval *datetime = NULL; |
| 169 | + zval *milliseconds = NULL; |
172 | 170 |
|
173 | 171 | zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC); |
174 | 172 | intern = Z_UTCDATETIME_OBJ_P(getThis()); |
175 | 173 |
|
176 | | - if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "|o!", &datetime) == SUCCESS) { |
177 | | - if (datetime == NULL) { |
178 | | - php_phongo_utcdatetime_init_from_current_time(intern); |
179 | | - } else if (instanceof_function(Z_OBJCE_P(datetime), php_date_get_date_ce() TSRMLS_CC)) { |
180 | | - php_phongo_utcdatetime_init_from_date(intern, Z_PHPDATE_P(datetime)); |
| 174 | + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z!", &milliseconds) == FAILURE) { |
| 175 | + zend_restore_error_handling(&error_handling TSRMLS_CC); |
| 176 | + return; |
| 177 | + } |
| 178 | + zend_restore_error_handling(&error_handling TSRMLS_CC); |
| 179 | + |
| 180 | + if (milliseconds == NULL) { |
| 181 | + php_phongo_utcdatetime_init_from_current_time(intern); |
| 182 | + return; |
| 183 | + } |
| 184 | + |
| 185 | + if (Z_TYPE_P(milliseconds) == IS_OBJECT) { |
| 186 | + if (instanceof_function(Z_OBJCE_P(milliseconds), php_date_get_date_ce() TSRMLS_CC)) { |
| 187 | + php_phongo_utcdatetime_init_from_date(intern, Z_PHPDATE_P(milliseconds)); |
181 | 188 | #if PHP_VERSION_ID >= 50500 |
182 | | - } else if (instanceof_function(Z_OBJCE_P(datetime), php_date_get_immutable_ce() TSRMLS_CC)) { |
183 | | - php_phongo_utcdatetime_init_from_date(intern, Z_PHPDATE_P(datetime)); |
| 189 | + } else if (instanceof_function(Z_OBJCE_P(milliseconds), php_date_get_immutable_ce() TSRMLS_CC)) { |
| 190 | + php_phongo_utcdatetime_init_from_date(intern, Z_PHPDATE_P(milliseconds)); |
184 | 191 | #endif |
185 | 192 | } else { |
186 | | - phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected instance of DateTimeInterface, %s given", ZSTR_VAL(Z_OBJCE_P(datetime)->name)); |
| 193 | + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected instance of DateTimeInterface, %s given", ZSTR_VAL(Z_OBJCE_P(milliseconds)->name)); |
187 | 194 | } |
| 195 | + return; |
| 196 | + } |
188 | 197 |
|
189 | | - zend_restore_error_handling(&error_handling TSRMLS_CC); |
| 198 | + if (Z_TYPE_P(milliseconds) == IS_LONG) { |
| 199 | + php_phongo_utcdatetime_init(intern, Z_LVAL_P(milliseconds)); |
190 | 200 | return; |
191 | 201 | } |
192 | 202 |
|
193 | | - { |
194 | | - char *s_milliseconds; |
195 | | - phongo_zpp_char_len s_milliseconds_len; |
| 203 | + if (Z_TYPE_P(milliseconds) == IS_DOUBLE) { |
| 204 | + char tmp[24]; |
| 205 | + int tmp_len; |
196 | 206 |
|
197 | | - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &s_milliseconds, &s_milliseconds_len) == FAILURE) { |
198 | | - zend_restore_error_handling(&error_handling TSRMLS_CC); |
199 | | - return; |
200 | | - } |
| 207 | + tmp_len = snprintf(tmp, sizeof(tmp), "%.0f", Z_DVAL_P(milliseconds) > 0 ? floor(Z_DVAL_P(milliseconds)) : ceil(Z_DVAL_P(milliseconds))); |
201 | 208 |
|
202 | | - php_phongo_utcdatetime_init_from_string(intern, s_milliseconds, s_milliseconds_len TSRMLS_CC); |
| 209 | + php_phongo_utcdatetime_init_from_string(intern, tmp, tmp_len TSRMLS_CC); |
| 210 | + return; |
203 | 211 | } |
204 | 212 |
|
205 | | - zend_restore_error_handling(&error_handling TSRMLS_CC); |
| 213 | + if (Z_TYPE_P(milliseconds) != IS_STRING) { |
| 214 | + phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected integer or string, %s given", zend_get_type_by_const(Z_TYPE_P(milliseconds))); |
| 215 | + return; |
| 216 | + } |
206 | 217 |
|
| 218 | + php_phongo_utcdatetime_init_from_string(intern, Z_STRVAL_P(milliseconds), Z_STRLEN_P(milliseconds) TSRMLS_CC); |
207 | 219 | } |
208 | 220 | /* }}} */ |
209 | 221 |
|
|
0 commit comments