将此转换为C#中的日期时间的正确方法是什么?

时间:2016-03-12 04:26:35

标签: c# datetime

我有一个asp.net-mvc网站正在从sharepoint网站读取一个字符串字段,我得到一个字符串

var stringDate = "3/11/2016 12:05:00 AM"

我被告知时间是在东部标准时间。我尝试使用:

转换为日期
 var date = DateTime.Parse(stringDate);

我想用这种格式显示它:

<%= Model.Date.ToString("MMM dd HH:mm")

当我在美国的机器上运行时,我得到了

Mar 14 00:05 (which is what i want to display)

但是当我在伦敦的机器上运行相同的代码时,我得到:

Mar 14 05:05 (which is NOT what i want to display)

无论服务器的托管位置如何,在东部标准时间显示日期的正确方法是什么?

5 个答案:

答案 0 :(得分:3)

在提供第一个答案后,问题发生了变化,所以这里对改变后的问题给出了不同的答案。

全局保持日期时间的方法是始终以UTC格式捕获和保存日期时间值,然后转换为上下文时区以供使用/显示。

在这种情况下,如果忽略夏令时,则向提供的解析值添加5小时将为我们提供UTC。必须考虑由夏令时引起的偏移的任何变化,并在确定UTC时相应地调整偏移。

DateTime dtInUTC = DateTime.ParseExact("3/11/2016 12:05:00 AM", "M/d/yyyy hh:mm:ss tt",
    CultureInfo.InvariantCulture).AddHours(5); // the source string is expressed in ET
Console.WriteLine(ToLocalTime(dtInUTC, "Eastern Standard Time")); // for ET
Console.WriteLine(ToLocalTime(dtInUTC, "GMT Standard Time")); // for GMT

这是我用来转换时区的时区:

private static DateTime ToLocalTime(DateTime utcDateTime, string tzId) {
   TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById(tzId);
   return TimeZoneInfo.ConvertTimeFromUtc(utcDateTime, tz);
}

通常情况下,我会使用给定用户的个人资料保留用户时区,而不是硬编码,但您明白了。

答案 1 :(得分:1)

因为你知道它在东部时间,所以在解析的价值中保留这个真理是很重要的。我附加-5偏移量并解析提供的字符串。一旦你明确解析它为ET

DateTime t = DateTime.ParseExact("3/11/2016 12:05:00 AM -05:00", 
    "M/d/yyyy hh:mm:ss tt zzz", CultureInfo.InvariantCulture);
Console.WriteLine(t.ToUniversalTime());

......结果如下:

3/11/2016 5:05:00 AM

我怀疑&#34;灵活&#34;您在问题中描述的行为是以下值的结果,显然是Parse方法中的默认值:AssumeLocal

以下是相关DateTime.ParseExact doc here的摘录。

  

AssumeLocal:指定如果s缺少任何时区信息,则假定它代表本地时间。除非   DateTimeStyles.AdjustToUniversal标志存在,Kind属性   返回的DateTime值设置为DateTimeKind.Local。

     

AssumeUniversal:指定如果s缺少任何时区信息,   假设它代表UTC。除非   DateTimeStyles.AdjustToUniversal标志存在,该方法转换   返回的DateTime值从UTC到本地时间并设置其种类   属于DateTimeKind.Local的属性。

夏令时是一个问题,但如果您捕获当前偏移并在解析中正确附加它而不是仅仅硬编码-05:00则不会。

答案 2 :(得分:0)

答案取决于远程服务器上生成时间字符串的方式。例如,如果字符串表示该远程服务器上的本地时间,那么您可以尝试ParseExact()ToUniversalTime()获取GMT(格林威治标准时间,又称UTC),然后减去5小时以获得EST (此操作应在远程服务器上执行):

DateTime _ny = 
DateTime.ParseExact("3/11/2016 12:05:00 AM", 
"mm/dd/yyyy HH:mm:ss UTC", 
CultureInfo.InvariantCulture).ToUniversalTime().AddHours(-5);

注意:纽约市的时间是EST(UTC-05:00,或GMT-05:00)。

通过使用TimeZoneInfo类来计算偏移量(re:https://msdn.microsoft.com/en-us/library/system.timezoneinfo(v=vs.110).aspx),可以进一步扩展解决方案。与您的问题相关,美国东部标准时间ID为720(UTC-05:00)(重新:https://msdn.microsoft.com/en-us/library/gg154758.aspx)。

另外,请注意,如果从远程服务器读取数据,则必须调整与该服务器时区相关的解决方案。一旦我遇到类似的问题,由我的实时网络应用程序驻留在远程Azure云服务器引起,所以我使用了类似的解决方案(re:清单10,http://www.codeproject.com/Articles/884183/enRoute-Real-time-NY-City-Bus-Tracking-Web-App

/// <summary>
/// Get the accurate NY Time value
/// </summary>
/// <returns>DateTime</returns>
protected DateTime GetTimeNYC()
{
    try { return DateTime.Now.ToUniversalTime().AddHours(_offsetHour); }
    catch { throw; }
}

希望这可能会有所帮助。

答案 3 :(得分:-1)

试一试:

DateTime _dt = DateTime.ParseExact(dateString, "your format",CultureInfo.InvariantCulture);

我希望它有所帮助。

答案 4 :(得分:-1)

您应该使用DateTimeOffset,因为它是为了正确处理时区而构建的。

然后你可以这样做:

var stringDate = "3/11/2016 12:05:00 AM";

var value =
    DateTimeOffset
        .ParseExact(
            stringDate + "-05:00",
            "M/dd/yyyy hh:mm:ss ttzzz",
            System.Globalization.CultureInfo.GetCultureInfo("en-us"));

这将始终解析您在EST("-05:00")时间内的输入。

当我将值写入控制台时,您会得到:

2016/03/11 00:05:00 -05:00

它只知道时区。这里没有混淆。