Convert datetime entered by user to UTC

21,239

Solution 1

Just like all the other methods on DateTime, SpecifyKind doesn't change an existing value - it returns a new value. You need:

combinedDateTime = DateTime.SpecifyKind(combinedDateTime,
                                        DateTimeKind.Unspecified);

Personally I'd recommend using Noda Time which makes this kind of thing rather clearer in my rather biased view (I'm the main author). You'd end up with this code instead:

DateTimeZone zone = ...;
LocalDate date = ...;
LocalTime time = ...;
LocalDateTime combined = date + time;
ZonedDateTime zoned = combined.InZoneLeniently(zone);
// You can now get the "Instant", or convert to UTC, or whatever...

The "leniently" part is because when you convert local times to a specific zone, there's the possibility for the local value being invalid or ambiguous in the time zone due to DST changes.

Solution 2

You can also try this

var combinedLocalTime = new DateTime((dateOnly + timeOnly.TimeOfDay).Ticks,DateTimeKind.Local);
var utcTime = combinedLocalTime.ToUniversalTime();
Share:
21,239
HTX9
Author by

HTX9

Updated on April 17, 2020

Comments

  • HTX9
    HTX9 about 4 years

    The user enters a date and a time in separate textboxes. I then combine the date and time into a datetime. I need to convert this datetime to UTC to save it in the database. I have the user's time zone id saved in the database (they select it when they register). First, I tried the following:

    string userTimeZoneID = "sometimezone"; // Retrieved from database
    TimeZoneInfo userTimeZone = TimeZoneInfo.FindSystemTimeZoneById(userTimeZoneID);
    
    DateTime dateOnly = someDate;
    DateTime timeOnly = someTime;
    DateTime combinedDateTime = dateOnly.Add(timeOnly.TimeOfDay);
    DateTime convertedTime = TimeZoneInfo.ConvertTimeToUtc(combinedDateTime, userTimeZone);
    

    This resulted in an exception:

    The conversion could not be completed because the supplied DateTime did not have the Kind property set correctly. For example, when the Kind property is DateTimeKind.Local, the source time zone must be TimeZoneInfo.Local

    I then tried setting the Kind property like so:

    DateTime.SpecifyKind(combinedDateTime, DateTimeKind.Local);
    

    This didn't work, so I tried:

    DateTime.SpecifyKind(combinedDateTime, DateTimeKind.Unspecified);
    

    This didn't work either. Can anyone explain what I need to do? Am I even going about this the correct way? Should I be using DateTimeOffset?