@@ -196,6 +196,14 @@ public DateTime(int year, int month, int day, Calendar calendar)
196196//
197197public DateTime ( int year , int month , int day , int hour , int minute , int second )
198198{
199+ if ( second == 60 && s_systemSupportsLeapSeconds && IsValidTimeWithLeapSeconds ( year , month , day , hour , minute , second , DateTimeKind . Unspecified ) )
200+ {
201+ // if we have leap second (second = 60) then we'll need to check if it is valid time.
202+ // if it is valid, then we adjust the second to 59 so DateTime will consider this second is last second
203+ // in the specified minute.
204+ // if it is not valid time, we'll eventually throw.
205+ second = 59 ;
206+ }
199207_dateData = ( ulong ) ( DateToTicks ( year , month , day ) + TimeToTicks ( hour , minute , second ) ) ;
200208}
201209
@@ -205,6 +213,16 @@ public DateTime(int year, int month, int day, int hour, int minute, int second,
205213{
206214throw new ArgumentException ( SR . Argument_InvalidDateTimeKind , nameof ( kind ) ) ;
207215}
216+
217+ if ( second == 60 && s_systemSupportsLeapSeconds && IsValidTimeWithLeapSeconds ( year , month , day , hour , minute , second , kind ) )
218+ {
219+ // if we have leap second (second = 60) then we'll need to check if it is valid time.
220+ // if it is valid, then we adjust the second to 59 so DateTime will consider this second is last second
221+ // in the specified minute.
222+ // if it is not valid time, we'll eventually throw.
223+ second = 59 ;
224+ }
225+
208226long ticks = DateToTicks ( year , month , day ) + TimeToTicks ( hour , minute , second ) ;
209227_dateData = ( ( ulong ) ticks | ( ( ulong ) kind << KindShift ) ) ;
210228}
@@ -216,7 +234,24 @@ public DateTime(int year, int month, int day, int hour, int minute, int second,
216234{
217235if ( calendar == null )
218236throw new ArgumentNullException ( nameof ( calendar ) ) ;
237+
238+ int originalSecond = second ;
239+ if ( second == 60 && s_systemSupportsLeapSeconds )
240+ {
241+ // Reset the second value now and then we'll validate it later when we get the final Gregorian date.
242+ second = 59 ;
243+ }
244+
219245_dateData = ( ulong ) calendar . ToDateTime ( year , month , day , hour , minute , second , 0 ) . Ticks ;
246+
247+ if ( originalSecond == 60 )
248+ {
249+ DateTime dt = new DateTime ( _dateData ) ;
250+ if ( ! IsValidTimeWithLeapSeconds ( dt . Year , dt . Month , dt . Day , dt . Hour , dt . Minute , 60 , DateTimeKind . Unspecified ) )
251+ {
252+ throw new ArgumentOutOfRangeException ( null , SR . ArgumentOutOfRange_BadHourMinuteSecond ) ;
253+ }
254+ }
220255}
221256
222257// Constructs a DateTime from a given year, month, day, hour,
@@ -228,6 +263,16 @@ public DateTime(int year, int month, int day, int hour, int minute, int second,
228263{
229264throw new ArgumentOutOfRangeException ( nameof ( millisecond ) , SR . Format ( SR . ArgumentOutOfRange_Range , 0 , MillisPerSecond - 1 ) ) ;
230265}
266+
267+ if ( second == 60 && s_systemSupportsLeapSeconds && IsValidTimeWithLeapSeconds ( year , month , day , hour , minute , second , DateTimeKind . Unspecified ) )
268+ {
269+ // if we have leap second (second = 60) then we'll need to check if it is valid time.
270+ // if it is valid, then we adjust the second to 59 so DateTime will consider this second is last second
271+ // in the specified minute.
272+ // if it is not valid time, we'll eventually throw.
273+ second = 59 ;
274+ }
275+
231276long ticks = DateToTicks ( year , month , day ) + TimeToTicks ( hour , minute , second ) ;
232277ticks += millisecond * TicksPerMillisecond ;
233278if ( ticks < MinTicks || ticks > MaxTicks )
@@ -245,6 +290,16 @@ public DateTime(int year, int month, int day, int hour, int minute, int second,
245290{
246291throw new ArgumentException ( SR . Argument_InvalidDateTimeKind , nameof ( kind ) ) ;
247292}
293+
294+ if ( second == 60 && s_systemSupportsLeapSeconds && IsValidTimeWithLeapSeconds ( year , month , day , hour , minute , second , kind ) )
295+ {
296+ // if we have leap second (second = 60) then we'll need to check if it is valid time.
297+ // if it is valid, then we adjust the second to 59 so DateTime will consider this second is last second
298+ // in the specified minute.
299+ // if it is not valid time, we'll eventually throw.
300+ second = 59 ;
301+ }
302+
248303long ticks = DateToTicks ( year , month , day ) + TimeToTicks ( hour , minute , second ) ;
249304ticks += millisecond * TicksPerMillisecond ;
250305if ( ticks < MinTicks || ticks > MaxTicks )
@@ -263,11 +318,28 @@ public DateTime(int year, int month, int day, int hour, int minute, int second,
263318{
264319throw new ArgumentOutOfRangeException ( nameof ( millisecond ) , SR . Format ( SR . ArgumentOutOfRange_Range , 0 , MillisPerSecond - 1 ) ) ;
265320}
321+
322+ int originalSecond = second ;
323+ if ( second == 60 && s_systemSupportsLeapSeconds )
324+ {
325+ // Reset the second value now and then we'll validate it later when we get the final Gregorian date.
326+ second = 59 ;
327+ }
328+
266329long ticks = calendar . ToDateTime ( year , month , day , hour , minute , second , 0 ) . Ticks ;
267330ticks += millisecond * TicksPerMillisecond ;
268331if ( ticks < MinTicks || ticks > MaxTicks )
269332throw new ArgumentException ( SR . Arg_DateTimeRange ) ;
270333_dateData = ( ulong ) ticks ;
334+
335+ if ( originalSecond == 60 )
336+ {
337+ DateTime dt = new DateTime ( _dateData ) ;
338+ if ( ! IsValidTimeWithLeapSeconds ( dt . Year , dt . Month , dt . Day , dt . Hour , dt . Minute , 60 , DateTimeKind . Unspecified ) )
339+ {
340+ throw new ArgumentOutOfRangeException ( null , SR . ArgumentOutOfRange_BadHourMinuteSecond ) ;
341+ }
342+ }
271343}
272344
273345public DateTime ( int year , int month , int day , int hour , int minute , int second , int millisecond , Calendar calendar , DateTimeKind kind )
@@ -282,11 +354,28 @@ public DateTime(int year, int month, int day, int hour, int minute, int second,
282354{
283355throw new ArgumentException ( SR . Argument_InvalidDateTimeKind , nameof ( kind ) ) ;
284356}
357+
358+ int originalSecond = second ;
359+ if ( second == 60 && s_systemSupportsLeapSeconds )
360+ {
361+ // Reset the second value now and then we'll validate it later when we get the final Gregorian date.
362+ second = 59 ;
363+ }
364+
285365long ticks = calendar . ToDateTime ( year , month , day , hour , minute , second , 0 ) . Ticks ;
286366ticks += millisecond * TicksPerMillisecond ;
287367if ( ticks < MinTicks || ticks > MaxTicks )
288368throw new ArgumentException ( SR . Arg_DateTimeRange ) ;
289369_dateData = ( ( ulong ) ticks | ( ( ulong ) kind << KindShift ) ) ;
370+
371+ if ( originalSecond == 60 )
372+ {
373+ DateTime dt = new DateTime ( _dateData ) ;
374+ if ( ! IsValidTimeWithLeapSeconds ( dt . Year , dt . Month , dt . Day , dt . Hour , dt . Minute , 60 , kind ) )
375+ {
376+ throw new ArgumentOutOfRangeException ( null , SR . ArgumentOutOfRange_BadHourMinuteSecond ) ;
377+ }
378+ }
290379}
291380
292381private DateTime ( SerializationInfo info , StreamingContext context )
@@ -338,8 +427,6 @@ private DateTime(SerializationInfo info, StreamingContext context)
338427}
339428}
340429
341-
342-
343430internal long InternalTicks
344431{
345432get
@@ -722,6 +809,11 @@ public static DateTime FromFileTimeUtc(long fileTime)
722809throw new ArgumentOutOfRangeException ( nameof ( fileTime ) , SR . ArgumentOutOfRange_FileTimeInvalid ) ;
723810}
724811
812+ if ( s_systemSupportsLeapSeconds )
813+ {
814+ return FromFileTimeLeapSecondsAware ( fileTime ) ;
815+ }
816+
725817// This is the ticks in Universal time for this fileTime.
726818long universalTicks = fileTime + FileTimeOffset ;
727819return new DateTime ( universalTicks , DateTimeKind . Utc ) ;
@@ -1223,11 +1315,18 @@ public long ToFileTimeUtc()
12231315{
12241316// Treats the input as universal if it is not specified
12251317long ticks = ( ( InternalKind & LocalMask ) != 0 ) ? ToUniversalTime ( ) . InternalTicks : this . InternalTicks ;
1318+
1319+ if ( s_systemSupportsLeapSeconds )
1320+ {
1321+ return ToFileTimeLeapSecondsAware ( ticks ) ;
1322+ }
1323+
12261324ticks -= FileTimeOffset ;
12271325if ( ticks < 0 )
12281326{
12291327throw new ArgumentOutOfRangeException ( null , SR . ArgumentOutOfRange_FileTimeInvalid ) ;
12301328}
1329+
12311330return ticks ;
12321331}
12331332
@@ -1574,14 +1673,32 @@ internal static bool TryCreate(int year, int month, int day, int hour, int minut
15741673{
15751674return false ;
15761675}
1577- if ( hour < 0 || hour >= 24 || minute < 0 || minute >= 60 || second < 0 || second >= 60 )
1676+ if ( hour < 0 || hour >= 24 || minute < 0 || minute >= 60 || second < 0 || second > 60 )
15781677{
15791678return false ;
15801679}
15811680if ( millisecond < 0 || millisecond >= MillisPerSecond )
15821681{
15831682return false ;
15841683}
1684+
1685+ if ( second == 60 )
1686+ {
1687+ if ( s_systemSupportsLeapSeconds && IsValidTimeWithLeapSeconds ( year , month , day , hour , minute , second , DateTimeKind . Unspecified ) )
1688+ {
1689+ // if we have leap second (second = 60) then we'll need to check if it is valid time.
1690+ // if it is valid, then we adjust the second to 59 so DateTime will consider this second is last second
1691+ // of this minute.
1692+ // if it is not valid time, we'll eventually throw.
1693+ // although this is unspecified datetime kind, we'll assume the passed time is UTC to check the leap seconds.
1694+ second = 59 ;
1695+ }
1696+ else
1697+ {
1698+ return false ;
1699+ }
1700+ }
1701+
15851702long ticks = DateToTicks ( year , month , day ) + TimeToTicks ( hour , minute , second ) ;
15861703
15871704ticks += millisecond * TicksPerMillisecond ;