Reputation: 2824
I need to convert Cocoa NSDate
to C# DateTime
and vice versa.
I am using the following method to achieve this:
public static DateTime NSDateToDateTime (Foundation.NSDate date)
{
DateTime reference = TimeZone.CurrentTimeZone.ToLocalTime (
new DateTime (2001, 1, 1, 0, 0, 0));
return reference.AddSeconds (date.SecondsSinceReferenceDate);
}
public static Foundation.NSDate DateTimeToNSDate (DateTime date)
{
DateTime reference = TimeZone.CurrentTimeZone.ToLocalTime (
new DateTime (2001, 1, 1, 0, 0, 0));
return Foundation.NSDate.FromTimeIntervalSinceReferenceDate (
(date - reference).TotalSeconds);
}
But it turns out, this way it is not accounting for Daylight Saving.
Eg. DateTime
object in which the time was 5AM in DST returns NSDate
with time 6AM.
Upvotes: 10
Views: 4996
Reputation: 430
There is a creepy bug on direct casting to NSDate
My solution was:
public static NSDate DateTimeToNSDate(this DateTime date)
{
var calendar = new NSCalendar(NSCalendarType.Gregorian);
calendar.TimeZone = NSTimeZone.FromName("UTC");
var components = new NSDateComponents { Day = date.Day, Month = date.Month, Year = date.Year, Hour = date.Hour,
Minute = date.Minute, Second = date.Second, Nanosecond = date.Millisecond * 1000000 };
var result = calendar.DateFromComponents(components);
return result;
}
I hope this helps
Upvotes: 0
Reputation: 1059
I'm pretty sure this is an outdated approach. You can cast a NSDate directly to a DateTime now.
Foundation.NSDate nsDate = // someValue
DateTime dateTime = (DateTime)nsDate;
Upvotes: 12
Reputation: 2824
Based on inputs from: https://forums.xamarin.com/discussion/27184/convert-nsdate-to-datetime
Local Time
changes during Daylight Saving
.
Hence, always convert to UTC
to do the calculations, then convert to Local time
if needed.
public static DateTime NSDateToDateTime (Foundation.NSDate date)
{
DateTime reference = new DateTime(2001, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
var utcDateTime = reference.AddSeconds(date.SecondsSinceReferenceDate);
return utcDateTime.ToLocalTime();
}
public static Foundation.NSDate DateTimeToNSDate (DateTime date)
{
DateTime reference = new DateTime(2001, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
var utcDateTime = date.ToUniversalTime();
return Foundation.NSDate.FromTimeIntervalSinceReferenceDate((utcDateTime - reference).TotalSeconds);
}
Upvotes: 6