C# 在c中的特定时区中创建日期时间#

C# 在c中的特定时区中创建日期时间#,c#,.net,datetime,timezone,.net-3.5,C#,.net,Datetime,Timezone,.net 3.5,我正在尝试创建一个单元测试来测试机器上的时区何时发生变化,因为它被错误地设置,然后被更正 在测试中,我需要能够在非本地时区中创建DateTime对象,以确保运行测试的人员能够成功地执行此操作,而不管他们位于何处 从DateTime构造函数中可以看到,我可以将时区设置为本地时区、UTC时区或未指定 如何创建具有特定时区(如PST)的日期时间?您必须为此创建自定义对象。自定义对象将包含两个值: 日期时间值 物体 不确定是否已经有CLR提供的数据类型具有该属性,但至少时区组件已经可用。谈到了,但我

我正在尝试创建一个单元测试来测试机器上的时区何时发生变化,因为它被错误地设置,然后被更正

在测试中,我需要能够在非本地时区中创建DateTime对象,以确保运行测试的人员能够成功地执行此操作,而不管他们位于何处

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


如何创建具有特定时区(如PST)的日期时间?

您必须为此创建自定义对象。自定义对象将包含两个值:

  • 日期时间值
  • 物体
不确定是否已经有CLR提供的数据类型具有该属性,但至少时区组件已经可用。

谈到了,但我建议改用

就我个人而言,我喜欢尽可能将事情保持在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结构正是为这种类型的使用而创建的

见:

以下是创建具有特定时区的DateTimeOffset对象的示例:


DateTimeOffset do1=新的DateTimeOffset(2008,8,22,1,0,0,新的时间跨度(-5,0,0))

这里的其他答案很有用,但它们没有具体介绍如何访问Pacific-给你:

public static DateTime GmtToPacific(DateTime dateTime)
{
    return TimeZoneInfo.ConvertTimeFromUtc(dateTime,
        TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time"));
}
奇怪的是,虽然“太平洋标准时间”通常与“太平洋昼时”的含义不同,但在本例中,它通常指的是太平洋时间。事实上,如果您使用
FindSystemTimeZoneById
获取它,可用的属性之一就是一个bool,告诉您该时区当前是否处于夏令时

你可以在一个库中看到更一般化的例子,我最终根据用户的要求,在不同的时区处理我需要的日期时间,等等:

这在Windows之外不起作用(例如Linux上的Mono),因为时间列表来自Windows注册表:
HKEY\U LOCAL\U MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\


在下面,您将找到键(注册表编辑器中的文件夹图标);这些键的名称是传递给
FindSystemTimeZoneById
的。在Linux上,您必须使用一组单独的Linux标准时区定义,我还没有对此进行充分的探讨。

我喜欢Jon Skeet的答案,但想补充一点。我不确定Jon是否希望ctor总是在本地时区传递。但我想用它来处理一些非本地的情况

我正在从数据库中读取值,我知道数据库所在的时区。在ctor中,我将传入数据库的时区。但是我想知道当地时间的值。Jon的LocalTime不返回转换为本地时区日期的原始日期。它返回转换为原始时区的日期(无论您传递给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);
}
我用扩展方法对web做了一些修改。它在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);   
}
}
公共静态类DateTimeWithZone
{
专用静态只读时区信息时区;
静态DateTimeWithZone()
{
//我添加了web.config
//您可以直接向函数中添加值。
时区=TimeZoneInfo.FindSystemTimeZoneById(ConfigurationManager.AppSettings[“CurrentTimeZoneId]”);
}
公共静态DateTime LocalTime(此DateTime t)
{
返回TimeZoneInfo.ConvertTime(t,时区);
}
}

使用时区类可以轻松创建特定于时区的日期

TimeZoneInfo.ConvertTime(DateTime.Now, TimeZoneInfo.FindSystemTimeZoneById(TimeZones.Paris.Id));

恐怕我不知道有任何等效的SQL Server结构。我建议将时区名称作为一列,UTC值作为另一列。单独获取它们,然后您就可以相当轻松地创建实例。不确定使用DateTime和TimeZoneInfo的构造函数的预期用途,但考虑到您正在调用DateTime.ToUniversalTime()方法,我怀疑您猜测它“可能”在本地时间。在这种情况下,我认为你真的应该使用传入的时区信息将其转换为UTC,因为他们告诉你它应该在该时区内。@ChrisMoschini:那时你只是在发明自己的ID方案——一个世界上没有人使用的方案。我会坚持使用行业标准的zoneinfo,谢谢。(例如,很难看出“欧洲/伦敦”是如何毫无意义的。)@ChrisMoschini:那么不同的例子是:CST。那是UTC-5还是UTC-6?IST怎么样?你的数据库中是以色列、印度还是爱尔兰?(即使你现在知道偏移量,使用同一缩写的不同国家可能会在不同的时间发生变化。因此,它所指的实际时区仍然不明确。时区!=偏移量。)回到你的案例:你声称使用缩写最能解决你的问题。使用行业标准的时区ID会变得更糟吗?@ChrisMoschini:我会继续推荐使用行业标准的、明确的zoneinfo ID,而不是含糊不清的缩写。这不是谁的图书馆更受欢迎的问题——图书馆的作者真的不是问题。如果有人希望使用另一个具有良好标识符选择的库,则可以。虽然时区标识符的选择很重要,但我认为读者意识到缩写词的模糊性非常重要,正如我在IST示例中所示。谢谢,这是一个很好的实现方法。在正确的时区内获取DateTimeOffset对象后,可以使用.UtcDateTime属性为您创建的对象获取UTC时间