我从另一台机器获取格式的时区信息:
"CET-1CEST,M3.5.0/2,M10.5.0/3"
(Posix 风格的时区)
我需要对其进行解析并将其转换为 c# .net TimeZoneInfo 类
。
有办法实现吗?
最佳答案
根据这篇文章:http://www.ibm.com/developerworks/aix/library/au-aix-posix/像“CST6CDT,M3.2.0/2:00:00,M11.1.0/2:00:00”这样的 POSIX 时间具有以下规范:
- CST6CDT 是时区名称
- CST 是 DST 关闭时使用的缩写
- 6 小时是与 GMT 的时差
- CDT 是夏令时的缩写
- ,M3是第三个月
- .2 是该月中第 2 次出现的日子
- .0 是星期天
- /2:00:00是时间
- ,M11是第十一个月
- .1 是该月中第一个出现的日子
- .0 是星期天
- /2:00:00是时间
并且日期是 Mm.n.d 格式,其中:
- MM (1-12) 12 个月
- n (1-5) 1 表示该月的第一周,5 表示该月的最后一周
- d (0-6) 周日为0,周六为6
那么,基于这些信息和可以在 TimeZoneInfo 类中找到的调整规则,您可以使用此代码进行转换:
public static TimeZoneInfo ConvertPosixToTimeZoneInfo(string posix)
{
string[] tokens = posix.Split(',');
tokens[0] = tokens[0].Replace("/", ".");
var match = Regex.Match(tokens[0], @"[-+]?[0-9]*\.?[0-9]+").Value;
var ticks = (long)(decimal.Parse(match, CultureInfo.InvariantCulture) * 60) * 600000000;
var baseOffset = new TimeSpan(ticks);
var systemTimeZones = TimeZoneInfo.GetSystemTimeZones().Where(t => t.BaseUtcOffset == baseOffset).ToList();
var startRuleTokens = tokens[1].TrimStart('M').Split('/');
var startDateRuleTokens = startRuleTokens[0].Split('.');
var startTimeRuleTokens = startRuleTokens[1].Split(':');
var endRuleTokens = tokens[2].TrimStart('M').Split('/');
var endDateRuleTokens = endRuleTokens[0].Split('.');
var endTimeRuleTokens = endRuleTokens[1].Split(':');
int? targetIndex = null;
for (int i = 0; i < systemTimeZones.Count; i++)
{
var adjustmentRules = systemTimeZones[i].GetAdjustmentRules();
foreach (var rule in adjustmentRules)
{
if (rule.DaylightTransitionStart.Month == int.Parse(startDateRuleTokens[0]) &&
rule.DaylightTransitionStart.Week == int.Parse(startDateRuleTokens[1]) &&
rule.DaylightTransitionStart.DayOfWeek == (DayOfWeek)int.Parse(startDateRuleTokens[2]) &&
rule.DaylightTransitionStart.TimeOfDay.Hour == int.Parse(startTimeRuleTokens[0]) &&
rule.DaylightTransitionStart.TimeOfDay.Minute == int.Parse(startTimeRuleTokens[1]) &&
rule.DaylightTransitionStart.TimeOfDay.Second == int.Parse(startTimeRuleTokens[2]) &&
rule.DaylightTransitionEnd.Month == int.Parse(endDateRuleTokens[0]) &&
rule.DaylightTransitionEnd.Week == int.Parse(endDateRuleTokens[1]) &&
rule.DaylightTransitionEnd.DayOfWeek == (DayOfWeek)int.Parse(endDateRuleTokens[2]) &&
rule.DaylightTransitionEnd.TimeOfDay.Hour == int.Parse(endTimeRuleTokens[0]) &&
rule.DaylightTransitionEnd.TimeOfDay.Minute == int.Parse(endTimeRuleTokens[1]) &&
rule.DaylightTransitionEnd.TimeOfDay.Second == int.Parse(endTimeRuleTokens[2]))
{
targetIndex = i;
break;
}
}
}
if (targetIndex.HasValue)
return systemTimeZones[targetIndex.Value];
return null;
}
关于c# - 在 c# .net 中将 posix 样式时区转换为 timezoneinfo,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26630249/