以下是我使用的方法,它接收三个输入:
dateTimeInput
这是一个表示日期的字符串。
inputFormat
是我的format
字符串,格式如下:yyyy-MM-dd'T'HH:mm:sszzz
。
timeZoneStandardName
是从var TimeZoneList = TimeZoneInfo.GetSystemTimeZones();
检索到的唯一时区标识符,其中ID是通过timeZoneList.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);
}
}
例如,这是Grasshopper组件中的这个方法,让我向您展示我的意思。 dateTimeToUnixTime()
是我的第一个"时钟",而unixTimeToDateTime()
是我的第二个"时钟"
考虑到这些时间列表的输入和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);
}
我的问题是,我的dateTimeToUnixTime()
方法中缺少哪些内容可以根据DST条件进行自动调整和偏移?
答案 0 :(得分:2)
假设您的纪元始于1970年1月1日,那么我们可以使用DateTimeOffset
_1970
作为您的纪元,将所需的秒数添加到_1970
,然后使用{{3使用夏令时调整(如果适用)获取指定时区的日期时间。使用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可能没有关于历史日期调整的TimeZoneInfo.ConvertTime,因此如果这对您很重要,那么您最好使用accurate information等库。