Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions src/NodaTime.Serialization.JsonNet/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,36 @@ public static JsonSerializer WithIsoDateIntervalConverter(this JsonSerializer se
return serializer;
}

/// <summary>
/// </summary>
/// <param name="settings">The existing serializer settings to add Noda Time converters to.</param>
/// <param name="replacementConverter"></param>
/// <returns>The original <paramref name="settings"/> value, for further chaining.</returns>
public static JsonSerializerSettings WithReplacementNodaTimeConverter<T>(this JsonSerializerSettings settings, JsonConverter replacementConverter)
{
if (settings == null)
{
throw new ArgumentNullException(nameof(settings));
}
ReplaceExistingConverters<T>(settings.Converters, replacementConverter);
return settings;
}

/// <summary>
/// </summary>
/// <param name="serializer">The existing serializer to add Noda Time converters to.</param>
/// <param name="replacementConverter"></param>
/// <returns>The original <paramref name="serializer"/> value, for further chaining.</returns>
public static JsonSerializer WithReplacementNodaTimeConverter<T>(this JsonSerializer serializer, JsonConverter replacementConverter)
{
if (serializer == null)
{
throw new ArgumentNullException(nameof(serializer));
}
ReplaceExistingConverters<T>(serializer.Converters, replacementConverter);
return serializer;
}

private static void AddDefaultConverters(IList<JsonConverter> converters, IDateTimeZoneProvider provider)
{
converters.Add(NodaConverters.InstantConverter);
Expand Down
10 changes: 10 additions & 0 deletions src/NodaTime.Serialization.JsonNet/NodaConverters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,16 @@ public static JsonConverter CreateZonedDateTimeConverter(IDateTimeZoneProvider p
ZonedDateTimePattern.CreateWithInvariantCulture("uuuu'-'MM'-'dd'T'HH':'mm':'ss;FFFFFFFFFo<G> z", provider),
CreateIsoValidator<ZonedDateTime>(x => x.Calendar));

/// <summary>
/// Create a converter for zoned date/times that uses the format defined in the
/// [proposed] extension to RFC 3339 for indicating time zones in IANA format
/// </summary>
/// <returns></returns>
public static JsonConverter CreateZonedDateTimeRFC3339() =>
new NodaPatternConverter<ZonedDateTime>(
ZonedDateTimePattern.CreateWithInvariantCulture("uuuu'-'MM'-'dd'T'HH':'mm':'ss;FFFo<G>'['z']'", DateTimeZoneProviders.Tzdb),
CreateIsoValidator<ZonedDateTime>(x => x.Calendar));

/// <summary>
/// Creates a converter for time zones, using the given provider.
/// </summary>
Expand Down
25 changes: 25 additions & 0 deletions src/NodaTime.Serialization.Test/JsonNet/ExtensionsTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,31 @@ public void Settings_ConfigureForNodaTime_WithIsoDateIntervalConverter()
JsonConvert.SerializeObject(interval, configuredSettings));
}

[Test]
public void Settings_ConfigureForNodaTime_DefaultConverters()
{
var configuredSettings = new JsonSerializerSettings().ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
var explicitSettings = new JsonSerializerSettings
{
Converters = { NodaConverters.CreateZonedDateTimeConverter(DateTimeZoneProviders.Tzdb) }
};
var zone = DateTimeZoneProviders.Tzdb["Europe/London"];
var zonedDateTime = new ZonedDateTime(new LocalDateTime(2012, 10, 28, 1, 30), zone, Offset.FromHours(1));
Assert.AreEqual(JsonConvert.SerializeObject(zonedDateTime, explicitSettings),
JsonConvert.SerializeObject(zonedDateTime, configuredSettings));
}

[Test]
public void Settings_ConfigureForNodaTime_WithReplacementNodaConverter()
{
var configuredSettings = new JsonSerializerSettings().ConfigureForNodaTime(DateTimeZoneProviders.Tzdb).WithReplacementNodaTimeConverter<ZonedDateTime>(NodaConverters.CreateZonedDateTimeRFC3339());
var explicitSettings = new JsonSerializerSettings { Converters = { NodaConverters.CreateZonedDateTimeRFC3339() } };
var zone = DateTimeZoneProviders.Tzdb["Europe/London"];
var zonedDateTime = new ZonedDateTime(new LocalDateTime(2012, 10, 28, 1, 30), zone, Offset.FromHours(1));
Assert.AreEqual(JsonConvert.SerializeObject(zonedDateTime, explicitSettings),
JsonConvert.SerializeObject(zonedDateTime, configuredSettings));
}

private static string Serialize<T>(T value, JsonSerializer serializer)
{
var writer = new StringWriter();
Expand Down
22 changes: 22 additions & 0 deletions src/NodaTime.Serialization.Test/JsonNet/NodaConvertersTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,28 @@ public void ZonedDateTimeConverter()
AssertConversions(laterValue, laterJson, converter);
}

[Test]
public void ZonedDateTimeRFC3339Converter_LocalTimeWithOffsetAndZone()
{
var zone = DateTimeZoneProviders.Tzdb["Europe/London"];
var value = new ZonedDateTime(new LocalDateTime(2012, 10, 28, 1, 30), zone, Offset.FromHours(1));
string json = "\"2012-10-28T01:30:00+01[Europe/London]\"";
var converter = NodaConverters.CreateZonedDateTimeRFC3339();

AssertConversions(value, json, converter);
}

[Test]
public void ZonedDateTimeRFC3339Converter_LocalTimeNoOffsetWithZoneAndMilliseconds()
{
var zone = DateTimeZoneProviders.Tzdb["Europe/London"];
var value = new ZonedDateTime(new LocalDateTime(2012, 10, 28, 1, 30).PlusMilliseconds(123), zone, Offset.FromHours(0));
string json = "\"2012-10-28T01:30:00.123Z[Europe/London]\"";
var converter = NodaConverters.CreateZonedDateTimeRFC3339();

AssertConversions(value, json, converter);
}

[Test]
public void OffsetDateTimeConverter()
{
Expand Down