Skip to content
Merged
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 builtin-functions/kphp-light/stdlib/time-functions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ function gmdate ($format ::: string, $timestamp ::: int = PHP_INT_MIN) ::: strin
function gmmktime ($h ::: int = PHP_INT_MIN, $m ::: int = PHP_INT_MIN, $s ::: int = PHP_INT_MIN,
$month ::: int = PHP_INT_MIN, $day ::: int = PHP_INT_MIN, $year ::: int = PHP_INT_MIN) ::: int;

function localtime ($timestamp ::: int = PHP_INT_MIN, $is_associative ::: bool = false) ::: mixed[];

function time() ::: int;

function strtotime ($time ::: string, $timestamp ::: int = PHP_INT_MIN) ::: int | false;
Expand Down Expand Up @@ -140,7 +142,5 @@ define('DATE_RFC3339', "Y-m-d\TH:i:sP");
define('DATE_RSS', "D, d M Y H:i:s O");
define('DATE_W3C', "Y-m-d\TH:i:sP");

/** @kphp-extern-func-info stub generation-required */
function localtime ($timestamp ::: int = PHP_INT_MIN, $is_associative ::: bool = false) ::: mixed[];
/** @kphp-extern-func-info stub generation-required */
function strftime ($format ::: string, $timestamp ::: int = PHP_INT_MIN) ::: string;
34 changes: 34 additions & 0 deletions runtime-light/stdlib/time/time-functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,40 @@ inline int64_t f$gmmktime(int64_t hour = std::numeric_limits<int64_t>::min(), in
year != std::numeric_limits<int64_t>::min() ? std::make_optional(kphp::time::impl::fix_year(year)) : std::nullopt);
}

inline array<mixed> f$localtime(int64_t timestamp = std::numeric_limits<int64_t>::min(), bool is_associative = false) noexcept {
if (timestamp == std::numeric_limits<int64_t>::min()) {
namespace chrono = std::chrono;
timestamp = static_cast<int64_t>(chrono::time_point_cast<chrono::seconds>(chrono::system_clock::now()).time_since_epoch().count());
}
tm t{};
time_t time{timestamp};
tm* tp{k2::localtime_r(std::addressof(time), std::addressof(t))};
if (tp == nullptr) {
kphp::log::warning("unknown error in localtime with timestamp {}", timestamp);
std::memset(std::addressof(t), 0, sizeof(tm));
}

if (!is_associative) {
return array<mixed>::create(t.tm_sec, t.tm_min, t.tm_hour, t.tm_mday, t.tm_mon, t.tm_year, t.tm_wday, t.tm_yday, t.tm_isdst);
}

const auto& time_image_state{TimeImageState::get()};

array<mixed> result{array_size{9, false}};

result.set_value(time_image_state.TM_SEC_STR, t.tm_sec);
result.set_value(time_image_state.TM_MIN_STR, t.tm_min);
result.set_value(time_image_state.TM_HOUR_STR, t.tm_hour);
result.set_value(time_image_state.TM_MDAY_STR, t.tm_mday);
result.set_value(time_image_state.TM_MON_STR, t.tm_mon);
result.set_value(time_image_state.TM_YEAR_STR, t.tm_year);
result.set_value(time_image_state.TM_WDAY_STR, t.tm_wday);
result.set_value(time_image_state.TM_YDAY_STR, t.tm_yday);
result.set_value(time_image_state.TM_ISDST_STR, t.tm_isdst);

return result;
}

