Skip to content

Commit 30c68b0

Browse files
committed
DOS date & time
1 parent 95a3af3 commit 30c68b0

1 file changed

Lines changed: 76 additions & 1 deletion

File tree

lib/source/pl/lib/std/time.cpp

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
namespace pl::lib::libstd::time {
1414

15+
const std::string s_invalid = "Invalid";
1516
const std::string s_canNotFormat = "Can not format";
1617

1718
static u128 packTMValue(const std::tm &tm, pl::PatternLanguage &runtime) {
@@ -113,7 +114,7 @@ namespace pl::lib::libstd::time {
113114
return { fmt::format(fmt::runtime(fmt::format("{{:{}}}", formatString)), time) };
114115
});
115116

116-
/* format_tt_locale(time_t) */
117+
/* format_tt(time_t) */
117118
runtime.addFunction(nsStdTime, "format_tt", FunctionParameterCount::exactly(1), [&runtime](Evaluator *, auto params) -> std::optional<Token::Literal> {
118119
auto tt = params[0].toUnsigned();
119120
const wolv::util::Locale &lc = runtime.getLocale();
@@ -126,6 +127,80 @@ namespace pl::lib::libstd::time {
126127

127128
return optval;
128129
});
130+
131+
/* format_dos_date(time_t) */
132+
runtime.addFunction(nsStdTime, "format_dos_date", FunctionParameterCount::exactly(1), [&runtime](Evaluator *, auto params) -> std::optional<Token::Literal> {
133+
auto p = params[0].toUnsigned();
134+
135+
struct DOSDate {
136+
unsigned day : 5;
137+
unsigned month : 4;
138+
unsigned year : 7;
139+
};
140+
141+
DOSDate dd;
142+
std::memcpy(&dd, &p, sizeof(dd));
143+
if ( (dd.day<1 || dd.day>31) || (dd.month<1 || dd.month>12) ) {
144+
return s_invalid;
145+
}
146+
147+
std::tm tm{};
148+
tm.tm_year = dd.year + 80;
149+
tm.tm_mon = dd.month - 1;
150+
tm.tm_mday = dd.day;
151+
152+
#if defined(OS_WINDOWS)
153+
time_t tt = _mkgmtime(&tm);
154+
#else
155+
time_t tt = timegm(&tm);
156+
#endif
157+
if (tt == -1) {
158+
return s_canNotFormat;
159+
}
160+
161+
const wolv::util::Locale &lc = runtime.getLocale();
162+
163+
using wolv::util::DTOpts;
164+
auto optval = wolv::util::formatTT(lc, tt, DTOpts::TT64 | DTOpts::D | DTOpts::LongDate);
165+
if (!optval) {
166+
return s_canNotFormat;
167+
}
168+
169+
return *optval;
170+
});
171+
172+
/* format_dos_time(time_t) */
173+
runtime.addFunction(nsStdTime, "format_dos_time", FunctionParameterCount::exactly(1), [&runtime](Evaluator *, auto params) -> std::optional<Token::Literal> {
174+
auto p = params[0].toUnsigned();
175+
176+
struct DOSTime {
177+
unsigned seconds : 5;
178+
unsigned minutes : 6;
179+
unsigned hours : 5;
180+
};
181+
182+
DOSTime dt;
183+
std::memcpy(&dt, &p, sizeof(dt));
184+
185+
if ( (dt.hours<0 || dt.hours>23) ||
186+
(dt.minutes<0 || dt.minutes>59) ||
187+
(dt.seconds<0 && dt.seconds>29) )
188+
{
189+
return s_invalid;
190+
}
191+
192+
time_t tt = dt.hours*60*60 + dt.minutes*60 + dt.seconds*2;
193+
194+
const wolv::util::Locale &lc = runtime.getLocale();
195+
196+
using wolv::util::DTOpts;
197+
auto optval = wolv::util::formatTT(lc, tt, DTOpts::TT64 | DTOpts::T);
198+
if (!optval) {
199+
return s_canNotFormat;
200+
}
201+
202+
return *optval;
203+
});
129204
}
130205
}
131206

0 commit comments

Comments
 (0)