diff --git a/net-core/Ical.Net/Ical.Net.UnitTests/CalendarEventTest.cs b/net-core/Ical.Net/Ical.Net.UnitTests/CalendarEventTest.cs index 7489282a7..9f16516cd 100644 --- a/net-core/Ical.Net/Ical.Net.UnitTests/CalendarEventTest.cs +++ b/net-core/Ical.Net/Ical.Net.UnitTests/CalendarEventTest.cs @@ -133,9 +133,7 @@ public bool EnsureAutomaticallySetDTSTAMPisSerializedAsKindUTC(string serialized var lines = serialized.Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries).ToList(); var result = lines.First(s => s.StartsWith("DTSTAMP")); - //Both of these are correct, since the library no longer asserts that UTC must elide an explicit TZID in favor of the Z suffix on UTC times - return !result.Contains("TZID=") && result.EndsWith("Z") - || result.Contains("TZID=") && !result.EndsWith("Z"); + return !result.Contains("TZID=") && result.EndsWith("Z"); } public static IEnumerable EnsureAutomaticallySetDtStampIsSerializedAsUtcKind_TestCases() diff --git a/net-core/Ical.Net/Ical.Net/Serialization/iCalendar/Serializers/DataTypes/DateTimeSerializer.cs b/net-core/Ical.Net/Ical.Net/Serialization/iCalendar/Serializers/DataTypes/DateTimeSerializer.cs index e54501d3d..a221f60a6 100644 --- a/net-core/Ical.Net/Ical.Net/Serialization/iCalendar/Serializers/DataTypes/DateTimeSerializer.cs +++ b/net-core/Ical.Net/Ical.Net/Serialization/iCalendar/Serializers/DataTypes/DateTimeSerializer.cs @@ -44,11 +44,16 @@ public override string SerializeToString(object obj) { var dt = obj as IDateTime; - //Historically, dday.ical substituted TZID=UTC with Z suffixes on DateTimes. However this behavior isn't part of the spec. Some popular libraries - //like Telerik's RadSchedule components will only understand the DateTimeKind.Utc if the ical text says TZID=UTC. Anything but that is treated as - //DateTimeKind.Unspecified, which is problematic. + // RFC 5545 3.3.5: + // The date with UTC time, or absolute time, is identified by a LATIN + // CAPITAL LETTER Z suffix character, the UTC designator, appended to + // the time value. The "TZID" property parameter MUST NOT be applied to DATE-TIME + // properties whose time values are specified in UTC. + if (dt.IsUniversalTime) + { + dt.Parameters.Remove("TZID"); - if (!string.IsNullOrWhiteSpace(dt.TzId)) + } else if (!string.IsNullOrWhiteSpace(dt.TzId)) { dt.Parameters.Set("TZID", dt.TzId); } diff --git a/v2/ical.NET.Collections/Constants.cs b/v2/ical.NET.Collections/Constants.cs index 60a8779c6..c65b02d99 100644 --- a/v2/ical.NET.Collections/Constants.cs +++ b/v2/ical.NET.Collections/Constants.cs @@ -1,6 +1,6 @@ using System; -namespace ical.net.collections +namespace Ical.Net.Collections { public class ObjectEventArgs : EventArgs diff --git a/v2/ical.NET.Collections/GroupedValueList.cs b/v2/ical.NET.Collections/GroupedValueList.cs index 8f983806d..501ca84cd 100644 --- a/v2/ical.NET.Collections/GroupedValueList.cs +++ b/v2/ical.NET.Collections/GroupedValueList.cs @@ -1,10 +1,10 @@ using System; using System.Collections.Generic; using System.Linq; -using ical.net.collections.Interfaces; -using ical.net.collections.Proxies; +using Ical.Net.Collections.Interfaces; +using Ical.Net.Collections.Proxies; -namespace ical.net.collections +namespace Ical.Net.Collections { public class GroupedValueList : GroupedList diff --git a/v2/ical.NET.Collections/Interfaces/IGroupedList.cs b/v2/ical.NET.Collections/Interfaces/IGroupedList.cs index b3d815ac6..34147ffd3 100644 --- a/v2/ical.NET.Collections/Interfaces/IGroupedList.cs +++ b/v2/ical.NET.Collections/Interfaces/IGroupedList.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -namespace ical.net.collections.Interfaces +namespace Ical.Net.Collections.Interfaces { public interface IGroupedList : IGroupedCollection, diff --git a/v2/ical.NET.Collections/Interfaces/IGroupedObject.cs b/v2/ical.NET.Collections/Interfaces/IGroupedObject.cs index 2a58eca3a..a7d082d47 100644 --- a/v2/ical.NET.Collections/Interfaces/IGroupedObject.cs +++ b/v2/ical.NET.Collections/Interfaces/IGroupedObject.cs @@ -1,4 +1,4 @@ -namespace ical.net.collections.Interfaces +namespace Ical.Net.Collections.Interfaces { public interface IGroupedObject { diff --git a/v2/ical.NET.Collections/Interfaces/IMultiLinkedList.cs b/v2/ical.NET.Collections/Interfaces/IMultiLinkedList.cs index 8d34e4096..c83dbfe49 100644 --- a/v2/ical.NET.Collections/Interfaces/IMultiLinkedList.cs +++ b/v2/ical.NET.Collections/Interfaces/IMultiLinkedList.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -namespace ical.net.collections.Interfaces +namespace Ical.Net.Collections.Interfaces { public interface IMultiLinkedList : IList diff --git a/v2/ical.NET.Collections/Interfaces/IValueObject.cs b/v2/ical.NET.Collections/Interfaces/IValueObject.cs index a1100b6d8..d6c61e9d2 100644 --- a/v2/ical.NET.Collections/Interfaces/IValueObject.cs +++ b/v2/ical.NET.Collections/Interfaces/IValueObject.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -namespace ical.net.collections.Interfaces +namespace Ical.Net.Collections.Interfaces { public interface IValueObject { diff --git a/v2/ical.NET.UnitTests/EventTest.cs b/v2/ical.NET.UnitTests/EventTest.cs index 5bbf82a4b..0b656996f 100644 --- a/v2/ical.NET.UnitTests/EventTest.cs +++ b/v2/ical.NET.UnitTests/EventTest.cs @@ -135,9 +135,7 @@ public bool EnsureAutomaticallySetDTSTAMPisSerializedAsKindUTC(string serialized var lines = serialized.Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries).ToList(); var result = lines.First(s => s.StartsWith("DTSTAMP")); - //Both of these are correct, since the library no longer asserts that UTC must elide an explicit TZID in favor of the Z suffix on UTC times - return !result.Contains("TZID=") && result.EndsWith("Z") - || result.Contains("TZID=") && !result.EndsWith("Z"); + return !result.Contains("TZID=") && result.EndsWith("Z"); } public static IEnumerable EnsureAutomaticallySetDtStampIsSerializedAsUtcKind_TestCases() diff --git a/v2/ical.NET/Serialization/iCalendar/Serializers/DataTypes/DateTimeSerializer.cs b/v2/ical.NET/Serialization/iCalendar/Serializers/DataTypes/DateTimeSerializer.cs index 0263c6f21..fc1f6bbac 100644 --- a/v2/ical.NET/Serialization/iCalendar/Serializers/DataTypes/DateTimeSerializer.cs +++ b/v2/ical.NET/Serialization/iCalendar/Serializers/DataTypes/DateTimeSerializer.cs @@ -45,11 +45,16 @@ public override string SerializeToString(object obj) { var dt = obj as IDateTime; - //Historically, dday.ical substituted TZID=UTC with Z suffixes on DateTimes. However this behavior isn't part of the spec. Some popular libraries - //like Telerik's RadSchedule components will only understand the DateTimeKind.Utc if the ical text says TZID=UTC. Anything but that is treated as - //DateTimeKind.Unspecified, which is problematic. + // RFC 5545 3.3.5: + // The date with UTC time, or absolute time, is identified by a LATIN + // CAPITAL LETTER Z suffix character, the UTC designator, appended to + // the time value. The "TZID" property parameter MUST NOT be applied to DATE-TIME + // properties whose time values are specified in UTC. + if (dt.IsUniversalTime) + { + dt.Parameters.Remove("TZID"); - if (!string.IsNullOrWhiteSpace(dt.TzId)) + } else if (!string.IsNullOrWhiteSpace(dt.TzId)) { dt.Parameters.Set("TZID", dt.TzId); }