@@ -805,7 +805,7 @@ public TimeSpan GetUtcOffset (DateTimeOffset dateTimeOffset)
805
805
return GetUtcOffset ( dateTimeOffset . UtcDateTime , out isDST ) ;
806
806
}
807
807
808
- private TimeSpan GetUtcOffset ( DateTime dateTime , out bool isDST )
808
+ private TimeSpan GetUtcOffset ( DateTime dateTime , out bool isDST , bool forOffset = false )
809
809
{
810
810
isDST = false ;
811
811
@@ -817,7 +817,7 @@ private TimeSpan GetUtcOffset (DateTime dateTime, out bool isDST)
817
817
tz = TimeZoneInfo . Local ;
818
818
819
819
bool isTzDst ;
820
- var tzOffset = GetUtcOffsetHelper ( dateTime , tz , out isTzDst ) ;
820
+ var tzOffset = GetUtcOffsetHelper ( dateTime , tz , out isTzDst , forOffset ) ;
821
821
822
822
if ( tz == this ) {
823
823
isDST = isTzDst ;
@@ -828,11 +828,11 @@ private TimeSpan GetUtcOffset (DateTime dateTime, out bool isDST)
828
828
if ( ! TryAddTicks ( dateTime , - tzOffset . Ticks , out utcDateTime , DateTimeKind . Utc ) )
829
829
return BaseUtcOffset ;
830
830
831
- return GetUtcOffsetHelper ( utcDateTime , this , out isDST ) ;
831
+ return GetUtcOffsetHelper ( utcDateTime , this , out isDST , forOffset ) ;
832
832
}
833
833
834
834
// This is an helper method used by the method above, do not use this on its own.
835
- private static TimeSpan GetUtcOffsetHelper ( DateTime dateTime , TimeZoneInfo tz , out bool isDST )
835
+ private static TimeSpan GetUtcOffsetHelper ( DateTime dateTime , TimeZoneInfo tz , out bool isDST , bool forOffset = false )
836
836
{
837
837
if ( dateTime . Kind == DateTimeKind . Local && tz != TimeZoneInfo . Local )
838
838
throw new Exception ( ) ;
@@ -843,7 +843,7 @@ private static TimeSpan GetUtcOffsetHelper (DateTime dateTime, TimeZoneInfo tz,
843
843
return TimeSpan . Zero ;
844
844
845
845
TimeSpan offset ;
846
- if ( tz . TryGetTransitionOffset ( dateTime , out offset , out isDST ) )
846
+ if ( tz . TryGetTransitionOffset ( dateTime , out offset , out isDST , forOffset ) )
847
847
return offset ;
848
848
849
849
if ( dateTime . Kind == DateTimeKind . Utc ) {
@@ -870,10 +870,12 @@ private static TimeSpan GetUtcOffsetHelper (DateTime dateTime, TimeZoneInfo tz,
870
870
871
871
if ( tzRule != null && tz . IsInDST ( tzRule , dateTime ) ) {
872
872
// Replicate what .NET does when given a time which falls into the hour which is lost when
873
- // DST starts. isDST should always be true but the offset should be BaseUtcOffset without the
873
+ // DST starts. isDST should be false and the offset should be BaseUtcOffset without the
874
874
// DST delta while in that hour.
875
- isDST = true ;
875
+ if ( forOffset )
876
+ isDST = true ;
876
877
if ( tz . IsInDST ( tzRule , dstUtcDateTime ) ) {
878
+ isDST = true ;
877
879
return tz . BaseUtcOffset + tzRule . DaylightDelta ;
878
880
} else {
879
881
return tz . BaseUtcOffset ;
@@ -982,7 +984,21 @@ internal bool IsDaylightSavingTime (DateTime dateTime, TimeZoneInfoOptions flags
982
984
983
985
public bool IsDaylightSavingTime ( DateTimeOffset dateTimeOffset )
984
986
{
985
- return IsDaylightSavingTime ( dateTimeOffset . DateTime ) ;
987
+ var dateTime = dateTimeOffset . DateTime ;
988
+
989
+ if ( dateTime . Kind == DateTimeKind . Local && IsInvalidTime ( dateTime ) )
990
+ throw new ArgumentException ( "dateTime is invalid and Kind is Local" ) ;
991
+
992
+ if ( this == TimeZoneInfo . Utc )
993
+ return false ;
994
+
995
+ if ( ! SupportsDaylightSavingTime )
996
+ return false ;
997
+
998
+ bool isDst ;
999
+ GetUtcOffset ( dateTime , out isDst , true ) ;
1000
+
1001
+ return isDst ;
986
1002
}
987
1003
988
1004
internal DaylightTime GetDaylightChanges ( int year )
@@ -1219,7 +1235,7 @@ private AdjustmentRule GetApplicableRule (DateTime dateTime)
1219
1235
return null ;
1220
1236
}
1221
1237
1222
- private bool TryGetTransitionOffset ( DateTime dateTime , out TimeSpan offset , out bool isDst )
1238
+ private bool TryGetTransitionOffset ( DateTime dateTime , out TimeSpan offset , out bool isDst , bool forOffset = false )
1223
1239
{
1224
1240
offset = BaseUtcOffset ;
1225
1241
isDst = false ;
@@ -1240,13 +1256,22 @@ private bool TryGetTransitionOffset (DateTime dateTime, out TimeSpan offset,out
1240
1256
return false ;
1241
1257
}
1242
1258
1243
- AdjustmentRule current = GetApplicableRule ( date ) ;
1259
+ AdjustmentRule current = GetApplicableRule ( date ) ;
1244
1260
if ( current != null ) {
1245
- DateTime tStart = TransitionPoint ( current . DaylightTransitionStart , date . Year ) ;
1246
- DateTime tEnd = TransitionPoint ( current . DaylightTransitionEnd , date . Year ) ;
1261
+ DateTime tStart = TransitionPoint ( current . DaylightTransitionStart , date . Year ) ;
1262
+ DateTime tEnd = TransitionPoint ( current . DaylightTransitionEnd , date . Year ) ;
1263
+ TryAddTicks ( tStart , - BaseUtcOffset . Ticks , out tStart , DateTimeKind . Utc ) ;
1264
+ TryAddTicks ( tEnd , - BaseUtcOffset . Ticks , out tEnd , DateTimeKind . Utc ) ;
1247
1265
if ( ( date >= tStart ) && ( date <= tEnd ) ) {
1248
- offset = baseUtcOffset + current . DaylightDelta ;
1249
- isDst = true ;
1266
+ if ( forOffset )
1267
+ isDst = true ;
1268
+ offset = baseUtcOffset ;
1269
+ if ( date >= new DateTime ( tStart . Ticks + current . DaylightDelta . Ticks , DateTimeKind . Utc ) )
1270
+ {
1271
+ offset += current . DaylightDelta ;
1272
+ isDst = true ;
1273
+ }
1274
+
1250
1275
return true ;
1251
1276
}
1252
1277
}
0 commit comments