summaryrefslogtreecommitdiff
path: root/xfa/fgas/crt
diff options
context:
space:
mode:
Diffstat (limited to 'xfa/fgas/crt')
-rw-r--r--xfa/fgas/crt/cfgas_formatstring.cpp27
-rw-r--r--xfa/fgas/crt/cfgas_formatstring_unittest.cpp122
2 files changed, 96 insertions, 53 deletions
diff --git a/xfa/fgas/crt/cfgas_formatstring.cpp b/xfa/fgas/crt/cfgas_formatstring.cpp
index 58e4c9562e..22e9325df2 100644
--- a/xfa/fgas/crt/cfgas_formatstring.cpp
+++ b/xfa/fgas/crt/cfgas_formatstring.cpp
@@ -448,9 +448,9 @@ bool ParseLocaleTime(const CFX_WideString& wsTime,
dwSymbol == FXBSTR_ID(0, 0, 'H', '1') ||
dwSymbol == FXBSTR_ID(0, 0, 'h', '1') ||
dwSymbol == FXBSTR_ID(0, 0, 'K', '1')) {
- if (!FXSYS_isDecimalDigit(str[cc])) {
+ if (!FXSYS_isDecimalDigit(str[cc]))
return false;
- }
+
hour = str[cc++] - '0';
if (cc < len && FXSYS_isDecimalDigit(str[cc]))
hour = hour * 10 + str[cc++] - '0';
@@ -871,7 +871,7 @@ bool TimeFormat(const CFX_WideString& wsTimePattern,
}
} else if (dwSymbol == FXBSTR_ID(0, 0, 'z', '1')) {
FX_TIMEZONE tz = pLocale->GetTimeZone();
- if (tz.tzHour != 0 && tz.tzMinute != 0) {
+ if (tz.tzHour != 0 || tz.tzMinute != 0) {
wsResult += tz.tzHour < 0 ? L"-" : L"+";
CFX_WideString wsTimezone;
@@ -996,6 +996,7 @@ bool FX_TimeFromCanonical(const CFX_WideStringC& wsTime,
hour = hour * 10 + str[cc++] - '0';
}
+
if (cc < 2 || hour >= 24)
return false;
if (cc < len) {
@@ -1042,6 +1043,23 @@ bool FX_TimeFromCanonical(const CFX_WideStringC& wsTime,
}
}
+ while (cc < len) {
+ // Skip until we find a + or - for the time zone.
+ if (str[cc] != '+' && str[cc] != '-') {
+ ++cc;
+ continue;
+ }
+
+ FX_TIMEZONE tzDiff;
+ tzDiff.tzHour = 0;
+ tzDiff.tzMinute = 0;
+ if (str[cc] != 'Z')
+ cc += ParseTimeZone(str + cc, len - cc, &tzDiff);
+
+ ResolveZone(hour, minute, tzDiff, pLocale);
+ break;
+ }
+
if (cc < len) {
FX_TIMEZONE tzDiff;
tzDiff.tzHour = 0;
@@ -1992,7 +2010,8 @@ bool CFGAS_FormatString::ParseDateTime(const CFX_WideString& wsSrcDateTime,
if (wsSrcDateTime.IsEmpty() || wsPattern.IsEmpty())
return false;
- CFX_WideString wsDatePattern, wsTimePattern;
+ CFX_WideString wsDatePattern;
+ CFX_WideString wsTimePattern;
IFX_Locale* pLocale = nullptr;
FX_DATETIMETYPE eCategory =
GetDateTimeFormat(wsPattern, pLocale, wsDatePattern, wsTimePattern);
diff --git a/xfa/fgas/crt/cfgas_formatstring_unittest.cpp b/xfa/fgas/crt/cfgas_formatstring_unittest.cpp
index e26c523a33..9a5239d7e4 100644
--- a/xfa/fgas/crt/cfgas_formatstring_unittest.cpp
+++ b/xfa/fgas/crt/cfgas_formatstring_unittest.cpp
@@ -20,13 +20,7 @@
class CFGAS_FormatStringTest : public testing::Test {
public:
CFGAS_FormatStringTest() {
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
- _putenv_s("TZ", "UTC");
- _tzset();
-#else
- setenv("TZ", "UTC", 1);
- tzset();
-#endif
+ SetTZ("UTC");
CPDF_ModuleMgr::Get()->Init();
}
@@ -37,6 +31,16 @@ class CFGAS_FormatStringTest : public testing::Test {
mgr_.reset();
}
+ void SetTZ(const char* tz) {
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
+ _putenv_s("TZ", tz);
+ _tzset();
+#else
+ setenv("TZ", tz, 1);
+ tzset();
+#endif
+ }
+
// Note, this re-creates the fmt on each call. If you need to multiple
// times store it locally.
CFGAS_FormatString* fmt(const CFX_WideString& locale) {
@@ -93,24 +97,10 @@ TEST_F(CFGAS_FormatStringTest, DateFormat) {
// {L"ja", L"2003-11-03", L"gY/M/D", L"H15/11/3"},
// {L"ja", L"1989-01-08", L"ggY-M-D", L"\u5e731-1-8"},
// {L"ja", L"1989-11-03", L"gggYY/MM/DD", L"\u5e73\u621089/11/03"},
-
- // Full width D == U+FF24
- // I don't actually know what ideograpic numeric value for 25 is.
- // {L"ja", L"2002-20-25", L"\uff24\uff24\uff24", L" .... "},
- // {L"ja", L"2002-20-25", L"\uff24\uff24\uff24\uff24", L" ... "},
- // Full width M == U+FF2D
- // {L"ja", L"2002-20-25", L"\uff2d\uff2d\uff2d", L" ... "},
- // {L"ja", L"2002-20-25", L"\uff2d\uff2d\uff2d\uff2d", L" ... "},
- // Full width E == U+FF25
- // {L"ja", L"2002-20-25", L"\uff25", L" ... "},
- // Full width e == U+FF45
- // {L"ja", L"2002-20-25", L"\uff45", L" ... "},
- // Full width g == U+FF47
- // {L"ja", L"1989-01-08", L"\uff47\uff47YY/MM/DD", L"\u337b89/01/08"}
- // Full width Y == U+FF39
- // {L"ja", L"2002-20-25", L"\uff39\uff39\uff39", L" ... "},
- // {L"ja", L"2002-20-25", L"\uff39\uff39\uff39\uff39\uff39", L" ... "}
};
+ // Note, none of the full width date symbols are listed here
+ // as they are not supported. In theory there are the full width versions
+ // of DDD, DDDD, MMM, MMMM, E, e, gg, YYY, YYYYY.
for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
CFX_WideString result;
@@ -127,11 +117,35 @@ TEST_F(CFGAS_FormatStringTest, TimeFormat) {
const wchar_t* input;
const wchar_t* pattern;
const wchar_t* output;
- } tests[] = {{L"en", L"11:11:11", L"h:MM A", L"11:11 AM"},
+ } tests[] = {{L"en", L"01:01:11", L"h:M A", L"1:1 AM"},
+ {L"en", L"01:01:11", L"hh:MM:SS A", L"01:01:11 AM"},
+ {L"en", L"01:01:11", L"hh:MM:SS A Z", L"01:01:11 AM GMT-02:00"},
+ {L"en", L"01:01:11", L"hh:MM:SS A z", L"01:01:11 AM -02:00"},
+ // {L"en", L"01:01:11", L"hh:MM:SS A zz", L"01:01:11 AM GMT"},
+ // Should change ?*+ into ' ' when formatting.
+ // {L"en", L"01:01:11", L"hh:MM:SS?*+A", L"01:01:11 AM"},
+ {L"en", L"12:01:01", L"k:MM:SS", L"12:01:01"},
+ {L"en", L"12:01:11", L"kk:MM", L"12:01"},
+ {L"en", L"12:01:11 +04:30", L"kk:MM", L"05:31"},
+ {L"en", L"12:01:11", L"kk:MM A", L"12:01 PM"},
+ {L"en", L"00:01:01", L"H:M:S", L"0:1:1"},
+ {L"en", L"13:02:11", L"H:M:S", L"13:2:11"},
+ {L"en", L"00:01:11.001", L"HH:M:S.FFF", L"00:1:11.001"},
+ {L"en", L"13:02:11", L"HH:M", L"13:2"},
+ {L"en", L"00:01:11", L"K:M", L"24:1"},
+ {L"en", L"00:02:11", L"KK:M", L"24:2"},
{L"en", L"11:11:11", L"HH:MM:SS 'o''clock' A Z",
- L"11:11:11 o'clock AM GMT"},
+ L"11:11:11 o'clock AM GMT-02:00"},
{L"en", L"14:30:59", L"h:MM A", L"2:30 PM"},
- {L"en", L"14:30:59", L"HH:MM:SS A Z", L"14:30:59 PM GMT"}};
+ {L"en", L"14:30:59", L"HH:MM:SS A Z", L"14:30:59 PM GMT-02:00"}};
+ // Note, none of the full width time symbols are listed here
+ // as they are not supported. In theory there are the full
+ // width versions of kkk, kkkk, HHH, HHHH, KKK, KKKK, MMM, MMMM,
+ // SSS, SSSS plus 2 more that the spec apparently forgot to
+ // list the symbol.
+
+ // The z modifier only appends if the TZ is outside of +0
+ SetTZ("UTC+2");
for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
CFX_WideString result;
@@ -140,6 +154,8 @@ TEST_F(CFGAS_FormatStringTest, TimeFormat) {
FX_DATETIMETYPE_Time));
EXPECT_STREQ(tests[i].output, result.c_str()) << " TEST: " << i;
}
+
+ SetTZ("UTC");
}
TEST_F(CFGAS_FormatStringTest, DateTimeFormat) {
@@ -191,29 +207,10 @@ TEST_F(CFGAS_FormatStringTest, DateParse) {
// CFX_DateTime(1989, 11, 3, 0, 0, 0, 0)},
// {L"ja", L"u337b99/01/08", L"\u0067\u0067YY/MM/DD",
// CFX_DateTime(1999, 1, 8, 0, 0, 0, 0)}
- // Full width D == U+FF24
- // I don't actually know what ideograpic numeric value for 25 is.
- // {L"ja", L"...", L"\uff24\uff24\uff24",
- // CFX_DateTime(2002, 20, 25, 0, 0, 0, 0)},
- // {L"ja", L"...", L"\uff24\uff24\uff24\uff24",
- // CFX_DateTime(2002, 20, 25, 0, 0, 0, 0)},
- // Full width M == U+FF2D
- // {L"ja", L"...", L"\uff2d\uff2d\uff2d",
- // CFX_DateTime(2002, 20, 25, 0, 0, 0, 0)},
- // {L"ja", L"...", L"\uff2d\uff2d\uff2d\uff2d",
- // CFX_DateTime(2002, 20, 25, 0, 0, 0, 0)},
- // Full width E == U+FF25
- // {L"ja", L"...", L"\uff25", CFX_DateTime(2002, 20, 25, 0, 0, 0, 0)},
- // Full width e == U+FF45
- // {L"ja", L"...", L"\uff45", CFX_DateTime(2002, 20, 25, 0, 0, 0, 0)},
- // Full width g == U+FF47
- // {L"ja", L"1989-01-08", L"\uff47\uff47YY/MM/DD", L"\u337b89/01/08"}
- // Full width Y == U+FF39
- // {L"ja", L"...", L"\uff39\uff39\uff39",
- // CFX_DateTime(2002, 20, 25, 0, 0, 0, 0)},
- // {L"ja", L"...", L"\uff39\uff39\uff39\uff39\uff39",
- // CFX_DateTime(2002, 20, 25, 0, 0, 0, 0)}
};
+ // Note, none of the full width date symbols are listed here as they are
+ // not supported. In theory there are the full width versions of DDD,
+ // DDDD, MMM, MMMM, E, e, gg, YYY, YYYYY.
for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
CFX_DateTime result;
@@ -224,6 +221,33 @@ TEST_F(CFGAS_FormatStringTest, DateParse) {
}
}
+// TODO(dsinclair): GetDateTimeFormat is broken and doesn't allow just returning
+// a parsed Time. It will assume it's a Date. The method needs to be re-written.
+// TEST_F(CFGAS_FormatStringTest, TimeParse) {
+// struct {
+// const wchar_t* locale;
+// const wchar_t* input;
+// const wchar_t* pattern;
+// CFX_DateTime output;
+// } tests[] = {
+// {L"en", L"18:00", L"HH:MM", CFX_DateTime(0, 0, 0, 18, 0, 0, 0)},
+// {L"en", L"12.59 Uhr", L"H.MM 'Uhr'", CFX_DateTime(0, 0, 0, 12, 59, 0,
+// 0)}, {L"en", L"1:05:10 PM PST", L"h:MM:SS A Z",
+// CFX_DateTime(0, 0, 0, 17, 05, 10, 0)}};
+// // Note, none of the full width date symbols are listed here as they are
+// // not supported. In theory there are the full width versions of kkk,
+// // kkkk, HHH, HHHH, KKK, KKKK, MMM, MMMM, SSS, SSSS plus 2 more that the
+// // spec apparently forgot to list the symbol.
+
+// for (size_t i = 0; i < FX_ArraySize(tests); ++i) {
+// CFX_DateTime result;
+// EXPECT_TRUE(fmt(tests[i].locale)
+// ->ParseDateTime(tests[i].input, tests[i].pattern,
+// FX_DATETIMETYPE_Time, &result));
+// EXPECT_EQ(tests[i].output, result) << " TEST: " << i;
+// }
+// }
+
TEST_F(CFGAS_FormatStringTest, SplitFormatString) {
std::vector<CFX_WideString> results;
fmt(L"en")->SplitFormatString(