11#include < Ark/Builtins/Builtins.hpp>
22
3+ #include < Ark/VM/DefaultValues.hpp>
4+ #include < Ark/VM/Value/Dict.hpp>
5+ #include < Ark/TypeChecker.hpp>
6+
37#undef abs
48#include < chrono>
9+ #include < ctime>
510
611#include < Ark/VM/VM.hpp>
712
@@ -15,11 +20,92 @@ namespace Ark::internal::Builtins::Time
1520 * =end
1621 * @author https://github.com/SuperFola
1722 */
23+ // cppcheck-suppress constParameterReference
1824 Value timeSinceEpoch (std::vector<Value>& n [[maybe_unused]] , VM * vm [[maybe_unused]] )
1925 {
2026 const auto now = std::chrono::system_clock::now ();
2127 const auto epoch = now.time_since_epoch ();
2228 const auto microseconds = std::chrono::duration_cast<std::chrono::microseconds>(epoch);
2329 return Value (static_cast <double >(microseconds.count ()) / 1000000 );
2430 }
31+
32+ Value timestampToDate (std::vector<Value>& n, VM * vm [[maybe_unused]] )
33+ {
34+ if (!types::check (n, ValueType::Number, ValueType::Any))
35+ throw types::TypeCheckingError (
36+ " timeToDate" ,
37+ { { types::Contract {
38+ { types::Typedef (" timestamp" , ValueType::Number),
39+ types::Typedef (" utc?" , ValueType::Any) } } } },
40+ n);
41+
42+ const bool is_utc = n[1 ] == True;
43+ const auto timestamp = std::chrono::milliseconds (static_cast <long long >(1000.0 * n[0 ].number ()));
44+ const auto timepoint = std::chrono::time_point<std::chrono::system_clock>(timestamp);
45+ const std::time_t time = std::chrono::system_clock::to_time_t (timepoint);
46+ const std::tm* calendar_time = is_utc ? std::gmtime (&time) : std::localtime (&time);
47+
48+ if (calendar_time != nullptr )
49+ {
50+ internal::Dict dict;
51+ dict.set (Value (" millisecond" ), Value (timestamp.count () % 1000 ));
52+ dict.set (Value (" second" ), Value (calendar_time->tm_sec ));
53+ dict.set (Value (" minute" ), Value (calendar_time->tm_min ));
54+ dict.set (Value (" hour" ), Value (calendar_time->tm_hour ));
55+ dict.set (Value (" day" ), Value (calendar_time->tm_mday ));
56+ dict.set (Value (" month" ), Value (calendar_time->tm_mon + 1 ));
57+ dict.set (Value (" year" ), Value (calendar_time->tm_year + 1900 ));
58+ dict.set (Value (" week_day" ), Value (calendar_time->tm_wday ));
59+ dict.set (Value (" year_day" ), Value (calendar_time->tm_yday ));
60+ dict.set (Value (" is_dst" ), calendar_time->tm_isdst ? True : False);
61+
62+ return Value (std::move (dict));
63+ }
64+ return Nil;
65+ }
66+
67+ int64_t makeTimestamp (const int tm_sec, const int tm_min, const int tm_hour, const int tm_mday, const int tm_mon, const int tm_year)
68+ {
69+ constexpr int MonthsPerYear = 12 ;
70+ static const std::array<int , MonthsPerYear> cumulative_days = { 0 , 31 , 59 , 90 , 120 , 151 , 181 , 212 , 243 , 273 , 304 , 334 };
71+
72+ const long year = 1900 + tm_year + tm_mon / MonthsPerYear;
73+ int64_t result = (year - 1970 ) * 365 + cumulative_days[static_cast <std::size_t >(tm_mon % MonthsPerYear)];
74+ result += (year - 1968 ) / 4 ;
75+ result -= (year - 1900 ) / 100 ;
76+ result += (year - 1600 ) / 400 ;
77+ if ((year % 4 ) == 0 &&
78+ ((year % 100 ) != 0 || (year % 400 ) == 0 ) &&
79+ (tm_mon % MonthsPerYear) < 2 )
80+ result--;
81+ result += tm_mday - 1 ;
82+ result *= 24 ;
83+ result += tm_hour;
84+ result *= 60 ;
85+ result += tm_min;
86+ result *= 60 ;
87+ result += tm_sec;
88+ return result;
89+ }
90+
91+ Value parseDate (std::vector<Value>& n, VM * vm [[maybe_unused]] )
92+ {
93+ if (!types::check (n, ValueType::String) && !types::check (n, ValueType::String, ValueType::String))
94+ throw types::TypeCheckingError (
95+ " parseDate" ,
96+ { { types::Contract {
97+ { types::Typedef (" date" , ValueType::String) } },
98+ types::Contract {
99+ { types::Typedef (" date" , ValueType::String),
100+ types::Typedef (" format" , ValueType::String) } } } },
101+ n);
102+
103+ std::tm t = {};
104+ std::istringstream ss (n[0 ].string ());
105+ ss >> std::get_time (&t, n.size () == 1 ? " %Y-%m-%dT%H:%M:%S" : n[1 ].string ().c_str ());
106+
107+ if (ss.fail ())
108+ return Nil;
109+ return Value (makeTimestamp (t.tm_sec , t.tm_min , t.tm_hour , t.tm_mday , t.tm_mon , t.tm_year ));
110+ }
25111}
0 commit comments