[MWF] Improve ellipsis handling
[mono.git] / mcs / class / System.Core / System / TimeZoneInfo.TransitionTime.cs
1 /*
2  * System.TimeZoneInfo.TransitionTime
3  *
4  * Author(s)
5  *      Stephane Delcroix <stephane@delcroix.org>
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
27 #if (INSIDE_CORLIB && NET_4_0) || (!INSIDE_CORLIB && (NET_3_5 && !NET_4_0 && !MOBILE))
28
29 using System.Runtime.CompilerServices;
30 using System.Runtime.Serialization;
31
32 namespace System
33 {
34         public 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
49                         int month;
50                         public int Month {
51                                 get { return month; }
52                         }
53
54                         int day;
55                         public int Day {
56                                 get { 
57 #if STRICT
58                                         if (!isFixedDateRule)
59                                                 throw new Exception ("Day property is not valid for floating date rules");
60 #endif
61                                         return day; 
62                                 }
63                         }
64
65                         int week;
66                         public int Week {
67                                 get { 
68 #if STRICT
69                                         if (isFixedDateRule)
70                                                 throw new Exception ("Week property is not valid for fixed date rules");
71 #endif
72                 
73                                         return week; 
74                                 }
75                         }
76
77                         DayOfWeek dayOfWeek;
78                         public DayOfWeek DayOfWeek {
79                                 get { 
80 #if STRICT
81                                         if (isFixedDateRule)
82                                                 throw new Exception ("DayOfWeek property is not valid for fixed date rules");
83 #endif
84         
85                                         return dayOfWeek; 
86                                 }
87                         }
88
89                         bool isFixedDateRule;
90                         public bool IsFixedDateRule {
91                                 get { return isFixedDateRule; }
92                         }
93
94                         public static TransitionTime CreateFixedDateRule (
95                                 DateTime timeOfDay, 
96                                 int month, 
97                                 int day)
98                         {
99                                 return new TransitionTime (timeOfDay, month, day);
100                         }
101
102                         public static TransitionTime CreateFloatingDateRule (
103                                 DateTime timeOfDay,
104                                 int month,
105                                 int week,
106                                 DayOfWeek dayOfWeek)
107                         {
108                                 return new TransitionTime (timeOfDay, month, week, dayOfWeek);
109                         }
110
111                         private TransitionTime (SerializationInfo info, StreamingContext context)
112                         {
113                                 if (info == null)
114                                         throw new ArgumentNullException ("info");
115                                 timeOfDay = (DateTime) info.GetValue ("TimeOfDay", typeof (DateTime));
116                                 month = (byte) info.GetValue ("Month", typeof (byte));
117                                 week = (byte) info.GetValue ("Week", typeof (byte));
118                                 day = (byte) info.GetValue ("Day", typeof (byte));
119                                 dayOfWeek = (DayOfWeek) info.GetValue ("DayOfWeek", typeof (DayOfWeek));
120                                 isFixedDateRule = (bool) info.GetValue ("IsFixedDateRule", typeof (bool));
121
122                                 if (isFixedDateRule)
123                                 {
124                                         week = -1;
125                                         dayOfWeek = (DayOfWeek) (-1);
126                                 }
127                                 if (!isFixedDateRule)                   
128                                         day = -1;
129                         }
130
131                         private TransitionTime (
132                                 DateTime timeOfDay,
133                                 int month,
134                                 int day) : this (timeOfDay, month)
135                         {
136                                 if (day < 1 || day > 31)
137                                         throw new ArgumentOutOfRangeException ("day parameter is less than 1 or greater than 31");
138
139                                 this.day = day; 
140                                 this.isFixedDateRule = true;
141                         }
142
143                         private TransitionTime (
144                                 DateTime timeOfDay,
145                                 int month,
146                                 int week,
147                                 DayOfWeek dayOfWeek)  : this (timeOfDay, month)
148                         {
149                                 if (week < 1 || week > 5)
150                                         throw new ArgumentOutOfRangeException ("week parameter is less than 1 or greater than 5");
151
152                                 if (dayOfWeek != DayOfWeek.Sunday &&
153                                                 dayOfWeek != DayOfWeek.Monday &&
154                                                 dayOfWeek != DayOfWeek.Tuesday &&
155                                                 dayOfWeek != DayOfWeek.Wednesday &&
156                                                 dayOfWeek != DayOfWeek.Thursday &&
157                                                 dayOfWeek != DayOfWeek.Friday &&
158                                                 dayOfWeek != DayOfWeek.Saturday)
159                                         throw new ArgumentOutOfRangeException ("dayOfWeek parameter is not a member od DayOfWeek enumeration");
160
161                                 this.week = week;
162                                 this.dayOfWeek = dayOfWeek;
163                                 this.isFixedDateRule = false;
164                         }
165
166                         private TransitionTime (
167                                 DateTime timeOfDay,
168                                 int month)
169                         {
170                                 if (timeOfDay.Year != 1 || timeOfDay.Month != 1 || timeOfDay.Day != 1)
171                                         throw new ArgumentException ("timeOfDay parameter has a non-default date component");
172
173                                 if (timeOfDay.Kind != DateTimeKind.Unspecified)
174                                         throw new ArgumentException ("timeOfDay parameter Kind's property is not DateTimeKind.Unspecified");
175
176                                 if (timeOfDay.Ticks % TimeSpan.TicksPerMillisecond != 0)
177                                         throw new ArgumentException ("timeOfDay parameter does not represent a whole number of milliseconds");
178
179                                 if (month < 1 || month > 12)
180                                         throw new ArgumentOutOfRangeException ("month parameter is less than 1 or greater than 12");
181                                 
182                                 this.timeOfDay = timeOfDay;
183                                 this.month = month;
184
185                                 this.week = -1;
186                                 this.dayOfWeek = (System.DayOfWeek)(-1);
187                                 this.day = -1;
188                                 this.isFixedDateRule = false;
189                         }
190
191                         public static bool operator == (TransitionTime t1, TransitionTime t2)
192                         {
193                                 return ( t1.day == t2.day &&
194                                                 t1.dayOfWeek == t2.dayOfWeek &&
195                                                 t1.isFixedDateRule == t2.isFixedDateRule &&
196                                                 t1.month == t2.month &&
197                                                 t1.timeOfDay == t2.timeOfDay &&
198                                                 t1.week == t2.week);    
199                         }
200
201                         public static bool operator != (TransitionTime t1, TransitionTime t2)
202                         {
203                                 return !(t1 == t2);
204                         }
205
206
207 #if NET_4_0
208                         void ISerializable.GetObjectData (SerializationInfo info, StreamingContext context)
209 #else
210                         public void GetObjectData (SerializationInfo info, StreamingContext context)
211 #endif
212                         {
213                                 if (info == null)
214                                         throw new ArgumentNullException ("info");
215                                 info.AddValue ("TimeOfDay", TimeOfDay);
216                                 info.AddValue ("Month", System.Convert.ToByte(Month));
217                                 if (week > -1)
218                                         info.AddValue ("Week", System.Convert.ToByte(week));
219                                 else 
220                                         info.AddValue ("Week", (byte) 1);
221                                 if (day > -1)
222                                         info.AddValue ("Day", System.Convert.ToByte(day));
223                                 else
224                                         info.AddValue ("Day", (byte) 1);
225                                 if (dayOfWeek !=  ((System.DayOfWeek) (-1)))
226                                         info.AddValue ("DayOfWeek", dayOfWeek);
227                                 else
228                                         info.AddValue ("DayOfWeek", DayOfWeek.Sunday);
229                                 info.AddValue ("IsFixedDateRule", IsFixedDateRule);
230                         }       
231         
232                         public override bool Equals (object obj)
233                         {
234                                 if (obj is TransitionTime)
235                                         return this == (TransitionTime) obj;
236                                 return false;
237                         }
238
239                         public bool Equals (TimeZoneInfo.TransitionTime other)
240                         {
241                                 return this == other;
242                         }
243
244                         public override int GetHashCode ()
245                         {
246                                 return (day ^ (int)dayOfWeek ^ month ^ (int)timeOfDay.Ticks ^ week);
247                         }
248
249 #if NET_4_0
250                         void IDeserializationCallback.OnDeserialization (object sender)
251 #else
252                         public void OnDeserialization (object sender)
253 #endif
254                         {
255                                 try {
256                                         TimeZoneInfo.TransitionTime.Validate (timeOfDay, month, week, day, dayOfWeek, isFixedDateRule);
257                                 } catch (ArgumentException ex) {
258                                         throw new SerializationException ("invalid serialization data", ex);
259                                 }
260                         }
261
262                         private static void Validate (DateTime timeOfDay, int month,int week, int day, DayOfWeek dayOfWeek, bool isFixedDateRule)
263                         {
264                                 if (timeOfDay.Year != 1 || timeOfDay.Month != 1 || timeOfDay.Day != 1)
265                                         throw new ArgumentException ("timeOfDay parameter has a non-default date component");
266
267                                 if (timeOfDay.Kind != DateTimeKind.Unspecified)
268                                         throw new ArgumentException ("timeOfDay parameter Kind's property is not DateTimeKind.Unspecified");
269
270                                 if (timeOfDay.Ticks % TimeSpan.TicksPerMillisecond != 0)
271                                         throw new ArgumentException ("timeOfDay parameter does not represent a whole number of milliseconds");
272
273                                 if (day < 1 || day > 31) {
274                                         if (!(!isFixedDateRule && day == -1))
275                                                 throw new ArgumentOutOfRangeException ("day parameter is less than 1 or greater than 31");
276                                 }
277
278                                 if (week < 1 || week > 5) {
279                                         if (!(isFixedDateRule && week == -1))
280                                                 throw new ArgumentOutOfRangeException ("week parameter is less than 1 or greater than 5");
281                                 }
282
283                                 if (month < 1 || month > 12)
284                                         throw new ArgumentOutOfRangeException ("month parameter is less than 1 or greater than 12");
285
286                                 if (dayOfWeek != DayOfWeek.Sunday &&
287                                                 dayOfWeek != DayOfWeek.Monday &&
288                                                 dayOfWeek != DayOfWeek.Tuesday &&
289                                                 dayOfWeek != DayOfWeek.Wednesday &&
290                                                 dayOfWeek != DayOfWeek.Thursday &&
291                                                 dayOfWeek != DayOfWeek.Friday &&
292                                                 dayOfWeek != DayOfWeek.Saturday) {
293                                         if (!(isFixedDateRule && dayOfWeek == (DayOfWeek) (-1)))
294                                                 throw new ArgumentOutOfRangeException ("dayOfWeek parameter is not a member od DayOfWeek enumeration");
295                                 }
296                         }
297                 }
298         }
299 }
300
301 #endif