實現時區的轉換--涉及到冬令時和夏令時的時候


時區轉換

主要是用來轉換時區用的,特別涉及到冬令時和夏令時的區域,這樣會很煩,所以需要用個方法來轉換

這個主要是創建一些模型

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();
        }


    }





}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM