summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTarek Mahmoud Sayed <tarekms@microsoft.com>2015-08-12 12:50:14 -0700
committerTarek Mahmoud Sayed <tarekms@microsoft.com>2015-08-12 12:50:14 -0700
commit64451083d5bb7204aa6ea46f04c7d0faaf40a260 (patch)
tree0b3fe8e24bbb169c1972ede421981363a1284a69 /src
parent42cf2d9a2a97a796a5a6c1080e56f15ee648234a (diff)
downloadcoreclr-64451083d5bb7204aa6ea46f04c7d0faaf40a260.tar.gz
coreclr-64451083d5bb7204aa6ea46f04c7d0faaf40a260.tar.bz2
coreclr-64451083d5bb7204aa6ea46f04c7d0faaf40a260.zip
Port the DateTime parser fix from the Desktop
This change is fixing the DateTime parser in cases of date/time strings for cultures which has the date and time separators are same. This happen with Norway, Serbia and Finland cultures [tfs-changeset: 1513801]
Diffstat (limited to 'src')
-rw-r--r--src/mscorlib/src/System/Globalization/DateTimeParse.cs56
1 files changed, 56 insertions, 0 deletions
diff --git a/src/mscorlib/src/System/Globalization/DateTimeParse.cs b/src/mscorlib/src/System/Globalization/DateTimeParse.cs
index bbece12b4f..2c644a9043 100644
--- a/src/mscorlib/src/System/Globalization/DateTimeParse.cs
+++ b/src/mscorlib/src/System/Globalization/DateTimeParse.cs
@@ -691,6 +691,18 @@ new DS[] { DS.ERROR, DS.TX_NNN, DS.TX_NNN, DS.TX_NNN, DS.ERROR, DS.ERROR,
case TokenType.SEP_Date:
dtok.dtt = DTT.YearDateSep;
break;
+ case TokenType.SEP_Time:
+ if (!raw.hasSameDateAndTimeSeparators)
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ LexTraceExit("0040 (Invalid separator after number)", dps);
+ return false;
+ }
+
+ // we have the date and time separators are same and getting a year number, then change the token to YearDateSep as
+ // we are sure we are not parsing time.
+ dtok.dtt = DTT.YearDateSep;
+ break;
case TokenType.SEP_DateOrOffset:
// The separator is either a date separator or the start of a time zone offset. If the token will complete the date then
// process just the number and roll back the index so that the outer loop can attempt to parse the time zone offset.
@@ -796,6 +808,14 @@ new DS[] { DS.ERROR, DS.TX_NNN, DS.TX_NNN, DS.TX_NNN, DS.ERROR, DS.ERROR,
raw.AddNumber(dtok.num);
break;
case TokenType.SEP_Time:
+ if (raw.hasSameDateAndTimeSeparators &&
+ (dps == DS.D_Y || dps == DS.D_YN || dps == DS.D_YNd || dps == DS.D_YM || dps == DS.D_YMd))
+ {
+ // we are parsing a date and we have the time separator same as date separator, so we mark the token as date separator
+ dtok.dtt = DTT.NumDatesep;
+ raw.AddNumber(dtok.num);
+ break;
+ }
dtok.dtt = DTT.NumTimesep;
raw.AddNumber(dtok.num);
break;
@@ -941,6 +961,18 @@ new DS[] { DS.ERROR, DS.TX_NNN, DS.TX_NNN, DS.TX_NNN, DS.ERROR, DS.ERROR,
case TokenType.SEP_Date:
dtok.dtt = DTT.MonthDatesep;
break;
+ case TokenType.SEP_Time:
+ if (!raw.hasSameDateAndTimeSeparators)
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ LexTraceExit("0130 (Invalid separator after month name)", dps);
+ return false;
+ }
+
+ // we have the date and time separators are same and getting a Month name, then change the token to MonthDatesep as
+ // we are sure we are not parsing time.
+ dtok.dtt = DTT.MonthDatesep;
+ break;
case TokenType.SEP_DateOrOffset:
// The separator is either a date separator or the start of a time zone offset. If the token will complete the date then
// process just the number and roll back the index so that the outer loop can attempt to parse the time zone offset.
@@ -2315,6 +2347,8 @@ new DS[] { DS.ERROR, DS.TX_NNN, DS.TX_NNN, DS.TX_NNN, DS.ERROR, DS.ERROR,
Int32 * numberPointer = stackalloc Int32[3];
raw.Init(numberPointer);
}
+ raw.hasSameDateAndTimeSeparators = dtfi.DateSeparator.Equals(dtfi.TimeSeparator, StringComparison.Ordinal);
+
result.calendar = dtfi.Calendar;
result.era = Calendar.CurrentEra;
@@ -2376,6 +2410,27 @@ new DS[] { DS.ERROR, DS.TX_NNN, DS.TX_NNN, DS.TX_NNN, DS.ERROR, DS.ERROR,
}
}
+ if (raw.hasSameDateAndTimeSeparators && (dtok.dtt == DTT.YearEnd || dtok.dtt == DTT.YearSpace || dtok.dtt == DTT.YearDateSep))
+ {
+ // When time and date separators are same and we are hitting a year number while the first parsed part of the string was recognized
+ // as part of time (and not a date) DS.T_Nt, DS.T_NNt then change the state to be a date so we try to parse it as a date instead
+ if (dps == DS.T_Nt)
+ {
+ dps = DS.D_Nd;
+ }
+ if (dps == DS.T_NNt)
+ {
+ dps = DS.D_NNd;
+
+ // we have the case of Serbia have dates in forms 'd.M.yyyy.' so we can expect '.' after the year number.
+ // changing the token to YearSpace instead of YearDateSep will make the parsing not failing this case.
+ if (dtok.dtt == DTT.YearDateSep)
+ {
+ dtok.dtt = DTT.YearSpace;
+ }
+ }
+ }
+
//
// Advance to the next state, and continue
//
@@ -4812,6 +4867,7 @@ Start:
internal int era;
internal DateTimeParse.TM timeMark;
internal double fraction;
+ internal bool hasSameDateAndTimeSeparators;
//
internal bool timeZone;