[sgen] Don't assert in GC.GetTotalMemory.
[mono.git] / mcs / class / corlib / System / TimeZoneInfo.AdjustmentRule.cs
1 /*
2  * System.TimeZoneInfo.AdjustmentRule
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 using System.Runtime.CompilerServices;
28 using System.Runtime.Serialization;
29
30 namespace System
31 {
32         public
33         sealed partial class TimeZoneInfo {
34                 [SerializableAttribute]
35 #if MOBILE
36         [TypeForwardedFrom (Consts.AssemblySystem_Core)]
37 #else
38         [TypeForwardedFrom (Consts.AssemblySystemCore_3_5)]
39 #endif
40                 public sealed class AdjustmentRule : IEquatable<TimeZoneInfo.AdjustmentRule>, ISerializable, IDeserializationCallback
41                 {
42                         DateTime dateEnd;
43                         public DateTime DateEnd {
44                                 get { return dateEnd; } 
45                         }
46
47                         DateTime dateStart;
48                         public DateTime DateStart {
49                                 get { return dateStart; }
50                         }
51
52                         TimeSpan daylightDelta;
53                         public TimeSpan DaylightDelta {
54                                 get { return daylightDelta; }
55                         }
56
57                         TransitionTime daylightTransitionEnd;
58                         public TransitionTime DaylightTransitionEnd {
59                                 get { return daylightTransitionEnd; }
60                         }
61
62                         TransitionTime daylightTransitionStart;
63                         public TransitionTime DaylightTransitionStart {
64                                 get { return daylightTransitionStart; }
65                         }
66
67                         public static AdjustmentRule CreateAdjustmentRule (
68                                 DateTime dateStart,
69                                 DateTime dateEnd,
70                                 TimeSpan daylightDelta,
71                                 TransitionTime daylightTransitionStart,
72                                 TransitionTime daylightTransitionEnd)
73                         {
74                                 return new AdjustmentRule (dateStart, dateEnd, daylightDelta, daylightTransitionStart, daylightTransitionEnd);
75                         }
76
77                         private AdjustmentRule (SerializationInfo info, StreamingContext context)
78                         {
79                                 if (info == null)
80                                         throw new ArgumentNullException ("info");
81                                 dateStart = (DateTime) info.GetValue ("DateStart", typeof (DateTime));
82                                 dateEnd = (DateTime) info.GetValue ("DateEnd", typeof (DateTime));
83                                 daylightDelta = (TimeSpan) info.GetValue ("DaylightDelta", typeof (TimeSpan));
84                                 daylightTransitionStart = (TimeZoneInfo.TransitionTime) info.GetValue ("DaylightTransitionStart", typeof (TimeZoneInfo.TransitionTime));
85                                 daylightTransitionEnd = (TimeZoneInfo.TransitionTime) info.GetValue ("DaylightTransitionEnd", typeof (TimeZoneInfo.TransitionTime));
86                         }
87                         
88                         private AdjustmentRule (
89                                 DateTime dateStart,
90                                 DateTime dateEnd,
91                                 TimeSpan daylightDelta,
92                                 TransitionTime daylightTransitionStart,
93                                 TransitionTime daylightTransitionEnd)
94                         {
95                                 if (dateStart.Kind != DateTimeKind.Unspecified || dateEnd.Kind != DateTimeKind.Unspecified)
96                                         throw new ArgumentException ("the Kind property of dateStart or dateEnd parameter does not equal DateTimeKind.Unspecified");
97
98                                 if (daylightTransitionStart == daylightTransitionEnd)
99                                         throw new ArgumentException ("daylightTransitionStart parameter cannot equal daylightTransitionEnd parameter");
100
101                                 if (dateStart.Ticks % TimeSpan.TicksPerDay != 0 || dateEnd.Ticks % TimeSpan.TicksPerDay != 0)
102                                         throw new ArgumentException ("dateStart or dateEnd parameter includes a time of day value");
103
104                                 if (dateEnd < dateStart)
105                                         throw new ArgumentOutOfRangeException ("dateEnd is earlier than dateStart");
106
107                                 if (daylightDelta > new TimeSpan (14, 0, 0) || daylightDelta < new TimeSpan (-14, 0, 0))
108                                         throw new ArgumentOutOfRangeException ("daylightDelta is less than -14 or greater than 14 hours");
109
110                                 if (daylightDelta.Ticks % TimeSpan.TicksPerSecond != 0)
111                                         throw new ArgumentOutOfRangeException ("daylightDelta parameter does not represent a whole number of seconds");
112
113                                 this.dateStart = dateStart;
114                                 this.dateEnd = dateEnd;
115                                 this.daylightDelta = daylightDelta;
116                                 this.daylightTransitionStart = daylightTransitionStart;
117                                 this.daylightTransitionEnd = daylightTransitionEnd;
118                         }
119
120                         public bool Equals (TimeZoneInfo.AdjustmentRule other)
121                         {
122                                 return dateStart == other.dateStart &&
123                                         dateEnd == other.dateEnd &&
124                                         daylightDelta == other.daylightDelta && 
125                                         daylightTransitionStart == other.daylightTransitionStart &&
126                                         daylightTransitionEnd == other.daylightTransitionEnd;
127                         }
128
129                         public override int GetHashCode ()
130                         {
131                                 return dateStart.GetHashCode () ^ 
132                                         dateEnd.GetHashCode () ^
133                                         daylightDelta.GetHashCode () ^
134                                         daylightTransitionStart.GetHashCode () ^
135                                         daylightTransitionEnd.GetHashCode ();
136                         }
137                                         
138                         void ISerializable.GetObjectData (SerializationInfo info, StreamingContext context)
139                         {
140                                 if (info == null)
141                                         throw new ArgumentNullException ("info");
142                                 info.AddValue ("DateStart", DateStart);
143                                 info.AddValue ("DateEnd", DateEnd);
144                                 info.AddValue ("DaylightDelta", DaylightDelta);
145                                 info.AddValue ("DaylightTransitionStart", DaylightTransitionStart);
146                                 info.AddValue ("DaylightTransitionEnd", DaylightTransitionEnd);
147                         }
148                         void IDeserializationCallback.OnDeserialization (object sender)
149                         {
150                                 try {
151                                         TimeZoneInfo.AdjustmentRule.Validate (dateStart, dateEnd, daylightDelta, 
152                                                                               daylightTransitionStart, daylightTransitionEnd);
153                                 } catch (ArgumentException ex) {
154                                         throw new SerializationException ("invalid serialization data", ex);
155                                 }
156                         }
157
158                         private static void Validate (
159                                 DateTime dateStart,
160                                 DateTime dateEnd,
161                                 TimeSpan daylightDelta,
162                                 TransitionTime daylightTransitionStart,
163                                 TransitionTime daylightTransitionEnd)
164                         {
165                                 if (dateStart.Kind != DateTimeKind.Unspecified || dateEnd.Kind != DateTimeKind.Unspecified)
166                                         throw new ArgumentException ("the Kind property of dateStart or dateEnd parameter does not equal DateTimeKind.Unspecified");
167
168                                 if (daylightTransitionStart == daylightTransitionEnd)
169                                         throw new ArgumentException ("daylightTransitionStart parameter cannot equal daylightTransitionEnd parameter");
170
171                                 if (dateStart.Ticks % TimeSpan.TicksPerDay != 0 || dateEnd.Ticks % TimeSpan.TicksPerDay != 0)
172                                         throw new ArgumentException ("dateStart or dateEnd parameter includes a time of day value");
173
174                                 if (dateEnd < dateStart)
175                                         throw new ArgumentOutOfRangeException ("dateEnd is earlier than dateStart");
176
177                                 if (daylightDelta > new TimeSpan (14, 0, 0) || daylightDelta < new TimeSpan (-14, 0, 0))
178                                         throw new ArgumentOutOfRangeException ("daylightDelta is less than -14 or greater than 14 hours");
179
180                                 if (daylightDelta.Ticks % TimeSpan.TicksPerSecond != 0)
181                                         throw new ArgumentOutOfRangeException ("daylightDelta parameter does not represent a whole number of seconds");
182                         }
183                 }
184         }
185 }