Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions ext/date/config.w32
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// vim:ft=javascript

EXTENSION("date", "php_date.c", false, "/Iext/date/lib /DHAVE_TIMELIB_CONFIG_H=1");
EXTENSION("date", "php_date.c php_time.c time_duration.c", false, "/Iext/date/lib /DHAVE_TIMELIB_CONFIG_H=1");
PHP_DATE = "yes";
ADD_SOURCES("ext/date/lib", "astro.c timelib.c dow.c parse_date.c parse_posix.c parse_tz.c tm2unixtime.c unixtime2tm.c parse_iso_intervals.c interval.c", "date");
ADD_SOURCES("ext/date/lib", "astro.c timelib.c dow.c duration.c parse_date.c parse_posix.c parse_tz.c tm2unixtime.c unixtime2tm.c parse_iso_intervals.c interval.c", "date");

ADD_FLAG('CFLAGS_DATE', "/wd4244");

Expand Down
4 changes: 2 additions & 2 deletions ext/date/config0.m4
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ PHP_DATE_CFLAGS="$PHP_DATE_CFLAGS -I@ext_builddir@/lib"
AX_CHECK_COMPILE_FLAG([-fwrapv],
[PHP_TIMELIB_CFLAGS="$PHP_TIMELIB_CFLAGS -fwrapv"])

timelib_sources="lib/astro.c lib/dow.c lib/parse_date.c lib/parse_tz.c lib/parse_posix.c
timelib_sources="lib/astro.c lib/dow.c lib/duration.c lib/parse_date.c lib/parse_tz.c lib/parse_posix.c
lib/timelib.c lib/tm2unixtime.c lib/unixtime2tm.c lib/parse_iso_intervals.c lib/interval.c"

PHP_NEW_EXTENSION([date],
[php_date.c],
[php_date.c php_time.c time_duration.c],
[no],,
[$PHP_DATE_CFLAGS])

Expand Down
2 changes: 1 addition & 1 deletion ext/date/lib/duration.c
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ int timelib_duration_div_static(
uint64_t divisor
) {
timelib_ull seconds;
uint32_t nanoseconds;
uint64_t nanoseconds;

if (divisor < 1) {
return TIMELIB_ERROR_DIVISION_BY_ZERO;
Expand Down
6 changes: 6 additions & 0 deletions ext/date/php_date.c
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,7 @@ static PHP_GINIT_FUNCTION(date)
date_globals->default_timezone = NULL;
date_globals->timezone = NULL;
date_globals->tzcache = NULL;
date_globals->duration_cache = NULL;
}
/* }}} */

Expand Down Expand Up @@ -418,6 +419,10 @@ PHP_RSHUTDOWN_FUNCTION(date)
efree(DATEG(timezone));
}
DATEG(timezone) = NULL;
if (DATEG(duration_cache)) {
zend_object_release(DATEG(duration_cache));
}
DATEG(duration_cache) = NULL;

return SUCCESS;
}
Expand Down Expand Up @@ -447,6 +452,7 @@ PHP_MINIT_FUNCTION(date)
REGISTER_INI_ENTRIES();
date_register_classes();
register_php_date_symbols(module_number);
PHP_MINIT(date_time)(INIT_FUNC_ARGS_PASSTHRU);

php_date_global_timezone_db = NULL;
php_date_global_timezone_db_enabled = 0;
Expand Down
5 changes: 5 additions & 0 deletions ext/date/php_date.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,11 @@ ZEND_BEGIN_MODULE_GLOBALS(date)
char *timezone;
HashTable *tzcache;
timelib_error_container *last_errors;
zend_object *duration_cache;
ZEND_END_MODULE_GLOBALS(date)

PHPAPI ZEND_EXTERN_MODULE_GLOBALS(date)

#define DATEG(v) ZEND_MODULE_GLOBALS_ACCESSOR(date, v)

