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.
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;
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.
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;
}
}
+ 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
//
internal int era;
internal DateTimeParse.TM timeMark;
internal double fraction;
+ internal bool hasSameDateAndTimeSeparators;
//
// <