private static void Dump(TimeZoneInfo zone, Options options, TextWriter writer) { writer.Write($"{zone.Id}\n"); // This will be a bit odd using Windows time zones, as most have permanent // daylight saving rules... but for tz data, it should be okay. var initial = new DateTimeOffset(2, 1, 1, 0, 0, 0, 0, TimeSpan.Zero); var initialOffset = zone.GetUtcOffset(initial); var initialDaylight = zone.IsDaylightSavingTime(initial); writer.Write("Initially: {0} {1} {2}\n", (initialOffset.Ticks >= 0 ? "+" : "-") + initialOffset.ToString("hh':'mm':'ss", CultureInfo.InvariantCulture), initialDaylight ? "daylight" : "standard", initialDaylight ? zone.DaylightName : zone.StandardName); int fromYear = options.FromYear ?? 1800; DateTimeOffset start = new DateTimeOffset(fromYear, 1, 1, 0, 0, 0, TimeSpan.Zero); DateTimeOffset end = new DateTimeOffset(options.ToYear, 1, 1, 0, 0, 0, TimeSpan.Zero); DateTimeOffset? transition = GetNextTransition(zone, start.AddTicks(-1), end); while (transition != null) { var offset = zone.GetUtcOffset(transition.Value); var isDaylight = zone.IsDaylightSavingTime(transition.Value); // It's unfortunate that TimeZoneInfo doesn't support the idea of different names // for different periods in history. Never mind - this is better than nothing, // for diagnostic purposes. writer.Write("{0} {1} {2} {3}\n", transition.Value.ToString("yyyy-MM-dd HH:mm:ss'Z'", CultureInfo.InvariantCulture), (offset.Ticks >= 0 ? "+" : "-") + offset.ToString("hh':'mm':'ss", CultureInfo.InvariantCulture), isDaylight ? "daylight" : "standard", isDaylight ? zone.DaylightName : zone.StandardName); transition = GetNextTransition(zone, transition.Value, end); } writer.Write("\n"); }
public override bool IsDaylightSavingTime(DateTime dateTime) { if (dateTime.Kind == DateTimeKind.Utc) { return(false); } return(LocalTimeZone.IsDaylightSavingTime(dateTime)); }
private static TimeSpan DetectStandardOffset(TimeZoneInfo zone, TimeZoneInfo.AdjustmentRule rule) { var offset = zone.GetUtcOffset(rule.DateStart); if (zone.IsDaylightSavingTime(rule.DateStart)) { offset -= rule.DaylightDelta; } return offset; }
/// <summary> /// Gets the offset from UT for the given date in the given timezone, /// taking into account daylight savings. /// </summary> /// <param name="date">the date that is the base for the offset</param> /// <param name="tz">the time-zone to calculate to offset to</param> /// <returns>the offset</returns> public static double GetOffset(this DateTime date, TimeZone tz) { if (tz.IsDaylightSavingTime(date)) { // TODO return(tz.BaseUtcOffset.TotalMilliseconds + 0); } return(tz.BaseUtcOffset.TotalMilliseconds); }
public static XElement TimeZoneToXml(TimeZoneInfo aTimeZoneInfo, DateTime aNow) { return new XElement("timezone", new XElement("name", aTimeZoneInfo.DisplayName), new XElement("daylightName", aTimeZoneInfo.DaylightName), new XElement("standardName", aTimeZoneInfo.StandardName), new XElement("hasDaylight", aTimeZoneInfo.SupportsDaylightSavingTime ? "yes" : "no"), new XElement("currentOffset", OffsetToString(aTimeZoneInfo.GetUtcOffset(aNow))), new XElement("isDaylight", aTimeZoneInfo.IsDaylightSavingTime(aNow) ? "yes" : "no")); }
/// <summary> /// Gets the offset from UT for the given date in the given timezone, /// taking into account daylight savings. /// </summary> /// <param name="date">the date that is the base for the offset</param> /// <param name="tz">the time-zone to calculate to offset to</param> /// <returns>the offset</returns> public static double GetOffset(DateTime date, TimeZone tz) { #if !NET_35 throw new Exception("UTC offset calculation not supported in < .NET 3.5"); #else if (tz.IsDaylightSavingTime(date)) { // TODO return(tz.BaseUtcOffset.TotalMilliseconds + 0); } return(tz.BaseUtcOffset.TotalMilliseconds); #endif }
private static DateTimeOffset? GetNextTransition(TimeZoneInfo zone, DateTimeOffset start, DateTimeOffset end) { TimeSpan startOffset = zone.GetUtcOffset(start); bool startDaylight = zone.IsDaylightSavingTime(start); DateTimeOffset now = start.AddDays(1); while (now <= end) { if (zone.GetUtcOffset(now) != startOffset || zone.IsDaylightSavingTime(now) != startDaylight) { // Right, so there's a transition strictly after now - (one day), and less than or equal to now. Binary search... long upperInclusiveTicks = now.Ticks; long lowerExclusiveTicks = now.AddDays(-1).Ticks; while (upperInclusiveTicks > lowerExclusiveTicks + 1) { long candidateTicks = (upperInclusiveTicks + lowerExclusiveTicks) / 2; var candidateDto = new DateTimeOffset(candidateTicks, TimeSpan.Zero); if (zone.GetUtcOffset(candidateDto) != startOffset || zone.IsDaylightSavingTime(candidateDto) != startDaylight) { // Still seeing a difference: look earlier upperInclusiveTicks = candidateTicks; } else { // Same as at start of day: look later lowerExclusiveTicks = candidateTicks; } } // If we turn out to have hit the end point, we're done without a final transition. return upperInclusiveTicks == end.Ticks ? (DateTimeOffset?)null : new DateTimeOffset(upperInclusiveTicks, TimeSpan.Zero); } now = now.AddDays(1); } return null; }
// TODO - document public static DateTime ToTimeZone(this DateTime date, string timeZoneId) { DateTime newTime = date; try { TimeZoneInfo timeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId); newTime = TimeZoneInfo.ConvertTimeFromUtc(date, timeZone); Console.WriteLine("The date and time are {0} {1}.", newTime, timeZone.IsDaylightSavingTime(newTime) ? timeZone.DaylightName : timeZone.StandardName); } catch (TimeZoneNotFoundException) { Console.WriteLine("The registry does not define the Time zone. [" + timeZoneId + "]"); } catch (InvalidTimeZoneException) { Console.WriteLine("Registry data on the Time zone has been corrupted. [" + timeZoneId + "]"); } return(newTime); }
private static PhpArray GetTimeOfDay(DateTime utc, TimeZoneInfo/*!*/ zone) { PhpArray result = new PhpArray(0, 4); DateTime local = TimeZoneInfo.ConvertTimeFromUtc(utc, zone); int current_dst = 0; if (zone.IsDaylightSavingTime(local)) { var rules = zone.GetAdjustmentRules(); for (int i = 0; i < rules.Length; i++) { if (rules[i].DateStart <= local && rules[i].DateEnd >= local) { current_dst = (int)rules[i].DaylightDelta.TotalHours; break; } } } const int ticks_per_microsecond = (int)TimeSpan.TicksPerMillisecond / 1000; result["sec"] = DateTimeUtils.UtcToUnixTimeStamp(utc); result["usec"] = (int)(local.Ticks % TimeSpan.TicksPerSecond) / ticks_per_microsecond; result["minuteswest"] = (int)(utc - local).TotalMinutes; result["dsttime"] = current_dst; return result;
/// <summary> /// Implementation of <see cref="FormatTime(string,int)"/> function. /// </summary> private static string FormatTime(string format, DateTime utc, TimeZoneInfo/*!*/ zone) { // Possibly bug in framework? "h" and "hh" just after midnight shows 12, not 0 if (format == null) return ""; DateTime local = TimeZoneInfo.ConvertTimeFromUtc(utc, zone);// zone.ToLocalTime(utc); DateTimeFormatInfo info = Locale.GetCulture(Locale.Category.Time).DateTimeFormat; StringBuilder result = new StringBuilder(); bool specialChar = false; foreach (char ch in format) { if (!specialChar) { if (ch == '%') specialChar = true; else result.Append(ch); continue; } // we have special character switch (ch) { case 'a': // abbreviated weekday name according to the current locale result.Append(local.ToString("ddd", info)); break; case 'A': // full weekday name according to the current locale result.Append(local.ToString("dddd", info)); break; case 'b': // abbreviated month name according to the current locale result.Append(local.ToString("MMM", info)); break; case 'B': // full month name according to the current locale result.Append(local.ToString("MMMM", info)); break; case 'c': // preferred date and time representation for the current locale result.Append(local.ToString(info)); break; case 'C': // century number (the year divided by 100 and truncated to an integer, range 00 to 99) result.Append(local.Year / 100); break; case 'd': // day of the month as a decimal number (range 01 to 31) result.Append(local.ToString("dd", info)); break; case 'D': // same as %m/%d/%y result.Append(local.ToString("MM\\/dd\\/yy", info)); break; case 'e': // day of the month as a decimal number, a single digit is preceded by a space (range ' 1' to '31') result.AppendFormat("{0,2}", local.Day); break; case 'g': { // like %G, but without the century. int week, year; GetIsoWeekAndYear(local, out week, out year); result.AppendFormat("{0:00}", year % 100); break; } case 'G': // The 4-digit year corresponding to the ISO week number. { int week, year; GetIsoWeekAndYear(local, out week, out year); result.AppendFormat("{0:0000}", year); break; } case 'h': // same as %b goto case 'b'; case 'H': // hour as a decimal number using a 24-hour clock (range 00 to 23) result.Append(local.ToString("HH", info)); break; case 'I': // hour as a decimal number using a 12-hour clock (range 01 to 12) result.Append(local.ToString("hh", info)); break; case 'j': // day of the year as a decimal number (range 001 to 366) result.AppendFormat("{0:000}", local.DayOfYear); break; case 'm': // month as a decimal number (range 01 to 12) result.Append(local.ToString("MM", info)); break; case 'M': // minute as a decimal number result.Append(local.ToString("mm", info)); break; case 'n': // newline character result.Append('\n'); break; case 'p': // either `am' or `pm' according to the given time value, // or the corresponding strings for the current locale result.Append(local.ToString("tt", info)); break; case 'r': // time in a.m. and p.m. notation result.Append(local.ToString("hh:mm:ss tt", info)); break; case 'R': // time in 24 hour notation result.Append(local.ToString("H:mm:ss", info)); break; case 'S': // second as a decimal number result.Append(local.ToString("ss", info)); break; case 't': // tab character result.Append('\t'); break; case 'T': // current time, equal to %H:%M:%S result.Append(local.ToString("HH:mm:ss", info)); break; case 'u': // weekday as a decimal number [1,7], with 1 representing Monday result.Append(((int)local.DayOfWeek + 5) % 7 + 1); break; case 'U': // week number of the current year as a decimal number, starting with the first // Sunday as the first day of the first week (formula taken from GlibC 2.3.5): result.AppendFormat("{0:00}", (local.DayOfYear - 1 - (int)local.DayOfWeek + 7) / 7); break; case 'V': { // The ISO 8601:1988 week number of the current year int week, year; GetIsoWeekAndYear(local, out week, out year); result.AppendFormat("{0:00}", week); break; } case 'w': // day of the week as a decimal, Sunday being 0 result.Append((int)local.DayOfWeek); break; case 'W': // week number of the current year as a decimal number, starting with the first // Monday as the first day of the first week (formula taken from GlibC 2.3.5): result.AppendFormat("{0:00}", (local.DayOfYear - 1 - ((int)local.DayOfWeek - 1 + 7) % 7 + 7) / 7); break; case 'x': // preferred date representation for the current locale without the time result.Append(local.ToString("d", info)); break; case 'X': // preferred time representation for the current locale without the date result.Append(local.ToString("T", info)); break; case 'y': // year as a decimal number without a century (range 00 to 99) result.Append(local.ToString("yy", info)); break; case 'Y': // year as a decimal number including the century result.Append(local.ToString("yyyy", info)); break; case 'z': case 'Z': result.Append(zone.IsDaylightSavingTime(local) ? zone.DaylightName : zone.StandardName); break; case '%': result.Append('%'); break; } specialChar = false; } if (specialChar) result.Append('%'); return result.ToString();
/// <summary> /// Gets the offset from UT for the given date in the given timezone, /// taking into account daylight savings. /// </summary> /// <param name="date"> /// the date that is the base for the offset /// </param> /// <param name="tz"> /// the time-zone to calculate to offset to /// </param> /// <returns> /// the offset /// </returns> public static double GetOffset(this DateTime date, TimeZoneInfo tz) { if (tz.IsDaylightSavingTime(date)) { return tz.BaseUtcOffset.TotalMilliseconds + 0; } return tz.BaseUtcOffset.TotalMilliseconds; }
internal BclAdjustmentRule(TimeZoneInfo zone, TimeZoneInfo.AdjustmentRule rule) { // With .NET 4.6, adjustment rules can have their own standard offsets, allowing // a much more reasonable set of time zone data. Unfortunately, this isn't directly // exposed, but we can detect it by just finding the UTC offset for an arbitrary // time within the rule - the start, in this case - and then take account of the // possibility of that being in daylight saving time. Fortunately, we only need // to do this during the setup. var ruleStandardOffset = zone.GetUtcOffset(rule.DateStart); if (zone.IsDaylightSavingTime(rule.DateStart)) { ruleStandardOffset -= rule.DaylightDelta; } StandardOffset = ruleStandardOffset.ToOffset(); // Although the rule may have its own standard offset, the start/end is still determined // using the zone's standard offset. var zoneStandardOffset = zone.BaseUtcOffset.ToOffset(); // Note: this extends back from DateTime.MinValue to start of time, even though the BCL can represent // as far back as 1AD. This is in the *spirit* of a rule which goes back that far. Start = rule.DateStart == DateTime.MinValue ? Instant.BeforeMinValue : rule.DateStart.ToLocalDateTime().WithOffset(zoneStandardOffset).ToInstant(); // The end instant (exclusive) is the end of the given date, so we need to add a day. End = rule.DateEnd == MaxDate ? Instant.AfterMaxValue : rule.DateEnd.ToLocalDateTime().PlusDays(1).WithOffset(zoneStandardOffset).ToInstant(); Savings = rule.DaylightDelta.ToOffset(); // Some rules have DST start/end of "January 1st", to indicate that they're just in standard time. This is important // for rules which have a standard offset which is different to the standard offset of the zone itself. if (IsStandardOffsetOnlyRule(rule)) { PartialMap = PartialZoneIntervalMap.ForZoneInterval(zone.StandardName, Start, End, StandardOffset, Offset.Zero); } else { var daylightRecurrence = new ZoneRecurrence(zone.DaylightName, Savings, ConvertTransition(rule.DaylightTransitionStart), int.MinValue, int.MaxValue); var standardRecurrence = new ZoneRecurrence(zone.StandardName, Offset.Zero, ConvertTransition(rule.DaylightTransitionEnd), int.MinValue, int.MaxValue); var recurringMap = new DaylightSavingsDateTimeZone("ignored", StandardOffset, standardRecurrence, daylightRecurrence); PartialMap = new PartialZoneIntervalMap(Start, End, recurringMap); } }
public string ShortNameForTime(DateTime utc, TimeZoneInfo tz) { TimeZoneId timeZoneId = TimeZoneIdMap.Current.TimeZoneInfoId(tz); string shortName; if (tz.IsDaylightSavingTime(utc) && timeZoneIdToDaylightShortName.TryGetValue(timeZoneId, out shortName)) return shortName; return timeZoneIdToStandardShortName[timeZoneId]; }
internal static PhpArray GetLocalTime(TimeZoneInfo currentTz, System_DateTime utc, bool returnAssociative) { PhpArray result; var local = TimeZoneInfo.ConvertTime(utc, currentTz); if (returnAssociative) { result = new PhpArray(0, 9); result["tm_sec"] = PhpValue.Create(local.Second); result["tm_min"] = PhpValue.Create(local.Minute); result["tm_hour"] = PhpValue.Create(local.Hour); result["tm_mday"] = PhpValue.Create(local.Day); result["tm_mon"] = PhpValue.Create(local.Month - 1); result["tm_year"] = PhpValue.Create(local.Year - 1900); result["tm_wday"] = PhpValue.Create((int)local.DayOfWeek); result["tm_yday"] = PhpValue.Create(local.DayOfYear - 1); result["tm_isdst"] = PhpValue.Create(currentTz.IsDaylightSavingTime(local) ? 1 : 0); } else { result = new PhpArray(9, 0); result.AddValue(PhpValue.Create(local.Second)); result.AddValue(PhpValue.Create(local.Minute)); result.AddValue(PhpValue.Create(local.Hour)); result.AddValue(PhpValue.Create(local.Day)); result.AddValue(PhpValue.Create(local.Month - 1)); result.AddValue(PhpValue.Create(local.Year - 1900)); result.AddValue(PhpValue.Create((int)local.DayOfWeek)); result.AddValue(PhpValue.Create(local.DayOfYear - 1)); result.AddValue(PhpValue.Create(currentTz.IsDaylightSavingTime(local) ? 1 : 0)); } return result; }
internal static PhpArray GetTimeOfDay(System_DateTime utc, TimeZoneInfo/*!*/ zone) { var result = new PhpArray(0, 4); var local = TimeZoneInfo.ConvertTime(utc, zone); //int current_dst = 0; if (zone.IsDaylightSavingTime(local)) { // TODO: current_dst //var rules = zone.GetAdjustmentRules(); //for (int i = 0; i < rules.Length; i++) //{ // if (rules[i].DateStart <= local && rules[i].DateEnd >= local) // { // current_dst = (int)rules[i].DaylightDelta.TotalHours; // break; // } //} } const int ticks_per_microsecond = (int)TimeSpan.TicksPerMillisecond / 1000; result["sec"] = PhpValue.Create(DateTimeUtils.UtcToUnixTimeStamp(utc)); result["usec"] = PhpValue.Create((int)(local.Ticks % TimeSpan.TicksPerSecond) / ticks_per_microsecond); result["minuteswest"] = PhpValue.Create((int)(utc - local).TotalMinutes); //result["dsttime"] = PhpValue.Create(current_dst); return result; }
private void ValidateZoneEquality(Instant instant, DateTimeZone nodaZone, TimeZoneInfo windowsZone) { // The BCL is basically broken (up to and including .NET 4.5.1 at least) around its interpretation // of its own data around the new year. See http://codeblog.jonskeet.uk/2014/09/30/the-mysteries-of-bcl-time-zone-data/ // for details. We're not trying to emulate this behaviour. // It's a lot *better* for .NET 4.6, var utc = instant.InUtc(); if ((utc.Month == 12 && utc.Day == 31) || (utc.Month == 1 && utc.Day == 1)) { return; } var interval = nodaZone.GetZoneInterval(instant); // Check that the zone interval really represents a transition. It could be a change in // wall offset, name, or the split between standard time and daylight savings for the interval. if (interval.RawStart != Instant.BeforeMinValue) { var previousInterval = nodaZone.GetZoneInterval(interval.Start - Duration.Epsilon); Assert.AreNotEqual(new {interval.WallOffset, interval.Name, interval.StandardOffset}, new {previousInterval.WallOffset, previousInterval.Name, previousInterval.StandardOffset}, "Non-transition from {0} to {1}", previousInterval, interval); } var nodaOffset = interval.WallOffset; var windowsOffset = windowsZone.GetUtcOffset(instant.ToDateTimeUtc()); Assert.AreEqual(windowsOffset, nodaOffset.ToTimeSpan(), $"Incorrect offset at {instant} in interval {interval}"); var bclDaylight = windowsZone.IsDaylightSavingTime(instant.ToDateTimeUtc()); Assert.AreEqual(bclDaylight, interval.Savings != Offset.Zero, $"At {instant}, BCL IsDaylightSavingTime={bclDaylight}; Noda savings={interval.Savings}"); }
public static string ValidateBaseUtcOffset(TimeZoneInfo timeZoneInfo) { var extra = timeZoneInfo.IsDaylightSavingTime(DateTime.Now) ? 1 : 0; var hour = timeZoneInfo.BaseUtcOffset.Hours + extra; var tempDate = new DateTime(DateTime.Now.Year, 1, 1, 0, 0, 0, 0); tempDate = tempDate.AddHours(Math.Abs(hour)).AddMinutes(Math.Abs(timeZoneInfo.BaseUtcOffset.Minutes)); return hour.ToString().Contains("-") ? "-" + tempDate.ToString("HH:mm") : tempDate.ToString("HH:mm"); }
private static long GetDatePart(char format, DateTime utc, TimeZoneInfo/*!*/ zone) { DateTime local = TimeZoneInfo.ConvertTimeFromUtc(utc, zone);// zone.ToLocalTime(utc); switch (format) { case 'B': // Swatch Beat (Internet Time) - 000 through 999 return GetSwatchBeat(utc); case 'd': // Day of the month return local.Day; case 'g': case 'h': // 12-hour format: return (local.Hour == 12) ? 12 : local.Hour % 12; case 'G': case 'H': // 24-hour format: return local.Hour; case 'i': return local.Minute; case 'I': return zone.IsDaylightSavingTime(local) ? 1 : 0; case 'j': goto case 'd'; case 'L': return DateTime.IsLeapYear(local.Year) ? 1 : 0; case 'm': return local.Month; case 'n': goto case 'm'; case 's': return local.Second; case 't': return DateTime.DaysInMonth(local.Year, local.Month); case 'U': return DateTimeUtils.UtcToUnixTimeStamp(utc); case 'w': // day of the week - 0 (for Sunday) through 6 (for Saturday) return (int)local.DayOfWeek; case 'W': { // ISO-8601 week number of year, weeks starting on Monday: int week, year; GetIsoWeekAndYear(local, out week, out year); return week; } case 'y': return local.Year % 100; case 'Y': return local.Year; case 'z': return local.DayOfYear - 1; case 'Z': return (int)zone.GetUtcOffset(local).TotalSeconds; default: PhpException.InvalidArgument("format"); return 0; }
/// <summary> /// Gets the offset from UT for the given date in the given time zone, /// taking into account daylight savings. /// </summary> /// <param name="date">the date that is the base for the offset</param> /// <param name="tz">the time-zone to calculate to offset to</param> /// <returns>the offset</returns> private static double GetOffset(DateTimeOffset date, TimeZoneInfo tz) { if (tz.IsDaylightSavingTime(date)) { // TODO return tz.BaseUtcOffset.TotalMilliseconds + 0; } return tz.BaseUtcOffset.TotalMilliseconds; }
private DateTimeOffset ConvertDateTimeToTimeZone(TimeZoneInfo imageSetDateTime) { bool currentlyDaylightSavings = this.timeZoneForDateTime.IsDaylightSavingTime(this.DateTime); TimeSpan utcOffsetChange = imageSetDateTime.BaseUtcOffset - this.timeZoneForDateTime.BaseUtcOffset; DateTimeOffset expectedDateTime = this.DateTime.ToNewOffset(utcOffsetChange); bool newlyDaylightSavings = imageSetDateTime.IsDaylightSavingTime(this.DateTime); if (newlyDaylightSavings != currentlyDaylightSavings) { TimeSpan daylightSavingsAdjustment = TimeSpan.FromHours(-1.0); if (newlyDaylightSavings && (currentlyDaylightSavings == false)) { daylightSavingsAdjustment = daylightSavingsAdjustment.Duration(); } expectedDateTime = expectedDateTime.ToNewOffset(daylightSavingsAdjustment); } return expectedDateTime; }
public static string ShortTZ(TimeZoneInfo tz, DateTime time) { if (tz.Id.IndexOf(" ") > 0) { string toabbr = ""; string abbr = ""; if (tz.SupportsDaylightSavingTime) { if (tz.IsDaylightSavingTime(time)) { toabbr = tz.DaylightName; } else { toabbr = tz.StandardName; } } else { toabbr = tz.Id; } string[] words = toabbr.Split(' '); foreach (var word in words) { abbr += word[0]; } return abbr; } return tz.Id; }
internal static string FormatDate(string format, DateTime utc, TimeZoneInfo zone) { Debug.Assert(zone != null); if (format == null) return string.Empty; DateTime local = TimeZoneInfo.ConvertTimeFromUtc(utc, zone); // here we are creating output string StringBuilder result = new StringBuilder(); bool escape = false; foreach (char ch in format) { if (escape) { result.Append(ch); escape = false; continue; } switch (ch) { case 'a': // Lowercase Ante meridiem and Post meridiem - am or pm result.Append(local.ToString("tt", DateTimeFormatInfo.InvariantInfo).ToLowerInvariant()); break; case 'A': // Uppercase Ante meridiem and Post meridiem - AM or PM result.Append(local.ToString("tt", DateTimeFormatInfo.InvariantInfo)); break; case 'B': // Swatch Beat (Internet Time) - 000 through 999 result.AppendFormat("{0:000}", GetSwatchBeat(utc)); break; case 'c': { // ISO 8601 date (added in PHP 5) 2004-02-12T15:19:21+00:00 result.Append(local.ToString("yyyy-MM-dd'T'HH:mm:ss", DateTimeFormatInfo.InvariantInfo)); TimeSpan offset = zone.GetUtcOffset(local); result.AppendFormat("{0}{1:00}:{2:00}", (offset.Ticks < 0) ? ""/*offset.Hours already < 0*/ : "+", offset.Hours, offset.Minutes); break; } case 'd': // Day of the month, 2 digits with leading zeros - 01 to 31 result.Append(local.ToString("dd", DateTimeFormatInfo.InvariantInfo)); break; case 'e': // Timezone identifier (added in PHP 5.1.0) result.Append(zone.Id); break; case 'D': // A textual representation of a day, three letters - Mon through Sun result.Append(local.ToString("ddd", DateTimeFormatInfo.InvariantInfo)); break; case 'F': // A full textual representation of a month, such as January or March - January through December result.Append(local.ToString("MMMM", DateTimeFormatInfo.InvariantInfo)); break; case 'g': // 12-hour format of an hour without leading zeros - 1 through 12 result.Append(local.ToString("%h", DateTimeFormatInfo.InvariantInfo)); break; case 'G': // 24-hour format of an hour without leading zeros - 0 through 23 result.Append(local.ToString("%H", DateTimeFormatInfo.InvariantInfo)); break; case 'h': // 12-hour format of an hour with leading zeros - 01 through 12 result.Append(local.ToString("hh", DateTimeFormatInfo.InvariantInfo)); break; case 'H': // 24-hour format of an hour with leading zeros - 00 through 23 result.Append(local.ToString("HH", DateTimeFormatInfo.InvariantInfo)); break; case 'i': // Minutes with leading zeros - 00 to 59 result.Append(local.ToString("mm", DateTimeFormatInfo.InvariantInfo)); break; case 'I': // Whether or not the date is in daylights savings time - 1 if Daylight Savings Time, 0 otherwise. result.Append(zone.IsDaylightSavingTime(local) ? "1" : "0"); break; case 'j': // Day of the month without leading zeros - 1 to 31 result.Append(local.ToString("%d", DateTimeFormatInfo.InvariantInfo)); break; case 'l': // A full textual representation of the day of the week - Sunday through Saturday result.Append(local.ToString("dddd", DateTimeFormatInfo.InvariantInfo)); break; case 'L': // Whether it's a leap year - 1 if it is a leap year, 0 otherwise. result.Append(DateTime.IsLeapYear(local.Year) ? "1" : "0"); break; case 'm': // Numeric representation of a month, with leading zeros - 01 through 12 result.Append(local.ToString("MM", DateTimeFormatInfo.InvariantInfo)); break; case 'M': // A short textual representation of a month, three letters - Jan through Dec result.Append(local.ToString("MMM", DateTimeFormatInfo.InvariantInfo)); break; case 'n': // Numeric representation of a month, without leading zeros - 1 through 12 result.Append(local.ToString("%M", DateTimeFormatInfo.InvariantInfo)); break; case 'N': // ISO-8601 numeric representation of the day of the week (added in PHP 5.1.0) int day_of_week = (int)local.DayOfWeek; result.Append(day_of_week == 0 ? 7 : day_of_week); break; case 'o': { // ISO-8601 year number. This has the same value as Y, except that if the ISO // week number (W) belongs to the previous or next year, that year is used instead. // (added in PHP 5.1.0) int week, year; GetIsoWeekAndYear(local, out week, out year); result.Append(year); break; } case 'O': { // Difference to Greenwich time (GMT) in hours Example: +0200 TimeSpan offset = zone.GetUtcOffset(local); string sign = (offset.Ticks < 0) ? ((offset.Hours < 0) ? string.Empty : "-") : "+"; result.AppendFormat("{0}{1:00}{2:00}", sign, offset.Hours, offset.Minutes); break; } case 'P': { // same as 'O' but with the extra colon between hours and minutes // Difference to Greenwich time (GMT) in hours Example: +02:00 TimeSpan offset = zone.GetUtcOffset(local); string sign = (offset.Ticks < 0) ? ((offset.Hours < 0) ? string.Empty : "-") : "+"; result.AppendFormat("{0}{1:00}:{2:00}", sign, offset.Hours, offset.Minutes); break; } case 'r': // RFC 822 formatted date Example: Thu, 21 Dec 2000 16:01:07 +0200 result.Append(local.ToString("ddd, dd MMM yyyy H:mm:ss ", DateTimeFormatInfo.InvariantInfo)); goto case 'O'; case 's': // Seconds, with leading zeros - 00 through 59 result.Append(local.ToString("ss", DateTimeFormatInfo.InvariantInfo)); break; case 'S': result.Append(GetDayNumberSuffix(local.Day)); break; case 't': // Number of days in the given month 28 through 31 result.Append(DateTime.DaysInMonth(local.Year, local.Month)); break; case 'T': // Timezone setting of this machine Examples: EST, MDT ... result.Append(zone.IsDaylightSavingTime(local) ? zone.DaylightName : zone.StandardName); break; case 'U': // Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT) result.Append(DateTimeUtils.UtcToUnixTimeStamp(utc)); break; case 'u': // Microseconds (added in PHP 5.2.2) result.Append((utc.Millisecond / 1000).ToString("D6")); break; case 'w': // Numeric representation of the day of the week - 0 (for Sunday) through 6 (for Saturday) result.Append((int)local.DayOfWeek); break; case 'W': { // ISO-8601 week number of year, weeks starting on Monday (added in PHP 4.1.0) Example: 42 (the 42nd week in the year) int week, year; GetIsoWeekAndYear(local, out week, out year); result.Append(week); break; } case 'y': // A two digit representation of a year Examples: 99 or 03 result.Append(local.ToString("yy", DateTimeFormatInfo.InvariantInfo)); break; case 'Y': // A full numeric representation of a year, 4 digits Examples: 1999 or 2003 result.Append(local.ToString("yyyy", DateTimeFormatInfo.InvariantInfo)); break; case 'z': // The day of the year starting from 0 result.Append(local.DayOfYear - 1); break; case 'Z': // TimeZone offset in seconds: result.Append((int)zone.GetUtcOffset(local).TotalSeconds); break; case '\\': // Escape char. Output next character directly to the result. escape = true; break; default: // unrecognized character, print it as-is. result.Append(ch); break; } } if (escape) result.Append('\\'); return result.ToString();
/// <summary> /// Gets the offset from UT for the given date in the given timezone, /// taking into account daylight savings. /// </summary> /// <param name="date">the date that is the base for the offset</param> /// <param name="tz">the time-zone to calculate to offset to</param> /// <returns>the offset</returns> public static double GetOffset(DateTime date, TimeZone tz) { #if !NET_35 throw new Exception("UTC offset calculation not supported in < .NET 3.5"); #else if (tz.IsDaylightSavingTime(date)) { // TODO return tz.BaseUtcOffset.TotalMilliseconds + 0; } return tz.BaseUtcOffset.TotalMilliseconds; #endif }