0

I want to use the NodaTime library to convert the date from one timezone to another like this.

string fromSystemTimeZoneId = "GMT Standard Time";
string toSystemTimeZoneId = "Central Standard Time";
TimeZoneInfo fromTimeZone = TimeZoneInfo.FindSystemTimeZoneById(fromSystemTimeZoneId);
TimeZoneInfo toTimeZone = TimeZoneInfo.FindSystemTimeZoneById(toSystemTimeZoneId);
var convertedTime = TimeZoneInfo.ConvertTime(inputDateTime, fromTimeZone, toTimeZone);

The above code works perfectly fine for me, But now I want to use IANA standard time zone (like Europe/London and America/Chicago) in place of windows OS-provided time zone ids.

I am using .net 4.7.2 and cannot upgrade the framework due to some limitations.

I have gone through this answer, But I am looking for simple few lines of code nothing complicated.

Vivek Nuna
  • 25,472
  • 25
  • 109
  • 197

1 Answers1

4

But I am looking for simple few lines of code nothing complicated.

But you're trying to do something complicated. Noda Time makes everything explicit, which means it's clear exactly what's going on - at the cost of being a little more verbose.

DateTime has no concept of a time zone itself (other than for the special cases where the Kind is Utc or Local). So TimeZoneInfo.ConvertTime has to:

  • Consider what instant in time is represented by inputDateTime in fromTimeZone
  • Work out what that instant in time looks like in outputDateTime

In Noda Time, those are are two separate operations, if you want to start and end with a LocalDateTime:

LocalDateTime inputDateTime = ...;
DateTimeZone fromTimeZone = ...;
DateTimeZone toTimeZone = ...;

// There are options for how this conversion is performed, as noted in other questions
ZonedDateTime inputDateTimeInFromTimeZone = inputDateTime.InZoneLeniently(fromTimeZone);
// This conversion is always unambiguous, because ZonedDateTime unambiguously
// refers to a single instant in time
ZonedDateTime inputDateTimeInToTimeZone = inputDateTimeInFromTimeZone.WithZone(toTimeZone);

LocalDateTime localPart = inputDateTimeInToTimeZone.LocalDateTime;

So that's basically the equivalent conversion - but you need to be explicit about how you want to handle skipped/ambiguous inputs. If you want everything in your app to use the same conversion, you can wrap that in a method that looks just like TimeZoneInfo.ConvertTime. But why not just keep things in a ZonedDateTime instead of LocalDateTime to start with? Then you don't get into the ambiguous position - other than potentially when converting user input (which is entirely separate from converting from one time zone to another).

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • I get the date as string `yyMMddHHmm` from different clients and I get to know the time zone from the client id. I want to store this date in DB in CST (America/Chicago). I may save this date in a different time zone tomorrow (just keep that in mind) – Vivek Nuna Oct 07 '22 at 17:19
  • @viveknuna: It's worth trying to be *really precise*. You don't get a *date*, you get a *date/time*. A date wouldn't have a time portion. So again, you should ask yourself: what do you want to do if the value you receive is skipped or ambiguous in the client's time zone? You need to keep reading this answer until you understand why there are really two conversions here - one to understand the "local" value in the client's time zone, and one to convert the result of that into the Chicago time zone. Once you've understood that, everything else is likely to make more sense. – Jon Skeet Oct 07 '22 at 17:38
  • @viveknuna: Also note that CST isn't the Chicago time zone. Chicago varies between CST and CDT. – Jon Skeet Oct 07 '22 at 17:39