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?
Convert DateTime to UTC Sometimes, you may need to store the user entered date and time. The user may enter the date and time according to his or her local time. However, you may need to store it in UTC. In such a scenario, you can convert the user entered date and time to UTC using the DATEDIFF and DATEADD functions.
Using AT TIME ZONE is an easy way to convert UTC date-time or DATETIMEOFFSET to your desired time zone in datetimeoffset format. While using AT TIME ZONE, you have to specify the destination time zone in their respective names like Eastern Standard Time, Pacific Standard Time, etc…
When working on SQL Server databases with multi time zone users, it is always good to store date and time in UTC (Universal Time Coordinated). However when displaying the date and time to a user, it may not be appropriate to show the date and time in UTC.
Each user has a Time Zone Code associated with their user settings. There is already a request named “ LocalTimeFromUtcTimeRequest” to convert UTC time into the user time zone. We have to pass DateTime in UTC, TimeZoneCode (Which we can retrieve) and IOrganizationService.
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.
You can also try this
var combinedLocalTime = new DateTime((dateOnly + timeOnly.TimeOfDay).Ticks,DateTimeKind.Local);
var utcTime = combinedLocalTime.ToUniversalTime();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With