Move portable thread pool to shared partition (dotnet/corert#7828)
[mono-project.git] / netcore / System.Private.CoreLib / shared / System / TimeZoneInfo.TransitionTime.cs
blob141b621f5cfa88a92fdc59f348a36a014aea9365
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
5 using System.Runtime.Serialization;
7 namespace System
9 public sealed partial class TimeZoneInfo
11 [Serializable]
12 public readonly struct TransitionTime : IEquatable<TransitionTime>, ISerializable, IDeserializationCallback
14 private readonly DateTime _timeOfDay;
15 private readonly byte _month;
16 private readonly byte _week;
17 private readonly byte _day;
18 private readonly DayOfWeek _dayOfWeek;
19 private readonly bool _isFixedDateRule;
21 public DateTime TimeOfDay => _timeOfDay;
23 public int Month => _month;
25 public int Week => _week;
27 public int Day => _day;
29 public DayOfWeek DayOfWeek => _dayOfWeek;
31 public bool IsFixedDateRule => _isFixedDateRule;
33 public override bool Equals(object? obj) =>
34 obj is TransitionTime && Equals((TransitionTime)obj);
36 public static bool operator ==(TransitionTime t1, TransitionTime t2) => t1.Equals(t2);
38 public static bool operator !=(TransitionTime t1, TransitionTime t2) => !t1.Equals(t2);
40 public bool Equals(TransitionTime other) =>
41 _isFixedDateRule == other._isFixedDateRule &&
42 _timeOfDay == other._timeOfDay &&
43 _month == other._month &&
44 (other._isFixedDateRule ?
45 _day == other._day :
46 _week == other._week && _dayOfWeek == other._dayOfWeek);
48 public override int GetHashCode() => (int)_month ^ (int)_week << 8;
50 private TransitionTime(DateTime timeOfDay, int month, int week, int day, DayOfWeek dayOfWeek, bool isFixedDateRule)
52 ValidateTransitionTime(timeOfDay, month, week, day, dayOfWeek);
54 _timeOfDay = timeOfDay;
55 _month = (byte)month;
56 _week = (byte)week;
57 _day = (byte)day;
58 _dayOfWeek = dayOfWeek;
59 _isFixedDateRule = isFixedDateRule;
62 public static TransitionTime CreateFixedDateRule(DateTime timeOfDay, int month, int day) =>
63 new TransitionTime(timeOfDay, month, 1, day, DayOfWeek.Sunday, isFixedDateRule: true);
65 public static TransitionTime CreateFloatingDateRule(DateTime timeOfDay, int month, int week, DayOfWeek dayOfWeek) =>
66 new TransitionTime(timeOfDay, month, week, 1, dayOfWeek, isFixedDateRule: false);
68 /// <summary>
69 /// Helper function that validates a TransitionTime instance.
70 /// </summary>
71 private static void ValidateTransitionTime(DateTime timeOfDay, int month, int week, int day, DayOfWeek dayOfWeek)
73 if (timeOfDay.Kind != DateTimeKind.Unspecified)
75 throw new ArgumentException(SR.Argument_DateTimeKindMustBeUnspecified, nameof(timeOfDay));
78 // Month range 1-12
79 if (month < 1 || month > 12)
81 throw new ArgumentOutOfRangeException(nameof(month), SR.ArgumentOutOfRange_MonthParam);
84 // Day range 1-31
85 if (day < 1 || day > 31)
87 throw new ArgumentOutOfRangeException(nameof(day), SR.ArgumentOutOfRange_DayParam);
90 // Week range 1-5
91 if (week < 1 || week > 5)
93 throw new ArgumentOutOfRangeException(nameof(week), SR.ArgumentOutOfRange_Week);
96 // DayOfWeek range 0-6
97 if ((int)dayOfWeek < 0 || (int)dayOfWeek > 6)
99 throw new ArgumentOutOfRangeException(nameof(dayOfWeek), SR.ArgumentOutOfRange_DayOfWeek);
102 timeOfDay.GetDatePart(out int timeOfDayYear, out int timeOfDayMonth, out int timeOfDayDay);
103 if (timeOfDayYear != 1 || timeOfDayMonth != 1 || timeOfDayDay != 1 || (timeOfDay.Ticks % TimeSpan.TicksPerMillisecond != 0))
105 throw new ArgumentException(SR.Argument_DateTimeHasTicks, nameof(timeOfDay));
109 void IDeserializationCallback.OnDeserialization(object? sender)
111 // OnDeserialization is called after each instance of this class is deserialized.
112 // This callback method performs TransitionTime validation after being deserialized.
114 // On Unix, TimeZoneInfos are created with empty/default TransitionTimes, since
115 // TransitionTimes are not used on Unix. When deserializing TransitionTimes, only
116 // validate it if it isn't an empty/default instance.
117 if (this != default)
121 ValidateTransitionTime(_timeOfDay, _month, _week, _day, _dayOfWeek);
123 catch (ArgumentException e)
125 throw new SerializationException(SR.Serialization_InvalidData, e);
130 void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
132 if (info == null)
134 throw new ArgumentNullException(nameof(info));
137 info.AddValue("TimeOfDay", _timeOfDay); // Do not rename (binary serialization)
138 info.AddValue("Month", _month); // Do not rename (binary serialization)
139 info.AddValue("Week", _week); // Do not rename (binary serialization)
140 info.AddValue("Day", _day); // Do not rename (binary serialization)
141 info.AddValue("DayOfWeek", _dayOfWeek); // Do not rename (binary serialization)
142 info.AddValue("IsFixedDateRule", _isFixedDateRule); // Do not rename (binary serialization)
145 private TransitionTime(SerializationInfo info, StreamingContext context)
147 if (info == null)
149 throw new ArgumentNullException(nameof(info));
152 _timeOfDay = (DateTime)info.GetValue("TimeOfDay", typeof(DateTime))!; // Do not rename (binary serialization)
153 _month = (byte)info.GetValue("Month", typeof(byte))!; // Do not rename (binary serialization)
154 _week = (byte)info.GetValue("Week", typeof(byte))!; // Do not rename (binary serialization)
155 _day = (byte)info.GetValue("Day", typeof(byte))!; // Do not rename (binary serialization)
156 _dayOfWeek = (DayOfWeek)info.GetValue("DayOfWeek", typeof(DayOfWeek))!; // Do not rename (binary serialization)
157 _isFixedDateRule = (bool)info.GetValue("IsFixedDateRule", typeof(bool))!; // Do not rename (binary serialization)