7#include "fxjs/fx_date_helpers.h"
16#include "build/build_config.h"
17#include "core/fxcrt/fx_extension.h"
18#include "core/fxcrt/fx_system.h"
19#include "fpdfsdk/cpdfsdk_helpers.h"
24constexpr std::array<uint16_t, 12> kDaysMonth = {
25 {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}};
27constexpr std::array<uint16_t, 12> kLeapDaysMonth = {
28 {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335}};
30double Mod(
double x,
double y) {
31 double r = fmod(x, y);
47 _get_timezone(&timezone);
52int GetDaylightSavingTA(
double d) {
55 time_t t = (time_t)(d / 1000);
59 if (tmp->tm_isdst > 0)
61 return (
int)60 * 60 * 1000;
65bool IsLeapYear(
int year) {
66 return (year % 4 == 0) && ((year % 100 != 0) || (year % 400 != 0));
69int DayFromYear(
int y) {
70 return (
int)(365 * (y - 1970.0) + floor((y - 1969.0) / 4) -
71 floor((y - 1901.0) / 100) + floor((y - 1601.0) / 400));
74double TimeFromYear(
int y) {
75 return 86400000.0 * DayFromYear(y);
78double TimeFromYearMonth(
int y,
int m) {
79 const uint16_t month = IsLeapYear(y) ? kLeapDaysMonth[m] : kDaysMonth[m];
80 return TimeFromYear(y) +
static_cast<
double>(month) * 86400000;
84 return static_cast<
int>(floor(t / 86400000.0));
87int YearFromTime(
double t) {
89 int y = 1970 +
static_cast<
int>(t / (365.2425 * 86400000.0));
90 if (TimeFromYear(y) <= t) {
91 while (TimeFromYear(y + 1) <= t)
94 while (TimeFromYear(y) > t)
100int DayWithinYear(
double t) {
101 int year = YearFromTime(t);
103 return day - DayFromYear(year);
106int MonthFromTime(
double t) {
108 int day = DayWithinYear(t);
114 if (IsLeapYear(YearFromTime(t)))
118 static constexpr std::array<
int, 11> kCumulativeDaysInMonths = {
119 {59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365}};
120 for (size_t i = 0; i <
std::size(kCumulativeDaysInMonths); ++i) {
121 if (day < kCumulativeDaysInMonths[i])
122 return static_cast<
int>(i) + 1;
128int DateFromTime(
double t) {
129 int day = DayWithinYear(t);
130 int year = YearFromTime(t);
131 int leap = IsLeapYear(year);
132 int month = MonthFromTime(t);
139 return day - 58 - leap;
141 return day - 89 - leap;
143 return day - 119 - leap;
145 return day - 150 - leap;
147 return day - 180 - leap;
149 return day - 211 - leap;
151 return day - 242 - leap;
153 return day - 272 - leap;
155 return day - 303 - leap;
157 return day - 333 - leap;
163size_t FindSubWordLength(
const WideString& str, size_t nStart) {
164 pdfium::span<
const wchar_t> data = str.span();
166 while (i < data.size() && iswalnum(data[i]))
173const std::array<
const char*, 12>
kMonths = {{
"Jan",
"Feb",
"Mar",
"Apr",
"May",
174 "Jun",
"Jul",
"Aug",
"Sep",
"Oct",
178 {
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
179 "September",
"October",
"November",
"December"}};
190 double t1 = TimeFromYear(pTm->tm_year + 1900);
191 return t1 + pTm->tm_yday * 86400000.0 + pTm->tm_hour * 3600000.0 +
192 pTm->tm_min * 60000.0 + pTm->tm_sec * 1000.0;
196 return YearFromTime(dt);
200 return MonthFromTime(dt);
204 return DateFromTime(dt);
208 return (
int)Mod(floor(dt / (60 * 60 * 1000)), 24);
212 return (
int)Mod(floor(dt / (60 * 1000)), 60);
216 return (
int)Mod(floor(dt / 1000), 60);
220 return m >= 1 && m <= 12;
225 return d >= 1 && d <= 31;
230 return h >= 0 && h <= 24;
234 return m >= 0 && m <= 60;
238 return s >= 0 && s <= 60;
242 return d + GetLocalTZA() + GetDaylightSavingTA(d);
246 double y =
static_cast<
double>(nYear);
247 double m =
static_cast<
double>(nMonth);
248 double dt =
static_cast<
double>(nDate);
249 double ym = y + floor(m / 12);
250 double mn = Mod(m, 12);
251 double t = TimeFromYearMonth(
static_cast<
int>(ym),
static_cast<
int>(mn));
252 if (YearFromTime(t) != ym || MonthFromTime(t) != mn || DateFromTime(t) != 1)
255 return Day(t) + dt - 1;
259 double h =
static_cast<
double>(nHour);
260 double m =
static_cast<
double>(nMin);
261 double s =
static_cast<
double>(nSec);
262 double milli =
static_cast<
double>(nMs);
263 return h * 3600000 + m * 60000 + s * 1000 + milli;
267 if (!isfinite(day) || !isfinite(time))
270 return day * 86400000 + time;
279 for (size_t i = nStart; i < str.GetLength(); ++i) {
289 if (nSkip >= nMaxStep)
301 if (format.IsEmpty() || value.IsEmpty()) {
315 bool bBadFormat =
false;
319 while (i < format.GetLength()) {
323 wchar_t c = format[i];
344 size_t remaining = format.GetLength() - i - 1;
346 if (remaining == 0 || format[i + 1] != c) {
353 nMonth = FX_ParseStringInteger(value, j, &nSkip, 2);
358 nDay = FX_ParseStringInteger(value, j, &nSkip, 2);
363 nHour = FX_ParseStringInteger(value, j, &nSkip, 2);
368 nHour = FX_ParseStringInteger(value, j, &nSkip, 2);
373 nMin = FX_ParseStringInteger(value, j, &nSkip, 2);
378 nSec = FX_ParseStringInteger(value, j, &nSkip, 2);
383 bPm = (j < value.GetLength() && value[j] ==
'p');
388 }
else if (remaining == 1 || format[i + 2] != c) {
391 nYear = FX_ParseStringInteger(value, j, &nSkip, 2);
396 nMonth = FX_ParseStringInteger(value, j, &nSkip, 2);
401 nDay = FX_ParseStringInteger(value, j, &nSkip, 2);
406 nHour = FX_ParseStringInteger(value, j, &nSkip, 2);
411 nHour = FX_ParseStringInteger(value, j, &nSkip, 2);
416 nMin = FX_ParseStringInteger(value, j, &nSkip, 2);
421 nSec = FX_ParseStringInteger(value, j, &nSkip, 2);
426 bPm = (j + 1 < value.GetLength() && value[j] ==
'p' &&
427 value[j + 1] ==
'm');
432 }
else if (remaining == 2 || format[i + 3] != c) {
436 nSkip = FindSubWordLength(value, j);
437 if (nSkip == KMonthAbbreviationLength) {
438 WideString sMonth = value.Substr(j, KMonthAbbreviationLength);
439 for (size_t m = 0; m <
std::size(kMonths); ++m) {
441 nMonth =
static_cast<
int>(m) + 1;
451 nMonth = FX_ParseStringInteger(value, j, &nSkip, 3);
463 }
else if (remaining == 3 || format[i + 4] != c) {
466 nYear = FX_ParseStringInteger(value, j, &nSkip, 4);
472 nSkip = FindSubWordLength(value, j);
473 if (nSkip <= kLongestFullMonthLength) {
476 for (size_t m = 0; m <
std::size(kFullMonths); ++m) {
478 sFullMonths.MakeLower();
479 if (sFullMonths.Contains(sMonth.AsStringView())) {
480 nMonth =
static_cast<
int>(m) + 1;
489 nMonth = FX_ParseStringInteger(value, j, &nSkip, 4);
500 if (j >= value.GetLength() || format[i] != value[j]) {
516 if (value.GetLength() <= j) {
518 }
else if (format[i] != value[j]) {
535 if (nYear >= 0 && nYear <= nYearSub)
bool EqualsASCIINoCase(ByteStringView that) const
static WideString FromASCII(ByteStringView str)
FPDF_BOOL IsPDFSandboxPolicyEnabled(FPDF_DWORD policy)
#define FPDF_POLICY_MACHINETIME_ACCESS
time_t FXSYS_time(time_t *tloc)
bool FXSYS_IsDecimalDigit(wchar_t c)
int FXSYS_DecimalCharToInt(wchar_t c)
struct tm * FXSYS_localtime(const time_t *tp)
int FX_GetMonthFromTime(double dt)
int FX_ParseStringInteger(const WideString &str, size_t nStart, size_t *pSkip, size_t nMaxStep)
int FX_GetYearFromTime(double dt)
ConversionStatus FX_ParseDateUsingFormat(const WideString &value, const WideString &format, double *result)
double FX_MakeDate(double day, double time)
static constexpr size_t kLongestFullMonthLength
static constexpr size_t KMonthAbbreviationLength
const std::array< const char *, 12 > kMonths
bool FX_IsValidMinute(int m)
int FX_GetDayFromTime(double dt)
int FX_GetSecFromTime(double dt)
bool FX_IsValidMonth(int m)
int FX_GetHourFromTime(double dt)
const std::array< const char *, 12 > kFullMonths
double FX_MakeDay(int nYear, int nMonth, int nDay)
bool FX_IsValidDay(int d)
bool FX_IsValidSecond(int s)
int FX_GetMinFromTime(double dt)
double FX_MakeTime(int nHour, int nMin, int nSec, int nMs)
double FX_LocalTime(double d)
bool FX_IsValid24Hour(int h)
QT_REQUIRE_CONFIG(timezone)
fxcrt::WideString WideString