Skip to content
Open
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
91759b3
stash
Shamzik Nov 13, 2025
c35762c
stash
Shamzik Nov 13, 2025
01f2476
stash
Shamzik Dec 10, 2025
b29deda
stash
Shamzik Dec 10, 2025
6c3b902
fixes
Shamzik Dec 10, 2025
d9da675
datetime methods
Shamzik Dec 10, 2025
9825b2b
kphp::memory::libc_alloc_guard
Shamzik Dec 11, 2025
7161d44
some tests
Shamzik Dec 11, 2025
283b554
fixes
Shamzik Dec 11, 2025
a7ac9db
format
Shamzik Dec 11, 2025
40b60bd
get_last_errors
Shamzik Dec 11, 2025
d5bb003
error messages
Shamzik Dec 11, 2025
6273913
test 12_create_interval.php
Shamzik Dec 11, 2025
cc608cb
remove extra ';'
Shamzik Dec 11, 2025
028e647
auto -> int32_t
Shamzik Dec 12, 2025
dc43023
fixes
Shamzik Dec 12, 2025
5362352
implement setISODate method
Shamzik Dec 12, 2025
9b7918d
implement sub methods
Shamzik Dec 12, 2025
a96050c
implement getOffset methods
Shamzik Dec 15, 2025
39cfffc
construct -> parse
Shamzik Dec 25, 2025
befbf8d
use destructor{}
Shamzik Dec 25, 2025
b55795f
move NOW_STR into time state
Shamzik Jan 14, 2026
9cc1a77
remove include
Shamzik Jan 14, 2026
22fede1
use type wrappers
Shamzik Jan 14, 2026
c2e2dd4
fix parse_interval
Shamzik Jan 14, 2026
18a490d
refactoring
Shamzik Jan 16, 2026
589fd73
destructors
Shamzik Jan 16, 2026
2a67c1e
revert string_decl
Shamzik Jan 19, 2026
35b8674
move string_back_insert_iterator into separated header
Shamzik Jan 19, 2026
580e3db
fixes
Shamzik Jan 19, 2026
8b8e1cc
move NOW_ into TimeImageState
Shamzik Jan 19, 2026
af121e2
move destructors into details namespace
Shamzik Jan 19, 2026
4cfcaf0
remove `_t` suffix
Shamzik Jan 19, 2026
8cc3b61
fix
Shamzik Jan 19, 2026
8bad775
rename
Shamzik Jan 19, 2026
eb0dc06
fixes
Shamzik Jan 19, 2026
08d673b
std::string_view
Shamzik Jan 19, 2026
e8ff62c
make tzinfo wrapper
Shamzik Jan 20, 2026
8afb7f3
lambdas & includes
Shamzik Jan 21, 2026
bfc6bc7
remove const
Shamzik Jan 21, 2026
a9f8712
fix fill_holes_with_now_info
Shamzik Jan 21, 2026
073ec0c
std::size_t -> size_t
Shamzik Jan 21, 2026
250dd49
optimize libc_alloc_guard
Shamzik Jan 21, 2026
e304ce6
fix weekYearSet
Shamzik Jan 21, 2026
58e3422
swap -> move
Shamzik Jan 21, 2026
575379d
Copyright (c) 2026 LLC «V Kontakte»
Shamzik Jan 21, 2026
6d9b904
rename files
Shamzik Jan 21, 2026
e2d6d90
move some functions into headers
Shamzik Jan 21, 2026
713c2b0
get_timezone_info
Shamzik Jan 21, 2026
079a6a7
remove _sv suffixes
Shamzik Jan 21, 2026
60fc83f
std::output_iterator<const char&>
Shamzik Jan 21, 2026
158f904
revert put method
Shamzik Jan 21, 2026
ad0755f
remove make method
Shamzik Jan 21, 2026
193f031
fixes
Shamzik Jan 21, 2026
5056017
fixed formatted_* args
Shamzik Jan 21, 2026
74bccbb
fixes
Shamzik Jan 21, 2026
b2d42e2
fix split commens
Shamzik Jan 21, 2026
ab5a00d
fix parse_interval
Shamzik Jan 22, 2026
b0fcb23
move some timelib functions to header
Shamzik Jan 22, 2026
ac16618
full qualified names
Shamzik Jan 22, 2026
3154b71
move chrono up
Shamzik Jan 22, 2026
66cfeb5
fix timelib_parse_tzfile usage
Shamzik Jan 22, 2026
933f4bd
refactor timezone_cache initialization
Shamzik Jan 22, 2026
1cd498e
move TimeInstanceState::get() to local var
Shamzik Jan 22, 2026
d449771
move small date-time functions into headers
Shamzik Jan 22, 2026
ea202ab
includes
Shamzik Jan 22, 2026
934873e
move common timelib functions into runtime-common
Shamzik Jan 27, 2026
f71df10
format
Shamzik Jan 27, 2026
da6c9d3
remove iterator.h
Shamzik Jan 27, 2026
fbc06e0
fixes
Shamzik Jan 29, 2026
c14fcfd
fix timelib.cmake
Shamzik Jan 29, 2026
332366e
fixes
Shamzik Jan 29, 2026
ba50508
common define for runtimes
Shamzik Jan 29, 2026
07fc8df
2026
Shamzik Jan 29, 2026
837ca6d
fix gen_error_msg
Shamzik Jan 29, 2026
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
88 changes: 26 additions & 62 deletions builtin-functions/kphp-light/stdlib/time-functions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,27 +30,19 @@ function set_timer(int $timeout, callable():void $callback) ::: void;

