• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ArkScript-lang / Ark / 27200108521

09 Jun 2026 10:29AM UTC coverage: 94.343% (+0.03%) from 94.31%
27200108521

Pull #692

github

web-flow
Merge 3a42b1d0b into 54225fe55
Pull Request #692: feat(builtins): add two new builtins to manipulate dates

87 of 88 new or added lines in 2 files covered. (98.86%)

10239 of 10853 relevant lines covered (94.34%)

925991.29 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.65
/src/arkreactor/Builtins/Time.cpp
1
#include <Ark/Builtins/Builtins.hpp>
2

3
#include <Ark/VM/DefaultValues.hpp>
4
#include <Ark/VM/Value/Dict.hpp>
5
#include <Ark/TypeChecker.hpp>
6

7
#undef abs
8
#include <chrono>
9

10
#include <newlib/gmtime_r.h>
11

12
namespace Ark::internal::Builtins::Time
13
{
14
    /**
15
     * @name time
16
     * @brief Return the time of the computer since epoch, in seconds, with at least milliseconds precision
17
     * =begin
18
     * (time)  # 1627134107.837558031082153
19
     * =end
20
     * @author https://github.com/SuperFola
21
     */
22
    // cppcheck-suppress constParameterReference
23
    Value timeSinceEpoch(std::vector<Value>& n [[maybe_unused]], VM* vm [[maybe_unused]])
76✔
24
    {
76✔
25
        const auto now = std::chrono::system_clock::now();
76✔
26
        const auto epoch = now.time_since_epoch();
76✔
27
        const auto microseconds = std::chrono::duration_cast<std::chrono::microseconds>(epoch);
76✔
28
        return Value(static_cast<double>(microseconds.count()) / 1000000);
76✔
29
    }
76✔
30

31
    Value timestampToDate(std::vector<Value>& n, VM* vm [[maybe_unused]])
121✔
32
    {
121✔
33
        if (!types::check(n, ValueType::Number))
121✔
34
            throw types::TypeCheckingError(
2✔
35
                "asUTCDate",
1✔
36
                { { types::Contract {
2✔
37
                    { types::Typedef("timestamp", ValueType::Number) } } } },
1✔
38
                n);
1✔
39

40
        nl_tm calendar_time {};
120✔
41
        nl_gmtime_r(static_cast<long long>(n[0].number()), &calendar_time);
120✔
42

43
        int week = calendar_time.tm_wday;
120✔
44
        if (week == 0)  // Sunday
120✔
45
            week = 6;
8✔
46
        else
47
            --week;  // 0-5: Monday-Saturday
112✔
48

49
        internal::Dict dict;
120✔
50
        const double ms = n[0].number() - static_cast<double>(static_cast<long long>(n[0].number()));
120✔
51

52
        dict.set(Value("millisecond"), Value(static_cast<int>(1000.0 * ms)));
120✔
53
        dict.set(Value("second"), Value(calendar_time.tm_sec));
120✔
54
        dict.set(Value("minute"), Value(calendar_time.tm_min));
120✔
55
        dict.set(Value("hour"), Value(calendar_time.tm_hour));
120✔
56
        dict.set(Value("day"), Value(calendar_time.tm_mday));
120✔
57
        dict.set(Value("month"), Value(calendar_time.tm_mon + 1));
120✔
58
        dict.set(Value("year"), Value(calendar_time.tm_year + 1900));
120✔
59
        dict.set(Value("week_day"), Value(week));
120✔
60
        dict.set(Value("year_day"), Value(calendar_time.tm_yday));
120✔
61
        dict.set(Value("is_dst"), calendar_time.tm_isdst ? True : False);
120✔
62

63
        return Value(std::move(dict));
120✔
64
    }
121✔
65

66
    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)
8✔
67
    {
8✔
68
        constexpr int MonthsPerYear = 12;
8✔
69
        static const std::array<int, MonthsPerYear> cumulative_days = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
70

71
        const long year = 1900 + tm_year + tm_mon / MonthsPerYear;
8✔
72
        int64_t result = (year - 1970) * 365 + cumulative_days[static_cast<std::size_t>(tm_mon % MonthsPerYear)];
8✔
73
        result += (year - 1968) / 4;
8✔
74
        result -= (year - 1900) / 100;
8✔
75
        result += (year - 1600) / 400;
8✔
76
        if ((year % 4) == 0 &&
12✔
77
            ((year % 100) != 0 || (year % 400) == 0) &&
4✔
78
            (tm_mon % MonthsPerYear) < 2)
4✔
79
            result--;
4✔
80
        result += tm_mday - 1;
8✔
81
        result *= 24;
8✔
82
        result += tm_hour;
8✔
83
        result *= 60;
8✔
84
        result += tm_min;
8✔
85
        result *= 60;
8✔
86
        result += tm_sec;
8✔
87
        return result;
16✔
88
    }
8✔
89

90
    Value parseDate(std::vector<Value>& n, VM* vm [[maybe_unused]])
10✔
91
    {
10✔
92
        if (!types::check(n, ValueType::String) && !types::check(n, ValueType::String, ValueType::String))
10✔
93
            throw types::TypeCheckingError(
4✔
94
                "parseDate",
2✔
95
                { { types::Contract {
6✔
96
                        { types::Typedef("date", ValueType::String) } },
2✔
97
                    types::Contract {
2✔
98
                        { types::Typedef("date", ValueType::String),
4✔
99
                          types::Typedef("format", ValueType::String) } } } },
2✔
100
                n);
2✔
101

102
        std::tm t = {};
8✔
103
        std::istringstream ss(n[0].string());
8✔
104
        ss >> std::get_time(&t, n.size() == 1 ? "%Y-%m-%dT%H:%M:%S" : n[1].string().c_str());
8✔
105

106
        if (ss.fail())
8✔
NEW
107
            return Nil;
×
108
        return Value(makeTimestamp(t.tm_sec, t.tm_min, t.tm_hour, t.tm_mday, t.tm_mon, t.tm_year));
8✔
109
    }
10✔
110
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc