PTR_CHECK(obj);
zend_long precision;
- zend_object *precision_obj;
+ zend_object *precision_obj = NULL, *format_obj = NULL;
zend_string *fmt = NULL, *dt = NULL;
zval *tz = NULL;
ZEND_PARSE_PARAMETERS_START(1, 4)
Z_PARAM_OBJ_OF_CLASS_OR_LONG(precision_obj, ce_Timestamp_Precision, precision)
Z_PARAM_OPTIONAL
- Z_PARAM_STR_OR_NULL(fmt)
+ Z_PARAM_OBJ_OF_CLASS_OR_STR_OR_NULL(format_obj, ce_Timestamp_Format, fmt)
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));
}
+ if (format_obj) {
+ fmt = Z_STR_P(zend_enum_fetch_case_value(format_obj));
+ }
php_ion_timestamp_ctor(obj, precision, fmt, dt, tz);
}
static ZEND_METHOD(ion_Timestamp, __toString)
if (SUCCESS != g_sym_init()) {
return FAILURE;
}
+ g_intern_str_init();
// Catalog
php_ion_register(catalog, Catalog, zend_ce_countable);
// Timestamp
ce_Timestamp = register_class_ion_Timestamp(php_date_get_date_ce());
+ ce_Timestamp_Format = register_class_ion_Timestamp_Format();
ce_Timestamp_Precision = register_class_ion_Timestamp_Precision();
// Type
case SecTZ = 0x1|0x2|0x4|0x10|0x20|0x80;
case FracTZ = 0x1|0x2|0x4|0x10|0x20|0x40|0x80;
}
+
+namespace ion\Timestamp;
+enum Format : string {
+ case Year = "Y\T";
+ case Month = "Y-m\T";
+ case Day = "Y-m-d\T";
+ case Min = "Y-m-d\TH:i";
+ case Sec = "Y-m-d\TH:i:s";
+ case Frac = "Y-m-d\TH:i:s.v";
+ case MinTZ = "Y-m-d\TH:iP";
+ case SecTZ = "Y-m-d\TH:i:sP";
+ case FracTZ = "Y-m-d\TH:i:s.vP";
+}
namespace ion;
class Timestamp extends \DateTime {
public readonly int $precision;
public function __construct(
Timestamp\Precision|int $precision,
- ?string $format = null,
+ Timestamp\Format|string|null $format = null,
?string $datetime = null,
?\DateTimeZone $timezone = null,
) {}
/* This is a generated file, edit the .stub.php file instead.
- * Stub hash: ab42c2a137aa474d0da60bcc65144da7a9472948 */
+ * Stub hash: 8e04adcc2af90243429a756e14d48507f8411309 */
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_ion_Symbol_Table_PHP, 0, 0, ion\\Symbol\\Table, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ion_Timestamp___construct, 0, 0, 1)
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_OBJ_TYPE_MASK(0, format, ion\\Timestamp\\Format, MAY_BE_STRING|MAY_BE_NULL, "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_Format_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_Format(void)
+{
+ zend_class_entry *class_entry = zend_register_internal_enum("ion\\Timestamp\\Format", IS_STRING, class_ion_Timestamp_Format_methods);
+
+ zval enum_case_Year_value;
+ zend_string *enum_case_Year_value_str = zend_string_init("Y\\T", sizeof("Y\\T") - 1, 1);
+ ZVAL_STR(&enum_case_Year_value, enum_case_Year_value_str);
+ zend_enum_add_case_cstr(class_entry, "Year", &enum_case_Year_value);
+
+ zval enum_case_Month_value;
+ zend_string *enum_case_Month_value_str = zend_string_init("Y-m\\T", sizeof("Y-m\\T") - 1, 1);
+ ZVAL_STR(&enum_case_Month_value, enum_case_Month_value_str);
+ zend_enum_add_case_cstr(class_entry, "Month", &enum_case_Month_value);
+
+ zval enum_case_Day_value;
+ zend_string *enum_case_Day_value_str = zend_string_init("Y-m-d\\T", sizeof("Y-m-d\\T") - 1, 1);
+ ZVAL_STR(&enum_case_Day_value, enum_case_Day_value_str);
+ zend_enum_add_case_cstr(class_entry, "Day", &enum_case_Day_value);
+
+ zval enum_case_Min_value;
+ zend_string *enum_case_Min_value_str = zend_string_init("Y-m-d\\TH:i", sizeof("Y-m-d\\TH:i") - 1, 1);
+ ZVAL_STR(&enum_case_Min_value, enum_case_Min_value_str);
+ zend_enum_add_case_cstr(class_entry, "Min", &enum_case_Min_value);
+
+ zval enum_case_Sec_value;
+ zend_string *enum_case_Sec_value_str = zend_string_init("Y-m-d\\TH:i:s", sizeof("Y-m-d\\TH:i:s") - 1, 1);
+ ZVAL_STR(&enum_case_Sec_value, enum_case_Sec_value_str);
+ zend_enum_add_case_cstr(class_entry, "Sec", &enum_case_Sec_value);
+
+ zval enum_case_Frac_value;
+ zend_string *enum_case_Frac_value_str = zend_string_init("Y-m-d\\TH:i:s.v", sizeof("Y-m-d\\TH:i:s.v") - 1, 1);
+ ZVAL_STR(&enum_case_Frac_value, enum_case_Frac_value_str);
+ zend_enum_add_case_cstr(class_entry, "Frac", &enum_case_Frac_value);
+
+ zval enum_case_MinTZ_value;
+ zend_string *enum_case_MinTZ_value_str = zend_string_init("Y-m-d\\TH:iP", sizeof("Y-m-d\\TH:iP") - 1, 1);
+ ZVAL_STR(&enum_case_MinTZ_value, enum_case_MinTZ_value_str);
+ zend_enum_add_case_cstr(class_entry, "MinTZ", &enum_case_MinTZ_value);
+
+ zval enum_case_SecTZ_value;
+ zend_string *enum_case_SecTZ_value_str = zend_string_init("Y-m-d\\TH:i:sP", sizeof("Y-m-d\\TH:i:sP") - 1, 1);
+ ZVAL_STR(&enum_case_SecTZ_value, enum_case_SecTZ_value_str);
+ zend_enum_add_case_cstr(class_entry, "SecTZ", &enum_case_SecTZ_value);
+
+ zval enum_case_FracTZ_value;
+ zend_string *enum_case_FracTZ_value_str = zend_string_init("Y-m-d\\TH:i:s.vP", sizeof("Y-m-d\\TH:i:s.vP") - 1, 1);
+ ZVAL_STR(&enum_case_FracTZ_value, enum_case_FracTZ_value_str);
+ zend_enum_add_case_cstr(class_entry, "FracTZ", &enum_case_FracTZ_value);
+
+ return class_entry;
+}
+
static zend_class_entry *register_class_ion_Timestamp(zend_class_entry *class_entry_DateTime)
{
zend_class_entry ce, *class_entry;
return SUCCESS;
}
+static struct {
+ zend_string *Year, *Month, *Day, *Min, *Sec, *Frac, *MinTZ, *SecTZ, *FracTZ;
+} g_intern_str;
+
+static void g_intern_str_init()
+{
+#define NEW_INTERN_STR(s) \
+ g_intern_str.s = zend_string_init_interned(#s, sizeof(#s)-1, 1)
+ NEW_INTERN_STR(Year);
+ NEW_INTERN_STR(Month);
+ NEW_INTERN_STR(Day);
+ NEW_INTERN_STR(Min);
+ NEW_INTERN_STR(Sec);
+ NEW_INTERN_STR(Frac);
+ NEW_INTERN_STR(MinTZ);
+ NEW_INTERN_STR(SecTZ);
+ NEW_INTERN_STR(FracTZ);
+#undef NEW_INTERN_STR
+}
+
typedef struct php_ion_serializer {
ION_WRITER *writer;
ION_WRITER_OPTIONS *options;
*ce_Symbol_Table_Shared,
*ce_Symbol_Table_System,
*ce_Timestamp,
+ *ce_Timestamp_Format,
*ce_Timestamp_Precision,
*ce_Type,
*ce_Unserializer,
return decQuadDivide(frac, decQuadFromInt32(&us, usec), decQuadFromInt32(µsecs, 1000000), ctx);
}
+LOCAL zend_string *php_ion_timestamp_format_fetch(zend_string *fmt_case)
+{
+ return Z_STR_P(zend_enum_fetch_case_value(zend_enum_get_case(ce_Timestamp_Format, fmt_case)));
+}
+
LOCAL zend_string *php_dt_format_from_precision(uint8_t precision)
{
- switch (precision & 0x7f) {
+ switch (precision) {
+ case ION_TS_FRAC | 0x80:
+ return php_ion_timestamp_format_fetch(g_intern_str.FracTZ);
case ION_TS_FRAC:
- return zend_string_init(ZEND_STRL("c"), 0);
+ return php_ion_timestamp_format_fetch(g_intern_str.Frac);
+ case ION_TS_SEC | 0x80:
+ return php_ion_timestamp_format_fetch(g_intern_str.SecTZ);
case ION_TS_SEC:
- return zend_string_init(ZEND_STRL("Y-m-d\\TH:i:sP"), 0);
+ return php_ion_timestamp_format_fetch(g_intern_str.Sec);
+ case ION_TS_MIN | 0x80:
+ return php_ion_timestamp_format_fetch(g_intern_str.MinTZ);
case ION_TS_MIN:
- return zend_string_init(ZEND_STRL("Y-m-d\\TH:iP"), 0);
+ return php_ion_timestamp_format_fetch(g_intern_str.Min);
case ION_TS_DAY:
- return zend_string_init(ZEND_STRL("Y-m-d\\T"), 0);
+ return php_ion_timestamp_format_fetch(g_intern_str.Day);
case ION_TS_MONTH:
- return zend_string_init(ZEND_STRL("Y-m\\T"), 0);
+ return php_ion_timestamp_format_fetch(g_intern_str.Month);
case ION_TS_YEAR:
- return zend_string_init(ZEND_STRL("Y\\T"), 0);
+ return php_ion_timestamp_format_fetch(g_intern_str.Year);
default:
- return zend_string_init(ZEND_STRL("c"), 0);
+ return zend_one_char_string['c'];
}
}
{
timelib_time *time = ecalloc(1, sizeof(*time));
- int precision = ION_TS_FRAC;
- ion_timestamp_get_precision(ts, &precision);
- switch (precision) {
+ switch (ts->precision & 0x7f) {
case ION_TS_FRAC:
time->us = php_usec_from_ion(&ts->fraction, ctx);
/* fallthrough */
/* fallthrough */
default:
time->z = ts->tz_offset * 60;
- if (time->z) {
+ if (time->z || ts->precision & 0x80) {
time->zone_type = TIMELIB_ZONETYPE_OFFSET;
} else {
time->zone_type = TIMELIB_ZONETYPE_ID;
}
if (fmt) {
- *fmt = php_dt_format_from_precision(precision);
+ *fmt = php_dt_format_from_precision(ts->precision);
}
return time;
}
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);
+$t->setTimezone(new DateTimeZone("Europe/Helsinki"));
+var_dump((string) $t);
var_dump($t=new Timestamp(Timestamp\Precision::Day, "!Y-m", "2000-10"),(string)$t);
-
var_dump(ion\unserialize(ion\serialize(clone new ion\Timestamp(ion\Timestamp\Precision::Sec, DateTime::RFC3339, "1971-02-03T04:05:06Z"))));
?>
DONE
["precision"]=>
int(23)
["format"]=>
- string(11) "Y-m-d\TH:iP"
+ string(10) "Y-m-d\TH:i"
["date"]=>
string(26) "2020-10-01 00:00:00.000000"
["timezone_type"]=>
["timezone"]=>
string(3) "CET"
}
-string(22) "2020-10-01T00:00+02:00"
+string(16) "2020-10-01T00:00"
+string(16) "2020-10-01T01:00"
object(ion\Timestamp)#%d (5) {
["precision"]=>
int(7)
string(3) "CET"
}
string(11) "2000-10-01T"
-object(ion\Timestamp)#8 (3) {
+object(ion\Timestamp)#%d (3) {
["precision"]=>
int(55)
["format"]=>
- string(13) "Y-m-d\TH:i:sP"
+ string(12) "Y-m-d\TH:i:s"
["date"]=>
string(26) "1971-02-03 04:05:06.000000"
}
TEST
<?php
$dt = ion\unserialize("1971-02-03T04:05:06.789Z");
-var_dump($dt);
+var_dump($dt, (string) $dt);
$ts = ion\serialize($dt);
var_dump($ts);
DONE
--EXPECTF--
TEST
-object(ion\Timestamp)#5 (3) {
+object(ion\Timestamp)#%d (3) {
["precision"]=>
int(247)
["format"]=>
- string(1) "c"
+ string(15) "Y-m-d\TH:i:s.vP"
["date"]=>
string(26) "1971-02-03 04:05:06.789000"
}
+string(29) "1971-02-03T04:05:06.789+00:00"
string(24) "1971-02-03T04:05:06.789Z"
-object(ion\Timestamp)#6 (3) {
+object(ion\Timestamp)#%d (3) {
["precision"]=>
int(247)
["format"]=>
- string(1) "c"
+ string(15) "Y-m-d\TH:i:s.vP"
["date"]=>
string(26) "1971-02-03 04:05:06.789000"
}