Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert DateTime from specific time zone to UTC using Nodatime?

Ok, So I have a web server that is hosted in the Central Standard Time Zone. The IIS server is configured with that as the Time Zone, so whenever use DateTime.Now on the server or create a new DateTime where the kind is Local, it is in Central time.

The issue is that the site is a (inter)national application and I could have clients anywhere within the US or Canada. One of the things the site has is a "Scheduler" of sorts for scheduling appointments. We decided for ease of development to store all DateTime values on the database in UTC format and that all traffic in and out of the API is in UTC as well. The problem is that I am frequently running into problems when I am creating date/time values on the server side.

Say for example I need to programmatically create an appointment for a client in the Pacific Standard Time zone on the server for 8 am. In the past, I have done things like this:

var appointment = new new DateTime(2015, 04, 17, 08, 00, 00, DateTimeKind.Unspecified)
var utcAppointment = TimeZoneInfo.ConvertTimeToUtc(appointment,
                        TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time"))

I do lots of other date/time manipulations as well within my program and am thinking of just going to Nodatime instead. I know I can get the UTC DateTime out of a Nodatime variable fairly easily. What I am confused about is how to create a Nodatime variable for a specific time zone at a specific date/time? All the examples I see have to do with Patterns and reading strings or creating an Instant which is essentially "Now". I want to do something like take an existing BCL DateTime object, regardless of the "Kind", and convert it to a Nodatime object with the specific time zone I set.

I think Nodatime is a great library, but reading the userguide just left me scratching my head about converting in and out of BCL.

like image 477
SpaceCowboy74 Avatar asked Apr 17 '15 19:04

SpaceCowboy74


1 Answers

What I am confused about is how to create a Nodatime variable for a specific time zone at a specific date/time?

That's relatively easy:

LocalDateTime local = new LocalDateTime(2015, 4, 17, 8, 0, 0);
DateTimeZone zone = DateTimeZoneProviders.Tzdb["America/Los_Angeles"];
ZonedDateTime zonedTime = local.InZoneLeniently(zone);

The "leniently" part really depends on what you want to happen if 8am turns out to be skipped or ambiguous - that won't happen in this case, but it's something to bear in mind. Noda Time lets you deal with this in various ways - the user guide goes into more detail.

Note that if you'd prefer to think in terms of the zone doing the conversion, you can use zone.AtLeniently(local) instead - they're absolutely equivalent.

like image 176
Jon Skeet Avatar answered Sep 19 '22 05:09

Jon Skeet