如何表示当前的英国时间?
我在服务器和客户端之间转换日期时遇到了问题,两者都在德国运行。 客户端计算机上的区域设置可以设置为英国或德国。我从服务器接收CET格式的日期,我需要在UI上将此时间表示为英国时间。 例如,从服务器收到的时间,例如01/07/2010 01:00:00应该在UI上表示为01/07/2010 00:00:00。 我已经为此目的编写了一个转换器,但是在运行它时会产生2小时的时差。下面是代码,请帮忙吗?
public class LocalToGmtConverter : IDateConverter { private readonly TimeZoneInfo timeZoneInfo; public LocalToGmtConverter() : this(TimeZoneInfo.Local) { } public LocalToGmtConverter(TimeZoneInfo timeZoneInfo) { this.timeZoneInfo = timeZoneInfo; } public DateTime Convert(DateTime localDate) { var utcKind = DateTime.SpecifyKind(localDate, DateTimeKind.Utc); return utcKind; } public DateTime ConvertBack(object fromServer) { DateTime serverDate = (DateTime)fromServer; var utcOffset = timeZoneInfo.GetUtcOffset(serverDate); var uiTime = serverDate- utcOffset; return uiTime; } }
我想你正在转换到UTC(而不是英国)时间。 由于中欧仍有夏季时间(如果温度不同,则会发生这种情况),差异是在10月31日之前的+2小时。
如果你知道你正在从德国转换到英国(即夏季将CEST转为BST,冬季转为CET转为GMT),为什么不减1小时呢?
如果您需要英国的时区信息,可以使用它来构建它
var britishZone = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
然后你可以使用转换日期
var newDate = TimeZoneInfo.ConvertTime(serverDate, TimeZoneInfo.Local, britishZone);
使用TimeZoneInfo.ConvertTime将原始输入时区(CET)转换为目标时区(UK)。
public static DateTime ConvertTime( DateTime dateTime, TimeZoneInfo sourceTimeZone, TimeZoneInfo destinationTimeZone )
有关MSDN的完整指导:
转换时区之间的时间
来自MSDN的修改代码示例:
DateTime ceTime = new DateTime(2007, 02, 01, 08, 00, 00); try { TimeZoneInfo ceZone = TimeZoneInfo.FindSystemTimeZoneById("Central Europe Standard Time"); TimeZoneInfo gmtZone = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time"); Console.WriteLine("{0} {1} is {2} GMT time.", ceTime, ceZone.IsDaylightSavingTime(ceTime) ? ceZone.DaylightName : ceZone.StandardName, TimeZoneInfo.ConvertTime(ceTime, ceZone, gmtZone)); } catch (TimeZoneNotFoundException) { Console.WriteLine("The registry does not define the required timezones."); } catch (InvalidTimeZoneException) { Console.WriteLine("Registry data on the required timezones has been corrupted."); }
处理本地时间的更好方法是将它们存储在统一表示中,例如UTC。
因此,您可以将所有输入时间转换为UTC(通过.ToUniversalTime()
),并存储(或传输)其值。 当你需要显示它时,只需使用.ToLocalTime()
转换回来。
因此,您可以避免要求知道哪个时区是原始值,并且可以轻松地在不同时区显示存储值。
此外,您可以避免传入的麻烦,您必须在下一个时区编写处理时间的特定逻辑,试图找出如何在所有可用的时间内转换它们。
这就是我做的:
var BritishZone = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time"); DateTime dt = DateTime.SpecifyKind(DateTime.UtcNow, DateTimeKind.Unspecified); DateTimeInBritishLocal = TimeZoneInfo.ConvertTime(dt, TimeZoneInfo.Local, BritishZone);
我需要添加SpecifyKind部分或ConvertTime引发exception
我意识到问题出在C#上,但是如果您想要做的只是一次转换,您可以从PowerShell命令行执行此操作:
$d = [DateTime]::Parse("04/02/2014 17:00:00") $gmt = [TimeZoneInfo]::FindSystemTimeZoneById("GMT Standard Time"); [TimeZoneInfo]::ConvertTime($d, $gmt, [TimeZoneInfo]::Local)
此脚本会将英国时间17:00转换为您当地的时区。 对我来说,这将是CST。 有趣的是,如果我将日期设置为2014年3月27日,结果会有所不同,因为英国的夏令时会在不同的日期开始。