Skip to content

Commit f136c5e

Browse files
author
Mikael Eliasson
committed
Make TimeSpan format configurable
1 parent 98d3387 commit f136c5e

3 files changed

Lines changed: 108 additions & 75 deletions

File tree

src/ServiceStack.Text/JsConfig.cs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,12 @@ public static JsonDateHandler DateHandler
8383
tsDateHandler = value;
8484
if (!sDateHandler.HasValue) sDateHandler = value;
8585
}
86-
}
87-
86+
}
87+
88+
/// <summary>
89+
/// Sets which format to use when serializing TimeSpans
90+
/// </summary>
91+
public static JsonTimeSpanHandler TimeSpanHandler { get; set; }
8892

8993
/// <summary>
9094
/// <see langword="true"/> if the <see cref="ITypeSerializer"/> is configured
@@ -427,6 +431,18 @@ public enum JsonDateHandler
427431
TimestampOffset,
428432
DCJSCompatible,
429433
ISO8601
430-
}
434+
}
435+
436+
public enum JsonTimeSpanHandler
437+
{
438+
/// <summary>
439+
/// Uses the xsd format like PT15H10M20S
440+
/// </summary>
441+
DurationFormat,
442+
/// <summary>
443+
/// Uses the standard .net ToString method of the TimeSpan class
444+
/// </summary>
445+
StandardFormat
446+
}
431447
}
432448

src/ServiceStack.Text/Json/JsonTypeSerializer.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,11 +129,14 @@ public void WriteNullableDateTimeOffset(TextWriter writer, object dateTimeOffset
129129
writer.Write(JsonUtils.Null);
130130
else
131131
WriteDateTimeOffset(writer, dateTimeOffset);
132-
}
133-
134-
public void WriteTimeSpan(TextWriter writer, object oTimeSpan)
132+
}
133+
134+
public void WriteTimeSpan(TextWriter writer, object oTimeSpan)
135135
{
136-
WriteRawString(writer, DateTimeSerializer.ToXsdTimeSpanString((TimeSpan)oTimeSpan));
136+
var stringValue = JsConfig.TimeSpanHandler == JsonTimeSpanHandler.StandardFormat
137+
? oTimeSpan.ToString()
138+
: DateTimeSerializer.ToXsdTimeSpanString((TimeSpan)oTimeSpan);
139+
WriteRawString(writer, stringValue);
137140
}
138141

