我正在尝试创建一个单元测试,以测试当机器上的时区因设置不正确而更改时的情况。

在测试中,我需要能够在非本地时区创建DateTime对象,以确保运行测试的人可以成功地这样做,而不管他们位于哪里。

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

我如何创建一个日期时间与特定的时区,如PST?


当前回答

我改变了乔恩斯基特回答一点网络与扩展方法。它在天蓝色上也有魔力。

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);   
}
}

其他回答

TimeZoneInfo试试。ConvertTime(dateTime, sourceTimeZone, destinationTimeZone)

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,告诉您该时区当前是否处于夏令时。

你可以在一个库中看到更通用的例子,我最终拼凑了一个库来处理我需要的不同时区的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的回答谈到了TimeZone,但我建议使用TimeZoneInfo代替。

就我个人而言,我喜欢尽可能将内容保存在UTC中(至少对于过去;为未来存储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”以使事情更清楚-我自己更喜欢简短的名称。

对于具有特定时区(既不是本地时区,也不是UTC时区)偏移量的日期/时间,您可以使用DateTimeOffset类:

  var time = TimeSpan.Parse("9:00");
  var est = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
  var nationalDateTime = new DateTimeOffset(DateTime.Today.Ticks + time.Ticks, est.BaseUtcOffset);