我有一个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)
无论服务器的托管位置如何,在东部标准时间显示日期的正确方法是什么?
答案 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
它只知道时区。这里没有混淆。