139142
public void WriteNullableTimeSpan(TextWriter writer, object oTimeSpan)
Lines changed: 82 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,82 @@
1-
using System;
2-
using NUnit.Framework;
3-
using ServiceStack.ServiceModel.Serialization;
4-
5-
namespace ServiceStack.Text.Tests
6-
{
7-
[TestFixture]
8-
public class DateTimeOffsetAndTimeSpanTests : TestBase
9-
{
10-
[TestFixtureSetUp]
11-
public void TestFixtureSetUp()
12-
{
13-
JsonDataContractSerializer.Instance.UseBcl = true;
14-
}
15-
16-
[TestFixtureTearDown]
17-
public void TestFixtureTearDown()
18-
{
19-
JsonDataContractSerializer.Instance.UseBcl = false;
20-
}
21-
22-
[Test]
23-
public void Can_Serializable_DateTimeOffset_Field()
24-
{
25-
var model = new SampleModel { Id = 1, Date = new DateTimeOffset(2012, 6, 27, 11, 26, 04, 524, TimeSpan.FromHours(7)) };
26-
27-
//Behaviour of .NET's BCL classes
28-
//JsonDataContractSerializer.Instance.SerializeToString(model).Print();
29-
//DataContractSerializer.Instance.Parse(model).Print();
30-
31-
var json = JsonSerializer.SerializeToString(model);
32-
Assert.That(json, Is.StringContaining("\"TimeSpan\":\"PT0S\""));
33-
34-
var fromJson = json.FromJson<SampleModel>();
35-
36-
Assert.That(model.Date, Is.EqualTo(fromJson.Date));
37-
Assert.That(model.TimeSpan, Is.EqualTo(fromJson.TimeSpan));
38-
39-
Serialize(fromJson);
40-
}
41-
42-
[Test]
43-
public void Can_serialize_TimeSpan_field()
44-
{
45-
var fromDate = new DateTime(2069, 01, 02);
46-
var toDate = new DateTime(2079, 01, 02);
47-
var period = toDate - fromDate;
48-
49-
var model = new SampleModel { Id = 1, TimeSpan = period };
50-
var json = JsonSerializer.SerializeToString(model);
51-
Assert.That(json, Is.StringContaining("\"TimeSpan\":\"P3652D\""));
52-
53-
//Behaviour of .NET's BCL classes
54-
//JsonDataContractSerializer.Instance.SerializeToString(model).Print();
55-
//DataContractSerializer.Instance.Parse(model).Print();
56-
57-
Serialize(model);
58-
}
59-
60-
public class SampleModel
61-
{
62-
public int Id { get; set; }
63-
64-
public DateTimeOffset Date { get; set; }
65-
public TimeSpan TimeSpan { get; set; }
66-
}
67-
}
68-
}
1+
using System;
2+
using NUnit.Framework;
3+
using ServiceStack.ServiceModel.Serialization;
4+
5+
namespace ServiceStack.Text.Tests
6+
{
7+
[TestFixture]
8+
public class DateTimeOffsetAndTimeSpanTests : TestBase
9+
{
10+
[TestFixtureSetUp]
11+
public void TestFixtureSetUp()
12+
{
13+
JsonDataContractSerializer.Instance.UseBcl = true;
14+
}
15+
16+
[TestFixtureTearDown]
17+
public void TestFixtureTearDown()
18+
{
19+
JsonDataContractSerializer.Instance.UseBcl = false;
20+
}
21+
22+
[Test]
23+
public void Can_Serializable_DateTimeOffset_Field()
24+
{
25+
var model = new SampleModel { Id = 1, Date = new DateTimeOffset(2012, 6, 27, 11, 26, 04, 524, TimeSpan.FromHours(7)) };
26+
27+
//Behaviour of .NET's BCL classes
28+
//JsonDataContractSerializer.Instance.SerializeToString(model).Print();
29+
//DataContractSerializer.Instance.Parse(model).Print();
30+
31+
var json = JsonSerializer.SerializeToString(model);
32+
Assert.That(json, Is.StringContaining("\"TimeSpan\":\"PT0S\""));
33+
34+
var fromJson = json.FromJson<SampleModel>();
35+
36+
Assert.That(model.Date, Is.EqualTo(fromJson.Date));
37+
Assert.That(model.TimeSpan, Is.EqualTo(fromJson.TimeSpan));
38+
39+
Serialize(fromJson);
40+
}
41+
42+
[Test]
43+
public void Can_serialize_TimeSpan_field()
44+
{
45+
var fromDate = new DateTime(2069, 01, 02);
46+
var toDate = new DateTime(2079, 01, 02);
47+
var period = toDate - fromDate;
48+
49+
var model = new SampleModel { Id = 1, TimeSpan = period };
50+
var json = JsonSerializer.SerializeToString(model);
51+
Assert.That(json, Is.StringContaining("\"TimeSpan\":\"P3652D\""));
52+
53+
//Behaviour of .NET's BCL classes
54+
//JsonDataContractSerializer.Instance.SerializeToString(model).Print();
55+
//DataContractSerializer.Instance.Parse(model).Print();
56+
57+
Serialize(model);
58+
}
59+
60+
[Test]
61+
public void Can_serialize_TimeSpan_field_with_StandardTimeSpanFormat()
62+
{
63+
var period = TimeSpan.FromSeconds(70);
64+
65+
JsConfig.TimeSpanHandler = JsonTimeSpanHandler.StandardFormat;
66+
67+
var model = new SampleModel { Id = 1, TimeSpan = period };
68+
var json = JsonSerializer.SerializeToString(model);
69+
Assert.That(json, Is.StringContaining("\"TimeSpan\":\"00:01:10\""));
70+
71+
JsConfig.TimeSpanHandler = JsonTimeSpanHandler.DurationFormat; //Revert so no other tests are affected
72+
}
73+
74+
public class SampleModel
75+
{
76+
public int Id { get; set; }
77+
78+
public DateTimeOffset Date { get; set; }
79+
public TimeSpan TimeSpan { get; set; }
80+
}
81+
}
82+
}

0 commit comments

Comments
 (0)