Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 2 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ insert_final_newline = true
csharp_new_line_before_members_in_anonymous_types = true

[*.cs]
#parsing and formatting should be implemented in a culture-invariant manner
dotnet_diagnostic.CA1305.severity = warning

#place catch statements on a new line
csharp_new_line_before_catch = true
Expand Down
1 change: 1 addition & 0 deletions Ical.Net.Benchmarks/Ical.Net.Benchmarks.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.14.0" />
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="9.0.0" PrivateAssets="all" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Ical.Net\Ical.Net.csproj" />
Expand Down
6 changes: 3 additions & 3 deletions Ical.Net.Tests/CalDateTimeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public static IEnumerable ToTimeZoneTestCases()
[Test(Description = "A certain date/time value applied to different timezones should return the same UTC date/time")]
public void SameDateTimeWithDifferentTzIdShouldReturnSameUtc()
{
var someTime = DateTimeOffset.Parse("2018-05-21T11:35:00-04:00");
var someTime = DateTimeOffset.Parse("2018-05-21T11:35:00-04:00", CultureInfo.InvariantCulture);

var someDt = new CalDateTime(someTime.DateTime, "America/New_York");
var firstUtc = someDt.AsUtc;
Expand All @@ -111,7 +111,7 @@ public DateTimeKind DateTimeKindOverrideTests(DateTime dateTime, string tzId)
public static IEnumerable DateTimeKindOverrideTestCases()
{
const string localTz = "America/New_York";
var localDt = DateTime.SpecifyKind(DateTime.Parse("2018-05-21T11:35:33"), DateTimeKind.Unspecified);
var localDt = DateTime.SpecifyKind(DateTime.Parse("2018-05-21T11:35:33", CultureInfo.InvariantCulture), DateTimeKind.Unspecified);

yield return new TestCaseData(localDt, "UTC")
.Returns(DateTimeKind.Unspecified)
Expand Down Expand Up @@ -317,7 +317,7 @@ public void Simple_PropertyAndMethod_HasTime_Tests()
Assert.That(c.DayOfYear, Is.EqualTo(dt.DayOfYear));
Assert.That(c.Time?.ToTimeSpan(), Is.EqualTo(dt.TimeOfDay));
Assert.That(c.Add(-Duration.FromSeconds(dt.Second)).Value.Second, Is.EqualTo(0));
Assert.That(c.ToString("dd.MM.yyyy"), Is.EqualTo("02.01.2025 Europe/Berlin"));
Assert.That(c.ToString("dd.MM.yyyy", CultureInfo.InvariantCulture), Is.EqualTo("02.01.2025 Europe/Berlin"));
// Create a date-only CalDateTime from a CalDateTime
Assert.That(new CalDateTime(new CalDateTime(2025, 1, 1)), Is.EqualTo(new CalDateTime(2025, 1, 1)));
});
Expand Down
13 changes: 7 additions & 6 deletions Ical.Net.Tests/DocumentationExamples.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Ical.Net.CalendarComponents;
using Ical.Net.DataTypes;
Expand Down Expand Up @@ -50,8 +51,8 @@ public void EveryOtherTuesdayUntilTheEndOfTheYear_Test()
// An event taking place between 07:00 and 08:00, beginning July 5 (a Tuesday)
var vEvent = new CalendarEvent
{
DtStart = new CalDateTime(DateTime.Parse("2016-07-05T07:00")),
DtEnd = new CalDateTime(DateTime.Parse("2016-07-05T08:00")),
DtStart = new CalDateTime(DateTime.Parse("2016-07-05T07:00", CultureInfo.InvariantCulture)),
DtEnd = new CalDateTime(DateTime.Parse("2016-07-05T08:00",CultureInfo.InvariantCulture)),
};

// Recurring every other Tuesday until Dec 31
Expand All @@ -77,8 +78,8 @@ public void FourthThursdayOfNovember_Tests()
// An event taking place between 07:00 and 19:00, beginning July 5 (a Tuesday)
var vEvent = new CalendarEvent
{
DtStart = new CalDateTime(DateTime.Parse("2000-11-23T07:00")),
DtEnd = new CalDateTime(DateTime.Parse("2000-11-23T19:00")),
DtStart = new CalDateTime(DateTime.Parse("2000-11-23T07:00", CultureInfo.InvariantCulture)),
DtEnd = new CalDateTime(DateTime.Parse("2000-11-23T19:00", CultureInfo.InvariantCulture)),
};

