tests/**/*.sh
tests/**/*.db
tests/**/*.mem
+tests/Timestamp/
tmp-php.ini
}
ZEND_METHOD(ion_Timestamp, __construct)
{
- zend_long precision;
- zend_string *fmt = NULL, *dt = NULL;
- zval *tz = NULL;
php_ion_timestamp *obj = php_ion_obj(timestamp, Z_OBJ_P(ZEND_THIS));
PTR_CHECK(obj);
+ zend_long precision;
+ zend_object *precision_obj;
+ zend_string *fmt = NULL, *dt = NULL;
+ zval *tz = NULL;
ZEND_PARSE_PARAMETERS_START(1, 4)
- Z_PARAM_LONG(precision)
+ Z_PARAM_OBJ_OF_CLASS_OR_LONG(precision_obj, ce_Timestamp_Precision, precision)
Z_PARAM_OPTIONAL
Z_PARAM_STR_OR_NULL(fmt)
- Z_PARAM_STR(dt)
+ Z_PARAM_STR_OR_NULL(dt)
Z_PARAM_ZVAL(tz)
ZEND_PARSE_PARAMETERS_END();
+ if (precision_obj) {
+ precision = Z_LVAL_P(zend_enum_fetch_case_value(precision_obj));
+ }
php_ion_timestamp_ctor(obj, precision, fmt, dt, tz);
}
ZEND_METHOD(ion_Timestamp, __toString)
php_ion_register(decimal, Decimal);
php_ion_register(decimal_ctx, Decimal_Context);
php_ion_register(timestamp, Timestamp, php_date_get_date_ce());
+ ce_Timestamp_Precision = register_class_ion_Timestamp_Precision();
php_ion_register(catalog, Catalog);
ce_Reader = register_class_ion_Reader(spl_ce_RecursiveIterator);
public function toInt() : int {}
}
+namespace ion\Timestamp;
+enum Precision : int {
+ case Year = 0x1;
+ case Month = 0x1|0x2;
+ case Day = 0x1|0x2|0x4;
+ case Min = 0x1|0x2|0x4|0x10;
+ case Sec = 0x1|0x2|0x4|0x10|0x20;
+ case Frac = 0x1|0x2|0x4|0x10|0x20|0x40;
+}
namespace ion;
class Timestamp extends \DateTime {
+ public readonly int $precision;
+ public readonly string $format;
+
public function __construct(
- public readonly int $precision,
- public readonly string $format = "c",
- string $datetime = "now",
+ Timestamp\Precision|int $precision,
+ ?string $format = null,
+ ?string $datetime = null,
?\DateTimeZone $timezone = null,
) {}
/* This is a generated file, edit the .stub.php file instead.
- * Stub hash: 9972b27bc2f7f20e59aae26777e1a674f1606c11 */
+ * Stub hash: 20996b59177d52516ad45582152909be017ba39d */
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_ion_serialize, 0, 1, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, data, IS_MIXED, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ion_Timestamp___construct, 0, 0, 1)
- ZEND_ARG_TYPE_INFO(0, precision, IS_LONG, 0)
- ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, format, IS_STRING, 0, "\"c\"")
- ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, datetime, IS_STRING, 0, "\"now\"")
+ ZEND_ARG_OBJ_TYPE_MASK(0, precision, ion\\Timestamp\\Precision, MAY_BE_LONG, NULL)
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, format, IS_STRING, 1, "null")
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, datetime, IS_STRING, 1, "null")
ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, timezone, DateTimeZone, 1, "null")
ZEND_END_ARG_INFO()
};
+static const zend_function_entry class_ion_Timestamp_Precision_methods[] = {
+ ZEND_FE_END
+};
+
+
static const zend_function_entry class_ion_Timestamp_methods[] = {
ZEND_ME(ion_Timestamp, __construct, arginfo_class_ion_Timestamp___construct, ZEND_ACC_PUBLIC)
ZEND_ME(ion_Timestamp, __toString, arginfo_class_ion_Timestamp___toString, ZEND_ACC_PUBLIC)
return class_entry;
}
+static zend_class_entry *register_class_ion_Timestamp_Precision(void)
+{
+ zend_class_entry *class_entry = zend_register_internal_enum("ion\\Timestamp\\Precision", IS_LONG, class_ion_Timestamp_Precision_methods);
+
+ zval enum_case_Year_value;
+ ZVAL_LONG(&enum_case_Year_value, 1);
+ zend_enum_add_case_cstr(class_entry, "Year", &enum_case_Year_value);
+
+ zval enum_case_Month_value;
+ ZVAL_LONG(&enum_case_Month_value, 3);
+ zend_enum_add_case_cstr(class_entry, "Month", &enum_case_Month_value);
+
+ zval enum_case_Day_value;
+ ZVAL_LONG(&enum_case_Day_value, 7);
+ zend_enum_add_case_cstr(class_entry, "Day", &enum_case_Day_value);
+
+ zval enum_case_Min_value;
+ ZVAL_LONG(&enum_case_Min_value, 23);
+ zend_enum_add_case_cstr(class_entry, "Min", &enum_case_Min_value);
+
+ zval enum_case_Sec_value;
+ ZVAL_LONG(&enum_case_Sec_value, 55);
+ zend_enum_add_case_cstr(class_entry, "Sec", &enum_case_Sec_value);
+
+ zval enum_case_Frac_value;
+ ZVAL_LONG(&enum_case_Frac_value, 119);
+ zend_enum_add_case_cstr(class_entry, "Frac", &enum_case_Frac_value);
+
+ return class_entry;
+}
+
static zend_class_entry *register_class_ion_Timestamp(zend_class_entry *class_entry_DateTime)
{
zend_class_entry ce, *class_entry;
*ce_Symbol_System_SID,
*ce_Symbol_Table,
*ce_Timestamp,
+ *ce_Timestamp_Precision,
*ce_Type,
*ce_Writer,
*ce_Writer_Options,
typedef php_date_obj php_ion_timestamp;
-static inline void php_ion_timestamp_ctor(php_ion_timestamp *obj, zend_long precision, zend_string *fmt, zend_string *dt, zval *tz)
-{
- if (!obj->time) {
- php_date_initialize(obj, dt ? dt->val : "now", dt ? dt->len : 3, fmt ? fmt->val : NULL, tz, PHP_DATE_INIT_CTOR);
- }
- zend_update_property_long(obj->std.ce, &obj->std, ZEND_STRL("precision"), precision);
- if (fmt) {
- zend_update_property_str(obj->std.ce, &obj->std, ZEND_STRL("format"), fmt);
- } else {
- zend_update_property_stringl(obj->std.ce, &obj->std, ZEND_STRL("format"), ZEND_STRL("c"));
- }
-}
-
-static inline void php_ion_timestamp_dtor(php_ion_timestamp *obj)
-{
- if (obj->time) {
- timelib_time_dtor(obj->time);
- }
-}
-
static inline zend_long php_usec_from_ion(const decQuad *frac, decContext *ctx)
{
decQuad microsecs, result;
return decQuadDivide(frac, decQuadFromInt32(&us, usec), decQuadFromInt32(µsecs, 1000000), ctx);
}
+static inline zend_string *php_dt_format_from_precision(uint8_t precision)
+{
+ switch (precision) {
+ case ION_TS_FRAC:
+ return zend_string_init(ZEND_STRL("c"), 0);
+ case ION_TS_SEC:
+ return zend_string_init(ZEND_STRL("Y-m-d\\TH:i:sP"), 0);
+ case ION_TS_MIN:
+ return zend_string_init(ZEND_STRL("Y-m-d\\TH:iP"), 0);
+ case ION_TS_DAY:
+ return zend_string_init(ZEND_STRL("Y-m-d\\T"), 0);
+ case ION_TS_MONTH:
+ return zend_string_init(ZEND_STRL("Y-m\\T"), 0);
+ case ION_TS_YEAR:
+ return zend_string_init(ZEND_STRL("Y\\T"), 0);
+ default:
+ return zend_string_init(ZEND_STRL("c"), 0);
+ }
+}
+
static inline timelib_time* php_time_from_ion(const ION_TIMESTAMP *ts, decContext *ctx, zend_string **fmt)
{
timelib_time *time = timelib_time_ctor();
switch (ts->precision) {
case ION_TS_FRAC:
time->us = php_usec_from_ion(&ts->fraction, ctx);
- if (fmt) *fmt = zend_string_init(ZEND_STRL("c"), 0);
/* fallthrough */
case ION_TS_SEC:
time->s = ts->seconds;
- if (fmt && !*fmt) *fmt = zend_string_init(ZEND_STRL("Y-m-d\\TH:i:sP"), 0);
/* fallthrough */
case ION_TS_MIN:
time->i = ts->minutes;
time->h = ts->hours;
- if (fmt && !*fmt) *fmt = zend_string_init(ZEND_STRL("Y-m-d\\TH:iP"), 0);
/* fallthrough */
case ION_TS_DAY:
time->d = ts->day;
- if (fmt && !*fmt) *fmt = zend_string_init(ZEND_STRL("Y-m-d\\T"), 0);
/* fallthrough */
case ION_TS_MONTH:
time->m = ts->month;
- if (fmt && !*fmt) *fmt = zend_string_init(ZEND_STRL("Y-m\\T"), 0);
/* fallthrough */
case ION_TS_YEAR:
time->y = ts->year;
- if (fmt && !*fmt) *fmt = zend_string_init(ZEND_STRL("Y\\T"), 0);
/* fallthrough */
default:
- if (fmt && !*fmt) *fmt = zend_string_init(ZEND_STRL("c"), 0);
time->z = ts->tz_offset * 60;
}
+ if (fmt) {
+ fmt = php_dt_format_from_precision(ts->precision);
+ }
return time;
}
return buf;
}
+static inline void php_ion_timestamp_ctor(php_ion_timestamp *obj, zend_long precision, zend_string *fmt, zend_string *dt, zval *tz)
+{
+ if (!obj->time) {
+ php_date_initialize(obj, dt ? dt->val : "", dt ? dt->len : 0, fmt ? fmt->val : NULL, tz, PHP_DATE_INIT_CTOR);
+ }
+ zend_update_property_long(obj->std.ce, &obj->std, ZEND_STRL("precision"), precision);
+
+ fmt = php_dt_format_from_precision(precision);
+ zend_update_property_str(obj->std.ce, &obj->std, ZEND_STRL("format"), fmt);
+ zend_string_release(fmt);
+}
+
+static inline void php_ion_timestamp_dtor(php_ion_timestamp *obj)
+{
+ if (obj->time) {
+ timelib_time_dtor(obj->time);
+ }
+}
+
typedef struct php_ion_catalog {
ION_CATALOG *cat;
zend_object std;
--- /dev/null
+--TEST--
+ion\Timestamp
+--EXTENSIONS--
+ion
+--FILE--
+TEST
+<?php
+use ion\Timestamp;
+
+try {
+ var_dump(new Timestamp);
+} catch (Throwable) {
+ echo "caught empty\n";
+}
+$full = "2021-12-07T14:08:51+00:00";
+var_dump($t=new Timestamp(Timestamp\Precision::Day, datetime:$full),(string)$t);
+var_dump($t=new Timestamp(Timestamp\Precision::Day->value, datetime:$full),(string)$t);
+var_dump($t=new Timestamp(Timestamp\Precision::Min, datetime:"2020-10-01"),(string)$t);
+var_dump($t=new Timestamp(Timestamp\Precision::Day, "!Y-m", "2000-10"),(string)$t);
+?>
+DONE
+--EXPECTF--
+TEST
+caught empty
+object(ion\Timestamp)#%d (2) {
+ ["precision"]=>
+ int(7)
+ ["format"]=>
+ string(7) "Y-m-d\T"
+}
+string(11) "2021-12-07T"
+object(ion\Timestamp)#%d (2) {
+ ["precision"]=>
+ int(7)
+ ["format"]=>
+ string(7) "Y-m-d\T"
+}
+string(11) "2021-12-07T"
+object(ion\Timestamp)#%d (2) {
+ ["precision"]=>
+ int(23)
+ ["format"]=>
+ string(11) "Y-m-d\TH:iP"
+}
+string(22) "2020-10-01T00:00+00:00"
+object(ion\Timestamp)#%d (2) {
+ ["precision"]=>
+ int(7)
+ ["format"]=>
+ string(7) "Y-m-d\T"
+}
+string(11) "2000-10-01T"
+DONE