简体   繁体   中英

.NET: Getting UTC DateTime from date with GMT offset

I have four integers:

  • Day of month (1 - 31)
  • Month of year (1 - 12)
  • Year
  • Hour of day (0 - 23)

These integers represent a date and time that a user on my web page has selected. They could be anywhere on earth.

Thankfully, I have the GMT offset of their location on earth. It's a decimal.

How do I take these four integers, plus GMT offset decimal, and get a DateTime in UTC that represents them?

To answer this question, fill in the method body of this function:

public static DateTime UtcDateTime(int day, int month, int year, int hour, decimal gmtOffset) { // todo }

I would recommend using DateTime in conjunction with TimeZoneInfo . You can store UTC time on your server, and convert time to every user using his own TimeZoneInfo . TimeZoneInfo can be set by user, or you can somehow extract it from Windows settings, if it is possible. We ask users to set their TimeZoneInfo (via drop-down list) on their settings page.

Update

While the Microsoft states in MSDN that we should use DateTimeOffset rather than DateTime there are some problems using DateTimeOffset . I failed trying to serialize/deserialize DataTimeOffset instances transferring them via WCF. And DateTime/TimeZoneInfo works fine. I like DateTimeOffset a lot, but it still isn't suitable for real apps in some ways.

And another one downside of DateTimeOffset is that it doesn't contain all the information you need to convert time, because it contains only an offset. But there can be several actual TimeZones with the same offset, so you can't restore time zone given only offset. And time zone is not just an offset, it is the set of rules defining time conversion, winter/summer time etc

Update

Here you are:

private static DateTime ToUTC(int day, int month, int year, int hour, decimal utcOffset)
{
    TimeSpan offset = TimeSpan.FromMinutes((double)(utcOffset * 60)); // time zone offset is always aligned to minutes
    return new DateTimeOffset(year, month, day, hour, 0, 0, offset).ToUniversalTime().DateTime;
}

You should use DateTimeOffset.

Convert the decimal into the precision you require then construct as below (using FromSeconds as an example):

new DateTimeOffset(year,month,day,hour,0,0,TimeSpan.FromSeconds(offset));

http://msdn.microsoft.com/en-us/library/system.datetimeoffset(v=VS.90).aspx

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM