Move Non-JS date functions to fx_date_helpers.cpp

These will never re-enter JS, so remove the JS prefix from the
name to indicate they are "safe" from this issue. A subsequent
CL will allow fuzzing without having to boot up V8. Add fxjs
namespace and using to prevent the possibility of link-time
collisions with these new (not all that unique) names.

Change-Id: I09ae077bc74011e953cf6e278399ffbce8fb6673
Reviewed-on: https://pdfium-review.googlesource.com/c/45090
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/fxjs/BUILD.gn b/fxjs/BUILD.gn
index e937126..32c435f 100644
--- a/fxjs/BUILD.gn
+++ b/fxjs/BUILD.gn
@@ -92,6 +92,8 @@
       "cjs_util.h",
       "cjs_zoomtype.cpp",
       "cjs_zoomtype.h",
+      "fx_date_helpers.cpp",
+      "fx_date_helpers.h",
       "global_timer.cpp",
       "global_timer.h",
       "js_define.cpp",
diff --git a/fxjs/cjs_publicmethods.cpp b/fxjs/cjs_publicmethods.cpp
index 261e464..b7790be 100644
--- a/fxjs/cjs_publicmethods.cpp
+++ b/fxjs/cjs_publicmethods.cpp
@@ -30,6 +30,7 @@
 #include "fxjs/cjs_object.h"
 #include "fxjs/cjs_runtime.h"
 #include "fxjs/cjs_util.h"
+#include "fxjs/fx_date_helpers.h"
 #include "fxjs/js_define.h"
 #include "fxjs/js_resources.h"
 
