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
2 changes: 1 addition & 1 deletion ext/date/config.w32
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// 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 duration.c parse_date.c parse_posix.c parse_tz.c tm2unixtime.c unixtime2tm.c parse_iso_intervals.c interval.c", "date");

Expand Down
2 changes: 1 addition & 1 deletion ext/date/config0.m4
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ timelib_sources="lib/astro.c lib/dow.c lib/duration.c lib/parse_date.c lib/parse
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
7 changes: 7 additions & 0 deletions ext/date/php_date.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "ext/standard/info.h"
#include "ext/standard/php_versioning.h"
#include "php_date.h"
#include "php_time.h"
#include "zend_attributes.h"
#include "zend_interfaces.h"
#include "zend_exceptions.h"
Expand Down Expand Up @@ -386,6 +387,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 +420,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 +453,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
3 changes: 3 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
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, /* seconds */ 0, /* nanoseconds */ 0, /* negative */ 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);

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): string {
$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