inline string f$date(const string& format, int64_t timestamp = std::numeric_limits<int64_t>::min()) noexcept {
if (timestamp == std::numeric_limits<int64_t>::min()) {
namespace chrono = std::chrono;
Expand Down
38 changes: 38 additions & 0 deletions runtime-light/stdlib/time/time-state.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
#pragma once

#include <optional>
#include <string_view>

#include "common/mixin/not_copyable.h"
#include "common/php-functions.h"
#include "runtime-common/core/runtime-core.h"
#include "runtime-common/stdlib/time/timelib-constants.h"
#include "runtime-light/core/reference-counter/reference-counter-functions.h"
Expand All @@ -21,6 +23,15 @@ struct TimeImageState final : private vk::not_copyable {
string WARNINGS_STR{WARNINGS_.data(), static_cast<string::size_type>(WARNINGS_.size())};
string ERROR_COUNT_STR{ERROR_COUNT_.data(), static_cast<string::size_type>(ERROR_COUNT_.size())};
string ERRORS_STR{ERRORS_.data(), static_cast<string::size_type>(ERRORS_.size())};
string TM_SEC_STR{TM_SEC_.data(), static_cast<string::size_type>(TM_SEC_.size())};
string TM_MIN_STR{TM_MIN_.data(), static_cast<string::size_type>(TM_MIN_.size())};
string TM_HOUR_STR{TM_HOUR_.data(), static_cast<string::size_type>(TM_HOUR_.size())};
string TM_MDAY_STR{TM_MDAY_.data(), static_cast<string::size_type>(TM_MDAY_.size())};
string TM_MON_STR{TM_MON_.data(), static_cast<string::size_type>(TM_MON_.size())};
string TM_YEAR_STR{TM_YEAR_.data(), static_cast<string::size_type>(TM_YEAR_.size())};
string TM_WDAY_STR{TM_WDAY_.data(), static_cast<string::size_type>(TM_WDAY_.size())};
string TM_YDAY_STR{TM_YDAY_.data(), static_cast<string::size_type>(TM_YDAY_.size())};
string TM_ISDST_STR{TM_ISDST_.data(), static_cast<string::size_type>(TM_ISDST_.size())};

kphp::timelib::timezone_cache timelib_zone_cache{kphp::timelib::timezones::MOSCOW, kphp::timelib::timezones::GMT3};

Expand All @@ -35,6 +46,24 @@ struct TimeImageState final : private vk::not_copyable {
kphp::core::is_reference_counter_recursive(ERROR_COUNT_STR, ExtraRefCnt::for_global_const)));
kphp::log::assertion((kphp::core::set_reference_counter_recursive(ERRORS_STR, ExtraRefCnt::for_global_const),
kphp::core::is_reference_counter_recursive(ERRORS_STR, ExtraRefCnt::for_global_const)));
kphp::log::assertion((kphp::core::set_reference_counter_recursive(TM_SEC_STR, ExtraRefCnt::for_global_const),
kphp::core::is_reference_counter_recursive(TM_SEC_STR, ExtraRefCnt::for_global_const)));
kphp::log::assertion((kphp::core::set_reference_counter_recursive(TM_MIN_STR, ExtraRefCnt::for_global_const),
kphp::core::is_reference_counter_recursive(TM_MIN_STR, ExtraRefCnt::for_global_const)));
kphp::log::assertion((kphp::core::set_reference_counter_recursive(TM_HOUR_STR, ExtraRefCnt::for_global_const),
kphp::core::is_reference_counter_recursive(TM_HOUR_STR, ExtraRefCnt::for_global_const)));
kphp::log::assertion((kphp::core::set_reference_counter_recursive(TM_MDAY_STR, ExtraRefCnt::for_global_const),
kphp::core::is_reference_counter_recursive(TM_MDAY_STR, ExtraRefCnt::for_global_const)));
kphp::log::assertion((kphp::core::set_reference_counter_recursive(TM_MON_STR, ExtraRefCnt::for_global_const),
kphp::core::is_reference_counter_recursive(TM_MON_STR, ExtraRefCnt::for_global_const)));
kphp::log::assertion((kphp::core::set_reference_counter_recursive(TM_YEAR_STR, ExtraRefCnt::for_global_const),
kphp::core::is_reference_counter_recursive(TM_YEAR_STR, ExtraRefCnt::for_global_const)));
kphp::log::assertion((kphp::core::set_reference_counter_recursive(TM_WDAY_STR, ExtraRefCnt::for_global_const),
kphp::core::is_reference_counter_recursive(TM_WDAY_STR, ExtraRefCnt::for_global_const)));
kphp::log::assertion((kphp::core::set_reference_counter_recursive(TM_YDAY_STR, ExtraRefCnt::for_global_const),
kphp::core::is_reference_counter_recursive(TM_YDAY_STR, ExtraRefCnt::for_global_const)));
kphp::log::assertion((kphp::core::set_reference_counter_recursive(TM_ISDST_STR, ExtraRefCnt::for_global_const),
kphp::core::is_reference_counter_recursive(TM_ISDST_STR, ExtraRefCnt::for_global_const)));
}

static const TimeImageState& get() noexcept;
Expand All @@ -46,6 +75,15 @@ struct TimeImageState final : private vk::not_copyable {
static constexpr std::string_view WARNINGS_ = "warnings";
static constexpr std::string_view ERROR_COUNT_ = "error_count";
static constexpr std::string_view ERRORS_ = "errors";
static constexpr std::string_view TM_SEC_ = "tm_sec";
static constexpr std::string_view TM_MIN_ = "tm_min";
static constexpr std::string_view TM_HOUR_ = "tm_hour";
static constexpr std::string_view TM_MDAY_ = "tm_mday";
static constexpr std::string_view TM_MON_ = "tm_mon";
static constexpr std::string_view TM_YEAR_ = "tm_year";
static constexpr std::string_view TM_WDAY_ = "tm_wday";
static constexpr std::string_view TM_YDAY_ = "tm_yday";
static constexpr std::string_view TM_ISDST_ = "tm_isdst";
};

struct TimeInstanceState final : private vk::not_copyable {
Expand Down
17 changes: 17 additions & 0 deletions tests/phpt/dl/484_localtime.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
@ok
<?php

function test() {
$time = 1234567890;//time();

#var_dump (localtime());
var_dump (localtime($time));

#var_dump (localtime(time(), true));
var_dump (localtime($time, true));
}

date_default_timezone_set ("Etc/GMT-3");
test();
date_default_timezone_set ("Europe/Moscow");
test();
6 changes: 0 additions & 6 deletions tests/phpt/dl/484_strftime.php
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,6 @@ function test() {

#var_dump (getdate());
var_dump (getdate($time));

#var_dump (localtime());
var_dump (localtime($time));

#var_dump (localtime(time(), true));
var_dump (localtime($time, true));
}

date_default_timezone_set ("Etc/GMT-3");
Expand Down
Loading