Handle half hour timezone offsets in Time2Num().

Otherwise, Time2Num() returns the wrong time for timezones like
Australia/Adelaide. Add a FX_TimeZoneOffsetInMinutes() helper to do
this.

Change-Id: Ieb5dba54efa596824823acefe7b45c244cc6a8b9
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/78751
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fxcrt/cfx_datetime.cpp b/core/fxcrt/cfx_datetime.cpp
index fcf9eb0..b1cbcc7 100644
--- a/core/fxcrt/cfx_datetime.cpp
+++ b/core/fxcrt/cfx_datetime.cpp
@@ -97,6 +97,10 @@
   return ((iYear % 4) == 0 && (iYear % 100) != 0) || (iYear % 400) == 0;
 }
 
+int FX_TimeZoneOffsetInMinutes(const FX_TIMEZONE& tz) {
+  return tz.tzHour * 60 + tz.tzMinute;
+}
+
 // static
 CFX_DateTime CFX_DateTime::Now() {
   FXUT_SYSTEMTIME utLocal;
diff --git a/core/fxcrt/cfx_datetime.h b/core/fxcrt/cfx_datetime.h
index a965df7..b482ee4 100644
--- a/core/fxcrt/cfx_datetime.h
+++ b/core/fxcrt/cfx_datetime.h
@@ -9,8 +9,14 @@
 
 #include "core/fxcrt/fx_system.h"
 
+struct FX_TIMEZONE {
+  int8_t tzHour;
+  uint8_t tzMinute;
+};
+
 bool FX_IsLeapYear(int32_t iYear);
 uint8_t FX_DaysInMonth(int32_t iYear, uint8_t iMonth);
+int FX_TimeZoneOffsetInMinutes(const FX_TIMEZONE& tz);
 
 class CFX_DateTime {
  public:
@@ -91,9 +97,4 @@
   uint16_t millisecond_;
 };
 
-struct FX_TIMEZONE {
-  int8_t tzHour;
-  uint8_t tzMinute;
-};
-
 #endif  // CORE_FXCRT_CFX_DATETIME_H_
diff --git a/fxjs/xfa/cfxjse_formcalc_context.cpp b/fxjs/xfa/cfxjse_formcalc_context.cpp
index 395275b..7dbca37 100644
--- a/fxjs/xfa/cfxjse_formcalc_context.cpp
+++ b/fxjs/xfa/cfxjse_formcalc_context.cpp
@@ -12,6 +12,7 @@
 #include <cctype>
 #include <utility>
 
+#include "core/fxcrt/cfx_datetime.h"
 #include "core/fxcrt/cfx_widetextbuf.h"
 #include "core/fxcrt/fx_extension.h"
 #include "core/fxcrt/fx_random.h"
@@ -2485,7 +2486,8 @@
 
   constexpr int kMinutesInDay = 24 * 60;
   int32_t minutes_with_tz =
-      hour * 60 + minute - (CXFA_TimeZoneProvider().GetTimeZone().tzHour * 60);
+      hour * 60 + minute -
+      FX_TimeZoneOffsetInMinutes(CXFA_TimeZoneProvider().GetTimeZone());
   minutes_with_tz %= kMinutesInDay;
   if (minutes_with_tz < 0)
     minutes_with_tz += kMinutesInDay;