Skip to content
This repository has been archived by the owner on Dec 24, 2022. It is now read-only.

Commit

Permalink
Switch to use new TimeSpanConverter with more test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
mythz committed Aug 27, 2015
1 parent 81dc4a3 commit 7841412
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 54 deletions.
15 changes: 0 additions & 15 deletions src/ServiceStack.Text/Common/DateTimeSerializer.cs
Expand Up @@ -355,18 +355,7 @@ public static string ToLocalXsdDateTimeString(DateTime dateTime)

public static string ToXsdTimeSpanString(TimeSpan timeSpan)
{
#if !PCL
var r = System.Xml.XmlConvert.ToString(timeSpan);
if (Env.IsMono)
{
// Mono returns DT even if time is 00:00:00
if (r.EndsWith("DT"))
return r.Substring(0, r.Length - 1);
}
return r;
#else
return TimeSpanConverter.ToXsdDuration(timeSpan);
#endif
}

public static string ToXsdTimeSpanString(TimeSpan? timeSpan)
Expand Down Expand Up @@ -404,11 +393,7 @@ public static TimeSpan ParseNSTimeInterval(string doubleInSecs)

public static TimeSpan ParseXsdTimeSpan(string dateTimeStr)
{
#if !PCL
return System.Xml.XmlConvert.ToTimeSpan(dateTimeStr);
#else
return TimeSpanConverter.FromXsdDuration(dateTimeStr);
#endif
}

public static TimeSpan? ParseXsdNullableTimeSpan(string dateTimeStr)
Expand Down
51 changes: 21 additions & 30 deletions src/ServiceStack.Text/Support/TimeSpanConverter.cs
@@ -1,7 +1,5 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;

namespace ServiceStack.Text.Support
Expand All @@ -12,40 +10,38 @@ public static string ToXsdDuration(TimeSpan timeSpan)
{
var sb = new StringBuilder("P");

double d = timeSpan.TotalSeconds;
double ticks = timeSpan.Ticks;

int totalSeconds = (int)(d);
int remainingMs = (int)(Math.Round(d - totalSeconds, 3) * 1000);
int sec = (totalSeconds >= 60 ? totalSeconds % 60 : totalSeconds);
int min = (totalSeconds = (totalSeconds / 60)) >= 60 ? totalSeconds % 60 : totalSeconds;
int hours = (totalSeconds = (totalSeconds / 60)) >= 24 ? totalSeconds % 24 : totalSeconds;
int days = (totalSeconds = (totalSeconds / 24)) >= 30 ? totalSeconds % 30 : totalSeconds;
double totalSeconds = ticks / TimeSpan.TicksPerSecond;
int wholeSeconds = (int) totalSeconds;
int seconds = wholeSeconds;
int sec = (seconds >= 60 ? seconds % 60 : seconds);
int min = (seconds = (seconds / 60)) >= 60 ? seconds % 60 : seconds;
int hours = (seconds = (seconds / 60)) >= 24 ? seconds % 24 : seconds;
int days = seconds / 24;
double remainingSecs = sec + (totalSeconds - wholeSeconds);

if (days > 0)
{
sb.Append(days + "D");
}

if (hours + min + sec + remainingMs > 0)
if (days == 0 || hours + min + sec + remainingSecs > 0)
{
sb.Append("T");
if (hours > 0)
{
sb.Append(hours + "H");
}

if (min > 0)
{
sb.Append(min + "M");
}


if (remainingMs > 0)
if (remainingSecs > 0)
{
sb.Append(sec + "." + remainingMs.ToString(CultureInfo.InvariantCulture).PadLeft(3, '0') + "S");
var secFmt = string.Format("{0:0.0000000}", remainingSecs);
secFmt = secFmt.TrimEnd('0').TrimEnd('.');
sb.Append(secFmt + "S");
}
else if (sec > 0)
else if (sb.Length == 2) //PT
{
sb.Append(sec + "S");
sb.Append("0S");
}
}

Expand All @@ -58,8 +54,7 @@ public static TimeSpan FromXsdDuration(string xsdDuration)
int days = 0;
int hours = 0;
int minutes = 0;
int seconds = 0;
double ms = 0.0;
double seconds = 0;

string[] t = xsdDuration.Substring(1).SplitOnFirst('T'); //strip P

Expand All @@ -72,7 +67,6 @@ public static TimeSpan FromXsdDuration(string xsdDuration)
if (int.TryParse(d[0], out day))
days = day;
}

if (hasTime)
{
string[] h = t[1].SplitOnFirst('H');
Expand All @@ -96,11 +90,8 @@ public static TimeSpan FromXsdDuration(string xsdDuration)
{
double millis;
if (double.TryParse(s[0], out millis))
ms = millis;
seconds = millis;
}

seconds = (int)ms;
ms -= seconds;
}

double totalSecs = 0
Expand All @@ -109,9 +100,9 @@ public static TimeSpan FromXsdDuration(string xsdDuration)
+ (minutes * 60)
+ (seconds);

double interval = totalSecs + ms;
var interval = (long) (totalSecs * TimeSpan.TicksPerSecond);

