C# 使用时区信息调整时区';s夏时制补偿

C# 使用时区信息调整时区';s夏时制补偿,c#,datetime,timezone,offset,dst,C#,Datetime,Timezone,Offset,Dst,下面是我使用的方法,它包含三个输入: dateTimeInput表示日期的字符串 inputFormat是我的format字符串,格式如下:yyyy-MM-dd'T'HH:MM:sszzz timeZoneStandardName是从var TimeZoneList=TimeZoneInfo.GetSystemTimeZones()检索到的唯一时区标识符其中通过时区列表.ID检索ID 我主要使用TimeZoneInfo获取我的小时和分钟偏移量,因为它非常明确地说明了它是哪个城市/时区,例如UTC

下面是我使用的方法,它包含三个输入:

dateTimeInput
表示日期的字符串

inputFormat
是我的
format
字符串,格式如下:
yyyy-MM-dd'T'HH:MM:sszzz

timeZoneStandardName
是从
var TimeZoneList=TimeZoneInfo.GetSystemTimeZones()检索到的唯一时区标识符其中通过
时区列表.ID
检索ID

我主要使用
TimeZoneInfo
获取我的小时和分钟偏移量,因为它非常明确地说明了它是哪个城市/时区,例如
UTC
是输入字符串

public int dateTimeToUnixTime(string dateTimeInput, string inputFormat, string timeZoneStandardName)
{
    DateTime result;
    CultureInfo provider = CultureInfo.InvariantCulture;
    TimeZoneInfo objTimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(timeZoneStandardName);
    int timeZoneHours = objTimeZoneInfo.BaseUtcOffset.Hours;
    int timeZoneMinutes = objTimeZoneInfo.BaseUtcOffset.Minutes;

    // if input format is "yyyy-MM-dd'T'HH:mm:sszzz"
    if (inputFormat == "yyyy-MM-dd'T'HH:mm:sszzz")
    {
        result = DateTime.ParseExact(dateTimeInput, inputFormat, provider, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal);
        int unixTime = (Int32)(result.Subtract(Epoch)).TotalSeconds;
        return unixTime;
    }
    else
    {
        // if other input formats
        result = DateTime.ParseExact(dateTimeInput, inputFormat, provider, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal);
        int unixTime = (Int32)(result.AddHours(-timeZoneHours).AddMinutes(-timeZoneMinutes).Subtract(Epoch)).TotalSeconds;
        return unixTime;
    }
}
我的第二个方法接收Unix时间戳和时区说明符,并作为位置相关时间输出:

public string unixTimeToDateTime(int unixInput, string outputFormat, string timeZoneStandardName)
{
    // output format is "yyyy-MM-dd'T'HH:mm:sszzz"
    TimeZoneInfo objTimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(timeZoneStandardName);
    int timeZoneHours = objTimeZoneInfo.BaseUtcOffset.Hours;
    int timeZoneMinutes = objTimeZoneInfo.BaseUtcOffset.Minutes;
    if (outputFormat == "yyyy-MM-dd'T'HH:mm:sszzz")
    {
        System.DateTime dateTime = Epoch.AddSeconds(unixInput);
        return dateTime.AddHours(timeZoneHours).AddMinutes(timeZoneMinutes).ToString("yyyy-MM-dd'T'HH:mm:ss") + toTimeSpan(timeZoneHours, timeZoneMinutes);
    }
    // output format is not
    else
    {
        System.DateTime dateTime = Epoch.AddSeconds(unixInput).AddHours(timeZoneHours).AddMinutes(timeZoneMinutes);
        return dateTime.ToString(outputFormat);
    }
}
例如,这里是一个蚱蜢组件中的这个方法,让我向您展示我的意思
dateTimeToUnixTime()
是我的第一个“时钟”,而
unixtimetodetime()
是我的第二个“时钟”

给定这些时间列表的输入和EST的时区标记,以及这些日期(请注意,2014年11月2日凌晨1-2点是我们再次获得DST调整的时间),理论上,该方法应调整其时区以抵消一小时

我知道
TimeZoneInfo
支持DST,因为我可以使用下面的方法显示相应时区DST状态的
bool

    var TimeZoneList = TimeZoneInfo.GetSystemTimeZones();

    for (int i = 0; i < TimeZoneList.Count; i++)
    {
        Console.WriteLine(TimeZoneList[i].Id + ": " + TimeZoneList[i].SupportsDaylightSavingTime);
    }
var TimeZoneList=TimeZoneInfo.GetSystemTimeZones();
对于(int i=0;i

我的问题是,我的
dateTimeToUnixTime()
方法缺少什么,它允许根据DST条件进行自动调整和偏移

假设您的历元从1970年1月1日开始,那么我们可以使用
日期时间偏移量
\u 1970
作为您的历元,将所需的秒数添加到
\u 1970
中,然后使用以获得指定时区的日期时间,并进行夏令时调整(如果适用)。重要的是使用
DateTimeOffset
而不是
DateTime
,以便在获取字符串时保持正确的偏移量

private static readonly DateTimeOffset _1970 = new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero);
public string UnixTimeToDateTime(int unixInput, string outputFormat, string timeZoneStandardName)
{
    var objTimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(timeZoneStandardName);
    var utcDate = _1970.AddSeconds(unixInput);
    DateTimeOffset localDate = TimeZoneInfo.ConvertTime(utcDate, objTimeZoneInfo);
    return localDate.ToString(outputFormat);
}

//1970-01-01T13:00:00+13:00
Console.WriteLine( UnixTimeToDateTime(0, "yyyy-MM-dd'T'HH:mm:sszzz", "New Zealand Standard Time"));

//1970-01-01T08:00:00+08:00
Console.WriteLine(UnixTimeToDateTime(0, "yyyy-MM-dd'T'HH:mm:sszzz", "Singapore Standard Time"));

//1969-12-31T19:00:00-05:00
Console.WriteLine(UnixTimeToDateTime(0, "yyyy-MM-dd'T'HH:mm:sszzz", "Eastern Standard Time"));

需要注意的是,使用TimeZoneInfo可能没有关于历史日期调整的信息,因此如果这对您很重要,那么您最好使用一个库,例如。

Unix epoch是基于UTC的。由于您假设所有输入都是基于UTC的,而输出必须是基于UTC的,因此调整DST偏移量的UTC偏移量没有任何意义。您是对的--我遗漏了问题中的一个重要部分。我道歉。我现在已经改正了。上面看到的第一个“时钟”是从
DateTime
UnixTime
的转换(实际上是UTC)。第二次转换采用带有时区说明符的
UnixTime
,因此输出与时区相关且本地化。我将在实现此功能后立即回复您。酷,该输出非常整洁!哦,是的。您还可以告诉我如何制作时区说明符,例如
zzz
格式吗?最初,我有我的
时间跨度(时区小时,时区分钟)
方法,允许我输入
时区小时数
时区分钟数
。除了本地日期.小时之外,我是否也要做同样的事情呢!它只是
DateTime localDate=TimeZoneInfo.ConvertTimeFromUtc(UTCDate,objTimeZoneInfo);返回localDate.ToString(“yyyy-MM-dd'HH:MM:sszzz”)嗯。出于某种原因,我上面发布的两个代码片段仍然传递
EST
时间,尽管有
UTC
说明符:这仅在我使用
“yyyy-MM-dd'T'HH:MM:sszzz”时存在