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

Commit 7841412

Browse files
committed
Switch to use new TimeSpanConverter with more test cases
1 parent 81dc4a3 commit 7841412

File tree

4 files changed

+37
-54
lines changed

4 files changed

+37
-54
lines changed

src/ServiceStack.Text/Common/DateTimeSerializer.cs

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -355,18 +355,7 @@ public static string ToLocalXsdDateTimeString(DateTime dateTime)
355355

356356
public static string ToXsdTimeSpanString(TimeSpan timeSpan)
357357
{
358-
#if !PCL
359-
var r = System.Xml.XmlConvert.ToString(timeSpan);
360-
if (Env.IsMono)
361-
{
362-
// Mono returns DT even if time is 00:00:00
363-
if (r.EndsWith("DT"))
364-
return r.Substring(0, r.Length - 1);
365-
}
366-
return r;
367-
#else
368358
return TimeSpanConverter.ToXsdDuration(timeSpan);
369-
#endif
370359
}
371360

372361
public static string ToXsdTimeSpanString(TimeSpan? timeSpan)
@@ -404,11 +393,7 @@ public static TimeSpan ParseNSTimeInterval(string doubleInSecs)
404393

405394
public static TimeSpan ParseXsdTimeSpan(string dateTimeStr)
406395
{
407-
#if !PCL
408-
return System.Xml.XmlConvert.ToTimeSpan(dateTimeStr);
409-
#else
410396
return TimeSpanConverter.FromXsdDuration(dateTimeStr);
411-
#endif
412397
}
413398

414399
public static TimeSpan? ParseXsdNullableTimeSpan(string dateTimeStr)
Lines changed: 21 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
using System;
2-
using System.Collections.Generic;
32
using System.Globalization;
4-
using System.Linq;
53
using System.Text;
64

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

15-
double d = timeSpan.TotalSeconds;
13+
double ticks = timeSpan.Ticks;
1614

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

2424
if (days > 0)
25-
{
2625
sb.Append(days + "D");
27-
}
2826

29-
if (hours + min + sec + remainingMs > 0)
27+
if (days == 0 || hours + min + sec + remainingSecs > 0)
3028
{
3129
sb.Append("T");
3230
if (hours > 0)
33-
{
3431
sb.Append(hours + "H");
35-
}
32+
3633
if (min > 0)
37-
{
3834
sb.Append(min + "M");
39-
}
4035

41-
42-
if (remainingMs > 0)
36+
if (remainingSecs > 0)
4337
{
44-
sb.Append(sec + "." + remainingMs.ToString(CultureInfo.InvariantCulture).PadLeft(3, '0') + "S");
38+
var secFmt = string.Format("{0:0.0000000}", remainingSecs);
39+
secFmt = secFmt.TrimEnd('0').TrimEnd('.');
40+
sb.Append(secFmt + "S");
4541
}
46-
else if (sec > 0)
42+
else if (sb.Length == 2) //PT
4743
{
48-
sb.Append(sec + "S");
44+
sb.Append("0S");
4945
}
5046
}
5147

@@ -58,8 +54,7 @@ public static TimeSpan FromXsdDuration(string xsdDuration)
5854
int days = 0;
5955
int hours = 0;
6056
int minutes = 0;
61-
int seconds = 0;
62-
double ms = 0.0;
57+
double seconds = 0;
6358

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

@@ -72,7 +67,6 @@ public static TimeSpan FromXsdDuration(string xsdDuration)
7267
if (int.TryParse(d[0], out day))
7368
days = day;
7469
}
75-
7670
if (hasTime)
7771
{
7872
string[] h = t[1].SplitOnFirst('H');
@@ -96,11 +90,8 @@ public static TimeSpan FromXsdDuration(string xsdDuration)
9690
{
9791
double millis;
9892
if (double.TryParse(s[0], out millis))
99-
ms = millis;
93+
seconds = millis;
10094
}
101-
102-
seconds = (int)ms;
103-
ms -= seconds;
10495
}
10596

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

112-
double interval = totalSecs + ms;
103+
var interval = (long) (totalSecs * TimeSpan.TicksPerSecond);
113104

114-
return TimeSpan.FromSeconds(interval);
105+
return TimeSpan.FromTicks(interval);
115106
}
116107
}
117108
}

