Guest

DDay.iCalUtilityDateUtil.cs

By: ctsf on Feb 12th, 2012  |  syntax: C#  |  size: 5.08 KB  |  hits: 80  |  expires: Never
download  |  raw  |  embed  |  report abuse
Copied
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Globalization;
  5. using System.Diagnostics;
  6.  
  7. namespace DDay.iCal
  8. {
  9.     public class DateUtil
  10.     {
  11.         static private System.Globalization.Calendar _Calendar;
  12.  
  13.         static DateUtil()
  14.         {
  15.             _Calendar = System.Globalization.CultureInfo.CurrentCulture.Calendar;
  16.         }
  17.  
  18.         public static IDateTime StartOfDay(IDateTime dt)
  19.         {
  20.             return dt.
  21.                 AddHours(-dt.Hour).
  22.                 AddMinutes(-dt.Minute).
  23.                 AddSeconds(-dt.Second);
  24.         }
  25.  
  26.         public static IDateTime EndOfDay(IDateTime dt)
  27.         {
  28.             return StartOfDay(dt).AddDays(1).AddTicks(-1);
  29.         }    
  30.  
  31.         public static DateTime GetSimpleDateTimeData(IDateTime dt)
  32.         {
  33.             return DateTime.SpecifyKind(dt.Value, dt.IsUniversalTime ? DateTimeKind.Utc : DateTimeKind.Local);
  34.         }
  35.  
  36.         public static DateTime SimpleDateTimeToMatch(IDateTime dt, IDateTime toMatch)
  37.         {
  38.             if (toMatch.IsUniversalTime && dt.IsUniversalTime)
  39.                 return dt.Value;
  40.             else if (toMatch.IsUniversalTime)
  41.                 return dt.Value.ToUniversalTime();
  42.             else if (dt.IsUniversalTime)
  43.                 return dt.Value.ToLocalTime();
  44.             else
  45.                 return dt.Value;
  46.         }
  47.  
  48.         public static IDateTime MatchTimeZone(IDateTime dt1, IDateTime dt2)
  49.         {
  50.             Debug.Assert(dt1 != null && dt2 != null);
  51.  
  52.             // Associate the date/time with the first.
  53.             IDateTime copy = dt2.Copy<IDateTime>();
  54.             copy.AssociateWith(dt1);
  55.  
  56.             // If the dt1 time does not occur in the same time zone as the
  57.             // dt2 time, then let's convert it so they can be used in the
  58.             // same context (i.e. evaluation).
  59.             if (dt1.TZID != null)
  60.             {
  61.                 if (!string.Equals(dt1.TZID, copy.TZID))
  62.                     return (dt1.TimeZoneObservance != null) ? copy.ToTimeZone(dt1.TimeZoneObservance.Value) : copy.ToTimeZone(dt1.TZID);
  63.                 else return copy;
  64.             }
  65.             else if (dt1.IsUniversalTime)
  66.             {
  67.                 // The first date/time is in UTC time, convert!
  68.                 return new iCalDateTime(copy.UTC);
  69.             }
  70.             else
  71.             {
  72.                 // The first date/time is in local time, convert!
  73.                 return new iCalDateTime(copy.Local);
  74.             }
  75.         }
  76.  
  77.         //
  78.         // Add weeks in a more naive manner because the existing AddWeeks() method was
  79.         // breaking for years between 2013-2015.
  80.         //
  81.         public static DateTime AddWeeks(DateTime dt, int interval, DayOfWeek firstDayOfWeek)
  82.         {
  83.             // Add N weeks to the specified date.
  84.             dt = dt.AddDays(interval * 7);
  85.  
  86.             // Wind back to the start of the week.
  87.             while (dt.DayOfWeek != firstDayOfWeek)
  88.                 dt = dt.AddDays(-1);
  89.  
  90.             return dt;
  91.         }
  92.  
  93.         public static DateTime AddWeeks(System.Globalization.Calendar calendar, DateTime dt, int interval, DayOfWeek firstDayOfWeek)
  94.         {
  95.             // How the week increments depends on the WKST indicated (defaults to Monday)
  96.             // So, basically, we determine the week of year using the necessary rules,
  97.             // and we increment the day until the week number matches our "goal" week number.
  98.             // So, if the current week number is 36, and our interval is 2, then our goal
  99.             // week number is 38.
  100.             // NOTE: fixes WeeklyUntilWkst2() eval.
  101.             int current = calendar.GetWeekOfYear(dt, System.Globalization.CalendarWeekRule.FirstFourDayWeek, firstDayOfWeek),
  102.                 lastLastYear = calendar.GetWeekOfYear(new DateTime(dt.Year - 1, 12, 31, 0, 0, 0, DateTimeKind.Local), System.Globalization.CalendarWeekRule.FirstFourDayWeek, firstDayOfWeek),
  103.                 last = calendar.GetWeekOfYear(new DateTime(dt.Year, 12, 31, 0, 0, 0, DateTimeKind.Local), System.Globalization.CalendarWeekRule.FirstFourDayWeek, firstDayOfWeek),
  104.                 goal = current + interval;
  105.  
  106.             // If the goal week is greater than the last week of the year, wrap it!
  107.             if (goal > last)
  108.                 goal = goal - last;
  109.             else if (goal <= 0)
  110.                 goal = lastLastYear + goal;
  111.  
  112.             int i = interval > 0 ? 7 : -7;
  113.             while (current != goal)
  114.             {
  115.                 dt = dt.AddDays(i);
  116.                 current = calendar.GetWeekOfYear(dt, CalendarWeekRule.FirstFourDayWeek, firstDayOfWeek);
  117.             }
  118.             while (dt.DayOfWeek != firstDayOfWeek)
  119.                 dt = dt.AddDays(-1);
  120.  
  121.             return dt;
  122.         }
  123.  
  124.         public static DateTime FirstDayOfWeek(DateTime dt, DayOfWeek firstDayOfWeek, out int offset)
  125.         {
  126.             offset = 0;
  127.             while (dt.DayOfWeek != firstDayOfWeek)
  128.             {
  129.                 dt = dt.AddDays(-1);
  130.                 offset++;
  131.             }
  132.             return dt;
  133.         }
  134.     }
  135. }