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
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;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the purpose of this change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was added to be able to use std::back_inserter

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";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's the context for strings part of standard library. Let's move this to one specific for time functions

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