我正在尝试创建一个单元测试来测试机器上时区变化的情况,因为它已被错误地设置然后更正.
在测试中,我需要能够在非本地时区创建DateTime对象,以确保运行测试的人员无论身在何处都能成功完成.
从我从DateTime构造函数中可以看到,我可以将TimeZone设置为本地时区,UTC时区或未指定.
如何使用PST等特定时区创建DateTime?
Jon的回答谈到了TimeZone,但我建议改用TimeZoneInfo.
我个人喜欢在可能的情况下保留UTC,所以我建议这样的结构:
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结构是为这种类型的使用而创建的.
请参阅:http: //msdn.microsoft.com/en-us/library/system.datetimeoffset.aspx
以下是使用特定时区创建DateTimeOffset对象的示例:
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,告诉您该时区当前是否在夏令时中.
您可以在库中看到更多关于此的一般化示例我最终会根据用户询问的位置等在不同的TimeZones中处理我需要的DateTimes:
https://github.com/b9chris/TimeZoneInfoLib.Net
这不适用于Windows之外(例如Linux上的Mono),因为时间列表来自Windows注册表:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\
在下面你会找到键(注册表编辑器中的文件夹图标); 这些键的名称是你传递给的FindSystemTimeZoneById
.在Linux上,你必须使用一组单独的Linux标准时区定义,我没有充分研究过.
我用扩展方法改变了Jon Skeet对网络的回答.它也适用于天蓝色的魅力.
public static class DateTimeWithZone { private static readonly TimeZoneInfo timeZone; static DateTimeWithZone() { //I added web.config//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); } }