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

Commit 36e812f

Browse files
committed
Merge pull request #367 from niltz/master
append the "+0000" offset to utc dates if specified
2 parents c45e8e3 + b350594 commit 36e812f

File tree

4 files changed

+71
-0
lines changed

4 files changed

+71
-0
lines changed

src/ServiceStack.Text/Common/DateTimeSerializer.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ public static class DateTimeSerializer
3535
public const string WcfJsonPrefix = "/Date(";
3636
public const char WcfJsonSuffix = ')';
3737
public const string UnspecifiedOffset = "-0000";
38+
public const string UtcOffset = "+0000";
3839

3940
/// <summary>
4041
/// If AlwaysUseUtc is set to true then convert all DateTime to UTC.
@@ -423,6 +424,13 @@ public static void WriteWcfJsonDate(TextWriter writer, DateTime dateTime)
423424
else
424425
offset = LocalTimeZone.GetUtcOffset(dateTime).ToTimeOffsetString();
425426
}
427+
else
428+
{
429+
// Normally the JsonDateHandler.TimestampOffset doesn't append an offset for Utc dates, but if
430+
// the JsConfig.AppendUtcOffset is set then we will
431+
if (JsConfig.DateHandler == JsonDateHandler.TimestampOffset && JsConfig.AppendUtcOffset.HasValue && JsConfig.AppendUtcOffset.Value)
432+
offset = UtcOffset;
433+
}
426434

427435
writer.Write(EscapedWcfJsonPrefix);
428436
writer.Write(timestamp);

src/ServiceStack.Text/JsConfig.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ public static JsConfigScope With(
4747
bool? treatEnumAsInteger = null,
4848
bool? alwaysUseUtc = null,
4949
bool? assumeUtc = null,
50+
bool? appendUtcOffset = null,
5051
bool? escapeUnicode = null,
5152
bool? includePublicFields = null,
5253
int? maxDepth = null,
@@ -72,6 +73,7 @@ public static JsConfigScope With(
7273
TreatEnumAsInteger = treatEnumAsInteger ?? sTreatEnumAsInteger,
7374
AlwaysUseUtc = alwaysUseUtc ?? sAlwaysUseUtc,
7475
AssumeUtc = assumeUtc ?? sAssumeUtc,
76+
AppendUtcOffset = appendUtcOffset ?? sAppendUtcOffset,
7577
EscapeUnicode = escapeUnicode ?? sEscapeUnicode,
7678
IncludePublicFields = includePublicFields ?? sIncludePublicFields,
7779
MaxDepth = maxDepth ?? sMaxDepth,
@@ -422,6 +424,26 @@ public static bool AssumeUtc
422424
}
423425
}
424426

427+
/// <summary>
428+
/// Gets or sets whether we should append the Utc offset when we serialize Utc dates. Defaults to no.
429+
/// Only supported for when the JsConfig.DateHandler == JsonDateHandler.TimestampOffset
430+
/// </summary>
431+
private static bool? sAppendUtcOffset;
432+
public static bool? AppendUtcOffset
433+
{
434+
// obeying the use of ThreadStatic, but allowing for setting JsConfig once as is the normal case
435+
get
436+
{
437+
return (JsConfigScope.Current != null ? JsConfigScope.Current.AppendUtcOffset : null)
438+
?? sAppendUtcOffset
439+
?? null;
440+
}
441+
set
442+
{
443+
if (sAppendUtcOffset == null) sAppendUtcOffset = value;
444+
}
445+
}
446+
425447
/// <summary>
426448
/// Gets or sets a value indicating if unicode symbols should be serialized as "\uXXXX".
427449
/// </summary>
@@ -563,6 +585,7 @@ public static void Reset()
563585
sTreatEnumAsInteger = null;
564586
sAlwaysUseUtc = null;
565587
sAssumeUtc = null;
588+
sAppendUtcOffset = null;
566589
sEscapeUnicode = null;
567590
sIncludePublicFields = null;
568591
HasSerializeFn = new HashSet<Type>();

src/ServiceStack.Text/JsConfigScope.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ public void Dispose()
7474
public bool? ThrowOnDeserializationError { get; set; }
7575
public bool? AlwaysUseUtc { get; set; }
7676
public bool? AssumeUtc { get; set; }
77+
public bool? AppendUtcOffset { get; set; }
7778
public bool? EscapeUnicode { get; set; }
7879
public bool? PreferInterfaces { get; set; }
7980
public bool? IncludePublicFields { get; set; }

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

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,19 @@ public void Can_serialize_json_date_timestampOffset_unspecified_assume_utc()
134134
JsConfig.Reset();
135135
}
136136

137+
[Test]
138+
public void Can_serialize_json_date_timestampOffset_unspecified_appendUtcOffset()
139+
{
140+
JsConfig.DateHandler = JsonDateHandler.TimestampOffset;
141+
JsConfig.AppendUtcOffset = true;
142+
143+
var dateTime = DateTime.SpecifyKind(DateTime.Parse("2013-06-14 19:43:37.663"), DateTimeKind.Utc);
144+
var ssJson = JsonSerializer.SerializeToString(dateTime);
145+
Assert.That(ssJson, Is.EqualTo(@"""\/Date(1371239017663+0000)\/"""));
146+
147+
JsConfig.Reset();
148+
}
149+
137150
#endregion
138151

139152
#region TimeSpan Tests
@@ -252,6 +265,19 @@ public void Can_serialize_json_date_dcjsCompatible_unspecified_assume_utc()
252265
Assert.That(ssJson, Is.EqualTo(@"""\/Date(1371239017663)\/"""));
253266
JsConfig.Reset();
254267
}
268+
269+
[Test]
270+
public void Can_serialize_json_date_dcjsCompatible_unspecified_appendUtcOffset()
271+
{
272+
JsConfig.DateHandler = JsonDateHandler.DCJSCompatible;
273+
JsConfig.AppendUtcOffset = true;
274+
275+
var dateTime = DateTime.SpecifyKind(DateTime.Parse("2013-06-14 19:43:37.663"), DateTimeKind.Utc);
276+
var ssJson = JsonSerializer.SerializeToString(dateTime);
277+
Assert.That(ssJson, Is.EqualTo(@"""\/Date(1371239017663)\/"""));
278+
279+
JsConfig.Reset();
280+
}
255281
#endif
256282
#endregion
257283

@@ -368,6 +394,19 @@ public void Can_serialize_json_date_iso8601_unspecified_assume_utc()
368394
JsConfig.Reset();
369395
}
370396

397+
[Test]
398+
public void Can_serialize_json_date_iso8601_unspecified_appendUtcOffset()
399+
{
400+
JsConfig.DateHandler = JsonDateHandler.ISO8601;
401+
JsConfig.AppendUtcOffset = true;
402+
403+
var dateTime = DateTime.SpecifyKind(DateTime.Parse("2013-06-14 19:43:37.663"), DateTimeKind.Utc);
404+
var ssJson = JsonSerializer.SerializeToString(dateTime);
405+
Assert.That(ssJson, Is.EqualTo(@"""2013-06-14T19:43:37.6630000Z"""));
406+
407+
JsConfig.Reset();
408+
}
409+
371410
#endregion
372411

373412
#region ISO-8601 TimeStampOffset Tests

0 commit comments

Comments
 (0)