Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
This repository was archived by the owner on Jan 23, 2023. It is now read-only.
/coreclrPublic archive

Leap Seconds Support#21420

Merged
tarekgh merged 3 commits intodotnet:masterfromtarekgh:LeapSeconds
Dec 8, 2018
Merged
Show file tree
Hide file tree
Changes from1 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
PrevPrevious commit
NextNext commit
Address Feedback
  • Loading branch information
@tarekgh
tarekgh committedDec 7, 2018
commit79a4612e3f1ee81a3fe77985cdb8b39c0cd7ce8e
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -432,6 +432,7 @@
</ItemGroup>
<ItemGroupCondition="'$(TargetsWindows)' == 'true'">
<CompileInclude="$(BclSourcesRoot)\System\DateTime.Windows.cs" />
<CompileInclude="shared/Interop/Windows/NtDll/Interop.NtQuerySystemInformation.cs" />
Copy link
Member

Choose a reason for hiding this comment

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

This should be in the project in the shared partition

<CompileInclude="$(BclSourcesRoot)\Interop\Windows\Kernel32\Interop.GetSystemDirectoryW.cs" />
<CompileInclude="$(BclSourcesRoot)\System\ApplicationModel.Windows.cs" />
<CompileInclude="$(BclSourcesRoot)\System\Diagnostics\DebugProvider.Windows.cs" />
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

usingSystem;
usingSystem.Runtime.InteropServices;

internalpartialclassInterop
{
internalpartialclassNtDll
{
[DllImport(Libraries.NtDll)]
internalstaticunsafeexternintNtQuerySystemInformation(intSystemInformationClass,void*SystemInformation,intSystemInformationLength,uint*ReturnLength);

[StructLayout(LayoutKind.Sequential)]
internalstructSYSTEM_LEAP_SECOND_INFORMATION
{
publicboolEnabled;
publicuintFlags;
}

internalconstintSystemLeapSecondInformation=206;
}
}
16 changes: 8 additions & 8 deletionssrc/System.Private.CoreLib/shared/System/DateTime.cs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -196,7 +196,7 @@ public DateTime(int year, int month, int day, Calendar calendar)
//
public DateTime(int year, int month, int day, int hour, int minute, int second)
{
if (second == 60 &&s_isLeapSecondsSupportedSystem && IsValidTimeWithLeapSeconds(year, month, day, hour, minute, second, DateTimeKind.Unspecified))
if (second == 60 &&s_systemSupportsLeapSeconds && IsValidTimeWithLeapSeconds(year, month, day, hour, minute, second, DateTimeKind.Unspecified))
{
// if we have leap second (second = 60) then we'll need to check if it is valid time.
// if it is valid, then we adjust the second to 59 so DateTime will consider this second is last second
Expand All@@ -214,7 +214,7 @@ public DateTime(int year, int month, int day, int hour, int minute, int second,
throw new ArgumentException(SR.Argument_InvalidDateTimeKind, nameof(kind));
}

if (second == 60 &&s_isLeapSecondsSupportedSystem && IsValidTimeWithLeapSeconds(year, month, day, hour, minute, second, kind))
if (second == 60 &&s_systemSupportsLeapSeconds && IsValidTimeWithLeapSeconds(year, month, day, hour, minute, second, kind))
{
// if we have leap second (second = 60) then we'll need to check if it is valid time.
// if it is valid, then we adjust the second to 59 so DateTime will consider this second is last second
Expand All@@ -236,7 +236,7 @@ public DateTime(int year, int month, int day, int hour, int minute, int second,
throw new ArgumentNullException(nameof(calendar));

int originalSecond = second;
if (second == 60 &&s_isLeapSecondsSupportedSystem)
if (second == 60 &&s_systemSupportsLeapSeconds)
{
// Reset the second value now and then we'll validate it later when we get the final Gregorian date.
second = 59;
Expand DownExpand Up@@ -264,7 +264,7 @@ public DateTime(int year, int month, int day, int hour, int minute, int second,
throw new ArgumentOutOfRangeException(nameof(millisecond), SR.Format(SR.ArgumentOutOfRange_Range, 0, MillisPerSecond - 1));
}

if (second == 60 &&s_isLeapSecondsSupportedSystem && IsValidTimeWithLeapSeconds(year, month, day, hour, minute, second, DateTimeKind.Unspecified))
if (second == 60 &&s_systemSupportsLeapSeconds && IsValidTimeWithLeapSeconds(year, month, day, hour, minute, second, DateTimeKind.Unspecified))
{
// if we have leap second (second = 60) then we'll need to check if it is valid time.
// if it is valid, then we adjust the second to 59 so DateTime will consider this second is last second
Expand All@@ -291,7 +291,7 @@ public DateTime(int year, int month, int day, int hour, int minute, int second,
throw new ArgumentException(SR.Argument_InvalidDateTimeKind, nameof(kind));
}

if (second == 60 &&s_isLeapSecondsSupportedSystem && IsValidTimeWithLeapSeconds(year, month, day, hour, minute, second, kind))
if (second == 60 &&s_systemSupportsLeapSeconds && IsValidTimeWithLeapSeconds(year, month, day, hour, minute, second, kind))
{
// if we have leap second (second = 60) then we'll need to check if it is valid time.
// if it is valid, then we adjust the second to 59 so DateTime will consider this second is last second
Expand DownExpand Up@@ -320,7 +320,7 @@ public DateTime(int year, int month, int day, int hour, int minute, int second,
}

int originalSecond = second;
if (second == 60 &&s_isLeapSecondsSupportedSystem)
if (second == 60 &&s_systemSupportsLeapSeconds)
{
// Reset the second value now and then we'll validate it later when we get the final Gregorian date.
second = 59;
Expand DownExpand Up@@ -356,7 +356,7 @@ public DateTime(int year, int month, int day, int hour, int minute, int second,
}

int originalSecond = second;
if (second == 60 &&s_isLeapSecondsSupportedSystem)
if (second == 60 &&s_systemSupportsLeapSeconds)
{
// Reset the second value now and then we'll validate it later when we get the final Gregorian date.
second = 59;
Expand DownExpand Up@@ -1650,7 +1650,7 @@ internal static bool TryCreate(int year, int month, int day, int hour, int minut

if (second == 60)
{
if (s_isLeapSecondsSupportedSystem && IsValidTimeWithLeapSeconds(year, month, day, hour, minute, second, DateTimeKind.Unspecified))
if (s_systemSupportsLeapSeconds && IsValidTimeWithLeapSeconds(year, month, day, hour, minute, second, DateTimeKind.Unspecified))
{
// if we have leap second (second = 60) then we'll need to check if it is valid time.
// if it is valid, then we adjust the second to 59 so DateTime will consider this second is last second
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -111,7 +111,7 @@ public DateTimeOffset(int year, int month, int day, int hour, int minute, int se
_offsetMinutes = ValidateOffset(offset);

int originalSecond = second;
if (second == 60 && DateTime.s_isLeapSecondsSupportedSystem)
if (second == 60 && DateTime.s_systemSupportsLeapSeconds)
{
// Reset the leap second to 59 for now and then we'll validate it after getting the final UTC time.
second = 59;
Expand All@@ -133,7 +133,7 @@ public DateTimeOffset(int year, int month, int day, int hour, int minute, int se
_offsetMinutes = ValidateOffset(offset);

int originalSecond = second;
if (second == 60 && DateTime.s_isLeapSecondsSupportedSystem)
if (second == 60 && DateTime.s_systemSupportsLeapSeconds)
{
// Reset the leap second to 59 for now and then we'll validate it after getting the final UTC time.
second = 59;
Expand All@@ -155,7 +155,7 @@ public DateTimeOffset(int year, int month, int day, int hour, int minute, int se
_offsetMinutes = ValidateOffset(offset);

int originalSecond = second;
if (second == 60 && DateTime.s_isLeapSecondsSupportedSystem)
if (second == 60 && DateTime.s_systemSupportsLeapSeconds)
{
// Reset the leap second to 59 for now and then we'll validate it after getting the final UTC time.
second = 59;
Expand Down
8 changes: 2 additions & 6 deletionssrc/System.Private.CoreLib/src/System/DateTime.Unix.cs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,17 +8,13 @@ namespace System
{
public readonly partial struct DateTime
{
internalstatic readonlybools_isLeapSecondsSupportedSystem = false;
internalconstbools_systemSupportsLeapSeconds = false;

public static DateTime UtcNow
{
get
{
// following code is tuned for speed. Don't change it without running benchmark.
long ticks = 0;
ticks = GetSystemTimeAsFileTime();

return new DateTime(((ulong)(ticks + FileTimeOffset)) | KindUtc);
return new DateTime(((ulong)(GetSystemTimeAsFileTime() + FileTimeOffset)) | KindUtc);
}
}

Expand Down
111 changes: 52 additions & 59 deletionssrc/System.Private.CoreLib/src/System/DateTime.Windows.cs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,24 +9,20 @@ namespace System
{
public readonly partial struct DateTime
{
internal static readonly bools_isLeapSecondsSupportedSystem =IsLeapSecondsSupportedSystem();
internal static readonly bools_systemSupportsLeapSeconds =SystemSupportsLeapSeconds();

public static DateTime UtcNow
{
get
{
// following code is tuned for speed. Don't change it without running benchmark.
long ticks = 0;

if (s_isLeapSecondsSupportedSystem)
if (s_systemSupportsLeapSeconds)
{
FullSystemTime time = new FullSystemTime();
GetSystemTimeWithLeapSecondsHandling(ref time);
return CreateDateTimeFromSystemTime(ref time);
FullSystemTime time;
GetSystemTimeWithLeapSecondsHandling(out time);
return CreateDateTimeFromSystemTime(in time);
}

ticks = GetSystemTimeAsFileTime();
return new DateTime(((ulong)(ticks + FileTimeOffset)) | KindUtc);
return new DateTime(((ulong)(GetSystemTimeAsFileTime() + FileTimeOffset)) | KindUtc);
}
}

Expand All@@ -37,7 +33,7 @@ public static DateTime FromFileTimeUtc(long fileTime)
throw new ArgumentOutOfRangeException(nameof(fileTime), SR.ArgumentOutOfRange_FileTimeInvalid);
}

if (s_isLeapSecondsSupportedSystem)
if (s_systemSupportsLeapSeconds)
{
return InternalFromFileTime(fileTime);
}
Expand All@@ -51,7 +47,7 @@ public long ToFileTimeUtc() {
// Treats the input as universal if it is not specified
long ticks = ((InternalKind & LocalMask) != 0) ? ToUniversalTime().InternalTicks : this.InternalTicks;

if (s_isLeapSecondsSupportedSystem)
if (s_systemSupportsLeapSeconds)
{
return InternalToFileTime(ticks);
}
Expand All@@ -71,64 +67,71 @@ internal static bool IsValidTimeWithLeapSeconds(int year, int month, int day, in

switch (kind)
{
case DateTimeKind.Local: return ValidateSystemTime(ref time, localTime: true);
case DateTimeKind.Utc: return ValidateSystemTime(ref time, localTime: false);
case DateTimeKind.Local: return ValidateSystemTime(ref time.systemTime, localTime: true);
case DateTimeKind.Utc: return ValidateSystemTime(ref time.systemTime, localTime: false);
default:
return ValidateSystemTime(ref time, localTime: true) || ValidateSystemTime(ref time, localTime: false);
return ValidateSystemTime(ref time.systemTime, localTime: true) || ValidateSystemTime(ref time.systemTime, localTime: false);
}
}

internal static DateTime InternalFromFileTime(long fileTime)
{
FullSystemTime time = new FullSystemTime();
if (SystemFileTimeToSystemTime(fileTime,ref time))
FullSystemTime time;
if (SystemFileTimeToSystemTime(fileTime,out time))
Copy link
Member

Choose a reason for hiding this comment

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

Nit:if (SystemFileTimeToSystemTime(fileTime, out FullSystemTime time))

{
time.hundredNanoSecond = fileTime % TicksPerMillisecond;
return CreateDateTimeFromSystemTime(ref time);
return CreateDateTimeFromSystemTime(in time);
}

throw new ArgumentOutOfRangeException("fileTime", SR.ArgumentOutOfRange_DateTimeBadTicks);
}

internal static long InternalToFileTime(long ticks)
{
long fileTime = 0;
long fileTime;
FullSystemTime time = new FullSystemTime(ticks);
if (SystemTimeToSystemFileTime(ref time, ref fileTime))
if (SystemTimeToSystemFileTime(ref time.systemTime, out fileTime))
Copy link
Member

Choose a reason for hiding this comment

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

Nit:if (SystemTimeToSystemFileTime(ref time.systemTime, out long fileTime))

{
return fileTime + ticks % TicksPerMillisecond;
}

throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_FileTimeInvalid);
}

// Just in case for any reason CreateDateTimeFromSystemTime not get inlined,
// we are passing time by ref to avoid copying the structure while calling the method.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static DateTime CreateDateTimeFromSystemTime(ref FullSystemTime time)
internal static DateTime CreateDateTimeFromSystemTime(in FullSystemTime time)
{
long ticks = DateToTicks(time.wYear, time.wMonth, time.wDay);
ticks += TimeToTicks(time.wHour, time.wMinute, time.wSecond);
ticks += time.wMillisecond * TicksPerMillisecond;
long ticks = DateToTicks(time.systemTime.Year, time.systemTime.Month, time.systemTime.Day);
ticks += TimeToTicks(time.systemTime.Hour, time.systemTime.Minute, time.systemTime.Second);
ticks += time.systemTime.Milliseconds * TicksPerMillisecond;
ticks += time.hundredNanoSecond;
return new DateTime( ((UInt64)(ticks)) | KindUtc);
}

// FullSystemTime struct matches Windows SYSTEMTIME struct, except we added the extra nanoSeconds field to store
// more precise time.
private static unsafe bool SystemSupportsLeapSeconds()
{
Interop.NtDll.SYSTEM_LEAP_SECOND_INFORMATION slsi = new Interop.NtDll.SYSTEM_LEAP_SECOND_INFORMATION();
return Interop.NtDll.NtQuerySystemInformation(
Interop.NtDll.SystemLeapSecondInformation,
(void *) &slsi,
sizeof(Interop.NtDll.SYSTEM_LEAP_SECOND_INFORMATION),
null) == 0 && slsi.Enabled;
}

// FullSystemTime struct is the SYSTEMTIME struct with extra hundredNanoSecond field to store more precise time.
[StructLayout(LayoutKind.Sequential)]
internal struct FullSystemTime
{
internal FullSystemTime(int year, int month, DayOfWeek dayOfWeek, int day, int hour, int minute, int second)
{
wYear = (ushort) year;
wMonth = (ushort) month;
wDayOfWeek = (ushort) dayOfWeek;
wDay = (ushort) day;
wHour = (ushort) hour;
wMinute = (ushort) minute;
wSecond = (ushort) second;
wMillisecond = 0;
systemTime.Year = (ushort) year;
systemTime.Month = (ushort) month;
systemTime.DayOfWeek = (ushort) dayOfWeek;
systemTime.Day = (ushort) day;
systemTime.Hour = (ushort) hour;
systemTime.Minute = (ushort) minute;
systemTime.Second = (ushort) second;
systemTime.Milliseconds = 0;
hundredNanoSecond = 0;
}

Expand All@@ -139,42 +142,32 @@ internal FullSystemTime(long ticks)
int year, month, day;
dt.GetDatePart(out year, out month, out day);

wYear = (ushort) year;
wMonth = (ushort) month;
wDayOfWeek = (ushort) dt.DayOfWeek;
wDay = (ushort) day;
wHour = (ushort) dt.Hour;
wMinute = (ushort) dt.Minute;
wSecond = (ushort) dt.Second;
wMillisecond = (ushort) dt.Millisecond;
systemTime.Year = (ushort) year;
systemTime.Month = (ushort) month;
systemTime.DayOfWeek = (ushort) dt.DayOfWeek;
systemTime.Day = (ushort) day;
systemTime.Hour = (ushort) dt.Hour;
systemTime.Minute = (ushort) dt.Minute;
systemTime.Second = (ushort) dt.Second;
systemTime.Milliseconds = (ushort) dt.Millisecond;
hundredNanoSecond = 0;
}

internal ushort wYear;
internal ushort wMonth;
internal ushort wDayOfWeek;
internal ushort wDay;
internal ushort wHour;
internal ushort wMinute;
internal ushort wSecond;
internal ushort wMillisecond;
internal Interop.Kernel32.SYSTEMTIME systemTime;
Copy link
Member

@jkotasjkotasDec 8, 2018
edited
Loading

Choose a reason for hiding this comment

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

The coding convention is to place the fields first.

internal long hundredNanoSecond;
};

[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern bool ValidateSystemTime(ref FullSystemTime time, bool localTime);

[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
internal static extern bool IsLeapSecondsSupportedSystem();
internal static extern bool ValidateSystemTime(ref Interop.Kernel32.SYSTEMTIME time, bool localTime);
Copy link
Member

Choose a reason for hiding this comment

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

The first argument can bein


[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern bool SystemFileTimeToSystemTime(long fileTime,ref FullSystemTime time);
internal static extern bool SystemFileTimeToSystemTime(long fileTime,out FullSystemTime time);
Copy link
Member

Choose a reason for hiding this comment

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

Is there a reason why we call some of these thingsSystemFileTime? There isSYSTEMTIME andFILETIME today, but there is no SystemFileTime today.

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

I was trying to have it clear FILETIME is always a system file time. if you think this is confusing, I can change it.


[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void GetSystemTimeWithLeapSecondsHandling(ref FullSystemTime time);
internal static extern void GetSystemTimeWithLeapSecondsHandling(out FullSystemTime time);

[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern bool SystemTimeToSystemFileTime(refFullSystemTime time,ref long fileTime);
internal static extern bool SystemTimeToSystemFileTime(refInterop.Kernel32.SYSTEMTIME time,out long fileTime);
Copy link
Member

Choose a reason for hiding this comment

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

The first argument can bein Interop.Kernel32.SYSTEMTIME


[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern long GetSystemTimeAsFileTime();
Expand Down
Loading

[8]ページ先頭

©2009-2025 Movatter.jp