How to get a DateTimeOffset having local time information

I have these input strings:

var timeStr = "03:22";
var dateStr = "2018/01/12";
var format = "yyyy/MM/dd";
var timeZone = "Asia/Tehran";

This is the information of a time that I have, the the timeStr is in Asia/Tehran time zone and is not in UTC.

Using NodaTime, how can I get a DateTimeOffset object having this information containing correct offset in it?

Jon Skeet

Let's convert all your information into appropriate Noda Time types:

// Input values (as per the question)
var timeStr = "03:22";
var dateStr = "2018/01/12";
var format = "yyyy/MM/dd";
var timeZone = "Asia/Tehran";

// The patterns we'll use to parse input values
LocalTimePattern timePattern = LocalTimePattern.CreateWithInvariantCulture("HH:mm");
LocalDatePattern datePattern = LocalDatePattern.CreateWithInvariantCulture(format);

// The local parts, parsed with the patterns and then combined.
// Note that this will throw an exception if the values can't be parsed -
// use the ParseResult<T> return from Parse to check for success before
// using Value if you want to avoid throwing.
LocalTime localTime = timePattern.Parse(timeStr).Value;
LocalDate localDate = datePattern.Parse(dateStr).Value;
LocalDateTime localDateTime = localDate + localTime;

// Now get the time zone by ID
DateTimeZone zone = DateTimeZoneProviders.Tzdb[timeZone];

// Work out the zoned date/time being represented by the local date/time. See below for the "leniently" part.
ZonedDateTime zonedDateTime = localDateTime.InZoneLeniently(zone);
// The Noda Time type you want would be OffsetDateTime
OffsetDateTime offsetDateTime = zonedDateTime.ToOffsetDateTime();
// If you really want the BCL type...
DateTimeOffset dateTimeOffset = zonedDateTime.ToDateTimeOffset();

Note the "InZoneLeniently" which handles ambiguous or skipped local date/time values like this:

ambiguous values map to the earlier of the alternatives, and "skipped" values are shifted forward by the duration of the "gap".

That may or may be what you want. There's also InZoneStrictly which will throw an exception if there isn't a single instant in time represented by the given local date/time, or you can call InZone and pass in your own ZoneLocalMappingResolver.


See more on this question at Stackoverflow