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

Commit 045c65d

Browse files
committed
Merge pull request #465 from yuinlin/FixXsdTimeSpanSerializeDeserialize
FixXsdTimeSpanSerializeDeserialize
2 parents 1ec026c + 029bdac commit 045c65d

File tree

2 files changed

+25
-3
lines changed

2 files changed

+25
-3
lines changed

src/ServiceStack.Text/Support/TimeSpanConverter.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@ public class TimeSpanConverter
88
{
99
public static string ToXsdDuration(TimeSpan timeSpan)
1010
{
11-
var sb = new StringBuilder("P");
11+
var sb = new StringBuilder();
1212

13-
double ticks = timeSpan.Ticks;
13+
sb.Append(timeSpan.Ticks < 0 ? "-P" : "P");
1414

15+
double ticks = Math.Abs(timeSpan.Ticks);
1516
double totalSeconds = ticks / TimeSpan.TicksPerSecond;
1617
int wholeSeconds = (int) totalSeconds;
1718
int seconds = wholeSeconds;
@@ -55,6 +56,7 @@ public static TimeSpan FromXsdDuration(string xsdDuration)
5556
int hours = 0;
5657
int minutes = 0;
5758
double seconds = 0;
59+
var sign = (xsdDuration.StartsWith("-", StringComparison.Ordinal) ? -1 : 1);
5860

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

@@ -100,7 +102,7 @@ public static TimeSpan FromXsdDuration(string xsdDuration)
100102
+ (minutes * 60)
101103
+ (seconds);
102104

103-
var interval = (long) (totalSecs * TimeSpan.TicksPerSecond);
105+
var interval = (long) (totalSecs * TimeSpan.TicksPerSecond * sign);
104106

105107
return TimeSpan.FromTicks(interval);
106108
}

tests/ServiceStack.Text.Tests/DateTimeOffsetAndTimeSpanTests.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,26 @@ public void Can_serialize_TimeSpan_field()
5959
Serialize(model);
6060
}
6161

62+
[Test]
63+
public void Can_serialize_negative_TimeSpan_field()
64+
{
65+
var period = new TimeSpan(0, 0, -15, 0);
66+
67+
var model = new SampleModel { Id = 1, TimeSpan = period };
68+
var json = JsonSerializer.SerializeToString(model);
69+
Assert.That(json, Is.StringContaining("\"TimeSpan\":\"-PT15M\""));
70+
}
71+
72+
[Test]
73+
public void Can_deserialize_negative_TimeSpan_string()
74+
{
75+
var expectedTimeSpan = new TimeSpan(0, 0, -15, 0);
76+
const string timeSpanString = @"-PT15M";
77+
78+
var timeSpan = JsonSerializer.DeserializeFromString<TimeSpan>(timeSpanString);
79+
Assert.That(timeSpan, Is.EqualTo(expectedTimeSpan));
80+
}
81+
6282
[Test]
6383
public void Can_serialize_TimeSpan_field_with_StandardTimeSpanFormat()
6484
{

0 commit comments

Comments
 (0)