PHPAPI time_t php_time(void);
Expand Down Expand Up @@ -153,4 +156,6 @@ PHPAPI bool php_date_initialize(php_date_obj *dateobj, const char *time_str, siz
PHPAPI void php_date_initialize_from_ts_long(php_date_obj *dateobj, zend_long sec, int usec);
PHPAPI bool php_date_initialize_from_ts_double(php_date_obj *dateobj, double ts);

# include "php_time.h"

#endif /* PHP_DATE_H */
65 changes: 65 additions & 0 deletions ext/date/php_time.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
+----------------------------------------------------------------------+
| Copyright © The PHP Group and Contributors. |
+----------------------------------------------------------------------+
| This source file is subject to the Modified BSD License that is |
| bundled with this package in the file LICENSE, and is available |
| through the World Wide Web at <https://www.php.net/license/>. |
| |
| SPDX-License-Identifier: BSD-3-Clause |
+----------------------------------------------------------------------+
| Authors: Derick Rethans <derick@derickrethans.nl> |
| Tim Düsterhus <timwolla@php.net> |
+----------------------------------------------------------------------+
*/

#include "php.h"
#include "Zend/zend_exceptions.h"

#include "php_time.h"
#include "time_arginfo.h"

zend_class_entry *php_date_ce_time_duration;
zend_class_entry *php_date_ce_time_timeexception;

static zend_object_handlers time_duration_object_handlers;

static zend_object *time_duration_object_create(zend_class_entry *ce)
{
php_date_time_duration *obj = zend_object_alloc(sizeof(*obj), ce);

zend_object_std_init(&obj->std, ce);
object_properties_init(&obj->std, ce);

timelib_duration_ctor_static(&obj->duration, 0,0, false);

return &obj->std;
}

static zend_object *time_duration_object_clone(zend_object *object)
{
const php_date_time_duration *obj = php_date_time_duration_from_obj(object);

php_date_time_duration *new_obj = php_date_time_duration_from_obj(object->ce->create_object(object->ce));

new_obj->duration = obj->duration;
zend_objects_clone_members(&new_obj->std, &obj->std);
Comment thread
TimWolla marked this conversation as resolved.

return &new_obj->std;
}

PHP_MINIT_FUNCTION(date_time)
{
/* Time\TimeException */
php_date_ce_time_timeexception = register_class_Time_TimeException(zend_ce_exception);

/* Time\Duration */
memcpy(&time_duration_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
time_duration_object_handlers.offset = offsetof(php_date_time_duration, std);
time_duration_object_handlers.clone_obj = time_duration_object_clone;
php_date_ce_time_duration = register_class_Time_Duration();
php_date_ce_time_duration->create_object = time_duration_object_create;
php_date_ce_time_duration->default_object_handlers = &time_duration_object_handlers;

return SUCCESS;
}
48 changes: 48 additions & 0 deletions ext/date/php_time.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
+----------------------------------------------------------------------+
| Copyright © The PHP Group and Contributors. |
+----------------------------------------------------------------------+
| This source file is subject to the Modified BSD License that is |
| bundled with this package in the file LICENSE, and is available |
| through the World Wide Web at <https://www.php.net/license/>. |
| |
| SPDX-License-Identifier: BSD-3-Clause |
+----------------------------------------------------------------------+
| Authors: Derick Rethans <derick@derickrethans.nl> |
| Tim Düsterhus <timwolla@php.net> |
+----------------------------------------------------------------------+
*/

#ifndef PHP_DATE_TIME_H
# define PHP_DATE_TIME_H

# include "php.h"
# include "lib/timelib.h"

typedef struct php_date_time_duration {
timelib_duration duration;
zend_object std;
} php_date_time_duration;

# define php_date_time_duration_from_obj(obj) ZEND_CONTAINER_OF(obj, php_date_time_duration, std)

# define Z_DATE_TIME_DURATION_P(zv) php_date_time_duration_from_obj(Z_OBJ_P((zv)))

# define Z_PARAM_DATE_TIME_DURATION(d) do { \
zend_object *__d; \
Z_PARAM_OBJ_OF_CLASS(__d, php_date_ce_time_duration); \
d = php_date_time_duration_from_obj(__d); \
} while (0);

# define Z_PARAM_DATE_TIME_DURATION_OR_NULL(d) do { \
zend_object *__d; \
Z_PARAM_OBJ_OF_CLASS_OR_NULL(__d, php_date_ce_time_duration); \
d = __d ? php_date_time_duration_from_obj(__d) : NULL; \
} while (0);

