2005-01-24 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / System.Data / System.Data.SqlTypes / SqlDateTime.cs
1 //
2 // System.Data.SqlTypes.SqlDateTime
3 //
4 // Author:
5 //   Tim Coleman <tim@timcoleman.com>
6 //   Ville Palo <vi64pa@koti.soon.fi>
7 //
8 // (C) Copyright 2002 Tim Coleman
9 //
10
11 //
12 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
21 // 
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
24 // 
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 //
33
34 using System;
35 using System.Globalization;
36
37 namespace System.Data.SqlTypes
38 {
39         public struct SqlDateTime : INullable, IComparable
40         {
41                 #region Fields
42                 private DateTime value;
43                 private bool notNull;
44
45                 public static readonly SqlDateTime MaxValue = new SqlDateTime (9999,12,31,23,59,59);
46                 public static readonly SqlDateTime MinValue = new SqlDateTime (1753,1,1);
47                 public static readonly SqlDateTime Null;
48                 public static readonly int SQLTicksPerHour = 1080000;
49                 public static readonly int SQLTicksPerMinute = 18000;
50                 public static readonly int SQLTicksPerSecond = 300;
51               
52                 #endregion
53
54                 #region Constructors
55
56                 public SqlDateTime (DateTime value) 
57                 {
58                         this.value = value;
59                         notNull = true;
60                         CheckRange (this);
61                 }
62
63                 public SqlDateTime (int dayTicks, int timeTicks) 
64                 {
65                         try {
66                                 DateTime temp = new DateTime (1900, 1, 1);
67                                 this.value = new DateTime (temp.Ticks + (long)(dayTicks + timeTicks));
68                         } catch (ArgumentOutOfRangeException ex) {
69                                 throw new SqlTypeException (ex.Message);
70                         }
71                         notNull = true;
72                         CheckRange (this);
73                 }
74
75                 public SqlDateTime (int year, int month, int day) 
76                 {
77                         try {
78                                 this.value = new DateTime (year, month, day);
79                         } catch (ArgumentOutOfRangeException ex) {
80                                 throw new SqlTypeException (ex.Message);
81                         }
82                         notNull = true;
83                         CheckRange (this);
84                 }
85
86                 public SqlDateTime (int year, int month, int day, int hour, int minute, int second) 
87                 {
88                         try {
89                                 this.value = new DateTime (year, month, day, hour, minute, second);
90                         } catch (ArgumentOutOfRangeException ex) {
91                                 throw new SqlTypeException (ex.Message);
92                         }
93                         notNull = true;
94                         CheckRange (this);
95                 }
96
97                 [MonoTODO ("Round milisecond")]
98                 public SqlDateTime (int year, int month, int day, int hour, int minute, int second, double millisecond) 
99                 {
100                         try {
101                                 DateTime t = new DateTime(year, month, day, hour, minute, second);
102                         
103                                 long ticks = (long) (t.Ticks + millisecond * 10000);
104                                 this.value = new DateTime (ticks);
105                         } catch (ArgumentOutOfRangeException ex) {
106                                 throw new SqlTypeException (ex.Message);
107                         }
108                         notNull = true;
109                         CheckRange (this);
110                 }
111
112                 [MonoTODO ("Round bilisecond")]
113                 public SqlDateTime (int year, int month, int day, int hour, int minute, int second, int bilisecond) // bilisecond??
114                 {
115                         try {
116                                 DateTime t = new DateTime(year, month, day, hour, minute, second);
117                         
118                                 long dateTick = (long) (t.Ticks + bilisecond * 10);
119                                 this.value = new DateTime (dateTick);
120                         } catch (ArgumentOutOfRangeException ex) {
121                                 throw new SqlTypeException (ex.Message);
122                         }
123                         notNull = true;
124                         CheckRange (this);
125                 }
126
127                 #endregion
128
129                 #region Properties
130
131                 public int DayTicks {
132                         get { 
133                                 float DateTimeTicksPerHour = 3.6E+10f;
134
135                                 DateTime temp = new DateTime (1900, 1, 1);
136                                 
137                                 int result = (int)((this.Value.Ticks - temp.Ticks) / (24 * DateTimeTicksPerHour));
138                                 return result;
139                         }
140                 }
141
142                 public bool IsNull { 
143                         get { return !notNull; }
144                 }
145
146                 public int TimeTicks {
147                         get {
148                                 if (this.IsNull)
149                                         throw new SqlNullValueException ();
150
151                                 return (int)(value.Hour * SQLTicksPerHour + 
152                                              value.Minute * SQLTicksPerMinute +
153                                              value.Second * SQLTicksPerSecond +
154                                              value.Millisecond);
155                         }
156                 }
157
158                 public DateTime Value {
159                         get { 
160                                 if (this.IsNull) 
161                                         throw new SqlNullValueException ("The property contains Null.");
162                                 else 
163                                         return value; 
164                         }
165                 }
166
167                 #endregion
168
169                 #region Methods
170                 private static void CheckRange (SqlDateTime target)
171                 {
172                         if (target.IsNull)
173                                 return;
174                         if (target.value > MaxValue.value || target.value < MinValue.value)
175                                 throw new SqlTypeException (String.Format ("SqlDateTime overflow. Must be between {0} and {1}. Value was {2}", MinValue.Value, MaxValue.Value, target.value));
176                 }
177
178                 public int CompareTo (object value)
179                 {
180                         if (value == null)
181                                 return 1;
182                         else if (!(value is SqlDateTime))
183                                 throw new ArgumentException (Locale.GetText ("Value is not a System.Data.SqlTypes.SqlDateTime"));
184                         else if (((SqlDateTime)value).IsNull)
185                                 return 1;
186                         else
187                                 return this.value.CompareTo (((SqlDateTime)value).Value);
188                 }
189
190                 public override bool Equals (object value)
191                 {
192                         if (!(value is SqlDateTime))
193                                 return false;
194                         else if (this.IsNull && ((SqlDateTime)value).IsNull)
195                                 return true;
196                         else if (((SqlDateTime)value).IsNull)
197                                 return false;
198                         else
199                                 return (bool) (this == (SqlDateTime)value);
200                 }
201
202                 public static SqlBoolean Equals (SqlDateTime x, SqlDateTime y)
203                 {
204                         return (x == y);
205                 }
206
207                 public override int GetHashCode ()
208                 {
209                         return value.GetHashCode ();
210                 }
211
212                 public static SqlBoolean GreaterThan (SqlDateTime x, SqlDateTime y)
213                 {
214                         return (x > y);
215                 }
216
217                 public static SqlBoolean GreaterThanOrEqual (SqlDateTime x, SqlDateTime y)
218                 {
219                         return (x >= y);
220                 }
221
222                 public static SqlBoolean LessThan (SqlDateTime x, SqlDateTime y)
223                 {
224                         return (x < y);
225                 }
226
227                 public static SqlBoolean LessThanOrEqual (SqlDateTime x, SqlDateTime y)
228                 {
229                         return (x <= y);
230                 }
231
232                 public static SqlBoolean NotEquals (SqlDateTime x, SqlDateTime y)
233                 {
234                         return (x != y);
235                 }
236
237                 public static SqlDateTime Parse (string s)
238                 {
239                         return new SqlDateTime (DateTime.Parse (s));
240                 }
241
242                 public SqlString ToSqlString ()
243                 {
244                         return ((SqlString)this);
245                 }
246
247                 public override string ToString ()
248                 {       
249                         if (this.IsNull)
250                                 return "Null";
251                         else
252                                 return value.ToString (CultureInfo.InvariantCulture);
253                 }
254         
255                 public static SqlDateTime operator + (SqlDateTime x, TimeSpan t)
256                 {
257                         if (x.IsNull)
258                                 return SqlDateTime.Null;
259                         
260                         return new SqlDateTime (x.Value + t);
261                 }
262
263                 public static SqlBoolean operator == (SqlDateTime x, SqlDateTime y)
264                 {
265                         if (x.IsNull || y.IsNull) 
266                                 return SqlBoolean.Null;
267                         else
268                                 return new SqlBoolean (x.Value == y.Value);
269                 }
270
271                 public static SqlBoolean operator > (SqlDateTime x, SqlDateTime y)
272                 {
273                         if (x.IsNull || y.IsNull) 
274                                 return SqlBoolean.Null;
275                         else
276                                 return new SqlBoolean (x.Value > y.Value);
277                 }
278
279                 public static SqlBoolean operator >= (SqlDateTime x, SqlDateTime y)
280                 {
281                         if (x.IsNull || y.IsNull) 
282                                 return SqlBoolean.Null;
283                         else
284                                 return new SqlBoolean (x.Value >= y.Value);
285                 }
286
287                 public static SqlBoolean operator != (SqlDateTime x, SqlDateTime y)
288                 {
289                         if (x.IsNull || y.IsNull) 
290                                 return SqlBoolean.Null;
291                         else
292                                 return new SqlBoolean (!(x.Value == y.Value));
293                 }
294
295                 public static SqlBoolean operator < (SqlDateTime x, SqlDateTime y)
296                 {
297                         if (x.IsNull || y.IsNull) 
298                                 return SqlBoolean.Null;
299                         else
300                                 return new SqlBoolean (x.Value < y.Value);
301                 }
302
303                 public static SqlBoolean operator <= (SqlDateTime x, SqlDateTime y)
304                 {
305                         if (x.IsNull || y.IsNull) 
306                                 return SqlBoolean.Null;
307                         else
308                                 return new SqlBoolean (x.Value <= y.Value);
309                 }
310
311                 public static SqlDateTime operator - (SqlDateTime x, TimeSpan t)
312                 {
313                         if (x.IsNull)
314                                 return x;
315                         return new SqlDateTime (x.Value - t);
316                 }
317
318                 public static explicit operator DateTime (SqlDateTime x)
319                 {
320                         return x.Value;
321                 }
322
323                 public static explicit operator SqlDateTime (SqlString x)
324                 {
325                         return SqlDateTime.Parse (x.Value);
326                 }
327
328                 public static implicit operator SqlDateTime (DateTime x)
329                 {
330                         return new SqlDateTime (x);
331                 }
332
333                 #endregion
334         }
335 }
336