我正在使用DateTime.Now
根据今天的日期显示某些内容,并且在本地工作(马耳他,欧洲)时,时间显示正确(显然是因为时区)但当我将其上传到我的托管服务器时(美国),DateTime.Now
不代表正确的时区。
因此,在我的代码中,如何转换DateTime.Now
以正确返回GMT + 1时区的时间?
答案 0 :(得分:16)
使用System.Core中的TimeZoneInfo类;
您必须将DateTimeKind设置为DateTimeKind.Utc。
DateTime MyTime = new DateTime(1990, 12, 02, 19, 31, 30, DateTimeKind.Utc);
DateTime MyTimeInWesternEurope = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(MyTime, "W. Europe Standard Time");
只有当你使用.Net 3.5时才会这样做!
答案 1 :(得分:15)
这取决于“GMT + 1时区”的含义。您是指永久UTC + 1,还是指UTC + 1或UTC + 2,具体取决于夏令时?
如果您使用的是.NET 3.5,请使用TimeZoneInfo
获取适当的时区,然后使用:
// Store this statically somewhere
TimeZoneInfo maltaTimeZone = TimeZoneInfo.FindSystemTimeZoneById("...");
DateTime utc = DateTime.UtcNow;
DateTime malta = TimeZoneInfo.ConvertTimeFromUtc(utc, maltaTimeZone );
您需要计算出马耳他时区的系统ID,但您可以通过在本地运行此代码轻松完成此操作:
Console.WriteLine(TimeZoneInfo.Local.Id);
根据你的评论判断,这一点将无关紧要,但仅限其他人......
如果你不使用.NET 3.5,你需要自己计算夏令时。说实话,最简单的方法是一个简单的查找表。计算出未来几年的DST变化,然后编写一个简单的方法,在特定的UTC时间返回偏移量,并对该列表进行硬编码。您可能只想要一个已知已更改的已排序List<DateTime>
,并且在您的日期是最后一次更改之后的1到2小时之间交替:
// Be very careful when building this list, and make sure they're UTC times!
private static readonly IEnumerable<DateTime> DstChanges = ...;
static DateTime ConvertToLocalTime(DateTime utc)
{
int hours = 1; // Or 2, depending on the first entry in your list
foreach (DateTime dstChange in DstChanges)
{
if (utc < dstChange)
{
return DateTime.SpecifyKind(utc.AddHours(hours), DateTimeKind.Local);
}
hours = 3 - hours; // Alternate between 1 and 2
}
throw new ArgumentOutOfRangeException("I don't have enough DST data!");
}
答案 2 :(得分:5)
我认为您不能在代码中设置一个属性,使DateTime.Now返回除代码执行的计算机当前时间以外的任何内容。如果你想要总是得到另一个时间,你可能需要包装另一个函数。您可以在UTC上进行往返并添加所需的偏移量:
private static DateTime GetMyTime()
{
return DateTime.UtcNow.AddHours(1);
}
(在Luke对DateTime.Now的内部工作方式发表评论后更新了代码示例)