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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/246498/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 19:43:04  来源:igfitidea点击:

Creating a DateTime in a specific Time Zone in c#

c#.netdatetimetimezone.net-3.5

提问by Hyman Hughes

I'm trying to create a unit test to test the case for when the timezone changes on a machine because it has been incorrectly set and then corrected.

我正在尝试创建一个单元测试来测试机器上时区何时更改的情况,因为时区设置不正确,然后更正。

In the test I need to be able to create DateTime objects in a none local time zone to ensure that people running the test can do so successfully irrespective of where they are located.

在测试中,我需要能够在非本地时区中创建 DateTime 对象,以确保运行测试的人员无论身在何处都可以成功执行此操作。

From what I can see from the DateTime constructor I can set the TimeZone to be either the local timezone, the UTC timezone or not specified.

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

How do I create a DateTime with a specific timezone like PST?

如何创建具有特定时区(如 PST)的 DateTime?

采纳答案by Jon Skeet

Jon's answertalks about TimeZone, but I'd suggest using TimeZoneInfoinstead.

Jon 的回答谈到了TimeZone,但我建议改用TimeZoneInfo

Personally I like keeping things in UTC where possible (at least for the past; storing UTC for the futurehas potential issues), so I'd suggest a structure like this:

就我个人而言,我喜欢在可能的情况下将内容保留在 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); 
        }
    }        
}

You may wish to change the "TimeZone" names to "TimeZoneInfo" to make things clearer - I prefer the briefer names myself.

您可能希望将“TimeZone”名称更改为“TimeZoneInfo”以使事情更清晰 - 我自己更喜欢简短的名称。

回答by Jon Limjap

You'll have to create a custom object for that. Your custom object will contain two values:

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

  • 日期时间值
  • 一个时对象

Not sure if there already is a CLR-provided data type that has that, but at least the TimeZone component is already available.

不确定是否已经有一个 CLR 提供的数据类型,但至少 TimeZone 组件已经可用。

回答by CleverPatrick

The DateTimeOffset structure was created for exactly this type of use.

DateTimeOffset 结构正是为这种用途而创建的。

See: http://msdn.microsoft.com/en-us/library/system.datetimeoffset.aspx

请参阅:http: //msdn.microsoft.com/en-us/library/system.datetimeoffset.aspx

Here's an example of creating a DateTimeOffset object with a specific time zone:

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

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

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

回答by Chris Moschini

The other answers here are useful but they don't cover how to access Pacific specifically - here you go:

此处的其他答案很有用,但它们并未具体介绍如何访问 Pacific - 在这里:

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

Oddly enough, although "Pacific Standard Time" normally means something different from "Pacific Daylight Time," in this case it refers to Pacific time in general. In fact, if you use FindSystemTimeZoneByIdto fetch it, one of the properties available is a bool telling you whether that timezone is currently in daylight savings or not.

奇怪的是,虽然“太平洋标准时间”通常与“太平洋夏令时”的含义不同,但在这种情况下,它泛指太平洋时间。事实上,如果你FindSystemTimeZoneById用来获取它,可用的属性之一是一个布尔值,告诉你该时区当前是否处于夏令时。

You can see more generalized examples of this in a library I ended up throwing together to deal with DateTimes I need in different TimeZones based on where the user is asking from, etc:

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

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

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

This won't work outside of Windows (for example Mono on Linux) since the list of times comes from the Windows Registry: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\

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

Underneath that you'll find keys (folder icons in Registry Editor); the names of those keys are what you pass to FindSystemTimeZoneById. On Linux you have to use a separate Linux-standard set of timezone definitions, which I've not adequately explored.

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

回答by Gabe Halsmer

I like Jon Skeet's answer, but would like to add one thing. I'm not sure if Jon was expecting the ctor to always be passed in the Local timezone. But I want to use it for cases where it's something other then local.

我喜欢 Jon Skeet 的回答,但想补充一件事。我不确定 Jon 是否希望 ctor 总是在本地时区传递。但我想将它用于其他地方而不是本地的情况。

I'm reading values from a database, and I know what timezone that database is in. So in the ctor, I'll pass in the timezone of the database. But then I would like the value in local time. Jon's LocalTime does not return the original date converted into a local timezone date. It returns the date converted into the original timezone (whatever you had passed into the ctor).

我正在从数据库中读取值,并且我知道该数据库所在的时区。所以在 ctor 中,我将传入数据库的时区。但是我想要当地时间的价值。Jon 的 LocalTime 不会返回转换为本地时区日期的原始日期。它返回转换为原始时区的日期(无论您传递给 ctor 的任何内容)。

I think these property names clear it up...

我认为这些属性名称清除了它...

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

回答by Jernej Novak

I altered Jon Skeet answera bit for the web with extension method. It also works on azure like a charm.

我使用扩展方法为网络更改了Jon Skeet 的答案。它也像魅力一样在 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);   
}
}

回答by Meghs Dhameliya

Using TimeZonesclass makes it easy to create timezone specific date.

使用TimeZones类可以轻松创建时区特定日期。

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