C#:确保 DateTime.Now 返回 GMT + 1 时间

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1108644/
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-06 08:26:08  来源:igfitidea点击:

C#: Making sure DateTime.Now returns a GMT + 1 time

c#datetimetimezone

提问by Andreas Grech

I am using DateTime.Nowto show something according to today's date, and when working locally (Malta, Europe) the times appear correctly (obviously because of the Time Zone) but ofcourse when I upload it to my hosting server (USA), DateTime.Nowdoes not represent the correct time zone.

我正在DateTime.Now根据今天的日期显示一些内容,并且在本地(马耳他,欧洲)工作时,时间显示正确(显然是因为时区),但是当然,当我将其上传到我的托管服务器(美国)时,DateTime.Now并不代表正确的时区。

Therefore, in my code, how can I convert DateTime.Nowto correctly return the time from a GMT + 1 timezone?

因此,在我的代码中,如何转换DateTime.Now为从 GMT + 1 时区正确返回时间

采纳答案by Lloyd Powell

Use the TimeZoneInfo class found in System.Core;

使用 System.Core 中的 TimeZoneInfo 类;

You must set the DateTimeKind to DateTimeKind.Utc for this.

为此,您必须将 DateTimeKind 设置为 DateTimeKind.Utc。

DateTime MyTime = new DateTime(1990, 12, 02, 19, 31, 30, DateTimeKind.Utc);

DateTime MyTimeInWesternEurope = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(MyTime, "W. Europe Standard Time");

Only if you're using .Net 3.5 though!

仅当您使用 .Net 3.5 时!

回答by Fredrik M?rk

I don't think that you can set a property in your code that will make DateTime.Now return anything else than the current time of the computer in which the code executes. If you want to have a way of always getting another time, you will probably need to wrap in another function. You can can do the round-trip over UTC and add the desired offset:

我认为您不能在代码中设置一个属性来使 DateTime.Now 返回除执行代码的计算机的当前时间之外的任何其他内容。如果你想有一种方法总是得到另一个时间,你可能需要包装在另一个函数中。您可以通过 UTC 进行往返并添加所需的偏移量:

private static DateTime GetMyTime()
{
    return DateTime.UtcNow.AddHours(1);
}

(code sample updated after Luke's comment on the inner workings of DateTime.Now)

(在 Luke 对 DateTime.Now 的内部工作发表评论后更新了代码示例)

回答by Jon Skeet

It depends on what you mean by "a GMT + 1 timezone". Do you mean permanently UTC+1, or do you mean UTC+1 or UTC+2 depending on DST?

这取决于您所说的“GMT + 1 时区”是什么意思。您的意思是永久 UTC+1,还是 UTC+1 或 UTC+2 取决于 DST?

If you're using .NET 3.5, use TimeZoneInfoto get an appropriate time zone, then use:

如果您使用 .NET 3.5,请使用TimeZoneInfo获取适当的时区,然后使用:

// Store this statically somewhere
TimeZoneInfo maltaTimeZone = TimeZoneInfo.FindSystemTimeZoneById("...");
DateTime utc = DateTime.UtcNow;
DateTime malta = TimeZoneInfo.ConvertTimeFromUtc(utc, maltaTimeZone );

You'll need to work out the system ID for the Malta time zone, but you can do that easily by running this code locally:

您需要计算马耳他时区的系统 ID,但您可以通过在本地运行以下代码轻松完成此操作:

Console.WriteLine(TimeZoneInfo.Local.Id);


Judging by your comments, this bit will be irrelevant, but just for others...

从你的评论来看,这一点无关紧要,但只是对其他人......

If you're notusing .NET 3.5, you'll need to work out the daylight savings yourself. To be honest, the easiestway to do that is going to be a simple lookup table. Work out the DST changes for the next few years, then write a simple method to return the offset at a particular UTC time with that list hardcoded. You might just want a sorted List<DateTime>with the known changes in, and alternate between 1 and 2 hours until your date is after the last change:

如果您使用 .NET 3.5,则需要自己计算夏令时。老实说,最简单的方法将是一个简单的查找表。计算出接下来几年的 DST 更改,然后编写一个简单的方法,以使用该列表硬编码返回特定 UTC 时间的偏移量。您可能只想List<DateTime>对已知更改进行排序,并在 1 到 2 小时之间交替,直到您的日期在最后一次更改之后:

// Be very careful when building this list, and make sure they're UTC times!
private static readonly IEnumerable<DateTime> DstChanges = ...;

static DateTime ConvertToLocalTime(DateTime utc)
{
    int hours = 1; // Or 2, depending on the first entry in your list
    foreach (DateTime dstChange in DstChanges)
    {
        if (utc < dstChange)
        {
            return DateTime.SpecifyKind(utc.AddHours(hours), DateTimeKind.Local);
        }
        hours = 3 - hours; // Alternate between 1 and 2
    }
    throw new ArgumentOutOfRangeException("I don't have enough DST data!");
}