2 * System.DateTimeOffset
5 * Stephane Delcroix <stephane@delcroix.org>
6 * Marek Safar (marek.safar@gmail.com)
8 * Copyright (C) 2007 Novell, Inc (http://www.novell.com)
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:
18 * The above copyright notice and this permission notice shall be
19 * included in all copies or substantial portions of the Software.
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.
31 #if NET_2_0 // Introduced by .NET 3.5 for 2.0 mscorlib
33 using System.Globalization;
34 using System.Runtime.InteropServices;
35 using System.Runtime.Serialization;
40 [StructLayout (LayoutKind.Auto)]
41 public struct DateTimeOffset : IComparable, IFormattable, ISerializable, IDeserializationCallback, IComparable<DateTimeOffset>, IEquatable<DateTimeOffset>
43 public static readonly DateTimeOffset MaxValue = new DateTimeOffset (DateTime.MaxValue);
44 public static readonly DateTimeOffset MinValue = new DateTimeOffset (DateTime.MaxValue);
49 public DateTimeOffset (DateTime dateTime)
53 if (dateTime.Kind == DateTimeKind.Utc)
54 utc_offset = TimeSpan.Zero;
56 utc_offset = TimeZone.CurrentTimeZone.GetUtcOffset (dateTime);
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.");
63 public DateTimeOffset (DateTime dateTime, TimeSpan offset)
65 if (dateTime.Kind == DateTimeKind.Utc && offset != TimeSpan.Zero)
66 throw new ArgumentException ("dateTime.Kind equals Utc and offset does not equal zero.");
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.");
71 if (offset.Ticks % TimeSpan.TicksPerMinute != 0)
72 throw new ArgumentException ("offset is not specified in whole minutes.");
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.");
80 if (UtcDateTime < DateTime.MinValue || UtcDateTime > DateTime.MaxValue)
81 throw new ArgumentOutOfRangeException ("The UtcDateTime property is earlier than MinValue or later than MaxValue.");
84 public DateTimeOffset (long ticks, TimeSpan offset) : this (new DateTime (ticks), offset)
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)
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)
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)
103 public DateTimeOffset Add (TimeSpan timeSpan)
105 return new DateTimeOffset (dt.Add (timeSpan), utc_offset);
108 public DateTimeOffset AddDays (double days)
110 return new DateTimeOffset (dt.AddDays (days), utc_offset);
113 public DateTimeOffset AddHours (double hours)
115 return new DateTimeOffset (dt.AddHours (hours), utc_offset);
118 public static DateTimeOffset operator + (DateTimeOffset dateTimeTz, TimeSpan timeSpan)
120 return dateTimeTz.Add (timeSpan);
123 public DateTimeOffset AddMilliseconds (double milliseconds)
125 return new DateTimeOffset (dt.AddMilliseconds (milliseconds), utc_offset);
128 public DateTimeOffset AddMinutes (double minutes)
130 return new DateTimeOffset (dt.AddMinutes (minutes), utc_offset);
133 public DateTimeOffset AddMonths (int months)
135 return new DateTimeOffset (dt.AddMonths (months), utc_offset);
138 public DateTimeOffset AddSeconds (double seconds)
140 return new DateTimeOffset (dt.AddSeconds (seconds), utc_offset);
143 public DateTimeOffset AddTicks (long ticks)
145 return new DateTimeOffset (dt.AddTicks (ticks), utc_offset);
148 public DateTimeOffset AddYears (int years)
150 return new DateTimeOffset (dt.AddYears (years), utc_offset);
153 public static int Compare (DateTimeOffset first, DateTimeOffset second)
155 return first.CompareTo (second);
158 public int CompareTo (DateTimeOffset other)
160 return UtcDateTime.CompareTo (other.UtcDateTime);
163 public int CompareTo (object other)
165 return CompareTo ((DateTimeOffset) other);
168 public static bool operator == (DateTimeOffset left, DateTimeOffset right)
170 return left.Equals (right);
173 public bool Equals (DateTimeOffset other)
175 return UtcDateTime == other.UtcDateTime;
178 public override bool Equals (object other)
180 return UtcDateTime == ((DateTimeOffset) other).UtcDateTime;
183 public static bool Equals (DateTimeOffset first, DateTimeOffset second)
185 return first.Equals (second);
188 public bool EqualsExact (DateTimeOffset other)
190 return dt == other.dt && utc_offset == other.utc_offset;
193 public static DateTimeOffset FromFileTime (long fileTime)
195 if (fileTime < 0 || fileTime > MaxValue.Ticks)
196 throw new ArgumentOutOfRangeException ("fileTime is less than zero or greater than DateTimeOffset.MaxValue.Ticks.");
198 return new DateTimeOffset (DateTime.FromFileTime (fileTime), TimeZone.CurrentTimeZone.GetUtcOffset (DateTime.FromFileTime (fileTime)));
202 public override int GetHashCode ()
204 return dt.GetHashCode () ^ utc_offset.GetHashCode ();
207 void ISerializable.GetObjectData (SerializationInfo info, StreamingContext context)
210 throw new ArgumentNullException ("info");
212 info.AddValue ("datetime", dt);
213 info.AddValue ("offset", utc_offset);
216 public static bool operator > (DateTimeOffset left, DateTimeOffset right)
218 return left.UtcDateTime > right.UtcDateTime;
221 public static bool operator >= (DateTimeOffset left, DateTimeOffset right)
223 return left.UtcDateTime >= right.UtcDateTime;
226 public static implicit operator DateTimeOffset (DateTime dateTime)
228 return new DateTimeOffset (dateTime);
231 public static bool operator != (DateTimeOffset left, DateTimeOffset right)
233 return left.UtcDateTime != right.UtcDateTime;
236 public static bool operator < (DateTimeOffset left, DateTimeOffset right)
238 return left.UtcDateTime < right.UtcDateTime;
241 public static bool operator <= (DateTimeOffset left, DateTimeOffset right)
243 return left.UtcDateTime <= right.UtcDateTime;
247 void IDeserializationCallback.OnDeserialization (object sender)
252 public static DateTimeOffset Parse (string input)
255 throw new ArgumentNullException ("input");
257 throw new NotImplementedException ();
261 public static DateTimeOffset Parse (string input, IFormatProvider formatProvider)
264 throw new ArgumentNullException ("input");
266 throw new NotImplementedException ();
270 public static DateTimeOffset Parse (string input, IFormatProvider formatProvider, DateTimeStyles styles)
273 throw new ArgumentNullException ("input");
275 throw new NotImplementedException ();
279 public static DateTimeOffset ParseExact (string input, string format, IFormatProvider formatProvider)
282 throw new ArgumentNullException ("input");
285 throw new ArgumentNullException ("format");
287 if (input == String.Empty)
288 throw new FormatException ("input is an empty string");
290 if (format == String.Empty)
291 throw new FormatException ("format is an empty string");
293 throw new NotImplementedException ();
297 public static DateTimeOffset ParseExact (string input, string format, IFormatProvider formatProvider, DateTimeStyles styles)
300 throw new ArgumentNullException ("input");
303 throw new ArgumentNullException ("format");
305 if (input == String.Empty)
306 throw new FormatException ("input is an empty string");
308 if (format == String.Empty)
309 throw new FormatException ("format is an empty string");
311 throw new NotImplementedException ();
315 public static DateTimeOffset ParseExact (string input, string[] formats, IFormatProvider formatProvider, DateTimeStyles styles)
318 throw new ArgumentNullException ("input");
321 if (input == String.Empty)
322 throw new FormatException ("input is an empty string");
324 throw new NotImplementedException ();
327 public TimeSpan Subtract (DateTimeOffset other)
329 return UtcDateTime - other.UtcDateTime;
332 public DateTimeOffset Subtract (TimeSpan timeSpan)
334 return Add (-timeSpan);
337 public static TimeSpan operator - (DateTimeOffset left, DateTimeOffset right)
339 return left.Subtract (right);
342 public static DateTimeOffset operator - (DateTimeOffset dateTimeTz, TimeSpan timeSpan)
344 return dateTimeTz.Subtract (timeSpan);
347 public long ToFileTime ()
349 return UtcDateTime.ToFileTime ();
352 public DateTimeOffset ToLocalTime ()
354 return new DateTimeOffset (UtcDateTime.ToLocalTime (), TimeZone.CurrentTimeZone.GetUtcOffset (UtcDateTime.ToLocalTime ()));
357 public DateTimeOffset ToOffset (TimeSpan offset)
359 return new DateTimeOffset (dt - utc_offset + offset, offset);
363 public override string ToString ()
365 throw new NotImplementedException ();
369 public string ToString (IFormatProvider formatProvider)
371 throw new NotImplementedException ();
375 public string ToString (string format)
377 throw new NotImplementedException ();
381 public string ToString (string format, IFormatProvider formatProvider)
383 throw new NotImplementedException ();
386 public DateTimeOffset ToUniversalTime ()
388 return new DateTimeOffset (UtcDateTime, TimeSpan.Zero);
391 public static bool TryParse (string input, out DateTimeOffset result)
394 result = Parse (input);
402 public static bool TryParse (string input, IFormatProvider formatProvider, DateTimeStyles styles, out DateTimeOffset result)
405 result = Parse (input, formatProvider, styles);
413 public static bool TryParseExact (string input, string format, IFormatProvider formatProvider, DateTimeStyles styles, out DateTimeOffset result)
416 result = ParseExact (input, format, formatProvider, styles);
424 public static bool TryParseExact (string input, string[] formats, IFormatProvider formatProvider, DateTimeStyles styles, out DateTimeOffset result)
427 result = ParseExact (input, formats, formatProvider, styles);
435 public DateTime Date {
436 get { return DateTime.SpecifyKind (dt.Date, DateTimeKind.Unspecified); }
439 public DateTime DateTime {
440 get { return DateTime.SpecifyKind (dt, DateTimeKind.Unspecified); }
444 get { return dt.Day; }
447 public DayOfWeek DayOfWeek {
448 get { return dt.DayOfWeek; }
451 public int DayOfYear {
452 get { return dt.DayOfYear; }
456 get { return dt.Hour; }
459 public DateTime LocalDateTime {
460 get { return UtcDateTime.ToLocalTime (); }
463 public int Millisecond {
464 get { return dt.Millisecond; }
468 get { return dt.Minute; }
472 get { return dt.Month; }
475 public static DateTimeOffset Now {
476 get { return new DateTimeOffset (DateTime.Now);}
479 public TimeSpan Offset {
480 get { return utc_offset; }
484 get { return dt.Second; }
488 get { return dt.Ticks; }
491 public TimeSpan TimeOfDay {
492 get { return dt.TimeOfDay; }
495 public DateTime UtcDateTime {
496 get { return DateTime.SpecifyKind (dt - utc_offset, DateTimeKind.Utc); }
499 public static DateTimeOffset UtcNow {
500 get { return new DateTimeOffset (DateTime.UtcNow); }
503 public long UtcTicks {
504 get { return UtcDateTime.Ticks; }
508 get { return dt.Year; }