PHPAPI extern zend_class_entry *php_date_ce_time_duration;
PHPAPI extern zend_class_entry *php_date_ce_time_timeexception;

PHP_MINIT_FUNCTION(date_time);

#endif /* PHP_DATE_TIME_H */
24 changes: 24 additions & 0 deletions ext/date/tests/time/duration/clone.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
--TEST--
Time\Duration: clone
--FILE--
<?php

require __DIR__ . '/helper.inc';

function fc(Time\Duration $d): string {
return f(clone($d));
}

echo fc(Time\Duration::fromSeconds(0, 0)), PHP_EOL;
echo fc(Time\Duration::fromSeconds(0, 1)), PHP_EOL;
echo fc(Time\Duration::fromSeconds(1, 1)), PHP_EOL;
echo fc(Time\Duration::fromSeconds(0, 1)->negate()), PHP_EOL;
echo fc(Time\Duration::fromSeconds(1, 1)->negate()), PHP_EOL;

?>
--EXPECT--
+0.000000000
+0.000000001
+1.000000001
-0.000000001
-1.000000001
31 changes: 31 additions & 0 deletions ext/date/tests/time/duration/helper.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

function f(Time\Duration $d, bool $pad = true, bool $plus_sign = true) {
$result = sprintf("%s%d.%09d", ($d->negative ? "-" : ($plus_sign ? "+" : " ")), $d->seconds, $d->nanoseconds);
if ($pad) {
$result = str_pad($result, 21, pad_type: STR_PAD_LEFT);
}

return $result;
}

function as_int(Time\Duration $d): int {
return ($d->negative ? -1 : 1) * ($d->seconds * 1_000_000_000 + $d->nanoseconds);
}

function negate(Time\Duration $d): Time\Duration {
return $d->negate();
}

function is_negative(Time\Duration $d): bool {
return $d->negative;
}

/** @return Time\Duration[] */
function negate_all(
array $d /** @param Time\Duration[] */,
): array {
return $d
|> array_map(negate(?), ?)
|> array_filter(?, is_negative(?));
}
29 changes: 29 additions & 0 deletions ext/date/tests/time/duration/methods/absolute.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
--TEST--
Time\Duration::absolute()
--FILE--
<?php

require __DIR__ . '/../helper.inc';

echo f(Time\Duration::fromSeconds(0, 0)->absolute()), PHP_EOL;
echo f(Time\Duration::fromSeconds(0, 0)->negate()->absolute()), PHP_EOL;

echo f(Time\Duration::fromSeconds(1, 0)->absolute()), PHP_EOL;
echo f(Time\Duration::fromSeconds(1, 0)->negate()->absolute()), PHP_EOL;

echo f(Time\Duration::fromSeconds(0, 1)->absolute()), PHP_EOL;
echo f(Time\Duration::fromSeconds(0, 1)->negate()->absolute()), PHP_EOL;

echo f(Time\Duration::fromSeconds(1, 1)->absolute()), PHP_EOL;
echo f(Time\Duration::fromSeconds(1, 1)->negate()->absolute()), PHP_EOL;

?>
--EXPECT--
+0.000000000
+0.000000000
+1.000000000
+1.000000000
+0.000000001
+0.000000001
+1.000000001
+1.000000001
Loading
Loading