// Recurring every other Tuesday until Dec 31
Expand Down Expand Up @@ -108,8 +109,8 @@ public void DailyExceptSunday_Test()
//An event that happens daily through 2016, except for Sundays
var vEvent = new CalendarEvent
{
DtStart = new CalDateTime(DateTime.Parse("2016-01-01T07:00")),
DtEnd = new CalDateTime(DateTime.Parse("2016-12-31T08:00")),
DtStart = new CalDateTime(DateTime.Parse("2016-01-01T07:00", CultureInfo.InvariantCulture)),
DtEnd = new CalDateTime(DateTime.Parse("2016-12-31T08:00", CultureInfo.InvariantCulture)),
RecurrenceRules = new List<RecurrencePattern> { new RecurrencePattern(FrequencyType.Daily, 1) },
};

Expand Down
3 changes: 2 additions & 1 deletion Ical.Net.Tests/EqualityAndHashingTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using Ical.Net.CalendarComponents;
Expand All @@ -19,7 +20,7 @@ namespace Ical.Net.Tests;
public class EqualityAndHashingTests
{
private const string TzId = "America/Los_Angeles";
private static readonly DateTime _nowTime = DateTime.SpecifyKind(DateTime.Parse("2016-07-16T16:47:02.9310521-04:00"), DateTimeKind.Unspecified);
private static readonly DateTime _nowTime = DateTime.SpecifyKind(DateTime.Parse("2016-07-16T16:47:02.9310521-04:00", CultureInfo.InvariantCulture), DateTimeKind.Unspecified);
private static readonly DateTime _later = _nowTime.AddHours(1);

[Test, TestCaseSource(nameof(CalDateTime_TestCases))]
Expand Down
9 changes: 5 additions & 4 deletions Ical.Net.Tests/GetOccurrenceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Ical.Net.CalendarComponents;
using Ical.Net.DataTypes;
Expand All @@ -20,12 +21,12 @@ internal class GetOccurrenceTests
[Test]
public void WrongDurationTest()
{
var firstStart = new CalDateTime(DateTime.Parse("2016-01-01"));
var firstEnd = new CalDateTime(DateTime.Parse("2016-01-05"));
var firstStart = new CalDateTime(DateTime.Parse("2016-01-01", CultureInfo.InvariantCulture));
var firstEnd = new CalDateTime(DateTime.Parse("2016-01-05", CultureInfo.InvariantCulture));
var vEvent = new CalendarEvent { DtStart = firstStart, DtEnd = firstEnd, };

var secondStart = new CalDateTime(DateTime.Parse("2016-03-01"));
var secondEnd = new CalDateTime(DateTime.Parse("2016-03-05"));
var secondStart = new CalDateTime(DateTime.Parse("2016-03-01", CultureInfo.InvariantCulture));
var secondEnd = new CalDateTime(DateTime.Parse("2016-03-05", CultureInfo.InvariantCulture));
var vEvent2 = new CalendarEvent { DtStart = secondStart, DtEnd = secondEnd, };

var calendar = new Calendar();
Expand Down
1 change: 1 addition & 0 deletions Ical.Net.Tests/Ical.Net.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
<PackageReference Include="NUnit" Version="4.2.2" />
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0" />
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="9.0.0" PrivateAssets="all" />
<PackageReference Include="NUnit.Analyzers" Version="4.3.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
44 changes: 22 additions & 22 deletions Ical.Net.Tests/RecurrenceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2773,7 +2773,7 @@ public void Issue432()
};
var vEvent = new CalendarEvent
{
Start = new CalDateTime(DateTime.Parse("2019-01-04T08:00Z").ToUniversalTime()),
Start = new CalDateTime(DateTime.Parse("2019-01-04T08:00Z", CultureInfo.InvariantCulture).ToUniversalTime()),
};

vEvent.RecurrenceRules.Add(rrule);
Expand Down Expand Up @@ -2806,8 +2806,8 @@ public void Issue432_AllDay()
{
var vEvent = new CalendarEvent
{
Start = new CalDateTime(DateTime.Parse("2020-01-11")), // no time means all day
End = new CalDateTime(DateTime.Parse("2020-01-11T00:00")),
Start = new CalDateTime(DateTime.Parse("2020-01-11", CultureInfo.InvariantCulture)), // no time means all day
End = new CalDateTime(DateTime.Parse("2020-01-11T00:00", CultureInfo.InvariantCulture)),
};

var occurrences = vEvent.GetOccurrences(new CalDateTime(2020,01, 10, 0, 0, 0)).TakeUntil(new CalDateTime(2020, 01, 11, 00, 00, 00));
Expand Down Expand Up @@ -3174,20 +3174,20 @@ public void RDateShouldBeUnionedWithRecurrenceSet()

var calendar = Calendar.Load(ical)!;
var firstEvent = calendar.Events.First();
var startSearch = new CalDateTime(DateTime.Parse("2015-08-28T07:00:00"), _tzid);
var endSearch = new CalDateTime(DateTime.Parse("2016-08-28T07:00:00").AddDays(7), _tzid);
var startSearch = new CalDateTime(DateTime.Parse("2015-08-28T07:00:00", CultureInfo.InvariantCulture), _tzid);
var endSearch = new CalDateTime(DateTime.Parse("2016-08-28T07:00:00", CultureInfo.InvariantCulture).AddDays(7), _tzid);

var occurrences = firstEvent.GetOccurrences(startSearch).TakeUntil(endSearch)
.Select(o => o.Period)
.ToList();

var firstExpectedOccurrence = new CalDateTime(DateTime.Parse("2016-08-29T08:00:00"), _tzid);
var firstExpectedOccurrence = new CalDateTime(DateTime.Parse("2016-08-29T08:00:00", CultureInfo.InvariantCulture), _tzid);
Assert.That(occurrences.First().StartTime, Is.EqualTo(firstExpectedOccurrence));

var firstExpectedRDate = new CalDateTime(DateTime.Parse("2016-08-30T10:00:00"), _tzid);
var firstExpectedRDate = new CalDateTime(DateTime.Parse("2016-08-30T10:00:00", CultureInfo.InvariantCulture), _tzid);
Assert.That(occurrences[1].StartTime.Equals(firstExpectedRDate), Is.True);

var secondExpectedRDate = new CalDateTime(DateTime.Parse("2016-08-31T10:00:00"), _tzid);
var secondExpectedRDate = new CalDateTime(DateTime.Parse("2016-08-31T10:00:00", CultureInfo.InvariantCulture), _tzid);
Assert.That(occurrences[2].StartTime.Equals(secondExpectedRDate), Is.True);
}

Expand Down Expand Up @@ -3215,7 +3215,7 @@ public void OccurrenceMustBeCompletelyContainedWithinSearchRange()
ByDay = new List<WeekDay> { new WeekDay(DayOfWeek.Wednesday) },
};

var start = DateTime.Parse("2016-08-01T07:00:00");
var start = DateTime.Parse("2016-08-01T07:00:00", CultureInfo.InvariantCulture);
var end = start.AddHours(1);
var e = new CalendarEvent
{
Expand All @@ -3233,10 +3233,10 @@ public void OccurrenceMustBeCompletelyContainedWithinSearchRange()

Assert.That(firstEvent, Is.EqualTo(e));

var startSearch = new CalDateTime(DateTime.Parse("2016-07-01T00:00:00"), "UTC");
var endSearch = new CalDateTime(DateTime.Parse("2016-08-31T07:00:00"), "UTC");
var startSearch = new CalDateTime(DateTime.Parse("2016-07-01T00:00:00", CultureInfo.InvariantCulture), "UTC");
var endSearch = new CalDateTime(DateTime.Parse("2016-08-31T07:00:00", CultureInfo.InvariantCulture), "UTC");

var lastExpected = new CalDateTime(DateTime.Parse("2016-08-31T07:00:00"), "UTC");
var lastExpected = new CalDateTime(DateTime.Parse("2016-08-31T07:00:00", CultureInfo.InvariantCulture), "UTC");
var occurrences = firstEvent.GetOccurrences(startSearch).TakeUntil(endSearch)
.Select(o => o.Period)
.ToList();
Expand Down Expand Up @@ -3320,16 +3320,16 @@ public void EventsWithShareUidsShouldGenerateASingleRecurrenceSet()
.Select(o => o.Period)
.ToList();

var expectedSept1Start = new CalDateTime(DateTime.Parse("2016-09-01T16:30:00"), "Europe/Bucharest");
var expectedSept1End = new CalDateTime(DateTime.Parse("2016-09-01T22:00:00"), "Europe/Bucharest");
var expectedSept1Start = new CalDateTime(DateTime.Parse("2016-09-01T16:30:00", CultureInfo.InvariantCulture), "Europe/Bucharest");
var expectedSept1End = new CalDateTime(DateTime.Parse("2016-09-01T22:00:00", CultureInfo.InvariantCulture), "Europe/Bucharest");
Assert.Multiple(() =>
{
Assert.That(orderedOccurrences[3].StartTime, Is.EqualTo(expectedSept1Start));
Assert.That(orderedOccurrences[3].EndTime, Is.EqualTo(expectedSept1End));
});

var expectedSept3Start = new CalDateTime(DateTime.Parse("2016-09-03T07:00:00"), "Europe/Bucharest");
var expectedSept3End = new CalDateTime(DateTime.Parse("2016-09-03T12:30:00"), "Europe/Bucharest");
var expectedSept3Start = new CalDateTime(DateTime.Parse("2016-09-03T07:00:00", CultureInfo.InvariantCulture), "Europe/Bucharest");
var expectedSept3End = new CalDateTime(DateTime.Parse("2016-09-03T12:30:00", CultureInfo.InvariantCulture), "Europe/Bucharest");
Assert.Multiple(() =>
{
Assert.That(orderedOccurrences[5].StartTime, Is.EqualTo(expectedSept3Start));
Expand Down Expand Up @@ -3432,8 +3432,8 @@ public void OneDayRange()
{
var vEvent = new CalendarEvent
{
Start = new CalDateTime(DateTime.Parse("2019-06-07 0:00:00")),
End = new CalDateTime(DateTime.Parse("2019-06-08 00:00:00"))
Start = new CalDateTime(DateTime.Parse("2019-06-07 0:00:00", CultureInfo.InvariantCulture)),
End = new CalDateTime(DateTime.Parse("2019-06-08 00:00:00", CultureInfo.InvariantCulture))
};

//Testing on both the first day and the next, results used to be different
Expand All @@ -3457,8 +3457,8 @@ public void SpecificMinute()
};
var vEvent = new CalendarEvent
{
Start = new CalDateTime(DateTime.Parse("2009-01-01 09:00:00")),
End = new CalDateTime(DateTime.Parse("2009-01-01 17:00:00"))
Start = new CalDateTime(DateTime.Parse("2009-01-01 09:00:00", CultureInfo.InvariantCulture)),
End = new CalDateTime(DateTime.Parse("2009-01-01 17:00:00", CultureInfo.InvariantCulture))
};

vEvent.RecurrenceRules.Add(rrule);
Expand Down Expand Up @@ -3703,8 +3703,8 @@ public void InclusiveRruleUntil()
const string timeZoneId = @"Eastern Standard Time";
var calendar = Calendar.Load(icalText)!;
var firstEvent = calendar.Events.First();
var startSearch = new CalDateTime(DateTime.Parse("2017-07-01T00:00:00"), timeZoneId);
var endSearch = new CalDateTime(DateTime.Parse("2018-07-01T00:00:00"), timeZoneId);
var startSearch = new CalDateTime(DateTime.Parse("2017-07-01T00:00:00", CultureInfo.InvariantCulture), timeZoneId);
var endSearch = new CalDateTime(DateTime.Parse("2018-07-01T00:00:00", CultureInfo.InvariantCulture), timeZoneId);

var occurrences = firstEvent.GetOccurrences(startSearch).TakeUntil(endSearch).ToList();
Assert.That(occurrences, Has.Count.EqualTo(5));
Expand Down
9 changes: 5 additions & 4 deletions Ical.Net.Tests/RecurrenceTests_From_Issues.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#nullable enable
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Ical.Net.CalendarComponents;
using Ical.Net.DataTypes;
Expand Down Expand Up @@ -314,8 +315,8 @@ public void Daylight_Savings_Changes_567()
{
// GetOccurrences Creates event with invalid time due to Daylight Savings changes #567

var calStart = new CalDateTime(DateTimeOffset.Parse("2023-01-14T19:21:03.700Z").UtcDateTime, "UTC");
var calFinish = new CalDateTime(DateTimeOffset.Parse("2023-03-14T18:21:03.700Z").UtcDateTime, "UTC");
var calStart = new CalDateTime(DateTimeOffset.Parse("2023-01-14T19:21:03.700Z", CultureInfo.InvariantCulture).UtcDateTime, "UTC");
var calFinish = new CalDateTime(DateTimeOffset.Parse("2023-03-14T18:21:03.700Z", CultureInfo.InvariantCulture).UtcDateTime, "UTC");
var tz = "Pacific Standard Time";
var pattern = new RecurrencePattern(
"FREQ=WEEKLY;BYDAY=SU,MO,TU,WE"); //Adjust the date to today so that the times remain constant
Expand Down Expand Up @@ -483,8 +484,8 @@ public void Except_Tuesday_Thursday_Saturday_Sunday()
Summary = "BIO CLASS",//subject
Description = "Details at CLASS",//description of meeting
Location = "Building 101",//location
DtStart = new CalDateTime(DateTime.Parse("2017-06-01T08:00")),
DtEnd = new CalDateTime(DateTime.Parse("2017-06-01T09:30")),
DtStart = new CalDateTime(DateTime.Parse("2017-06-01T08:00", CultureInfo.InvariantCulture)),
DtEnd = new CalDateTime(DateTime.Parse("2017-06-01T09:30", CultureInfo.InvariantCulture)),
RecurrenceRules = new List<RecurrencePattern> { new RecurrencePattern(FrequencyType.Daily, 1) },
};

Expand Down
55 changes: 49 additions & 6 deletions Ical.Net.Tests/SerializationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
Expand Down Expand Up @@ -115,19 +114,19 @@ public static void CompareEnumerables(IEnumerable a1, IEnumerable a2, string val
public static string InspectSerializedSection(string serialized, string sectionName, IEnumerable<string> elements)
{
const string notFound = "expected '{0}' not found";
var searchFor = "BEGIN:" + sectionName;
var searchFor = string.Format(CultureInfo.InvariantCulture, "BEGIN:{0}", sectionName);
var begin = serialized.IndexOf(searchFor, StringComparison.Ordinal);
Assert.That(begin, Is.Not.EqualTo(-1), () => string.Format(notFound, searchFor));
Assert.That(begin, Is.Not.EqualTo(-1), () => string.Format(CultureInfo.InvariantCulture, notFound, searchFor));

searchFor = "END:" + sectionName;
searchFor = string.Format(CultureInfo.InvariantCulture, "END:{0}", sectionName);
var end = serialized.IndexOf(searchFor, begin, StringComparison.Ordinal);
Assert.That(end, Is.Not.EqualTo(-1), () => string.Format(notFound, searchFor));
Assert.That(end, Is.Not.EqualTo(-1), () => string.Format(CultureInfo.InvariantCulture, notFound, searchFor));

var searchRegion = serialized.Substring(begin, end - begin + searchFor.Length);

foreach (var e in elements)
{
Assert.That(searchRegion, Does.Contain(SerializationConstants.LineBreak + e + SerializationConstants.LineBreak), () => string.Format(notFound, e));
Assert.That(searchRegion, Does.Contain(SerializationConstants.LineBreak + e + SerializationConstants.LineBreak), () => string.Format(CultureInfo.InvariantCulture, notFound, e));
}

return searchRegion;
Expand Down Expand Up @@ -601,4 +600,48 @@ public void SerializeSubcomponent()
Assert.That(!serialized.Contains("VCALENDAR", StringComparison.Ordinal), Is.True);
});
}

[TestCase("en-US")] // English (United States)
[TestCase("de-DE")] // German (Germany)
// failed before fixing CA1305 warnings
[TestCase("ar-SA")] // Arabic (Saudi Arabia)
// failed before fixing CA1305 warnings
[TestCase("he-IL")] // Hebrew (Israel)
[TestCase("hi-IN")] // Hindi (India)
[TestCase("zh-CN")] // Chinese (Simplified, China)
[TestCase("ja-JP")] // Japanese (Japan)
[TestCase("th-TH")] // Thai (Thailand)
[TestCase("ru-RU")] // Russian (Russia)
[TestCase("ko-KR")] // Korean (Korea)
public void TestConvertToInt32WithNegativeNumberInDifferentCultures(string cultureStr)
{
var originalCulture = CultureInfo.CurrentCulture;
try
{
var culture = new CultureInfo(cultureStr);
CultureInfo.CurrentCulture = culture;

Assert.Multiple(() =>
{
// Deserialize
Assert.That(() => Calendar.Load(
"""
BEGIN:VCALENDAR
BEGIN:VEVENT
DTSTART:20251231
RRULE:FREQ=YEARLY;BYYEARDAY=-1
END:VEVENT
END:VCALENDAR
"""), Throws.Nothing);
// Serialize
Assert.That(() => new DurationSerializer().SerializeToString(new Duration(null, -1)), Is.EqualTo("-P1D"));

});
}
finally
{
CultureInfo.CurrentCulture = originalCulture;
}
}

}
Loading
Loading