7#include "fxjs/fx_date_helpers.h"
15#include "build/build_config.h"
16#include "core/fxcrt/fx_extension.h"
17#include "core/fxcrt/fx_system.h"
18#include "fpdfsdk/cpdfsdk_helpers.h"
23constexpr uint16_t daysMonth[12] = {0, 31, 59, 90, 120, 151,
24 181, 212, 243, 273, 304, 334};
25constexpr uint16_t leapDaysMonth[12] = {0, 31, 60, 91, 121, 152,
26 182, 213, 244, 274, 305, 335};
28double Mod(
double x,
double y) {
29 double r = fmod(x, y);
45 _get_timezone(&timezone);
47 return (
double)(-(timezone * 1000));
50int GetDaylightSavingTA(
double d) {
53 time_t t = (time_t)(d / 1000);
57 if (tmp->tm_isdst > 0)
59 return (
int)60 * 60 * 1000;
63bool IsLeapYear(
int year) {
64 return (year % 4 == 0) && ((year % 100 != 0) || (year % 400 != 0));
67int DayFromYear(
int y) {
68 return (
int)(365 * (y - 1970.0) + floor((y - 1969.0) / 4) -
69 floor((y - 1901.0) / 100) + floor((y - 1601.0) / 400));
72double TimeFromYear(
int y) {
73 return 86400000.0 * DayFromYear(y);
76double TimeFromYearMonth(
int y,
int m) {
77 const uint16_t* pMonth = IsLeapYear(y) ? leapDaysMonth : daysMonth;
78 return TimeFromYear(y) + ((
double)pMonth[m]) * 86400000;
82 return static_cast<
int>(floor(t / 86400000.0));
85int YearFromTime(
double t) {
87 int y = 1970 +
static_cast<
int>(t / (365.2425 * 86400000.0));
88 if (TimeFromYear(y) <= t) {
89 while (TimeFromYear(y + 1) <= t)
92 while (TimeFromYear(y) > t)
98int DayWithinYear(
double t) {
99 int year = YearFromTime(t);
101 return day - DayFromYear(year);
104int MonthFromTime(
double t) {
106 int day = DayWithinYear(t);
112 if (IsLeapYear(YearFromTime(t)))
116 static constexpr int kCumulativeDaysInMonths[] = {
117 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
118 for (size_t i = 0; i <
std::size(kCumulativeDaysInMonths); ++i) {
119 if (day < kCumulativeDaysInMonths[i])
120 return static_cast<
int>(i) + 1;
126int DateFromTime(
double t) {
127 int day = DayWithinYear(t);
128 int year = YearFromTime(t);
129 int leap = IsLeapYear(year);
130 int month = MonthFromTime(t);
137 return day - 58 - leap;
139 return day - 89 - leap;
141 return day - 119 - leap;
143 return day - 150 - leap;
145 return day - 180 - leap;
147 return day - 211 - leap;
149 return day - 242 - leap;
151 return day - 272 - leap;
153 return day - 303 - leap;
155 return day - 333 - leap;
161size_t FindSubWordLength(
const WideString& str, size_t nStart) {
162 pdfium::span<
const wchar_t> data = str.span();
164 while (i < data.size() && iswalnum(data[i]))
171const wchar_t*
const kMonths[12] = {L"Jan", L"Feb", L"Mar", L"Apr",
172 L"May", L"Jun", L"Jul", L"Aug",
173 L"Sep", L"Oct", L"Nov", L"Dec"};
175const wchar_t*
const kFullMonths[12] = {L"January", L"February", L"March",
176 L"April", L"May", L"June",
177 L"July", L"August", L"September",
178 L"October", L"November", L"December"};
189 double t1 = TimeFromYear(pTm->tm_year + 1900);
190 return t1 + pTm->tm_yday * 86400000.0 + pTm->tm_hour * 3600000.0 +
191 pTm->tm_min * 60000.0 + pTm->tm_sec * 1000.0;
195 return YearFromTime(dt);
199 return MonthFromTime(dt);
203 return DateFromTime(dt);
207 return (
int)Mod(floor(dt / (60 * 60 * 1000)), 24);
211 return (
int)Mod(floor(dt / (60 * 1000)), 60);
215 return (
int)Mod(floor(dt / 1000), 60);
219 return m >= 1 && m <= 12;
224 return d >= 1 && d <= 31;
229 return h >= 0 && h <= 24;
233 return m >= 0 && m <= 60;
237 return s >= 0 && s <= 60;
241 return d + GetLocalTZA() + GetDaylightSavingTA(d);
245 double y =
static_cast<
double>(nYear);
246 double m =
static_cast<
double>(nMonth);
247 double dt =
static_cast<
double>(nDate);
248 double ym = y + floor(m / 12);
249 double mn = Mod(m, 12);
250 double t = TimeFromYearMonth(
static_cast<
int>(ym),
static_cast<
int>(mn));
251 if (YearFromTime(t) != ym || MonthFromTime(t) != mn || DateFromTime(t) != 1)
254 return Day(t) + dt - 1;
258 double h =
static_cast<
double>(nHour);
259 double m =
static_cast<
double>(nMin);
260 double s =
static_cast<
double>(nSec);
261 double milli =
static_cast<
double>(nMs);
262 return h * 3600000 + m * 60000 + s * 1000 + milli;
266 if (!isfinite(day) || !isfinite(time))
269 return day * 86400000 + time;
278 for (size_t i = nStart; i < str.GetLength(); ++i) {
288 if (nSkip >= nMaxStep)
297 const WideString& format,
314 bool bBadFormat =
false;
318 while (i < format.GetLength()) {
322 wchar_t c = format[i];
343 size_t remaining = format.GetLength() - i - 1;
345 if (remaining == 0 || format[i + 1] != c) {
352 nMonth = FX_ParseStringInteger(value, j, &nSkip, 2);
357 nDay = FX_ParseStringInteger(value, j, &nSkip, 2);
362 nHour = FX_ParseStringInteger(value, j, &nSkip, 2);
367 nHour = FX_ParseStringInteger(value, j, &nSkip, 2);
372 nMin = FX_ParseStringInteger(value, j, &nSkip, 2);
377 nSec = FX_ParseStringInteger(value, j, &nSkip, 2);
382 bPm = (j < value.GetLength() && value[j] ==
'p');
387 }
else if (remaining == 1 || format[i + 2] != c) {
390 nYear = FX_ParseStringInteger(value, j, &nSkip, 2);
395 nMonth = FX_ParseStringInteger(value, j, &nSkip, 2);
400 nDay = FX_ParseStringInteger(value, j, &nSkip, 2);
405 nHour = FX_ParseStringInteger(value, j, &nSkip, 2);
410 nHour = FX_ParseStringInteger(value, j, &nSkip, 2);
415 nMin = FX_ParseStringInteger(value, j, &nSkip, 2);
420 nSec = FX_ParseStringInteger(value, j, &nSkip, 2);
425 bPm = (j + 1 < value.GetLength() && value[j] ==
'p' &&
426 value[j + 1] ==
'm');
431 }
else if (remaining == 2 || format[i + 3] != c) {
435 nSkip = FindSubWordLength(value, j);
436 if (nSkip == KMonthAbbreviationLength) {
437 WideString sMonth = value.Substr(j, KMonthAbbreviationLength);
438 for (size_t m = 0; m <
std::size(
kMonths); ++m) {
440 nMonth =
static_cast<
int>(m) + 1;
450 nMonth = FX_ParseStringInteger(value, j, &nSkip, 3);
462 }
else if (remaining == 3 || format[i + 4] != c) {
465 nYear = FX_ParseStringInteger(value, j, &nSkip, 4);
471 nSkip = FindSubWordLength(value, j);
472 if (nSkip <= kLongestFullMonthLength) {
473 WideString sMonth = value.Substr(j, nSkip);
476 WideString sFullMonths = WideString(
kFullMonths[m]);
478 if (sFullMonths.Contains(sMonth.AsStringView())) {
479 nMonth =
static_cast<
int>(m) + 1;
488 nMonth = FX_ParseStringInteger(value, j, &nSkip, 4);
499 if (j >= value.GetLength() || format[i] != value[j]) {
515 if (value.GetLength() <= j) {
517 }
else if (format[i] != value[j]) {
534 if (nYear >= 0 && nYear <= nYearSub)
int CompareNoCase(const wchar_t *str) const
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)
const wchar_t *const kMonths[12]
int FX_ParseStringInteger(const WideString &str, size_t nStart, size_t *pSkip, size_t nMaxStep)
int FX_GetYearFromTime(double dt)
const wchar_t *const kFullMonths[12]
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
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)
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)