Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

Add DateTime Leap Seconds Tests #33939

Merged
merged 4 commits into from
Dec 12, 2018
Merged
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
56 changes: 55 additions & 1 deletion src/System.Runtime/tests/System/DateTimeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Globalization;
using System.Linq;
using System.Runtime.Serialization;
using System.Runtime.InteropServices;
using Xunit;

namespace System.Tests
Expand Down Expand Up @@ -721,7 +722,7 @@ public void Subtract_TimeSpan_ReturnsExpected(DateTime dateTime, TimeSpan timeSp
Assert.Equal(expected, dateTime.Subtract(timeSpan));
Assert.Equal(expected, dateTime - timeSpan);
}

public static IEnumerable<object[]> Subtract_OutOfRangeTimeSpan_TestData()
{
yield return new object[] { DateTime.Now, TimeSpan.MinValue };
Expand Down Expand Up @@ -2177,6 +2178,59 @@ public void GetObjectData_NullInfo_ThrowsArgumentNullException()
AssertExtensions.Throws<ArgumentNullException>("info", () => ((ISerializable)DateTime.Now).GetObjectData(null, new StreamingContext()));
}

[Fact]
public void TestRoundTrippingDateTimeAndFileTime()
{
// This test ensure the round tripping of DateTime with the system file time.
// It is important to have this working on systems support leap seconds as the conversion wouldn't be simple
tarekgh marked this conversation as resolved.
Show resolved Hide resolved
// conversion but involve some OS calls to ensure the right conversion is happening.

DateTime now = DateTime.UtcNow;
long fileTime = now.ToFileTimeUtc();
DateTime roundTrippedDateTime = DateTime.FromFileTimeUtc(fileTime);
Assert.Equal(now, roundTrippedDateTime);

now = DateTime.Now;
fileTime = now.ToFileTime();
roundTrippedDateTime = DateTime.FromFileTime(fileTime);
Assert.Equal(now, roundTrippedDateTime);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need a similar test for DateTimeOffset?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DateTimeOffset is using DateTime for such operations.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't that an implementation detail?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


[Fact]
[PlatformSpecific(TestPlatforms.Windows)]
public void TestTimeSynchronizationWithTheSystem()
{
// The reported time by the framework should be synchronized with the OS.
// There shouldn't be any shift by more than one second, otherwise there is something wrong.
// This test is useful when running on a system supporting leap seconds to ensure when the system
// has leap seconds, the framework reported time will still be synchronized.

SYSTEMTIME st;
GetSystemTime(out st);
DateTime dt = DateTime.UtcNow;
tarekgh marked this conversation as resolved.
Show resolved Hide resolved

DateTime systemDateTimeNow = new DateTime(st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMillisecond, DateTimeKind.Utc);
TimeSpan diff = systemDateTimeNow - dt;

Assert.True(diff < TimeSpan.FromSeconds(1), $"Reported DateTime.UtcNow {dt} is shifted by more than one second then the system time {systemDateTimeNow}");
}

[DllImport("Kernel32.dll")]
internal static extern void GetSystemTime(out SYSTEMTIME lpSystemTime);

[StructLayout(LayoutKind.Sequential)]
internal struct SYSTEMTIME
{
internal ushort wYear;
internal ushort wMonth;
internal ushort wDayOfWeek;
internal ushort wDay;
internal ushort wHour;
internal ushort wMinute;
internal ushort wSecond;
internal ushort wMillisecond;
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have or need tests that constructs a specific leap second time and validates that the right things happen?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we can do that in the current time as we don't have a system with a leap seconds.

private class DateMaxCalendar : Calendar
{
public override int[] Eras => throw new NotImplementedException();
Expand Down