Skip to content
Open
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
14 changes: 7 additions & 7 deletions ext/date/lib/duration.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

int timelib_duration_ctor_static(
timelib_duration *duration,
timelib_ull seconds,
uint64_t seconds,
uint32_t nanoseconds,
bool negative
) {
Expand All @@ -51,7 +51,7 @@ int timelib_duration_ctor_static(
}

timelib_duration *timelib_duration_ctor(
timelib_ull seconds,
uint64_t seconds,
uint32_t nanoseconds,
bool negative,
int *error_code
Expand Down Expand Up @@ -134,7 +134,7 @@ static int timelib_duration_add_abs_internal(
const timelib_duration *original,
const timelib_duration *additional
) {
timelib_ull seconds = original->seconds + additional->seconds;
uint64_t seconds = original->seconds + additional->seconds;
uint32_t nanoseconds = original->nanoseconds + additional->nanoseconds;

if (nanoseconds >= NSECS_PER_SEC) {
Expand All @@ -151,8 +151,8 @@ static int timelib_duration_sub_abs_internal(
const timelib_duration *original,
const timelib_duration *minus
) {
timelib_ull seconds = original->seconds - minus->seconds;
timelib_sll nanoseconds = (timelib_sll)original->nanoseconds - (timelib_sll)minus->nanoseconds;
uint64_t seconds = original->seconds - minus->seconds;
int32_t nanoseconds = (int32_t)original->nanoseconds - (int32_t)minus->nanoseconds;

if (nanoseconds < 0) {
seconds--;
Expand Down Expand Up @@ -343,8 +343,8 @@ int timelib_duration_div_static(
const timelib_duration *original,
uint64_t divisor
) {
timelib_ull seconds;
uint32_t nanoseconds;
uint64_t seconds;
uint64_t nanoseconds;
Comment thread
TimWolla marked this conversation as resolved.

if (divisor < 1) {
return TIMELIB_ERROR_DIVISION_BY_ZERO;
Expand Down
6 changes: 3 additions & 3 deletions ext/date/lib/timelib.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ typedef struct _timelib_abbr_info {
} timelib_abbr_info;

typedef struct _timelib_duration {
timelib_ull seconds;
uint64_t seconds;
uint32_t nanoseconds;
bool negative;
} timelib_duration;
Expand Down Expand Up @@ -1054,7 +1054,7 @@ void timelib_get_transitions_for_year(timelib_tzinfo *tz, timelib_sll year, time
* *error_code set to a value from the TIMELIB_ERROR_* set.
*/
timelib_duration *timelib_duration_ctor(
timelib_ull seconds,
uint64_t seconds,
uint32_t nanoseconds,
bool negative,
int *error_code
Expand All @@ -1068,7 +1068,7 @@ timelib_duration *timelib_duration_ctor(
*/
int timelib_duration_ctor_static(
timelib_duration *duration,
timelib_ull seconds,
uint64_t seconds,
uint32_t nanoseconds,
bool negative
);
Expand Down
4 changes: 2 additions & 2 deletions ext/date/lib/timelib_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@
#define SECS_PER_DAY 86400
#define SECS_PER_HOUR 3600
#define USECS_PER_HOUR TIMELIB_LL_CONST(3600000000)
#define NSECS_PER_SEC TIMELIB_LL_CONST(1000000000)
#define MAX_DURATION_SECONDS TIMELIB_LL_CONST(9223372035)
#define NSECS_PER_SEC 1000000000
#define MAX_DURATION_SECONDS UINT64_C(9223372035)

#define DAYS_PER_WEEK 7
#define DAYS_PER_YEAR 365
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, 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;
Comment thread
derickr marked this conversation as resolved.

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