function checkdate ($month ::: int, $day ::: int, $year ::: int) ::: bool;

// ===== UNSUPPORTED =====

/** @kphp-generate-stub-class */
class DateInterval {
/** @kphp-extern-func-info can_throw stub generation-required */
/** @kphp-extern-func-info can_throw */
public function __construct(string $duration);
/** @kphp-extern-func-info stub generation-required */
public static function createFromDateString(string $datetime): ?DateInterval;
/** @kphp-extern-func-info stub generation-required */
public function format(string $format): string;
}

/** @kphp-generate-stub-class */
class DateTimeZone {
/** @kphp-extern-func-info can_throw stub generation-required */
/** @kphp-extern-func-info can_throw */
public function __construct(string $timezone);
/** @kphp-extern-func-info stub generation-required */
public function getName(): string;
}

/** @kphp-generate-stub-class */
interface DateTimeInterface {
/* Constants */
const ATOM = "Y-m-d\TH:i:sP";
Expand Down Expand Up @@ -86,84 +78,56 @@ interface DateTimeInterface {
public function getTimestamp(): int;
}

/** @kphp-generate-stub-class */
class DateTime implements DateTimeInterface {
/** @kphp-extern-func-info can_throw stub generation-required */
class DateTimeImmutable implements DateTimeInterface {
/** @kphp-extern-func-info can_throw */
public function __construct(string $datetime = "now", ?DateTimeZone $timezone = null);
/** @kphp-extern-func-info stub generation-required */
public function add(DateInterval $interval): DateTime;
/** @kphp-extern-func-info stub generation-required */
public static function createFromFormat(string $format, string $datetime, ?DateTimeZone $timezone = null): ?DateTime;
/** @kphp-extern-func-info stub generation-required */
public static function createFromImmutable(DateTimeImmutable $object): DateTime;
/** @kphp-extern-func-info stub generation-required */
public function add(DateInterval $interval): DateTimeImmutable;
public static function createFromFormat(string $format, string $datetime, ?DateTimeZone $timezone = null): ?DateTimeImmutable;
public static function createFromMutable(DateTime $object): DateTimeImmutable;
public static function getLastErrors(): array|false;
/** @kphp-extern-func-info stub generation-required */
public function modify(string $modifier): ?DateTime;
/** @kphp-extern-func-info stub generation-required */
public function setDate(int $year, int $month, int $day): DateTime;
/** @kphp-extern-func-info stub generation-required */
public function setISODate(int $year, int $week, int $dayOfWeek = 1): DateTime;
/** @kphp-extern-func-info stub generation-required */
public function modify(string $modifier): ?DateTimeImmutable;
public function setDate(int $year, int $month, int $day): DateTimeImmutable;
public function setISODate(int $year, int $week, int $dayOfWeek = 1): DateTimeImmutable;
public function setTime(
int $hour,
int $minute,
int $second = 0,
int $microsecond = 0
): DateTime;
/** @kphp-extern-func-info stub generation-required */
public function setTimestamp(int $timestamp): DateTime;
/** @kphp-extern-func-info stub generation-required */
public function sub(DateInterval $interval): DateTime;
/** @kphp-extern-func-info stub generation-required */
): DateTimeImmutable;
public function setTimestamp(int $timestamp): DateTimeImmutable;
public function sub(DateInterval $interval): DateTimeImmutable;
public function diff(DateTimeInterface $targetObject, bool $absolute = false): DateInterval;
/** @kphp-extern-func-info stub generation-required */
public function format(string $format): string;
/** @kphp-extern-func-info stub generation-required */
public function getOffset(): int;
/** @kphp-extern-func-info stub generation-required */
public function getTimestamp(): int;
}

/** @kphp-generate-stub-class */
class DateTimeImmutable implements DateTimeInterface {
/** @kphp-extern-func-info can_throw stub generation-required */
class DateTime implements DateTimeInterface {
/** @kphp-extern-func-info can_throw */
public function __construct(string $datetime = "now", ?DateTimeZone $timezone = null);
/** @kphp-extern-func-info stub generation-required */
public function add(DateInterval $interval): DateTimeImmutable;
/** @kphp-extern-func-info stub generation-required */
public static function createFromFormat(string $format, string $datetime, ?DateTimeZone $timezone = null): ?DateTimeImmutable;
/** @kphp-extern-func-info stub generation-required */
public static function createFromMutable(DateTime $object): DateTimeImmutable;
/** @kphp-extern-func-info stub generation-required */
public function add(DateInterval $interval): DateTime;
public static function createFromFormat(string $format, string $datetime, ?DateTimeZone $timezone = null): ?DateTime;
public static function createFromImmutable(DateTimeImmutable $object): DateTime;
public static function getLastErrors(): array|false;
/** @kphp-extern-func-info stub generation-required */
public function modify(string $modifier): ?DateTimeImmutable;
/** @kphp-extern-func-info stub generation-required */
public function setDate(int $year, int $month, int $day): DateTimeImmutable;
/** @kphp-extern-func-info stub generation-required */
public function setISODate(int $year, int $week, int $dayOfWeek = 1): DateTimeImmutable;
/** @kphp-extern-func-info stub generation-required */
public function modify(string $modifier): ?DateTime;
public function setDate(int $year, int $month, int $day): DateTime;
public function setISODate(int $year, int $week, int $dayOfWeek = 1): DateTime;
public function setTime(
int $hour,
int $minute,
int $second = 0,
int $microsecond = 0
): DateTimeImmutable;
/** @kphp-extern-func-info stub generation-required */
public function setTimestamp(int $timestamp): DateTimeImmutable;
/** @kphp-extern-func-info stub generation-required */
public function sub(DateInterval $interval): DateTimeImmutable;
/** @kphp-extern-func-info stub generation-required */
): DateTime;
public function setTimestamp(int $timestamp): DateTime;
public function sub(DateInterval $interval): DateTime;
public function diff(DateTimeInterface $targetObject, bool $absolute = false): DateInterval;
/** @kphp-extern-func-info stub generation-required */
public function format(string $format): string;
/** @kphp-extern-func-info stub generation-required */
public function getOffset(): int;
/** @kphp-extern-func-info stub generation-required */
public function getTimestamp(): int;
}

// ===== UNSUPPORTED =====

define('DATE_ATOM', "Y-m-d\TH:i:sP");
define('DATE_COOKIE', "l, d-M-y H:i:s T");
define('DATE_ISO8601', "Y-m-d\TH:i:sO");
Expand Down
1 change: 1 addition & 0 deletions runtime-common/core/core-types/decl/string_decl.inl
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ struct ArrayBucketDummyStrTag;
class string {
public:
using size_type = string_size_type;
using value_type = char;
static constexpr size_type npos = (size_type)-1;

private:
Expand Down
3 changes: 3 additions & 0 deletions runtime-common/stdlib/string/string-context.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ inline constexpr std::string_view COMMA_ = ",";
inline constexpr std::string_view BACKSLASH_ = "\\";
inline constexpr std::string_view QUOTE_ = "\"";
inline constexpr std::string_view NEWLINE_ = "\n";
inline constexpr std::string_view NOW_ = "now";
inline constexpr std::string_view SPACE_ = " ";
inline constexpr std::string_view WHAT_ = " \n\r\t\v\0"sv;
inline constexpr std::string_view ONE_ = "1";
Expand Down Expand Up @@ -60,6 +61,7 @@ struct StringLibConstants final : vk::not_copyable {
string BACKSLASH_STR{string_context_impl_::BACKSLASH_.data(), static_cast<string::size_type>(string_context_impl_::BACKSLASH_.size())};
string QUOTE_STR{string_context_impl_::QUOTE_.data(), static_cast<string::size_type>(string_context_impl_::QUOTE_.size())};
string NEWLINE_STR{string_context_impl_::NEWLINE_.data(), static_cast<string::size_type>(string_context_impl_::NEWLINE_.size())};
string NOW_STR{string_context_impl_::NOW_.data(), static_cast<string::size_type>(string_context_impl_::NOW_.size())};
string SPACE_STR{string_context_impl_::SPACE_.data(), static_cast<string::size_type>(string_context_impl_::SPACE_.size())};
string WHAT_STR{string_context_impl_::WHAT_.data(), static_cast<string::size_type>(string_context_impl_::WHAT_.size())};
string ONE_STR{string_context_impl_::ONE_.data(), static_cast<string::size_type>(string_context_impl_::ONE_.size())};
Expand All @@ -85,6 +87,7 @@ struct StringLibConstants final : vk::not_copyable {
BACKSLASH_STR.set_reference_counter_to(ExtraRefCnt::for_global_const);
QUOTE_STR.set_reference_counter_to(ExtraRefCnt::for_global_const);
NEWLINE_STR.set_reference_counter_to(ExtraRefCnt::for_global_const);
NOW_STR.set_reference_counter_to(ExtraRefCnt::for_global_const);
SPACE_STR.set_reference_counter_to(ExtraRefCnt::for_global_const);
WHAT_STR.set_reference_counter_to(ExtraRefCnt::for_global_const);
ONE_STR.set_reference_counter_to(ExtraRefCnt::for_global_const);
Expand Down
4 changes: 4 additions & 0 deletions runtime-light/stdlib/stdlib.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ prepend(
string/string-state.cpp
system/system-functions.cpp
system/system-state.cpp
time/dateinterval.cpp
time/datetime.cpp
time/datetimeimmutable.cpp
time/datetimezone.cpp
time/time-functions.cpp
time/time-state.cpp
time/timelib-functions.cpp
Expand Down
44 changes: 44 additions & 0 deletions runtime-light/stdlib/time/dateinterval.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Compiler for PHP (aka KPHP)
// Copyright (c) 2020 LLC «V Kontakte»
// Distributed under the GPL v3 License, see LICENSE.notice.txt

#include "runtime-light/stdlib/time/dateinterval.h"

#include <format>
#include <iterator>

#include "common/containers/final_action.h"
#include "runtime-common/core/allocator/script-allocator.h"
#include "runtime-common/core/runtime-core.h"
#include "runtime-light/stdlib/diagnostics/exception-functions.h"
#include "runtime-light/stdlib/diagnostics/logs.h"

class_instance<C$DateInterval> f$DateInterval$$__construct(const class_instance<C$DateInterval>& self, const string& duration) noexcept {
auto expected_rel_time{kphp::timelib::parse_interval({duration.c_str(), duration.size()})};
if (!expected_rel_time.has_value()) [[unlikely]] {
string err_msg{"DateInterval::__construct(): "};
format_to(std::back_inserter(err_msg), expected_rel_time.error(), duration.c_str());
THROW_EXCEPTION(kphp::exception::make_throwable<C$Exception>(err_msg));
return {};
}
self->rel_time = std::move(*expected_rel_time);
return self;
}

class_instance<C$DateInterval> f$DateInterval$$createFromDateString(const string& datetime) noexcept {
auto [time, errors]{kphp::timelib::parse_time({datetime.c_str(), datetime.size()})};
if (time == nullptr) [[unlikely]] {
kphp::log::warning("DateInterval::createFromDateString(): Unknown or bad format ({}) {}", datetime.c_str(), errors);
return {};
}
class_instance<C$DateInterval> date_interval;
date_interval.alloc();
date_interval->rel_time = kphp::timelib::clone(time->relative);
return date_interval;
}

string f$DateInterval$$format(const class_instance<C$DateInterval>& self, const string& format) noexcept {
string str;
kphp::timelib::format_to(std::back_inserter(str), {format.c_str(), format.size()}, *self->rel_time);
return str;
}
35 changes: 35 additions & 0 deletions runtime-light/stdlib/time/dateinterval.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Compiler for PHP (aka KPHP)
// Copyright (c) 2022 LLC «V Kontakte»
// Distributed under the GPL v3 License, see LICENSE.notice.txt

#pragma once

#include <cstdint>
#include <string_view>

#include "common/algorithms/hashes.h"
#include "runtime-common/core/class-instance/refcountable-php-classes.h"
#include "runtime-common/core/runtime-core.h"
#include "runtime-common/stdlib/visitors/dummy-visitor-methods.h"
#include "runtime-light/stdlib/time/timelib-functions.h"

struct C$DateInterval : public refcountable_polymorphic_php_classes_virt<>, private DummyVisitorMethods {
using DummyVisitorMethods::accept;

kphp::timelib::rel_time_t rel_time{nullptr};

virtual const char* get_class() const noexcept {
return R"(DateInterval)";
}

virtual int32_t get_hash() const noexcept {
std::string_view name_view{C$DateInterval::get_class()};
return static_cast<int32_t>(vk::murmur_hash<uint32_t>(name_view.data(), name_view.size()));
}
};

class_instance<C$DateInterval> f$DateInterval$$__construct(const class_instance<C$DateInterval>& self, const string& duration) noexcept;

class_instance<C$DateInterval> f$DateInterval$$createFromDateString(const string& datetime) noexcept;

string f$DateInterval$$format(const class_instance<C$DateInterval>& self, const string& format) noexcept;
Loading
Loading