使用TimeZoneInfo:
static void Main()
{
TimeZoneInfo wa = TimeZoneInfo.FindSystemTimeZoneById
("W. Australia Standard Time");
Console.WriteLine (wa.Id); // W. Australia Standard Time
Console.WriteLine (wa.DisplayName); // (GMT+08:00) Perth
Console.WriteLine (wa.BaseUtcOffset); // 08:00:00
Console.WriteLine (wa.SupportsDaylightSavingTime); // True
foreach (TimeZoneInfo.AdjustmentRule rule in wa.GetAdjustmentRules())
{
Console.WriteLine ("Rule: applies from " + rule.DateStart +
" to " + rule.DateEnd);
Console.WriteLine (" Delta: " + rule.DaylightDelta);
Console.WriteLine (" Start: " + FormatTransitionTime
(rule.DaylightTransitionStart, false));
Console.WriteLine (" End: " + FormatTransitionTime
(rule.DaylightTransitionEnd, true));
Console.WriteLine();
}
}
static string FormatTransitionTime (TimeZoneInfo.TransitionTime tt,
bool endTime)
{
if (endTime && tt.IsFixedDateRule
&& tt.Day == 1 && tt.Month == 1
&& tt.TimeOfDay == DateTime.MinValue)
return "-";
string s;
if (tt.IsFixedDateRule)
s = tt.Day.ToString();
else
s = "The " +
"first second third fourth last".Split() [tt.Week - 1] +
" " + tt.DayOfWeek + " in";
return s + " " + DateTimeFormatInfo.CurrentInfo.MonthNames [tt.Month-1]
+ " at " + tt.TimeOfDay.TimeOfDay;
}
DateTime和daylight保存:
DaylightTime changes = TimeZone.CurrentTimeZone.GetDaylightChanges (2008);
TimeSpan halfDelta = new TimeSpan (changes.Delta.Ticks / 2);
DateTime utc1 = changes.End.ToUniversalTime() - halfDelta;
DateTime utc2 = utc1 - changes.Delta;
// Converting these variables to local times demonstrates why you should use
// UTC and not local time if your code relies on time moving forward:
DateTime loc1 = utc1.ToLocalTime(); // (Pacific Standard Time)
DateTime loc2 = utc2.ToLocalTime();
Console.WriteLine (loc1); // 2/11/2008 1:30:00 AM
Console.WriteLine (loc2); // 2/11/2008 1:30:00 AM
Console.WriteLine (loc1 == loc2); // True
Console.Write (loc1.ToString ("o")); // 2008-11-02T02:30:00.0000000-08:00
Console.Write (loc2.ToString ("o")); // 2008-11-02T02:30:00.0000000-07:00
Console.WriteLine (loc1.ToUniversalTime() == utc1); // True
Console.WriteLine (loc2.ToUniversalTime() == utc2); // True
写一个自定义格式provider:
public class WordyFormatProvider : IFormatProvider, ICustomFormatter
{
static readonly string[] _numberWords =
"zero one two three four five six seven eight nine minus point".Split();
IFormatProvider _parent; // Allows consumers to chain format providers
public WordyFormatProvider() : this (CultureInfo.CurrentCulture) { }
public WordyFormatProvider (IFormatProvider parent)
{
_parent = parent;
}
public object GetFormat (Type formatType)
{
if (formatType == typeof (ICustomFormatter)) return this;
return null;
}
public string Format (string format, object arg, IFormatProvider prov)
{
// If it's not our format string, defer to the parent provider:
if (arg == null || format != "W")
return string.Format (_parent, "{0:" + format + "}", arg);
StringBuilder result = new StringBuilder();
string digitList = string.Format (CultureInfo.InvariantCulture,
"{0}", arg);
foreach (char digit in digitList)
{
int i = "0123456789-.".IndexOf (digit);
if (i == -1) continue;
if (result.Length > 0) result.Append (' ');
result.Append (_numberWords[i]);
}
return result.ToString();
}
}
重载相等语义:
public struct Area : IEquatable <Area>
{
public readonly int Measure1;
public readonly int Measure2;
public Area (int m1, int m2)
{
Measure1 = m1;
Measure2 = m2;
}
public override bool Equals (object other)
{
if (!(other is Area)) return false;
return Equals ((Area) other); // Calls method below
}
public bool Equals (Area other) // Implements IEquatable<Area>
{
return Measure1 == other.Measure1 && Measure2 == other.Measure2
|| Measure1 == other.Measure2 && Measure2 == other.Measure1;
}
public override int GetHashCode()
{
if (Measure1 > Measure2)
return Measure1 * 37 + Measure2; // 37 = a prime number
else
return Measure2 * 37 + Measure1;
}
public static bool operator == (Area a1, Area a2)
{
return a1.Equals (a2);
}
public static bool operator != (Area a1, Area a2)
{
return !a1.Equals (a2);
}
}
实现IComparable接口:
public struct Note : IComparable<Note>, IEquatable<Note>, IComparable
{
int _semitonesFromA;
public Note (int semitonesFromA)
{
_semitonesFromA = semitonesFromA;
}
public int CompareTo (Note other) // Generic IComparable<T>
{
if (Equals (other)) return 0; // Fail-safe check
return _semitonesFromA.CompareTo (other._semitonesFromA);
}
int IComparable.CompareTo (object other) // Nongeneric IComparable
{
if (!(other is Note))
throw new InvalidOperationException ("CompareTo: Not a note");
return CompareTo ((Note) other);
}
public static bool operator < (Note n1, Note n2)
{
return n1.CompareTo (n2) < 0;
}
public static bool operator > (Note n1, Note n2)
{
return n1.CompareTo (n2) > 0;
}
public bool Equals (Note other) // for IEquatable<Note>
{
return _semitonesFromA == other._semitonesFromA;
}
public override bool Equals (object other)
{
if (!(other is Note)) return false;
return Equals ((Note) other);
}
public override int GetHashCode()
{
return _semitonesFromA.GetHashCode();
}
public static bool operator == (Note n1, Note n2)
{
return n1.Equals (n2);
}
public static bool operator != (Note n1, Note n2)
{
return !(n1 == n2);
}
}
浙公网安备 33010602011771号