return TimeSpan.FromSeconds(interval);
return TimeSpan.FromTicks(interval);
}
}
}
14 changes: 8 additions & 6 deletions tests/ServiceStack.Text.Tests/JsonTests/JsonDateTimeTests.cs
Expand Up @@ -166,15 +166,15 @@ public void ParseShortestXsdDateTime_TwoDateTimesWithDifferentPrecision_ReturnsS
[Test]
public void JsonSerializerReturnsTimeSpanAsString()
{
Assert.AreEqual("\"PT0S\"", JsonSerializer.SerializeToString(new TimeSpan()));
Assert.AreEqual("\"PT0.0000001S\"", JsonSerializer.SerializeToString(new TimeSpan(1)));
Assert.That(JsonSerializer.SerializeToString(new TimeSpan()), Is.EqualTo("\"PT0S\""));
Assert.That(JsonSerializer.SerializeToString(new TimeSpan(1)), Is.EqualTo("\"PT0.0000001S\""));
}

[Test]
public void JsonDeserializerReturnsTimeSpanFromString()
{
Assert.AreEqual(TimeSpan.Zero, JsonSerializer.DeserializeFromString<TimeSpan>("\"PT0S\""));
Assert.AreEqual(new TimeSpan(1), JsonSerializer.DeserializeFromString<TimeSpan>("\"PT0.0000001S\""));
Assert.That(JsonSerializer.DeserializeFromString<TimeSpan>("\"PT0S\""), Is.EqualTo(TimeSpan.Zero));
Assert.That(JsonSerializer.DeserializeFromString<TimeSpan>("\"PT0.0000001S\""), Is.EqualTo(new TimeSpan(1)));
}
#endregion

Expand Down Expand Up @@ -527,7 +527,8 @@ public void Can_serialize_json_date_rfc1123_local()
var offset = offsetSpan.ToTimeOffsetString(":");

Assert.That(ssJson, Is.EqualTo(@"""Thu, 24 Nov 1994 04:34:56 GMT"""). //Convert to UTC on wire
Or.EqualTo(@"""Thu, 24 Nov 1994 17:34:56 GMT"""));
Or.EqualTo(@"""Thu, 24 Nov 1994 17:34:56 GMT""").
Or.EqualTo(@"""Thu, 24 Nov 1994 20:34:56 GMT"""));
JsConfig.Reset();
}

Expand All @@ -540,7 +541,8 @@ public void Can_serialize_json_date_rfc1123_unspecified()
var ssJson = JsonSerializer.SerializeToString(dateTime);

Assert.That(ssJson, Is.EqualTo(@"""Thu, 24 Nov 1994 04:34:56 GMT"""). //Convert to UTC on wire
Or.EqualTo(@"""Thu, 24 Nov 1994 17:34:56 GMT"""));
Or.EqualTo(@"""Thu, 24 Nov 1994 17:34:56 GMT""").
Or.EqualTo(@"""Thu, 24 Nov 1994 20:34:56 GMT"""));
JsConfig.Reset();
}

Expand Down
11 changes: 8 additions & 3 deletions tests/ServiceStack.Text.Tests/TimeSpanConverterTests.cs
@@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using ServiceStack.Text.Support;

Expand All @@ -19,6 +16,10 @@ public void Can_Serialize_TimeSpan()
Assert.That(TimeSpanConverter.ToXsdDuration(new TimeSpan(0, 0, 1)), Is.EqualTo("PT1S"));
Assert.That(TimeSpanConverter.ToXsdDuration(new TimeSpan(0, 0, 0, 0, 1)), Is.EqualTo("PT0.001S"));
Assert.That(TimeSpanConverter.ToXsdDuration(new TimeSpan(1, 1, 1, 1, 1)), Is.EqualTo("P1DT1H1M1.001S"));

Assert.That(TimeSpanConverter.ToXsdDuration(new TimeSpan(1)), Is.EqualTo("PT0.0000001S"));
Assert.That(TimeSpanConverter.ToXsdDuration(TimeSpan.Zero), Is.EqualTo("PT0S"));
Assert.That(TimeSpanConverter.ToXsdDuration(new DateTime(2010,1,1) - new DateTime(2000,1,1)), Is.EqualTo("P3653D"));
}

[Test]
Expand All @@ -30,6 +31,10 @@ public void Can_deserialize_TimeSpan()
Assert.That(TimeSpanConverter.FromXsdDuration("PT1S"), Is.EqualTo(new TimeSpan(0, 0, 1)));
Assert.That(TimeSpanConverter.FromXsdDuration("PT0.001S"), Is.EqualTo(new TimeSpan(0, 0, 0, 0, 1)));
Assert.That(TimeSpanConverter.FromXsdDuration("P1DT1H1M1.001S"), Is.EqualTo(new TimeSpan(1, 1, 1, 1, 1)));

Assert.That(TimeSpanConverter.FromXsdDuration("PT0.0000001S"), Is.EqualTo(new TimeSpan(1)));
Assert.That(TimeSpanConverter.FromXsdDuration("PT0S"), Is.EqualTo(TimeSpan.Zero));
Assert.That(TimeSpanConverter.FromXsdDuration("P3650D"), Is.EqualTo(TimeSpan.FromDays(3650)));
}
}
}

0 comments on commit 7841412

Please sign in to comment.