時區轉換
主要是用來轉換時區用的,特別涉及到冬令時和夏令時的區域,這樣會很煩,所以需要用個方法來轉換
這個主要是創建一些模型
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();
}
}
}
