2007-01-08 Nagappan A <anagappan@novell.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, (double)997);
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                         if (s == null)
240                                 throw new ArgumentNullException ("Argument cannot be null");
241
242                         // try parsing in local culture
243                         DateTimeFormatInfo fmtInfo = DateTimeFormatInfo.CurrentInfo;
244                         try {
245                                 return new SqlDateTime (DateTime.Parse (s, fmtInfo));
246                         } catch (Exception) { }
247
248                         // try parsing in invariant culture
249                         try {
250                                 return new SqlDateTime (DateTime.Parse (s, CultureInfo.InvariantCulture));
251                         } catch (Exception) { }
252
253                         // Not a recognizable format.
254                         throw new FormatException (String.Format ("String {0} is not recognized as "+
255                                                                   " valid DateTime.", s));
256
257                 }
258
259                 public SqlString ToSqlString ()
260                 {
261                         return ((SqlString)this);
262                 }
263
264                 public override string ToString ()
265                 {       
266                         if (this.IsNull)
267                                 return "Null";
268                         else
269                                 return value.ToString (CultureInfo.InvariantCulture);
270                 }
271         
272                 public static SqlDateTime operator + (SqlDateTime x, TimeSpan t)
273                 {
274                         if (x.IsNull)
275                                 return SqlDateTime.Null;
276                         
277                         return new SqlDateTime (x.Value + t);
278                 }
279
280                 public static SqlBoolean operator == (SqlDateTime x, SqlDateTime y)
281                 {
282                         if (x.IsNull || y.IsNull) 
283                                 return SqlBoolean.Null;
284                         else
285                                 return new SqlBoolean (x.Value == y.Value);
286                 }
287
288                 public static SqlBoolean operator > (SqlDateTime x, SqlDateTime y)
289                 {
290                         if (x.IsNull || y.IsNull) 
291                                 return SqlBoolean.Null;
292                         else
293                                 return new SqlBoolean (x.Value > y.Value);
294                 }
295
296                 public static SqlBoolean operator >= (SqlDateTime x, SqlDateTime y)
297                 {
298                         if (x.IsNull || y.IsNull) 
299                                 return SqlBoolean.Null;
300                         else
301                                 return new SqlBoolean (x.Value >= y.Value);
302                 }
303
304                 public static SqlBoolean operator != (SqlDateTime x, SqlDateTime y)
305                 {
306                         if (x.IsNull || y.IsNull) 
307                                 return SqlBoolean.Null;
308                         else
309                                 return new SqlBoolean (!(x.Value == y.Value));
310                 }
311
312                 public static SqlBoolean operator < (SqlDateTime x, SqlDateTime y)
313                 {
314                         if (x.IsNull || y.IsNull) 
315                                 return SqlBoolean.Null;
316                         else
317                                 return new SqlBoolean (x.Value < y.Value);
318                 }
319
320                 public static SqlBoolean operator <= (SqlDateTime x, SqlDateTime y)
321                 {
322                         if (x.IsNull || y.IsNull) 
323                                 return SqlBoolean.Null;
324                         else
325                                 return new SqlBoolean (x.Value <= y.Value);
326                 }
327
328                 public static SqlDateTime operator - (SqlDateTime x, TimeSpan t)
329                 {
330                         if (x.IsNull)
331                                 return x;
332                         return new SqlDateTime (x.Value - t);
333                 }
334
335                 public static explicit operator DateTime (SqlDateTime x)
336                 {
337                         return x.Value;
338                 }
339
340                 public static explicit operator SqlDateTime (SqlString x)
341                 {
342                         return SqlDateTime.Parse (x.Value);
343                 }
344
345                 public static implicit operator SqlDateTime (DateTime x)
346                 {
347                         return new SqlDateTime (x);
348                 }
349
350                 #endregion
351         }
352 }
353