c# - 在 c# .net 中将 posix 样式时区转换为 timezoneinfo

标签 c# .net timezone posix

我从另一台机器获取格式的时区信息:

"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/

相关文章:

c# - Nunit:检查两个对象是否相同

c# - Web API 自定义身份验证过滤器

c# - SQLiteDataReader 类型亲和性错误?

c# - 对 Interlocked.CompareExchange 延迟初始化的字段执行定期读取是否正确?

c++ - 奇怪的 mktime 行为 - 如果将返回值分配给变量则更改

django - 根据 django 项目中的用户更改时区

php - 在 php 中使用 EST、CET、PST 等时区

c# - VS2010 设计器 Z 顺序

c# - 无法使用服务帐户在谷歌驱动器上上传图片

c# - Entity Framework 4 TPH 继承,如何将一种类型更改为另一种类型?