在C#.net中将posix样式的时区转换为timezoneinfo [英] Convert a posix style timezone to timezoneinfo in c# .net

查看:223
本文介绍了在C#.net中将posix样式的时区转换为timezoneinfo的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从另一台计算机上获取时区信息,格式为:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