MonoTODO is cAsE SenSItIve stephane! :)
[mono.git] / mcs / class / corlib / System / DateTimeOffset.cs
1 /*
2  * System.DateTimeOffset
3  *
4  * Author(s)
5  *      Stephane Delcroix <stephane@delcroix.org>
6  *      Marek Safar (marek.safar@gmail.com)
7  *
8  *  Copyright (C) 2007 Novell, Inc (http://www.novell.com) 
9  *
10  * Permission is hereby granted, free of charge, to any person obtaining
11  * a copy of this software and associated documentation files (the
12  * "Software"), to deal in the Software without restriction, including
13  * without limitation the rights to use, copy, modify, merge, publish,
14  * distribute, sublicense, and/or sell copies of the Software, and to
15  * permit persons to whom the Software is furnished to do so, subject to
16  * the following conditions:
17  * 
18  * The above copyright notice and this permission notice shall be
19  * included in all copies or substantial portions of the Software.
20  * 
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28  */
29
30
31 #if NET_2_0 // Introduced by .NET 3.5 for 2.0 mscorlib
32
33 using System.Globalization;
34 using System.Runtime.InteropServices;
35 using System.Runtime.Serialization;
36
37 namespace System
38 {
39         [Serializable]
40         [StructLayout (LayoutKind.Auto)]
41         public struct DateTimeOffset : IComparable, IFormattable, ISerializable, IDeserializationCallback, IComparable<DateTimeOffset>, IEquatable<DateTimeOffset>
42         {
43                 public static readonly DateTimeOffset MaxValue = new DateTimeOffset (DateTime.MaxValue);
44                 public static readonly DateTimeOffset MinValue = new DateTimeOffset (DateTime.MaxValue);
45                 
46                 DateTime dt;
47                 TimeSpan utc_offset;
48         
49                 public DateTimeOffset (DateTime dateTime)
50                 {
51                         dt = dateTime;
52
53                         if (dateTime.Kind == DateTimeKind.Utc)
54                                 utc_offset = TimeSpan.Zero;
55                         else 
56                                 utc_offset = TimeZone.CurrentTimeZone.GetUtcOffset (dateTime);
57                                 
58                         if (UtcDateTime < DateTime.MinValue || UtcDateTime > DateTime.MaxValue)
59                                 throw new ArgumentOutOfRangeException ("The UTC date and time that results from applying the offset is earlier than MinValue or later than MaxValue.");
60
61                 }
62                 
63                 public DateTimeOffset (DateTime dateTime, TimeSpan offset)
64                 {
65                         if (dateTime.Kind == DateTimeKind.Utc && offset != TimeSpan.Zero)
66                                 throw new ArgumentException ("dateTime.Kind equals Utc and offset does not equal zero.");
67
68                         if (dateTime.Kind == DateTimeKind.Local && offset != TimeZone.CurrentTimeZone.GetUtcOffset (dateTime))
69                                 throw new ArgumentException ("dateTime.Kind equals Local and offset does not equal the offset of the system's local time zone.");
70
71                         if (offset.Ticks % TimeSpan.TicksPerMinute != 0)
72                                 throw new ArgumentException ("offset is not specified in whole minutes.");
73
74                         if (offset < new TimeSpan (-14, 0 ,0) || offset > new TimeSpan (14, 0, 0))
75                                 throw new ArgumentOutOfRangeException ("offset is less than -14 hours or greater than 14 hours.");
76
77                         dt = dateTime;
78                         utc_offset = offset;
79
80                         if (UtcDateTime < DateTime.MinValue || UtcDateTime > DateTime.MaxValue)
81                                 throw new ArgumentOutOfRangeException ("The UtcDateTime property is earlier than MinValue or later than MaxValue.");
82                 }
83
84                 public DateTimeOffset (long ticks, TimeSpan offset) : this (new DateTime (ticks), offset)
85                 {
86                 }
87
88                 public DateTimeOffset (int year, int month, int day, int hour, int minute, int second, TimeSpan offset) : 
89                         this (new DateTime (year, month, day, hour, minute, second), offset)
90                 {
91                 }
92
93                 public DateTimeOffset (int year, int month, int day, int hour, int minute, int second, int millisecond, TimeSpan offset) :
94                         this (new DateTime (year, month, day, hour, minute, second, millisecond), offset)
95                 {
96                 }
97
98                 public DateTimeOffset (int year, int month, int day, int hour, int minute, int second, int millisecond, Calendar calendar, TimeSpan offset) :
99                         this (new DateTime (year, month, day, hour, minute, second, millisecond, calendar), offset)
100                 {
101                 }
102
103                 public DateTimeOffset Add (TimeSpan timeSpan)
104                 {
105                         return new DateTimeOffset (dt.Add (timeSpan), utc_offset);
106                 }
107         
108                 public DateTimeOffset AddDays (double days)
109                 {
110                         return new DateTimeOffset (dt.AddDays (days), utc_offset);      
111                 }
112                 
113                 public DateTimeOffset AddHours (double hours)
114                 {
115                         return new DateTimeOffset (dt.AddHours (hours), utc_offset);
116                 }
117
118                 public static DateTimeOffset operator + (DateTimeOffset dateTimeTz, TimeSpan timeSpan)
119                 {
120                         return dateTimeTz.Add (timeSpan);
121                 }
122
123                 public DateTimeOffset AddMilliseconds (double milliseconds)
124                 {
125                         return new DateTimeOffset (dt.AddMilliseconds (milliseconds), utc_offset);
126                 }
127
128                 public DateTimeOffset AddMinutes (double minutes)
129                 {
130                         return new DateTimeOffset (dt.AddMinutes (minutes), utc_offset);        
131                 }
132
133                 public DateTimeOffset AddMonths (int months)
134                 {
135                         return new DateTimeOffset (dt.AddMonths (months), utc_offset);
136                 }
137
138                 public DateTimeOffset AddSeconds (double seconds)
139                 {
140                         return new DateTimeOffset (dt.AddSeconds (seconds), utc_offset);
141                 }
142
143                 public DateTimeOffset AddTicks (long ticks)
144                 {
145                         return new DateTimeOffset (dt.AddTicks (ticks), utc_offset);    
146                 }
147
148                 public DateTimeOffset AddYears (int years)
149                 {
150                         return new DateTimeOffset (dt.AddYears (years), utc_offset);
151                 }
152
153                 public static int Compare (DateTimeOffset first, DateTimeOffset second)
154                 {
155                         return first.CompareTo (second);        
156                 }
157
158                 public int CompareTo (DateTimeOffset other)
159                 {
160                         return UtcDateTime.CompareTo (other.UtcDateTime);
161                 }
162
163                 public int CompareTo (object other)
164                 {
165                         return CompareTo ((DateTimeOffset) other);
166                 }
167
168                 public static bool operator == (DateTimeOffset left, DateTimeOffset right)
169                 {
170                         return left.Equals (right);     
171                 }
172
173                 public bool Equals (DateTimeOffset other)
174                 {
175                         return UtcDateTime == other.UtcDateTime;
176                 }
177
178                 public override bool Equals (object other)
179                 {
180                         return UtcDateTime == ((DateTimeOffset) other).UtcDateTime;
181                 }
182
183                 public static bool Equals (DateTimeOffset first, DateTimeOffset second)
184                 {
185                         return first.Equals (second);   
186                 }
187
188                 public bool EqualsExact (DateTimeOffset other)
189                 {
190                         return dt == other.dt && utc_offset == other.utc_offset;        
191                 }
192
193                 public static DateTimeOffset FromFileTime (long fileTime)
194                 {
195                         if (fileTime < 0 || fileTime > MaxValue.Ticks)
196                                 throw new ArgumentOutOfRangeException ("fileTime is less than zero or greater than DateTimeOffset.MaxValue.Ticks.");
197                         
198                         return new DateTimeOffset (DateTime.FromFileTime (fileTime), TimeZone.CurrentTimeZone.GetUtcOffset (DateTime.FromFileTime (fileTime)));
199
200                 }
201
202                 public override int GetHashCode ()
203                 {
204                         return dt.GetHashCode () ^ utc_offset.GetHashCode ();
205                 }
206
207                 void ISerializable.GetObjectData (SerializationInfo info, StreamingContext context)
208                 {
209                         if (info == null)
210                                 throw new ArgumentNullException ("info");
211
212                         info.AddValue ("datetime", dt);
213                         info.AddValue ("offset", utc_offset);
214                 }
215
216                 public static bool operator > (DateTimeOffset left, DateTimeOffset right)
217                 {
218                         return left.UtcDateTime > right.UtcDateTime;
219                 }                       
220
221                 public static bool operator >= (DateTimeOffset left, DateTimeOffset right)
222                 {
223                         return left.UtcDateTime >= right.UtcDateTime;
224                 }                       
225
226                 public static implicit operator DateTimeOffset (DateTime dateTime)
227                 {
228                         return new DateTimeOffset (dateTime);
229                 }
230
231                 public static bool operator != (DateTimeOffset left, DateTimeOffset right)
232                 {
233                         return left.UtcDateTime != right.UtcDateTime;
234                 }
235
236                 public static bool operator < (DateTimeOffset left, DateTimeOffset right)
237                 {
238                         return left.UtcDateTime < right.UtcDateTime;
239                 }
240                 
241                 public static bool operator <= (DateTimeOffset left, DateTimeOffset right)
242                 {
243                         return left.UtcDateTime <= right.UtcDateTime;
244                 }
245         
246                 [MonoTODO]
247                 void IDeserializationCallback.OnDeserialization (object sender)
248                 {
249                 }
250
251                 [MonoTODO]
252                 public static DateTimeOffset Parse (string input)
253                 {
254                         if (input == null)
255                                 throw new ArgumentNullException ("input");
256
257                         throw new NotImplementedException ();
258                 }
259
260                 [MonoTODO]
261                 public static DateTimeOffset Parse (string input, IFormatProvider formatProvider)
262                 {
263                         if (input == null)
264                                 throw new ArgumentNullException ("input");
265
266                         throw new NotImplementedException ();
267                 }
268
269                 [MonoTODO]
270                 public static DateTimeOffset Parse (string input, IFormatProvider formatProvider, DateTimeStyles styles)
271                 {
272                         if (input == null)
273                                 throw new ArgumentNullException ("input");
274
275                         throw new NotImplementedException ();
276                 }
277
278                 [MonoTODO]
279                 public static DateTimeOffset ParseExact (string input, string format, IFormatProvider formatProvider)
280                 {
281                         if (input == null)
282                                 throw new ArgumentNullException ("input");
283                                 
284                         if (format == null)
285                                 throw new ArgumentNullException ("format");
286
287                         if (input == String.Empty)
288                                 throw new FormatException ("input is an empty string");
289
290                         if (format == String.Empty)
291                                 throw new FormatException ("format is an empty string");
292
293                         throw new NotImplementedException ();
294                 }
295
296                 [MonoTODO]
297                 public static DateTimeOffset ParseExact (string input, string format, IFormatProvider formatProvider, DateTimeStyles styles)
298                 {
299                         if (input == null)
300                                 throw new ArgumentNullException ("input");
301                                 
302                         if (format == null)
303                                 throw new ArgumentNullException ("format");
304
305                         if (input == String.Empty)
306                                 throw new FormatException ("input is an empty string");
307
308                         if (format == String.Empty)
309                                 throw new FormatException ("format is an empty string");
310
311                         throw new NotImplementedException ();
312                 }
313
314                 [MonoTODO]
315                 public static DateTimeOffset ParseExact (string input, string[] formats, IFormatProvider formatProvider, DateTimeStyles styles)
316                 {
317                         if (input == null)
318                                 throw new ArgumentNullException ("input");
319                                 
320
321                         if (input == String.Empty)
322                                 throw new FormatException ("input is an empty string");
323
324                         throw new NotImplementedException ();
325                 }
326
327                 public TimeSpan Subtract (DateTimeOffset other)
328                 {
329                         return UtcDateTime - other.UtcDateTime;
330                 }
331
332                 public DateTimeOffset Subtract (TimeSpan timeSpan)
333                 {
334                         return Add (-timeSpan);
335                 }
336
337                 public static TimeSpan operator - (DateTimeOffset left, DateTimeOffset right)
338                 {
339                         return left.Subtract (right);
340                 }
341
342                 public static DateTimeOffset operator - (DateTimeOffset dateTimeTz, TimeSpan timeSpan)
343                 {
344                         return dateTimeTz.Subtract (timeSpan);  
345                 }
346
347                 public long ToFileTime ()
348                 {
349                         return UtcDateTime.ToFileTime ();
350                 }
351
352                 public DateTimeOffset ToLocalTime ()
353                 {
354                         return new DateTimeOffset (UtcDateTime.ToLocalTime (), TimeZone.CurrentTimeZone.GetUtcOffset (UtcDateTime.ToLocalTime ()));
355                 }
356
357                 public DateTimeOffset ToOffset (TimeSpan offset)
358                 {
359                         return new DateTimeOffset (dt - utc_offset + offset, offset);
360                 }
361
362                 [MonoTODO]
363                 public override string ToString ()
364                 {
365                         throw new NotImplementedException ();
366                 }
367
368                 [MonoTODO]
369                 public string ToString (IFormatProvider formatProvider)
370                 {
371                         throw new NotImplementedException ();   
372                 }
373
374                 [MonoTODO]
375                 public string ToString (string format)
376                 {
377                         throw new NotImplementedException ();
378                 }
379
380                 [MonoTODO]
381                 public string ToString (string format, IFormatProvider formatProvider)
382                 {
383                         throw new NotImplementedException ();   
384                 }
385
386                 public DateTimeOffset ToUniversalTime ()
387                 {
388                         return new DateTimeOffset (UtcDateTime, TimeSpan.Zero); 
389                 }
390
391                 public static bool TryParse (string input, out DateTimeOffset result)
392                 {
393                         try {
394                                 result = Parse (input);
395                                 return true;
396                         } catch {
397                                 result = MinValue;
398                                 return false;
399                         }
400                 }
401
402                 public static bool TryParse (string input, IFormatProvider formatProvider, DateTimeStyles styles, out DateTimeOffset result)
403                 {
404                         try {
405                                 result = Parse (input, formatProvider, styles);
406                                 return true;
407                         } catch {
408                                 result = MinValue;
409                                 return false;
410                         }       
411                 }
412
413                 public static bool TryParseExact (string input, string format, IFormatProvider formatProvider, DateTimeStyles styles, out DateTimeOffset result)
414                 {
415                         try {
416                                 result = ParseExact (input, format, formatProvider, styles);
417                                 return true;
418                         } catch {
419                                 result = MinValue;
420                                 return false;
421                         }
422                 }
423
424                 public static bool TryParseExact (string input, string[] formats, IFormatProvider formatProvider, DateTimeStyles styles, out DateTimeOffset result)
425                 {
426                         try {
427                                 result = ParseExact (input, formats, formatProvider, styles);
428                                 return true;
429                         } catch {
430                                 result = MinValue;
431                                 return false;
432                         }
433                 }
434
435                 public DateTime Date {
436                         get { return DateTime.SpecifyKind (dt.Date, DateTimeKind.Unspecified); }
437                 }
438
439                 public DateTime DateTime {
440                         get { return DateTime.SpecifyKind (dt, DateTimeKind.Unspecified); }
441                 }
442
443                 public int Day {
444                         get { return dt.Day; }
445                 }
446
447                 public DayOfWeek DayOfWeek {
448                         get { return dt.DayOfWeek; }
449                 }
450
451                 public int DayOfYear {
452                         get { return dt.DayOfYear; }
453                 }
454
455                 public int Hour {
456                         get { return dt.Hour; }
457                 }
458
459                 public DateTime LocalDateTime {
460                         get { return UtcDateTime.ToLocalTime (); }
461                 }
462
463                 public int Millisecond {
464                         get { return dt.Millisecond; }
465                 }
466
467                 public int Minute {
468                         get { return dt.Minute; }
469                 }
470
471                 public int Month {
472                         get { return dt.Month; }
473                 }
474
475                 public static DateTimeOffset Now {
476                         get { return new DateTimeOffset (DateTime.Now);}
477                 }
478
479                 public TimeSpan Offset {
480                         get { return utc_offset; }      
481                 }
482
483                 public int Second {
484                         get { return dt.Second; }
485                 }
486
487                 public long Ticks {
488                         get { return dt.Ticks; }        
489                 }
490
491                 public TimeSpan TimeOfDay {
492                         get { return dt.TimeOfDay; }
493                 }
494
495                 public DateTime UtcDateTime {
496                         get { return DateTime.SpecifyKind (dt - utc_offset, DateTimeKind.Utc); }        
497                 }
498                 
499                 public static DateTimeOffset UtcNow {
500                         get { return new DateTimeOffset (DateTime.UtcNow); }
501                 }
502
503                 public long UtcTicks {
504                         get { return UtcDateTime.Ticks; }
505                 }
506
507                 public int Year {
508                         get { return dt.Year; }
509                 }
510         }
511 }
512 #endif