tests/ServiceStack.Text.Tests/JsonTests/JsonDateTimeTests.cs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -166,15 +166,15 @@ public void ParseShortestXsdDateTime_TwoDateTimesWithDifferentPrecision_ReturnsS
166166
[Test]
167167
public void JsonSerializerReturnsTimeSpanAsString()
168168
{
169-
Assert.AreEqual("\"PT0S\"", JsonSerializer.SerializeToString(new TimeSpan()));
170-
Assert.AreEqual("\"PT0.0000001S\"", JsonSerializer.SerializeToString(new TimeSpan(1)));
169+
Assert.That(JsonSerializer.SerializeToString(new TimeSpan()), Is.EqualTo("\"PT0S\""));
170+
Assert.That(JsonSerializer.SerializeToString(new TimeSpan(1)), Is.EqualTo("\"PT0.0000001S\""));
171171
}
172172

173173
[Test]
174174
public void JsonDeserializerReturnsTimeSpanFromString()
175175
{
176-
Assert.AreEqual(TimeSpan.Zero, JsonSerializer.DeserializeFromString<TimeSpan>("\"PT0S\""));
177-
Assert.AreEqual(new TimeSpan(1), JsonSerializer.DeserializeFromString<TimeSpan>("\"PT0.0000001S\""));
176+
Assert.That(JsonSerializer.DeserializeFromString<TimeSpan>("\"PT0S\""), Is.EqualTo(TimeSpan.Zero));
177+
Assert.That(JsonSerializer.DeserializeFromString<TimeSpan>("\"PT0.0000001S\""), Is.EqualTo(new TimeSpan(1)));
178178
}
179179
#endregion
180180

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

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

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

542543
Assert.That(ssJson, Is.EqualTo(@"""Thu, 24 Nov 1994 04:34:56 GMT"""). //Convert to UTC on wire
543-
Or.EqualTo(@"""Thu, 24 Nov 1994 17:34:56 GMT"""));
544+
Or.EqualTo(@"""Thu, 24 Nov 1994 17:34:56 GMT""").
545+
Or.EqualTo(@"""Thu, 24 Nov 1994 20:34:56 GMT"""));
544546
JsConfig.Reset();
545547
}
546548

tests/ServiceStack.Text.Tests/TimeSpanConverterTests.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
using System;
2-
using System.Collections.Generic;
3-
using System.Linq;
4-
using System.Text;
52
using NUnit.Framework;
63
using ServiceStack.Text.Support;
74

@@ -19,6 +16,10 @@ public void Can_Serialize_TimeSpan()
1916
Assert.That(TimeSpanConverter.ToXsdDuration(new TimeSpan(0, 0, 1)), Is.EqualTo("PT1S"));
2017
Assert.That(TimeSpanConverter.ToXsdDuration(new TimeSpan(0, 0, 0, 0, 1)), Is.EqualTo("PT0.001S"));
2118
Assert.That(TimeSpanConverter.ToXsdDuration(new TimeSpan(1, 1, 1, 1, 1)), Is.EqualTo("P1DT1H1M1.001S"));
19+
20+
Assert.That(TimeSpanConverter.ToXsdDuration(new TimeSpan(1)), Is.EqualTo("PT0.0000001S"));
21+
Assert.That(TimeSpanConverter.ToXsdDuration(TimeSpan.Zero), Is.EqualTo("PT0S"));
22+
Assert.That(TimeSpanConverter.ToXsdDuration(new DateTime(2010,1,1) - new DateTime(2000,1,1)), Is.EqualTo("P3653D"));
2223
}
2324

2425
[Test]
@@ -30,6 +31,10 @@ public void Can_deserialize_TimeSpan()
3031
Assert.That(TimeSpanConverter.FromXsdDuration("PT1S"), Is.EqualTo(new TimeSpan(0, 0, 1)));
3132
Assert.That(TimeSpanConverter.FromXsdDuration("PT0.001S"), Is.EqualTo(new TimeSpan(0, 0, 0, 0, 1)));
3233
Assert.That(TimeSpanConverter.FromXsdDuration("P1DT1H1M1.001S"), Is.EqualTo(new TimeSpan(1, 1, 1, 1, 1)));
34+
35+
Assert.That(TimeSpanConverter.FromXsdDuration("PT0.0000001S"), Is.EqualTo(new TimeSpan(1)));
36+
Assert.That(TimeSpanConverter.FromXsdDuration("PT0S"), Is.EqualTo(TimeSpan.Zero));
37+
Assert.That(TimeSpanConverter.FromXsdDuration("P3650D"), Is.EqualTo(TimeSpan.FromDays(3650)));
3338
}
3439
}
3540
}

0 commit comments

Comments
 (0)