@@ -414,14 +415,13 @@
 
 double CJS_PublicMethods::ParseDate(const WideString& value,
                                     bool* bWrongFormat) {
-  double dt = JS_GetDateTime();
-
-  int nYear = JS_GetYearFromTime(dt);
-  int nMonth = JS_GetMonthFromTime(dt) + 1;
-  int nDay = JS_GetDayFromTime(dt);
-  int nHour = JS_GetHourFromTime(dt);
-  int nMin = JS_GetMinFromTime(dt);
-  int nSec = JS_GetSecFromTime(dt);
+  double dt = FX_GetDateTime();
+  int nYear = FX_GetYearFromTime(dt);
+  int nMonth = FX_GetMonthFromTime(dt) + 1;
+  int nDay = FX_GetDayFromTime(dt);
+  int nHour = FX_GetHourFromTime(dt);
+  int nMin = FX_GetMinFromTime(dt);
+  int nSec = FX_GetSecFromTime(dt);
 
   int number[3];
 
@@ -493,17 +493,17 @@
 double CJS_PublicMethods::ParseDateUsingFormat(const WideString& value,
                                                const WideString& format,
                                                bool* bWrongFormat) {
-  double dt = JS_GetDateTime();
+  double dt = FX_GetDateTime();
 
   if (format.IsEmpty() || value.IsEmpty())
     return dt;
 
-  int nYear = JS_GetYearFromTime(dt);
-  int nMonth = JS_GetMonthFromTime(dt) + 1;
-  int nDay = JS_GetDayFromTime(dt);
-  int nHour = JS_GetHourFromTime(dt);
-  int nMin = JS_GetMinFromTime(dt);
-  int nSec = JS_GetSecFromTime(dt);
+  int nYear = FX_GetYearFromTime(dt);
+  int nMonth = FX_GetMonthFromTime(dt) + 1;
+  int nDay = FX_GetDayFromTime(dt);
+  int nHour = FX_GetHourFromTime(dt);
+  int nMin = FX_GetMinFromTime(dt);
+  int nSec = FX_GetSecFromTime(dt);
 
   int nYearSub = 99;  // nYear - 2000;
 
@@ -738,8 +738,8 @@
   if (bBadFormat) {
     dRet = ParseDate(value, &bBadFormat);
   } else {
-    dRet = JS_MakeDate(JS_MakeDay(nYear, nMonth - 1, nDay),
-                       JS_MakeTime(nHour, nMin, nSec, 0));
+    dRet = FX_MakeDate(FX_MakeDay(nYear, nMonth - 1, nDay),
+                       FX_MakeTime(nHour, nMin, nSec, 0));
     if (std::isnan(dRet))
       dRet = JS_DateParse(value);
   }
@@ -758,12 +758,12 @@
   WideString sRet;
   WideString sPart;
 
-  int nYear = JS_GetYearFromTime(dDate);
-  int nMonth = JS_GetMonthFromTime(dDate) + 1;
-  int nDay = JS_GetDayFromTime(dDate);
-  int nHour = JS_GetHourFromTime(dDate);
-  int nMin = JS_GetMinFromTime(dDate);
-  int nSec = JS_GetSecFromTime(dDate);
+  int nYear = FX_GetYearFromTime(dDate);
+  int nMonth = FX_GetMonthFromTime(dDate) + 1;
+  int nDay = FX_GetDayFromTime(dDate);
+  int nHour = FX_GetHourFromTime(dDate);
+  int nMin = FX_GetMinFromTime(dDate);
+  int nSec = FX_GetSecFromTime(dDate);
 
   size_t i = 0;
   while (i < format.GetLength()) {
@@ -1236,8 +1236,8 @@
   int nMin = FX_atof(wsArray[4].AsStringView());
   int nSec = FX_atof(wsArray[5].AsStringView());
   int nYear = FX_atof(wsArray[7].AsStringView());
-  double dRet = JS_MakeDate(JS_MakeDay(nYear, nMonth - 1, nDay),
-                            JS_MakeTime(nHour, nMin, nSec, 0));
+  double dRet = FX_MakeDate(FX_MakeDay(nYear, nMonth - 1, nDay),
+                            FX_MakeTime(nHour, nMin, nSec, 0));
   if (std::isnan(dRet))
     dRet = JS_DateParse(strValue);
 
diff --git a/fxjs/cjs_util.cpp b/fxjs/cjs_util.cpp
index 2e77732..b30c535 100644
--- a/fxjs/cjs_util.cpp
+++ b/fxjs/cjs_util.cpp
@@ -20,6 +20,7 @@
 #include "fxjs/cjs_object.h"
 #include "fxjs/cjs_publicmethods.h"
 #include "fxjs/cjs_runtime.h"
+#include "fxjs/fx_date_helpers.h"
 #include "fxjs/js_define.h"
 #include "fxjs/js_resources.h"
 
@@ -169,13 +170,13 @@
   if (v8_date.IsEmpty() || std::isnan(pRuntime->ToDouble(v8_date)))
     return CJS_Result::Failure(JSMessage::kSecondParamInvalidDateError);
 
-  double date = JS_LocalTime(pRuntime->ToDouble(v8_date));
-  int year = JS_GetYearFromTime(date);
-  int month = JS_GetMonthFromTime(date) + 1;  // One-based.
-  int day = JS_GetDayFromTime(date);
-  int hour = JS_GetHourFromTime(date);
-  int min = JS_GetMinFromTime(date);
-  int sec = JS_GetSecFromTime(date);
+  double date = FX_LocalTime(pRuntime->ToDouble(v8_date));
+  int year = FX_GetYearFromTime(date);
+  int month = FX_GetMonthFromTime(date) + 1;  // One-based.
+  int day = FX_GetDayFromTime(date);
+  int hour = FX_GetHourFromTime(date);
+  int min = FX_GetMinFromTime(date);
+  int sec = FX_GetSecFromTime(date);
 
   if (params[0]->IsNumber()) {
     WideString swResult;
@@ -368,7 +369,7 @@
 
   WideString sFormat = pRuntime->ToWideString(params[0]);
   WideString sDate = pRuntime->ToWideString(params[1]);
-  double dDate = JS_GetDateTime();
+  double dDate = FX_GetDateTime();
   if (sDate.GetLength() > 0)
     dDate = CJS_PublicMethods::ParseDateUsingFormat(sDate, sFormat, nullptr);
   if (std::isnan(dDate))
diff --git a/fxjs/fx_date_helpers.cpp b/fxjs/fx_date_helpers.cpp
new file mode 100644
index 0000000..dbcdcf7
--- /dev/null
+++ b/fxjs/fx_date_helpers.cpp
@@ -0,0 +1,234 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "fxjs/fx_date_helpers.h"
+
+#include <time.h>
+
+#include "core/fxcrt/fx_extension.h"
+#include "core/fxcrt/fx_system.h"
+#include "fpdfsdk/cpdfsdk_helpers.h"
+
+namespace fxjs {
+namespace {
+
+constexpr uint16_t daysMonth[12] = {0,   31,  59,  90,  120, 151,
+                                    181, 212, 243, 273, 304, 334};
+constexpr uint16_t leapDaysMonth[12] = {0,   31,  60,  91,  121, 152,
+                                        182, 213, 244, 274, 305, 335};
+
+double Mod(double x, double y) {
+  double r = fmod(x, y);
+  if (r < 0)
+    r += y;
+  return r;
+}
+
+double GetLocalTZA() {
+  if (!FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
+    return 0;
+  time_t t = 0;
+  FXSYS_time(&t);
+  FXSYS_localtime(&t);
+#if _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
+  // In gcc 'timezone' is a global variable declared in time.h. In VC++, that
+  // variable was removed in VC++ 2015, with _get_timezone replacing it.
+  long timezone = 0;
+  _get_timezone(&timezone);
+#endif  // _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
+  return (double)(-(timezone * 1000));
+}
+
+int GetDaylightSavingTA(double d) {
+  if (!FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
+    return 0;
+  time_t t = (time_t)(d / 1000);
+  struct tm* tmp = FXSYS_localtime(&t);
+  if (!tmp)
+    return 0;
+  if (tmp->tm_isdst > 0)
+    // One hour.
+    return (int)60 * 60 * 1000;
+  return 0;
+}
+
+bool IsLeapYear(int year) {
+  return (year % 4 == 0) && ((year % 100 != 0) || (year % 400 != 0));
+}
+
+int DayFromYear(int y) {
+  return (int)(365 * (y - 1970.0) + floor((y - 1969.0) / 4) -
+               floor((y - 1901.0) / 100) + floor((y - 1601.0) / 400));
+}
+
+double TimeFromYear(int y) {
+  return 86400000.0 * DayFromYear(y);
+}
+
+double TimeFromYearMonth(int y, int m) {
+  const uint16_t* pMonth = IsLeapYear(y) ? leapDaysMonth : daysMonth;
+  return TimeFromYear(y) + ((double)pMonth[m]) * 86400000;
+}
+
+int Day(double t) {
+  return static_cast<int>(floor(t / 86400000.0));
+}
+
+int YearFromTime(double t) {
+  // estimate the time.
+  int y = 1970 + static_cast<int>(t / (365.2425 * 86400000.0));
+  if (TimeFromYear(y) <= t) {
+    while (TimeFromYear(y + 1) <= t)
+      y++;
+  } else {
+    while (TimeFromYear(y) > t)
+      y--;
+  }
+  return y;
+}
+
+int DayWithinYear(double t) {
+  int year = YearFromTime(t);
+  int day = Day(t);
+  return day - DayFromYear(year);
+}
+
+int MonthFromTime(double t) {
+  int day = DayWithinYear(t);
+  int year = YearFromTime(t);
+  if (0 <= day && day < 31)
+    return 0;
+  if (31 <= day && day < 59 + IsLeapYear(year))
+    return 1;
+  if ((59 + IsLeapYear(year)) <= day && day < (90 + IsLeapYear(year)))
+    return 2;
+  if ((90 + IsLeapYear(year)) <= day && day < (120 + IsLeapYear(year)))
+    return 3;
+  if ((120 + IsLeapYear(year)) <= day && day < (151 + IsLeapYear(year)))
+    return 4;
+  if ((151 + IsLeapYear(year)) <= day && day < (181 + IsLeapYear(year)))
+    return 5;
+  if ((181 + IsLeapYear(year)) <= day && day < (212 + IsLeapYear(year)))
+    return 6;
+  if ((212 + IsLeapYear(year)) <= day && day < (243 + IsLeapYear(year)))
+    return 7;
+  if ((243 + IsLeapYear(year)) <= day && day < (273 + IsLeapYear(year)))
+    return 8;
+  if ((273 + IsLeapYear(year)) <= day && day < (304 + IsLeapYear(year)))
+    return 9;
+  if ((304 + IsLeapYear(year)) <= day && day < (334 + IsLeapYear(year)))
+    return 10;
+  if ((334 + IsLeapYear(year)) <= day && day < (365 + IsLeapYear(year)))
+    return 11;
+
+  return -1;
+}
+
+int DateFromTime(double t) {
+  int day = DayWithinYear(t);
+  int year = YearFromTime(t);
+  int leap = IsLeapYear(year);
+  int month = MonthFromTime(t);
+  switch (month) {
+    case 0:
+      return day + 1;
+    case 1:
+      return day - 30;
+    case 2:
+      return day - 58 - leap;
+    case 3:
+      return day - 89 - leap;
+    case 4:
+      return day - 119 - leap;
+    case 5:
+      return day - 150 - leap;
+    case 6:
+      return day - 180 - leap;
+    case 7:
+      return day - 211 - leap;
+    case 8:
+      return day - 242 - leap;
+    case 9:
+      return day - 272 - leap;
+    case 10:
+      return day - 303 - leap;
+    case 11:
+      return day - 333 - leap;
+    default:
+      return 0;
+  }
+}
+
+}  // namespace
+
+double FX_GetDateTime() {
+  if (!FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
+    return 0;
+
+  time_t t = FXSYS_time(nullptr);
+  struct tm* pTm = FXSYS_localtime(&t);
+  double t1 = TimeFromYear(pTm->tm_year + 1900);
+  return t1 + pTm->tm_yday * 86400000.0 + pTm->tm_hour * 3600000.0 +
+         pTm->tm_min * 60000.0 + pTm->tm_sec * 1000.0;
+}
+
+int FX_GetYearFromTime(double dt) {
+  return YearFromTime(dt);
+}
+
+int FX_GetMonthFromTime(double dt) {
+  return MonthFromTime(dt);
+}
+
+int FX_GetDayFromTime(double dt) {
+  return DateFromTime(dt);
+}
+
+int FX_GetHourFromTime(double dt) {
+  return (int)Mod(floor(dt / (60 * 60 * 1000)), 24);
+}
+
+int FX_GetMinFromTime(double dt) {
+  return (int)Mod(floor(dt / (60 * 1000)), 60);
+}
+
+int FX_GetSecFromTime(double dt) {
+  return (int)Mod(floor(dt / 1000), 60);
+}
+
+double FX_LocalTime(double d) {
+  return d + GetLocalTZA() + GetDaylightSavingTA(d);
+}
+
+double FX_MakeDay(int nYear, int nMonth, int nDate) {
+  double y = static_cast<double>(nYear);
+  double m = static_cast<double>(nMonth);
+  double dt = static_cast<double>(nDate);
+  double ym = y + floor(m / 12);
+  double mn = Mod(m, 12);
+  double t = TimeFromYearMonth(static_cast<int>(ym), static_cast<int>(mn));
+  if (YearFromTime(t) != ym || MonthFromTime(t) != mn || DateFromTime(t) != 1)
+    return std::nan("");
+
+  return Day(t) + dt - 1;
+}
+
+double FX_MakeTime(int nHour, int nMin, int nSec, int nMs) {
+  double h = static_cast<double>(nHour);
+  double m = static_cast<double>(nMin);
+  double s = static_cast<double>(nSec);
+  double milli = static_cast<double>(nMs);
+  return h * 3600000 + m * 60000 + s * 1000 + milli;
+}
+
+double FX_MakeDate(double day, double time) {
+  if (!std::isfinite(day) || !std::isfinite(time))
+    return std::nan("");
+
+  return day * 86400000 + time;
+}
+
+}  // namespace fxjs
diff --git a/fxjs/fx_date_helpers.h b/fxjs/fx_date_helpers.h
new file mode 100644
index 0000000..dbcc94a
--- /dev/null
+++ b/fxjs/fx_date_helpers.h
@@ -0,0 +1,38 @@
+// Copyright 2018 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FXJS_FX_DATE_HELPERS_H_
+#define FXJS_FX_DATE_HELPERS_H_
+
+namespace fxjs {
+
+double FX_GetDateTime();
+int FX_GetYearFromTime(double dt);
+int FX_GetMonthFromTime(double dt);
+int FX_GetDayFromTime(double dt);
+int FX_GetHourFromTime(double dt);
+int FX_GetMinFromTime(double dt);
+int FX_GetSecFromTime(double dt);
+double FX_LocalTime(double d);
+double FX_MakeDay(int nYear, int nMonth, int nDay);
+double FX_MakeTime(int nHour, int nMin, int nSec, int nMs);
+double FX_MakeDate(double day, double time);
+
+}  // namespace fxjs
+
+using fxjs::FX_GetDateTime;
+using fxjs::FX_GetYearFromTime;
+using fxjs::FX_GetMonthFromTime;
+using fxjs::FX_GetDayFromTime;
+using fxjs::FX_GetHourFromTime;
+using fxjs::FX_GetMinFromTime;
+using fxjs::FX_GetSecFromTime;
+using fxjs::FX_LocalTime;
+using fxjs::FX_MakeDay;
+using fxjs::FX_MakeTime;
+using fxjs::FX_MakeDate;
+
+#endif  // FXJS_FX_DATE_HELPERS_H_
diff --git a/fxjs/js_define.cpp b/fxjs/js_define.cpp
index b4e0197..6089132 100644
--- a/fxjs/js_define.cpp
+++ b/fxjs/js_define.cpp
@@ -6,8 +6,6 @@
 
 #include "fxjs/js_define.h"
 
-#include <time.h>
-
 #include <algorithm>
 #include <cmath>
 #include <limits>
@@ -16,201 +14,12 @@
 #include "core/fxcrt/fx_extension.h"
 #include "fxjs/cjs_document.h"
 #include "fxjs/cjs_object.h"
-
-namespace {
-
-double GetLocalTZA() {
-  if (!FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
-    return 0;
-  time_t t = 0;
-  FXSYS_time(&t);
-  FXSYS_localtime(&t);
-#if _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
-  // In gcc 'timezone' is a global variable declared in time.h. In VC++, that
-  // variable was removed in VC++ 2015, with _get_timezone replacing it.
-  long timezone = 0;
-  _get_timezone(&timezone);
-#endif  // _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
-  return (double)(-(timezone * 1000));
-}
-
-int GetDaylightSavingTA(double d) {
-  if (!FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
-    return 0;
-  time_t t = (time_t)(d / 1000);
-  struct tm* tmp = FXSYS_localtime(&t);
-  if (!tmp)
-    return 0;
-  if (tmp->tm_isdst > 0)
-    // One hour.
-    return (int)60 * 60 * 1000;
-  return 0;
-}
-
-double Mod(double x, double y) {
-  double r = fmod(x, y);
-  if (r < 0)
-    r += y;
-  return r;
-}
-
-bool IsLeapYear(int year) {
-  return (year % 4 == 0) && ((year % 100 != 0) || (year % 400 != 0));
-}
-
-int DayFromYear(int y) {
-  return (int)(365 * (y - 1970.0) + floor((y - 1969.0) / 4) -
-               floor((y - 1901.0) / 100) + floor((y - 1601.0) / 400));
-}
-
-double TimeFromYear(int y) {
-  return 86400000.0 * DayFromYear(y);
-}
-
-static const uint16_t daysMonth[12] = {0,   31,  59,  90,  120, 151,
-                                       181, 212, 243, 273, 304, 334};
-static const uint16_t leapDaysMonth[12] = {0,   31,  60,  91,  121, 152,
-                                           182, 213, 244, 274, 305, 335};
-
-double TimeFromYearMonth(int y, int m) {
-  const uint16_t* pMonth = IsLeapYear(y) ? leapDaysMonth : daysMonth;
-  return TimeFromYear(y) + ((double)pMonth[m]) * 86400000;
-}
-
-int Day(double t) {
-  return static_cast<int>(floor(t / 86400000.0));
-}
-
-int YearFromTime(double t) {
-  // estimate the time.
-  int y = 1970 + static_cast<int>(t / (365.2425 * 86400000.0));
-  if (TimeFromYear(y) <= t) {
-    while (TimeFromYear(y + 1) <= t)
-      y++;
-  } else {
-    while (TimeFromYear(y) > t)
-      y--;
-  }
-  return y;
-}
-
-int DayWithinYear(double t) {
-  int year = YearFromTime(t);
-  int day = Day(t);
-  return day - DayFromYear(year);
-}
-
-int MonthFromTime(double t) {
-  int day = DayWithinYear(t);
-  int year = YearFromTime(t);
-  if (0 <= day && day < 31)
-    return 0;
-  if (31 <= day && day < 59 + IsLeapYear(year))
-    return 1;
-  if ((59 + IsLeapYear(year)) <= day && day < (90 + IsLeapYear(year)))
-    return 2;
-  if ((90 + IsLeapYear(year)) <= day && day < (120 + IsLeapYear(year)))
-    return 3;
-  if ((120 + IsLeapYear(year)) <= day && day < (151 + IsLeapYear(year)))
-    return 4;
-  if ((151 + IsLeapYear(year)) <= day && day < (181 + IsLeapYear(year)))
-    return 5;
-  if ((181 + IsLeapYear(year)) <= day && day < (212 + IsLeapYear(year)))
-    return 6;
-  if ((212 + IsLeapYear(year)) <= day && day < (243 + IsLeapYear(year)))
-    return 7;
-  if ((243 + IsLeapYear(year)) <= day && day < (273 + IsLeapYear(year)))
-    return 8;
-  if ((273 + IsLeapYear(year)) <= day && day < (304 + IsLeapYear(year)))
-    return 9;
-  if ((304 + IsLeapYear(year)) <= day && day < (334 + IsLeapYear(year)))
-    return 10;
-  if ((334 + IsLeapYear(year)) <= day && day < (365 + IsLeapYear(year)))
-    return 11;
-
-  return -1;
-}
-
-int DateFromTime(double t) {
-  int day = DayWithinYear(t);
-  int year = YearFromTime(t);
-  int leap = IsLeapYear(year);
-  int month = MonthFromTime(t);
-  switch (month) {
-    case 0:
-      return day + 1;
-    case 1:
-      return day - 30;
-    case 2:
-      return day - 58 - leap;
-    case 3:
-      return day - 89 - leap;
-    case 4:
-      return day - 119 - leap;
-    case 5:
-      return day - 150 - leap;
-    case 6:
-      return day - 180 - leap;
-    case 7:
-      return day - 211 - leap;
-    case 8:
-      return day - 242 - leap;
-    case 9:
-      return day - 272 - leap;
-    case 10:
-      return day - 303 - leap;
-    case 11:
-      return day - 333 - leap;
-    default:
-      return 0;
-  }
-}
-
-}  // namespace
+#include "fxjs/fx_date_helpers.h"
 
 void JSDestructor(v8::Local<v8::Object> obj) {
   CFXJS_Engine::SetObjectPrivate(obj, nullptr);
 }
 
-double JS_GetDateTime() {
-  if (!FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
-    return 0;
-
-  time_t t = FXSYS_time(nullptr);
-  struct tm* pTm = FXSYS_localtime(&t);
-  double t1 = TimeFromYear(pTm->tm_year + 1900);
-  return t1 + pTm->tm_yday * 86400000.0 + pTm->tm_hour * 3600000.0 +
-         pTm->tm_min * 60000.0 + pTm->tm_sec * 1000.0;
-}
-
-int JS_GetYearFromTime(double dt) {
-  return YearFromTime(dt);
-}
-
-int JS_GetMonthFromTime(double dt) {
-  return MonthFromTime(dt);
-}
-
-int JS_GetDayFromTime(double dt) {
-  return DateFromTime(dt);
-}
-
-int JS_GetHourFromTime(double dt) {
-  return (int)Mod(floor(dt / (60 * 60 * 1000)), 24);
-}
-
-int JS_GetMinFromTime(double dt) {
-  return (int)Mod(floor(dt / (60 * 1000)), 60);
-}
-
-int JS_GetSecFromTime(double dt) {
-  return (int)Mod(floor(dt / 1000), 60);
-}
-
-double JS_LocalTime(double d) {
-  return d + GetLocalTZA() + GetDaylightSavingTA(d);
-}
-
 double JS_DateParse(const WideString& str) {
   v8::Isolate* pIsolate = v8::Isolate::GetCurrent();
   v8::Isolate::Scope isolate_scope(pIsolate);
@@ -245,41 +54,13 @@
         double date = v->ToNumber(context).ToLocalChecked()->Value();
         if (!std::isfinite(date))
           return date;
-        return JS_LocalTime(date);
+        return FX_LocalTime(date);
       }
     }
   }
   return 0;
 }
 
-double JS_MakeDay(int nYear, int nMonth, int nDate) {
-  double y = static_cast<double>(nYear);
-  double m = static_cast<double>(nMonth);
-  double dt = static_cast<double>(nDate);
-  double ym = y + floor(m / 12);
-  double mn = Mod(m, 12);
-  double t = TimeFromYearMonth(static_cast<int>(ym), static_cast<int>(mn));
-  if (YearFromTime(t) != ym || MonthFromTime(t) != mn || DateFromTime(t) != 1)
-    return std::nan("");
-
-  return Day(t) + dt - 1;
-}
-
-double JS_MakeTime(int nHour, int nMin, int nSec, int nMs) {
-  double h = static_cast<double>(nHour);
-  double m = static_cast<double>(nMin);
-  double s = static_cast<double>(nSec);
-  double milli = static_cast<double>(nMs);
-  return h * 3600000 + m * 60000 + s * 1000 + milli;
-}
-
-double JS_MakeDate(double day, double time) {
-  if (!std::isfinite(day) || !std::isfinite(time))
-    return std::nan("");
-
-  return day * 86400000 + time;
-}
-
 std::vector<v8::Local<v8::Value>> ExpandKeywordParams(
     CJS_Runtime* pRuntime,
     const std::vector<v8::Local<v8::Value>>& originals,
diff --git a/fxjs/js_define.h b/fxjs/js_define.h
index 0705dfe..2c15c9f 100644
--- a/fxjs/js_define.h
+++ b/fxjs/js_define.h
@@ -18,18 +18,7 @@
 
 class CJS_Object;
 
-double JS_GetDateTime();
-int JS_GetYearFromTime(double dt);
-int JS_GetMonthFromTime(double dt);
-int JS_GetDayFromTime(double dt);
-int JS_GetHourFromTime(double dt);
-int JS_GetMinFromTime(double dt);
-int JS_GetSecFromTime(double dt);
-double JS_LocalTime(double d);
 double JS_DateParse(const WideString& str);
-double JS_MakeDay(int nYear, int nMonth, int nDay);
-double JS_MakeTime(int nHour, int nMin, int nSec, int nMs);
-double JS_MakeDate(double day, double time);
 
 // Some JS methods have the bizarre convention that they may also be called
 // with a single argument which is an object containing the actual arguments