Convert UTC DateTime to DateTimeOffset
Asked Answered
A

4

37

I need to convert UTC date strings to DateTimeOffsets.

This must work with a timezone which differs from the computers timezone. E.g. current computer timezone is +02:00, but I want to create a DateTimeOffset with offset -4:00.

I already read lot of questions here on stackoverflow, but none of them solved my problem.

That is what I need to do:

Input: "2012-11-20T00:00:00Z"

Output: DateTimeOffset with:

  • UtcDateTime of 2012-11-20 00:00
  • the correct Utc offset for the defined timezone (01:00 in this example)
  • LocalDateTime: 2012-11-20 01:00 (= UtcDateTime + Offset)

Of course daylight saving must be taken into account.

edit: To make things even clearer, please try to complete the following code snippet:

DateTimeOffset result;
const string dateString = "2012-11-20T00:00:00Z";
var timezone = TimeZoneInfo.FindSystemTimeZoneById("W. Europe Standard Time"); //this timezone has an offset of +01:00:00 on this date

//do conversion here

Assert.AreEqual(result.Offset, new TimeSpan(1, 0, 0));  //the correct utc offset, in this case +01:00:00
Assert.AreEqual(result.UtcDateTime, new DateTime(2012, 11, 20, 0, 0, 0)); //equals the original date
Assert.AreEqual(result.LocalDateTime, new DateTime(2012, 11, 20, 1, 0, 0));
Abstain answered 18/12, 2012 at 13:2 Comment(0)
G
23

Here is the solution you are looking for:

const string dateString = "2012-11-20T00:00:00Z";
TimeZoneInfo timezone = TimeZoneInfo.FindSystemTimeZoneById("W. Europe Standard Time"); //this timezone has an offset of +01:00:00 on this date

DateTimeOffset utc = DateTimeOffset.Parse(dateString);
DateTimeOffset result = TimeZoneInfo.ConvertTime(utc, timezone);
        
Assert.AreEqual(result.Offset, new TimeSpan(1, 0, 0));  //the correct utc offset, in this case +01:00:00
Assert.AreEqual(result.UtcDateTime, new DateTime(2012, 11, 20, 0, 0, 0)); //equals the original date
Assert.AreEqual(result.DateTime, new DateTime(2012, 11, 20, 1, 0, 0));

Note that you were incorrectly testing the .LocalDateTime property - which is always going to convert the result to the local time zone of the computer. You simply need the .DateTime property instead.

Gentry answered 14/1, 2013 at 16:45 Comment(2)
@BojidarStanchev - Nothing wrong with var, but I agree that examples are clearer with explicit typing. I edited the answer accordingly. Keep in mind the original answer was posted 8 years ago. Also, you can always propose an edit instead of complaining.Gentry
the complaining worked just as well and was way less effortPronoun
M
8

Is this what you want:

[Test]
public void ParseUtcDateTimeTest()
{
    DateTime dateTime = DateTime.Parse("2012-11-20T00:00:00Z");
    Assert.AreEqual(new DateTime(2012, 11, 20, 01, 00, 00), dateTime);
    DateTimeOffset dateTimeOffset = new DateTimeOffset(dateTime);
    Assert.AreEqual(new TimeSpan(0, 1, 0, 0), dateTimeOffset.Offset);
}
  • Note that my asserts are valid in Sweden (CET)
  • There are a couple of overloads on DateTime.Parse()

Is this useful for your conversion:

[Test]
public void ConvertTimeTest()
{
    DateTime dateTime = DateTime.Parse("2012-11-20T00:00:00Z");
    TimeZoneInfo cstZone = TimeZoneInfo.FindSystemTimeZoneById("Central Standard     Time");
    DateTime convertedTime = TimeZoneInfo.ConvertTime(dateTime, cstZone);
    Assert.AreEqual(new DateTime(2012, 11, 19, 18, 00, 00), convertedTime);
    TimeSpan baseUtcOffset = cstZone.BaseUtcOffset;
    Assert.AreEqual(new TimeSpan(0, -6, 0, 0), baseUtcOffset);
}
Milone answered 18/12, 2012 at 13:34 Comment(3)
This won't work if I want to use another timezone than the current timezone.Abstain
@Abstain Updated my answer, hope it helpsMilone
I'm not sure how this can help me. Converting the DateTime is nice and all, but how do I get a DateTimeOffset?Abstain
P
1
    public static DateTimeOffset ToDatetimeOffsetFromUtc(this DateTime date) =>
        new DateTimeOffset(DateTime.SpecifyKind(date, DateTimeKind.Utc));

try this extension

Penurious answered 27/10, 2023 at 9:47 Comment(0)
L
-1
const String dateString = "2012-11-20T00:00:00Z"; 
var offsetDate = DateTimeOffset.Parse(dateString); 
var offsetDate2 = DateTime.Parse(dateString);

Output is

offsetDate  {20-11-2012 0:00:00 +00:00}    System.DateTimeOffset
offsetDate2 {20-11-2012 1:00:00}           System.DateTime
Ludlow answered 18/12, 2012 at 13:41 Comment(3)
This won't work if I want to use another timezone than the current timezone.Abstain
Add the second parameter, the cultureinfo. here is a list sharpertutorials.com/list-of-culture-codes. example : var fmt = new CultureInfo("en-AU").DateTimeFormat;Ludlow
I tried this, but no matter which CultureInfo I use the DateTimeOffset always has an offset of 00:00:00, which is not what I want!Abstain

© 2022 - 2024 — McMap. All rights reserved.