简体   繁体   English

将DateTime.Now转换为其他时区

[英]Converting DateTime.Now To A Different Time Zone

This code has been working for a long time now but has broken now when I try to pass DateTime.Now as the outageEndDate parameter: 这段代码已经使用了很长时间了,但是当我尝试将DateTime.Now作为outageEndDate参数传递时,该代码现在已经损坏了:

public Outage(DateTime outageStartDate, DateTime outageEndDate, Dictionary<string, string> weeklyHours, string province, string localProvince)
    {
        this.outageStartDate = outageStartDate;
        this.outageEndDate = outageEndDate;
        this.weeklyHours = weeklyHours;
        this.province = province;
        localTime = TimeZoneInfo.FindSystemTimeZoneById(timeZones[localProvince]);

        if (outageStartDate < outageEndDate)
        {
            TimeZoneInfo remoteTime = TimeZoneInfo.FindSystemTimeZoneById(timeZones[province]);
            outageStartDate = TimeZoneInfo.ConvertTime(outageStartDate, localTime, remoteTime);
            outageEndDate = TimeZoneInfo.ConvertTime(outageEndDate, localTime, remoteTime);

The error message I am getting on the last line is that the Kind property is not set correctly on the DateTime parameter (outageEndDate). 我在最后一行收到的错误消息是DateTime参数(outageEndDate)上的Kind属性设置不正确。 I've Googled and checked SO for examples but I don't really understand the error message. 我已经用Google搜索并检查了示例,但我不太理解错误消息。

Any advice is appreciated. 任何建议表示赞赏。

Regards. 问候。

EDIT - The exact error message is: 编辑-确切的错误消息是:

The conversion could not be completed because the supplied DateTime did not have the Kind
property set correctly.  For example, when the Kind property is DateTimeKind.Local, the source
time zone must be TimeZoneInfo.Local.  Parameter name: sourceTimeZone

EDIT: outageEndDate.Kind = Utc 编辑:outageEndDate.Kind = Utc

Thanks for clarifying your question. 感谢您澄清您的问题。

If the DateTime instance Kind is Local , then TimeZoneInfo.ConvertTime will expect the second parameter to be the local timezone of your computer. 如果DateTime实例的KindLocal ,则TimeZoneInfo.ConvertTime将期望第二个参数为计算机的本地时区。

If DateTime instance Kind is Utc , then TimeZoneInfo.ConvertTime will expect the second parameter to be the Utc timezone. 如果DateTime实例KindUtc ,则TimeZoneInfo.ConvertTime将期望第二个参数为Utc时区。

You need to convert outageEndDate to the right timezone first, just in case the localProvice timezone doesn't match the timezone on your computer. 您首先需要将outageEndDate转换为正确的时区,以防localProvice时区与您计算机上的时区不匹配。

outageEndDate = TimeZoneInfo.ConvertTime(outageEndDate, localTime);

here is an example of something that you could try 这是您可以尝试的示例

It depends on what you mean by "a GMT + 1 timezone". 这取决于您所说的“格林尼治标准时间+ 1时区”。 Do you mean permanently UTC+1, or do you mean UTC+1 or UTC+2 depending on DST? 您是指永久性的UTC + 1,还是指DTC的UTC + 1或UTC + 2?

If you're using .NET 3.5, use TimeZoneInfo to 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);

If you're not using .NET 3.5, you'll need to work out the daylight savings yourself. 如果您使用.NET 3.5,则需要自己计算夏令时。 To be honest, the easiest way 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. 计算出未来几年的DST更改,然后编写一种简单的方法,以硬编码该列表在特定UTC时间返回偏移量。 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: 您可能只需要排序的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!");
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM