实现时区的转换--涉及到冬令时和夏令时的时候

#时区转换
主要是用来转换时区用的,特别涉及到冬令时和夏令时的区域,这样会很烦,所以需要用个方法来转换

这个主要是创建一些模型

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Tools.TimeZone
{

    /// <summary>
    /// 国家时区类型
    /// </summary>
    public enum ZoneType
    {
        Same = 0,//普通的时区转换
        Summer = 1,//启用夏时令 在夏令时的时候比冬令时早1个小时
    }


    /// <summary>
    /// 时区
    /// </summary>
    public class TimeZoneModel
    {
        /// <summary>
        /// 冬令时GMT
        /// </summary>
        public int GMT { get; set; }


        /// <summary>
        /// 这个国家应用的时区是什么
        /// </summary>
        public ZoneType ZoneType { get; set; }

        /// <summary>
        /// 时区名称
        /// </summary>
        public string ZoneName { get; set; }
        /// <summary>
        /// 时区备注
        /// </summary>
        public string ZoneRemark { get; set; }

        /// <summary>
        /// 夏时令开始时间
        /// </summary>
        public TimeNode BeginDate { get; set; }

        /// <summary>
        /// 夏时令结束时间
        /// </summary>
        public TimeNode EndDate { get; set; }


    }
    /// <summary>
    /// 时间节点
    /// </summary>
    public class TimeNode
    {
        /// <summary>
        /// 月份
        /// </summary>
        public int Month { get; set; }
        /// <summary>
        /// 排序方式
        /// </summary>
        public Sort Sort { get; set; }
        /// <summary>
        /// 第几个
        /// </summary>
        public int Num { get; set; }
        /// <summary>
        /// 周几
        /// </summary>
        public DayOfWeek DayOfWeek { get; set; }

        /// <summary>
        /// 几点开始
        /// </summary>
        public int Hours { get; set; } = 0;//一般是0点开始
    }
    /// <summary>
    /// 查找方式
    /// </summary>
    public enum Sort
    {
        /// <summary>
        /// 倒数第几个
        /// </summary>
        desc = 0,
        /// <summary>
        /// 正数第几个
        /// </summary>
        asc=1,
    }
}

下面的是具体的方法


using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


namespace Tools.TimeZone
{
    public static class DateZoneHelper
    {
        private static List<TimeZoneModel> _zoneList;
        private static readonly string PATH = "TimeZone.json";

        public static List<TimeZoneModel> ZoneList
        {
            get
            {
                if (_zoneList == null)
                {
                    //从数据源中获取数据
                    //string Path = "TimeZone.json";
                    if (!File.Exists(PATH))
                    {
                        _zoneList = new List<TimeZoneModel>();
                    }
                    else
                    {
                        string str = File.ReadAllText(PATH);
                        //JArray array = JArray.Parse(str);
                        _zoneList=JsonConvert.DeserializeObject<List<TimeZoneModel>>(str);
                    }
                }

                return _zoneList;
            }
        }

        public static TimeZoneModel GetZone(string ZoneName)
        {
            return ZoneList.SingleOrDefault(a => a.ZoneName == ZoneName);
        }

        public static DateTimeOffset ConvertDate(this DateTimeOffset dateTime, string ZoneName)
        {

            TimeZoneModel zone = GetZone(ZoneName);//获取当前时区的参数
            return dateTime.ConvertDate(zone);
        }

        public static DateTimeOffset ConvertDate(this DateTimeOffset dateTime, TimeZoneModel zone)
        {
            if (zone==null)
            {
                return DateTimeOffset.MinValue;
            }

            DateTimeOffset date = DateTimeOffset.MinValue;

            DateTime dtUTC = dateTime.UtcDateTime;
            
            switch (zone.ZoneType)
            {
                case ZoneType.Summer:
                    
                    DateTime dtToDate = dtUTC.AddHours(zone.GMT+1);//假设当前时间是夏令时
                    DateTime BeginDate = GetDateByNodeTime(dtToDate.Year,zone.BeginDate).AddHours(1);//夏令时开始时间
                    DateTime EndDate = GetDateByNodeTime(dtToDate.Year, zone.EndDate);//夏令时结束时间
                    if (BeginDate<= dtToDate&& dtToDate< EndDate)
                    {
                        date= dateTime.ToOffset(new TimeSpan(TimeSpan.TicksPerHour * (zone.GMT+1)));
                    }
                    else
                    {
                        date = dateTime.ToOffset(new TimeSpan(TimeSpan.TicksPerHour * (zone.GMT)));
                        //date = new DateTimeOffset(dtUTC.AddHours(zone.GMT), new TimeSpan(TimeSpan.TicksPerHour * zone.GMT));
                    }


                    break;
                case ZoneType.Same:
                default:
                    DateTime dtTemp = dtUTC.AddHours(zone.GMT);

                    date = dateTime.ToOffset(new TimeSpan(TimeSpan.TicksPerHour * (zone.GMT)));
                    //date = new DateTimeOffset(dtTemp, new TimeSpan(TimeSpan.TicksPerHour * zone.GMT));
                    break;
            }

            return date;
        }

