在C#.net中将posix样式的时区转换为timezoneinfo [英] Convert a posix style timezone to timezoneinfo in c# .net
问题描述
我从另一台计算机上获取时区信息,格式为:
I get timezone information from another machine in the format :
"CET-1CEST,M3.5.0/2,M10.5.0/3"
(Posix样式时区)
(Posix style timezones)
我需要对此进行解析并将其转换为c# .net TimeZoneInfo class
.
I need to parse this and convert this into a c# .net TimeZoneInfo class
.
有没有办法做到这一点?
Is there a way to achieve this ?
推荐答案
根据本文: http://www.ibm.com/developerworks/aix/library/au-aix-posix/ POSIX时间,例如"CST6CDT,M3.2.0/2:00:00,M11 .1.0/2:00:00"具有以下规范:
According to this article: http://www.ibm.com/developerworks/aix/library/au-aix-posix/ a POSIX time like "CST6CDT,M3.2.0/2:00:00,M11.1.0/2:00:00" has the following specifications:
- CST6CDT是时区的名称
- CST是DST关闭时使用的缩写
- 6小时是与格林尼治标准时间的时差
- CDT是DST启用时使用的缩写
- ,M3是第三个月
- .2是该月中一天中的第二次出现
- .0是星期日
- /2:00:00是时间
- ,M11是第11个月
- .1是该月中一天中的第一个出现
- .0是星期日
- /2:00:00是时间
- CST6CDT is the name of the time zone
- CST is the abbreviation used when DST is off
- 6 hours is the time difference from GMT
- CDT is the abbreviation used when DST is on
- ,M3 is the third month
- .2 is the second occurrence of the day in the month
- .0 is Sunday
- /2:00:00 is the time
- ,M11 is the eleventh month
- .1 is the first occurrence of the day in the month
- .0 is Sunday
- /2:00:00 is the time
,日期采用Mm.n.d格式,其中:
and the date is in the Mm.n.d format, where:
- 妈妈(1-12)持续12个月
- n(1-5)1表示第一周,5表示最后一个月
- d(0-6)星期日为0,星期六为6
基于这些信息以及在TimeZoneInfo类中可以找到的调整规则,您可以使用以下代码进行转换:
Well, based on these information and the adjustment rules that could be found in TimeZoneInfo class, you can use this code to do the conversion:
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#.net中将posix样式的时区转换为timezoneinfo的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!