-Added support for 24 hour ISO dates

This commit is contained in:
James Newton-King
2015-11-23 20:15:37 +13:00
parent 7903b4b2e2
commit 331fcc0ebb
4 changed files with 60 additions and 7 deletions
@@ -70,6 +70,32 @@ namespace Newtonsoft.Json.Tests.Utilities
Assert.AreEqual(value, parsedDt); Assert.AreEqual(value, parsedDt);
} }
[Test]
public void Parse24HourDateTime()
{
DateTime dt;
Assert.IsTrue(DateTimeUtils.TryParseDateTimeIso(CreateStringReference("2000-12-15T24:00:00Z"), DateTimeZoneHandling.RoundtripKind, out dt));
Assert.AreEqual(new DateTime(2000, 12, 16, 0, 0, 0, DateTimeKind.Utc), dt);
Assert.IsFalse(DateTimeUtils.TryParseDateTimeIso(CreateStringReference("2000-12-15T24:01:00Z"), DateTimeZoneHandling.RoundtripKind, out dt));
Assert.IsFalse(DateTimeUtils.TryParseDateTimeIso(CreateStringReference("2000-12-15T24:00:01Z"), DateTimeZoneHandling.RoundtripKind, out dt));
Assert.IsFalse(DateTimeUtils.TryParseDateTimeIso(CreateStringReference("2000-12-15T24:00:00.0000001Z"), DateTimeZoneHandling.RoundtripKind, out dt));
}
#if !NET20
[Test]
public void Parse24HourDateTimeOffset()
{
DateTimeOffset dt;
Assert.IsTrue(DateTimeUtils.TryParseDateTimeOffsetIso(CreateStringReference("2000-12-15T24:00:00Z"), out dt));
Assert.AreEqual(new DateTimeOffset(2000, 12, 16, 0, 0, 0, TimeSpan.Zero), dt);
Assert.IsFalse(DateTimeUtils.TryParseDateTimeOffsetIso(CreateStringReference("2000-12-15T24:01:00Z"), out dt));
Assert.IsFalse(DateTimeUtils.TryParseDateTimeOffsetIso(CreateStringReference("2000-12-15T24:00:01Z"), out dt));
Assert.IsFalse(DateTimeUtils.TryParseDateTimeOffsetIso(CreateStringReference("2000-12-15T24:00:00.0000001Z"), out dt));
}
#endif
[Test] [Test]
public void NewDateTimeParse() public void NewDateTimeParse()
{ {
@@ -138,7 +138,7 @@ namespace Newtonsoft.Json
} }
/// <summary> /// <summary>
/// Gets or sets a collection <see cref="JsonConverter"/> that will be used during serialization. /// Gets or sets a <see cref="JsonConverter"/> collection that will be used during serialization.
/// </summary> /// </summary>
/// <value>The converters.</value> /// <value>The converters.</value>
public IList<JsonConverter> Converters { get; set; } public IList<JsonConverter> Converters { get; set; }
@@ -123,13 +123,14 @@ namespace Newtonsoft.Json.Utilities
private bool ParseTime(ref int start) private bool ParseTime(ref int start)
{ {
if (!(Parse2Digit(start, out Hour) if (!(Parse2Digit(start, out Hour)
&& Hour < 24 && Hour <= 24
&& ParseChar(start + LzHH, ':') && ParseChar(start + LzHH, ':')
&& Parse2Digit(start + LzHH_, out Minute) && Parse2Digit(start + LzHH_, out Minute)
&& Minute < 60 && Minute < 60
&& ParseChar(start + LzHH_mm, ':') && ParseChar(start + LzHH_mm, ':')
&& Parse2Digit(start + LzHH_mm_, out Second) && Parse2Digit(start + LzHH_mm_, out Second)
&& Second < 60)) && Second < 60
&& (Hour != 24 || (Minute == 0 && Second == 0)))) // hour can be 24 if minute/second is zero)
{ {
return false; return false;
} }
@@ -162,6 +163,11 @@ namespace Newtonsoft.Json.Utilities
Fraction *= Power10[MaxFractionDigits - numberOfDigits]; Fraction *= Power10[MaxFractionDigits - numberOfDigits];
} }
if (Hour == 24 && Fraction != 0)
{
return false;
}
} }
return true; return true;
} }
+25 -4
View File
@@ -206,8 +206,7 @@ namespace Newtonsoft.Json.Utilities
return false; return false;
} }
DateTime d = new DateTime(dateTimeParser.Year, dateTimeParser.Month, dateTimeParser.Day, dateTimeParser.Hour, dateTimeParser.Minute, dateTimeParser.Second); DateTime d = CreateDateTime(dateTimeParser);
d = d.AddTicks(dateTimeParser.Fraction);
long ticks; long ticks;
@@ -269,8 +268,7 @@ namespace Newtonsoft.Json.Utilities
return false; return false;
} }
DateTime d = new DateTime(dateTimeParser.Year, dateTimeParser.Month, dateTimeParser.Day, dateTimeParser.Hour, dateTimeParser.Minute, dateTimeParser.Second); DateTime d = CreateDateTime(dateTimeParser);
d = d.AddTicks(dateTimeParser.Fraction);
TimeSpan offset; TimeSpan offset;
@@ -302,6 +300,29 @@ namespace Newtonsoft.Json.Utilities
} }
#endif #endif
private static DateTime CreateDateTime(DateTimeParser dateTimeParser)
{
bool is24Hour;
if (dateTimeParser.Hour == 24)
{
is24Hour = true;
dateTimeParser.Hour = 0;
}
else
{
is24Hour = false;
}
DateTime d = new DateTime(dateTimeParser.Year, dateTimeParser.Month, dateTimeParser.Day, dateTimeParser.Hour, dateTimeParser.Minute, dateTimeParser.Second);
d = d.AddTicks(dateTimeParser.Fraction);
if (is24Hour)
{
d = d.AddDays(1);
}
return d;
}
internal static bool TryParseDateTime(StringReference s, DateTimeZoneHandling dateTimeZoneHandling, string dateFormatString, CultureInfo culture, out DateTime dt) internal static bool TryParseDateTime(StringReference s, DateTimeZoneHandling dateTimeZoneHandling, string dateFormatString, CultureInfo culture, out DateTime dt)
{ {
if (s.Length > 0) if (s.Length > 0)