TimeZoneInfo.TransitionTime.cs 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. /*
  2. * System.TimeZoneInfo.TransitionTime
  3. *
  4. * Author(s)
  5. * Stephane Delcroix <[email protected]>
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining
  8. * a copy of this software and associated documentation files (the
  9. * "Software"), to deal in the Software without restriction, including
  10. * without limitation the rights to use, copy, modify, merge, publish,
  11. * distribute, sublicense, and/or sell copies of the Software, and to
  12. * permit persons to whom the Software is furnished to do so, subject to
  13. * the following conditions:
  14. *
  15. * The above copyright notice and this permission notice shall be
  16. * included in all copies or substantial portions of the Software.
  17. *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  19. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  20. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  21. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  22. * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  23. * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  24. * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25. */
  26. #if INSIDE_CORLIB || (NET_3_5 && !NET_4_0 && !MOBILE)
  27. using System.Runtime.CompilerServices;
  28. using System.Runtime.Serialization;
  29. namespace System
  30. {
  31. #if NET_4_0 || !INSIDE_CORLIB
  32. public
  33. #endif
  34. sealed partial class TimeZoneInfo
  35. {
  36. [SerializableAttribute]
  37. #if MOBILE
  38. [TypeForwardedFrom (Consts.AssemblySystem_Core)]
  39. #elif NET_4_0
  40. [TypeForwardedFrom (Consts.AssemblySystemCore_3_5)]
  41. #endif
  42. public struct TransitionTime : IEquatable<TimeZoneInfo.TransitionTime>, ISerializable, IDeserializationCallback
  43. {
  44. DateTime timeOfDay;
  45. public DateTime TimeOfDay {
  46. get { return timeOfDay; }
  47. }
  48. int month;
  49. public int Month {
  50. get { return month; }
  51. }
  52. int day;
  53. public int Day {
  54. get {
  55. #if STRICT
  56. if (!isFixedDateRule)
  57. throw new Exception ("Day property is not valid for floating date rules");
  58. #endif
  59. return day;
  60. }
  61. }
  62. int week;
  63. public int Week {
  64. get {
  65. #if STRICT
  66. if (isFixedDateRule)
  67. throw new Exception ("Week property is not valid for fixed date rules");
  68. #endif
  69. return week;
  70. }
  71. }
  72. DayOfWeek dayOfWeek;
  73. public DayOfWeek DayOfWeek {
  74. get {
  75. #if STRICT
  76. if (isFixedDateRule)
  77. throw new Exception ("DayOfWeek property is not valid for fixed date rules");
  78. #endif
  79. return dayOfWeek;
  80. }
  81. }
  82. bool isFixedDateRule;
  83. public bool IsFixedDateRule {
  84. get { return isFixedDateRule; }
  85. }
  86. public static TransitionTime CreateFixedDateRule (
  87. DateTime timeOfDay,
  88. int month,
  89. int day)
  90. {
  91. return new TransitionTime (timeOfDay, month, day);
  92. }
  93. public static TransitionTime CreateFloatingDateRule (
  94. DateTime timeOfDay,
  95. int month,
  96. int week,
  97. DayOfWeek dayOfWeek)
  98. {
  99. return new TransitionTime (timeOfDay, month, week, dayOfWeek);
  100. }
  101. private TransitionTime (SerializationInfo info, StreamingContext context)
  102. {
  103. if (info == null)
  104. throw new ArgumentNullException ("info");
  105. timeOfDay = (DateTime) info.GetValue ("TimeOfDay", typeof (DateTime));
  106. month = (byte) info.GetValue ("Month", typeof (byte));
  107. week = (byte) info.GetValue ("Week", typeof (byte));
  108. day = (byte) info.GetValue ("Day", typeof (byte));
  109. dayOfWeek = (DayOfWeek) info.GetValue ("DayOfWeek", typeof (DayOfWeek));
  110. isFixedDateRule = (bool) info.GetValue ("IsFixedDateRule", typeof (bool));
  111. if (isFixedDateRule)
  112. {
  113. week = -1;
  114. dayOfWeek = (DayOfWeek) (-1);
  115. }
  116. if (!isFixedDateRule)
  117. day = -1;
  118. }
  119. private TransitionTime (
  120. DateTime timeOfDay,
  121. int month,
  122. int day) : this (timeOfDay, month)
  123. {
  124. if (day < 1 || day > 31)
  125. throw new ArgumentOutOfRangeException ("day parameter is less than 1 or greater than 31");
  126. this.day = day;
  127. this.isFixedDateRule = true;
  128. }
  129. private TransitionTime (
  130. DateTime timeOfDay,
  131. int month,
  132. int week,
  133. DayOfWeek dayOfWeek) : this (timeOfDay, month)
  134. {
  135. if (week < 1 || week > 5)
  136. throw new ArgumentOutOfRangeException ("week parameter is less than 1 or greater than 5");
  137. if (dayOfWeek != DayOfWeek.Sunday &&
  138. dayOfWeek != DayOfWeek.Monday &&
  139. dayOfWeek != DayOfWeek.Tuesday &&
  140. dayOfWeek != DayOfWeek.Wednesday &&
  141. dayOfWeek != DayOfWeek.Thursday &&
  142. dayOfWeek != DayOfWeek.Friday &&
  143. dayOfWeek != DayOfWeek.Saturday)
  144. throw new ArgumentOutOfRangeException ("dayOfWeek parameter is not a member od DayOfWeek enumeration");
  145. this.week = week;
  146. this.dayOfWeek = dayOfWeek;
  147. this.isFixedDateRule = false;
  148. }
  149. private TransitionTime (
  150. DateTime timeOfDay,
  151. int month)
  152. {
  153. if (timeOfDay.Year != 1 || timeOfDay.Month != 1 || timeOfDay.Day != 1)
  154. throw new ArgumentException ("timeOfDay parameter has a non-default date component");
  155. if (timeOfDay.Kind != DateTimeKind.Unspecified)
  156. throw new ArgumentException ("timeOfDay parameter Kind's property is not DateTimeKind.Unspecified");
  157. if (timeOfDay.Ticks % TimeSpan.TicksPerMillisecond != 0)
  158. throw new ArgumentException ("timeOfDay parameter does not represent a whole number of milliseconds");
  159. if (month < 1 || month > 12)
  160. throw new ArgumentOutOfRangeException ("month parameter is less than 1 or greater than 12");
  161. this.timeOfDay = timeOfDay;
  162. this.month = month;
  163. this.week = -1;
  164. this.dayOfWeek = (System.DayOfWeek)(-1);
  165. this.day = -1;
  166. this.isFixedDateRule = false;
  167. }
  168. public static bool operator == (TransitionTime t1, TransitionTime t2)
  169. {
  170. return ( t1.day == t2.day &&
  171. t1.dayOfWeek == t2.dayOfWeek &&
  172. t1.isFixedDateRule == t2.isFixedDateRule &&
  173. t1.month == t2.month &&
  174. t1.timeOfDay == t2.timeOfDay &&
  175. t1.week == t2.week);
  176. }
  177. public static bool operator != (TransitionTime t1, TransitionTime t2)
  178. {
  179. return !(t1 == t2);
  180. }
  181. #if NET_4_0
  182. void ISerializable.GetObjectData (SerializationInfo info, StreamingContext context)
  183. #else
  184. public void GetObjectData (SerializationInfo info, StreamingContext context)
  185. #endif
  186. {
  187. if (info == null)
  188. throw new ArgumentNullException ("info");
  189. info.AddValue ("TimeOfDay", TimeOfDay);
  190. info.AddValue ("Month", System.Convert.ToByte(Month));
  191. if (week > -1)
  192. info.AddValue ("Week", System.Convert.ToByte(week));
  193. else
  194. info.AddValue ("Week", (byte) 1);
  195. if (day > -1)
  196. info.AddValue ("Day", System.Convert.ToByte(day));
  197. else
  198. info.AddValue ("Day", (byte) 1);
  199. if (dayOfWeek != ((System.DayOfWeek) (-1)))
  200. info.AddValue ("DayOfWeek", dayOfWeek);
  201. else
  202. info.AddValue ("DayOfWeek", DayOfWeek.Sunday);
  203. info.AddValue ("IsFixedDateRule", IsFixedDateRule);
  204. }
  205. public override bool Equals (object obj)
  206. {
  207. if (obj is TransitionTime)
  208. return this == (TransitionTime) obj;
  209. return false;
  210. }
  211. public bool Equals (TimeZoneInfo.TransitionTime other)
  212. {
  213. return this == other;
  214. }
  215. public override int GetHashCode ()
  216. {
  217. return (day ^ (int)dayOfWeek ^ month ^ (int)timeOfDay.Ticks ^ week);
  218. }
  219. #if NET_4_0
  220. void IDeserializationCallback.OnDeserialization (object sender)
  221. #else
  222. public void OnDeserialization (object sender)
  223. #endif
  224. {
  225. try {
  226. TimeZoneInfo.TransitionTime.Validate (timeOfDay, month, week, day, dayOfWeek, isFixedDateRule);
  227. } catch (ArgumentException ex) {
  228. throw new SerializationException ("invalid serialization data", ex);
  229. }
  230. }
  231. private static void Validate (DateTime timeOfDay, int month,int week, int day, DayOfWeek dayOfWeek, bool isFixedDateRule)
  232. {
  233. if (timeOfDay.Year != 1 || timeOfDay.Month != 1 || timeOfDay.Day != 1)
  234. throw new ArgumentException ("timeOfDay parameter has a non-default date component");
  235. if (timeOfDay.Kind != DateTimeKind.Unspecified)
  236. throw new ArgumentException ("timeOfDay parameter Kind's property is not DateTimeKind.Unspecified");
  237. if (timeOfDay.Ticks % TimeSpan.TicksPerMillisecond != 0)
  238. throw new ArgumentException ("timeOfDay parameter does not represent a whole number of milliseconds");
  239. if (day < 1 || day > 31) {
  240. if (!(!isFixedDateRule && day == -1))
  241. throw new ArgumentOutOfRangeException ("day parameter is less than 1 or greater than 31");
  242. }
  243. if (week < 1 || week > 5) {
  244. if (!(isFixedDateRule && week == -1))
  245. throw new ArgumentOutOfRangeException ("week parameter is less than 1 or greater than 5");
  246. }
  247. if (month < 1 || month > 12)
  248. throw new ArgumentOutOfRangeException ("month parameter is less than 1 or greater than 12");
  249. if (dayOfWeek != DayOfWeek.Sunday &&
  250. dayOfWeek != DayOfWeek.Monday &&
  251. dayOfWeek != DayOfWeek.Tuesday &&
  252. dayOfWeek != DayOfWeek.Wednesday &&
  253. dayOfWeek != DayOfWeek.Thursday &&
  254. dayOfWeek != DayOfWeek.Friday &&
  255. dayOfWeek != DayOfWeek.Saturday) {
  256. if (!(isFixedDateRule && dayOfWeek == (DayOfWeek) (-1)))
  257. throw new ArgumentOutOfRangeException ("dayOfWeek parameter is not a member od DayOfWeek enumeration");
  258. }
  259. }
  260. }
  261. }
  262. }
  263. #endif