在c#fx 3.5的特定时区中创build一个DateTime

我正在尝试创build一个unit testing来testing机器上时区更改的情况,因为它已被错误地设置并更正。

在testing中,我需要能够在非本地时区创buildDateTime对象,以确保运行testing的人员可以成功地执行此操作,而不pipe它们位于何处。

从我可以从DateTime构造函数中看到,我可以将TimeZone设置为本地时区,UTC时区或未指定。

如何创build一个像PST一样的特定时区的date时间?

乔恩的答案谈到时区 ,但我build议使用TimeZoneInfo来代替。

就我个人而言,我喜欢在可能的情况下用UTC来保存东西,所以我build议这样的结构:

public struct DateTimeWithZone { private readonly DateTime utcDateTime; private readonly TimeZoneInfo timeZone; public DateTimeWithZone(DateTime dateTime, TimeZoneInfo timeZone) { var dateTimeUnspec = DateTime.SpecifyKind(dateTime, DateTimeKind.Unspecified); utcDateTime = TimeZoneInfo.ConvertTimeToUtc(dateTimeUnspec, timeZone); this.timeZone = timeZone; } public DateTime UniversalTime { get { return utcDateTime; } } public TimeZoneInfo TimeZone { get { return timeZone; } } public DateTime LocalTime { get { return TimeZoneInfo.ConvertTime(utcDateTime, timeZone); } } } 

您可能希望将“TimeZone”名称更改为“TimeZoneInfo”以使事情更清晰 – 我更喜欢简要地说出自己的名字。

DateTimeOffset结构是为这种types的使用而创build的。

请参阅: http : //msdn.microsoft.com/zh-CN/library/system.datetimeoffset.aspx

以下是使用特定时区创buildDateTimeOffset对象的示例:

DateTimeOffset do1 = new DateTimeOffset(2008, 8, 22, 1, 0, 0, new TimeSpan(-5, 0, 0));

在这里的其他答案是有用的,但他们不包括如何访问太平洋具体 – 在这里你去:

 public static DateTime GmtToPacific(DateTime dateTime) { return TimeZoneInfo.ConvertTimeFromUtc(dateTime, TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time")); } 

奇怪的是,虽然“太平洋标准时间”通常意味着与“太平洋时间”不同的东西,但在这种情况下,泛指太平洋时间。 实际上,如果使用FindSystemTimeZoneById来获取它,其中一个可用属性是一个bool,告诉你该时区当前是否在夏令时。

你可以在库中看到更多的一般化的例子,我最终根据用户的要求,在不同的时区处理DateTimes。

https://github.com/b9chris/TimeZoneInfoLib.Net

因为时间列表来自Windowsregistry:这不会在Windows以外的工作(例如Linux上的Mono): HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\

在下面你会find键(registry编辑器中的文件夹图标); 这些密钥的名称是您传递给FindSystemTimeZoneById 。 在Linux上,您必须使用单独的Linux标准时区定义集,这一点我还没有充分探讨。

我使用扩展方法改变了Jon Skeet对networking的一点回答 。 它也像魅力一样在azure色的地方工作。

 public static class DateTimeWithZone { private static readonly TimeZoneInfo timeZone; static DateTimeWithZone() { //I added web.config <add key="CurrentTimeZoneId" value="Central Europe Standard Time" /> //You can add value directly into function. timeZone = TimeZoneInfo.FindSystemTimeZoneById(ConfigurationManager.AppSettings["CurrentTimeZoneId"]); } public static DateTime LocalTime(this DateTime t) { return TimeZoneInfo.ConvertTime(t, timeZone); } } 

你将不得不为此创build一个自定义对象。 您的自定义对象将包含两个值:

  • DateTime值
  • 一个TimeZone对象

不知道是否已经有CLR提供的数据types,但至lessTimeZone组件已经可用。

我喜欢Jon Skeet的回答,但是想补充一点。 我不确定琼恩是否期待总是在当地时区传球。 但是我想用于当地以外的情况。

我正在读取数据库中的值,并且知道数据库在哪个时区。因此,在数据库中,我将传入数据库的时区。 但是,我想在当地时间的价值。 Jon的LocalTime不会返回转换为本地时区date的原始date。 它将返回转换为原始时区的date(无论您传递给ctor)。

我认为这些财产名称清理了…

 public DateTime TimeInOriginalZone { get { return TimeZoneInfo.ConvertTime(utcDateTime, timeZone); } } public DateTime TimeInLocalZone { get { return TimeZoneInfo.ConvertTime(utcDateTime, TimeZoneInfo.Local); } } public DateTime TimeInSpecificZone(TimeZoneInfo tz) { return TimeZoneInfo.ConvertTime(utcDateTime, tz); }