        /// <summary>
        /// 获取当前年份的节点
        /// </summary>
        /// <param name="Year">年份</param>
        /// <param name="node">节点</param>
        /// <returns></returns>
        private static DateTime GetDateByNodeTime(int Year, TimeNode node)
        {
            DateTime dt = new DateTime(Year, node.Month, 1, node.Hours, 0, 0);//获取当前月的第一天
            int times = 0;
            switch (node.Sort)
            {
                case Sort.desc:
                    dt = dt.AddMonths(1).AddDays(-1);//获取当前月的最后一天
                    times = 0;
                    while (true)//第几个时间
                    {
                        if (dt.DayOfWeek == node.DayOfWeek)
                        {
                            times++;
                            if (times >= node.Num)
                            {
                                break;
                            }
                            if (times > 31)
                            {
                                Console.WriteLine($"超过天数范围:dt={dt.ToString("yyyy-MM-dd")};times={times}");
                                break;
                            }
                        }
                        dt = dt.AddDays(-1);
                    }
                    break;
                case Sort.asc:
                    
                    times = 0;
                    while (true)//第几个时间
                    {
                        if (dt.DayOfWeek == node.DayOfWeek)
                        {
                            times++;
                            if (times >= node.Num)
                            {
                                break;
                            }

                            if (times > 31)
                            {
                                Console.WriteLine($"超过天数范围:dt={dt.ToString("yyyy-MM-dd")};times={times}");
                                break;
                            }
                        }
                        dt = dt.AddDays(1);
                    }
                    break;
                default:
                    break;
            }

            return dt;
        }


        public static void Add(TimeZoneModel model)
        {
            ZoneList.Add(model);
        }
        public static void Save()
        {
            JArray array = JArray.FromObject(ZoneList);
            File.WriteAllText(PATH,array.ToString());
        }
    }
}


具体用法如下面的代码所示

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tools.TimeZone;

namespace 时区转换工具
{
    public class Program
    {
        static void Main(string[] args)
        {

            IsZoneEnd();
            Console.ReadLine();
        }


        /// <summary>
        /// 检查是否是夏令时结束
        /// </summary>
        private static void IsZoneEnd()
        {
            for (int i = 0; i < 200; i++)
            {
                DateTimeOffset date = new DateTimeOffset(2019, 11, 3, 8 + i / 60, i % 60, 0, new TimeSpan(0));
                DateTimeOffset offset = date.ConvertDate("US.PST");

                Console.WriteLine($"i={i}当前时间是{offset.ToString("yyyy-MM-dd HH:mm:ss")}===时区是{offset.Offset}");

            }
        }
        /// <summary>
        /// 检查是否是夏令时开始
        /// </summary>
        private static void IsZoneBegin()
        {
            for (int i = 0; i < 100; i++)
            {
                DateTimeOffset date = new DateTimeOffset(2019, 3, 10, 9 + i / 60, i % 60, 0, new TimeSpan(0));
                DateTimeOffset offset = date.ConvertDate("US.PST");

                Console.WriteLine($"i={i}当前时间是{offset.ToString("yyyy-MM-dd HH:mm:ss")}===时区是{offset.Offset}");

            }
        }

        private static void USZoneWrite()
        {
            TimeNode AMBegin = new TimeNode
            {
                Month = 3,
                Num = 2,
                DayOfWeek = DayOfWeek.Sunday,
                Hours = 2,
                Sort = Sort.asc,
            };

            TimeNode AMEnd = new TimeNode
            {
                Month = 11,
                Num = 1,
                DayOfWeek = DayOfWeek.Sunday,
                Hours = 2,
                Sort = Sort.asc,
            };
            DateZoneHelper.ZoneList.Add(new TimeZoneModel()
            {
                ZoneName = "US.EST",
                ZoneRemark = "美国东部时间 西五区时间 美国从每年3月的第二个星期日至11月的第一个星期日采用夏令时",
                GMT = -5,
                ZoneType = ZoneType.Summer,
                BeginDate = AMBegin,
                EndDate = AMEnd,
            });

            DateZoneHelper.ZoneList.Add(new TimeZoneModel()
            {
                ZoneName = "US.CST",
                ZoneRemark = "美国中部时间(CST)(西六区时间) 美国从每年3月的第二个星期日至11月的第一个星期日采用夏令时",
                GMT = -6,
                ZoneType = ZoneType.Summer,
                BeginDate = AMBegin,
                EndDate = AMEnd,
            });
            DateZoneHelper.ZoneList.Add(new TimeZoneModel()
            {
                ZoneName = "US.MST",
                ZoneRemark = "美国山地时间(MST)(西七区时间) 美国从每年3月的第二个星期日至11月的第一个星期日采用夏令时",//东部时间 西五区时间
                GMT = -7,
                ZoneType = ZoneType.Summer,
                BeginDate = AMBegin,
                EndDate = AMEnd,
            });
            DateZoneHelper.ZoneList.Add(new TimeZoneModel()
            {
                ZoneName = "US.PST",
                ZoneRemark = "太平洋时间(西部时间)(PST)(西八区时间) 美国从每年3月的第二个星期日至11月的第一个星期日采用夏令时",//东部时间 西五区时间
                GMT = -8,
                ZoneType = ZoneType.Summer,
                BeginDate = AMBegin,
                EndDate = AMEnd,
            });
            DateZoneHelper.ZoneList.Add(new TimeZoneModel()
            {
                ZoneName = "US.AKST",
                ZoneRemark = "阿拉斯加时间(AKST)(西九区时间)美国从每年3月的第二个星期日至11月的第一个星期日采用夏令时",//东部时间 西五区时间
                GMT = -9,
                ZoneType = ZoneType.Summer,
                BeginDate = AMBegin,
                EndDate = AMEnd,
            });

            DateZoneHelper.ZoneList.Add(new TimeZoneModel()
            {
                ZoneName = "US.HST",
                ZoneRemark = "夏威夷时间(HST)(西十区时间)美国从每年3月的第二个星期日至11月的第一个星期日采用夏令时",//东部时间 西五区时间
                GMT = -10,
                ZoneType = ZoneType.Summer,
                BeginDate = AMBegin,
                EndDate = AMEnd,
            });


            DateZoneHelper.Save();
        }


    }





}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值