This lesson will show you how to handle date and time. Also we’ll learn how to compare and clone objects well.

Agenda

DateTime, DateTimeOffset and TimeSpan

DateTime and DateTimeOffset are immutable structs for representing a date, and optionally, a time. They have a resolution of 100 ns and a range covering the years 0001 through 9999

DateTimeOffset was added in Framework 3.5 and is functionally similar to DateTime. Its distinguishing feature is that it also stores a UTC offset; this allows more meaningful results when comparing values across different time zones.

var dateTimeNow = DateTime.Now;
var dateTimeOffsetNow = DateTimeOffset.Now;

Console.WriteLine(dateTimeNow);
Console.WriteLine(dateTimeNow.Kind);
Console.WriteLine(dateTimeNow.ToUniversalTime());

Console.WriteLine("---");
Console.WriteLine(dateTimeOffsetNow);
Console.WriteLine(dateTimeOffsetNow.Offset);

TypeSpan just represents a time interval:

TimeSpan timeSpan = DateTime.Today.AddDays(2) - DateTime.Today.AddDays(1);
var h = timeSpan.TotalHours; // 24

DateTime.Now is always unique.

TimeZone and TimeZoneInfo

The TimeZone and TimeZoneInfo classes provide information on time zone names UTC offsets, and daylight saving time rules. TimeZoneInfo is the more powerful of the two and was introduced in Framework 3.5. The biggest difference between the two types is that TimeZone lets you access the current local time zone, whereas TimeZoneInfo provides access to all the world’s time zones. Further, TimeZoneInfo exposes a richer (although at times, more awkward) rules-based model for describing daylight saving time

TimeZoneInfo zone = TimeZoneInfo.Local;
Console.WriteLine(zone.StandardName);
Console.WriteLine(zone.DaylightName);
TimeZoneInfo zone = TimeZoneInfo.Local;
Console.WriteLine(zone.StandardName);
Console.WriteLine(zone.DaylightName);

TimeZoneInfo class can return a full list of time zones.

Example on how to gwt some local time in some time zone:

var bangkokTime = TimeZoneInfo.ConvertTime(DateTime.Now, TimeZoneInfo.FindSystemTimeZoneById("SE Asia Standard Time"));
Console.WriteLine("Loca time in Bangkok is: {0}", bangkokTime);

Equality Comparison

Value equality: two values are equivalent in some sense

int x = 5, y = 5;
Console.WriteLine(x == y);

Referential equality: two references refer to exactly the same object

A a1 = new A {N = 5};
A a2 = new A { N = 5 };
Console.WriteLine(a1 == a2); // False
a1 = a2;
Console.WriteLine(a1 == a2); // True

null-safe equality comparison

object x = 3, y = 3;
Console.WriteLine(object.Equals(x, y)); // True
x = null;
Console.WriteLine(object.Equals(x, y)); // False
y = null;
Console.WriteLine(object.Equals(x, y)); // True

The double type’s == operator enforces that one NaN can never equal anything else — even another NaN. This is most natural from a mathematical perspective, and it reflects the underlying CPU behavior

var sb1 = new StringBuilder("foo");
var sb2 = new StringBuilder("foo");
Console.WriteLine(sb1 == sb2); // False (referential equality)
Console.WriteLine(sb1.Equals(sb2)); // True (value equality)

Override Equals

Equals method can be overriden:

class A
{
    public int N { get; set; }
    public bool Equals(A obj)
    {
        return obj.N == N;
    }

    public override bool Equals(object obj)
    {
        return ((A)obj).N == N;
    }
}
A a1 = new A { N = 5 };
A a2 = new A { N = 5 };
Console.WriteLine(a1.Equals((object)a2));

ICloneable

.NET Framework has ICloneable in order to implement cloning object functonality. Example:

class Book: ICloneable
{
    public string Author { get; set; }
    public string Title { get; set; }
    public object Clone()
    {
        return new Book
        {
            Author = Author,
            Title = Title
        };
    }
}
Book b1 = new Book
{
    Author = "Tom",
    Title = "Adventures"
};

Book b2 = (Book)b1.Clone();

References

Presentation

Lesson9 from Alex Honcharuk