Skip to content

Commit 9eaa5f0

Browse files
committed
添加 TimeZoneConverter
1 parent 0af3901 commit 9eaa5f0

File tree

3 files changed

+251
-2
lines changed

3 files changed

+251
-2
lines changed

src/Senparc.CO2NET/Helpers/DateTimeHelper.cs renamed to src/Senparc.CO2NET/Helpers/DateTime/DateTimeHelper.cs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ and limitations under the License.
5757

5858

5959
using System;
60+
using System.Runtime.InteropServices;
6061
using System.Threading.Tasks;
6162

6263
namespace Senparc.CO2NET.Helpers
@@ -96,11 +97,31 @@ public static DateTime GetDateTimeFromXml(string dateTimeFromXml)
9697
/// </summary>
9798
/// <param name="dateTimeFromXml">微信DateTime</param>
9899
/// <returns></returns>
99-
public static DateTimeOffset GetDateTimeOffsetFromXml(long dateTimeFromXml, string timezoneId = "China Standard Time")
100+
public static DateTimeOffset GetDateTimeOffsetFromXml(long dateTimeFromXml,
101+
string timezoneId = "China Standard Time"
102+
#if !NET462
103+
, IRuntimeInformation runtimeInformation = null
104+
#endif
105+
)
100106
{
101107
DateTimeOffset utcDateTime = BaseTime.AddSeconds(dateTimeFromXml);
102108
Console.WriteLine($"UTC Time: {utcDateTime}");
103-
TimeZoneInfo timeZone = TimeZoneInfo.FindSystemTimeZoneById(timezoneId);
109+
110+
string ianaTimeZoneId;
111+
if (runtimeInformation.IsOSPlatform(OSPlatform.Windows))
112+
{
113+
ianaTimeZoneId = TimeZoneConverter.WindowsToIana(timezoneId);
114+
}
115+
else if (runtimeInformation.IsOSPlatform(OSPlatform.Linux) || runtimeInformation.IsOSPlatform(OSPlatform.OSX))
116+
{
117+
ianaTimeZoneId = timezoneId;
118+
}
119+
else
120+
{
121+
throw new PlatformNotSupportedException();
122+
}
123+
124+
TimeZoneInfo timeZone = TimeZoneInfo.FindSystemTimeZoneById(ianaTimeZoneId);
104125
DateTimeOffset localDateTime = TimeZoneInfo.ConvertTime(utcDateTime, timeZone);
105126
Console.WriteLine($"Local Time ({timezoneId}): {localDateTime}");
106127
return localDateTime;
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Runtime.InteropServices;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
8+
namespace Senparc.CO2NET.Helpers
9+
{
10+
#if !NET462
11+
public interface IRuntimeInformation
12+
{
13+
bool IsOSPlatform(OSPlatform osPlatform);
14+
}
15+
16+
public class RuntimeInformationWrapper : IRuntimeInformation
17+
{
18+
public bool IsOSPlatform(OSPlatform osPlatform)
19+
{
20+
return RuntimeInformation.IsOSPlatform(osPlatform);
21+
}
22+
}
23+
#endif
24+
}
Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
#region Apache License Version 2.0
2+
/*----------------------------------------------------------------
3+
4+
Copyright 2023 Suzhou Senparc Network Technology Co.,Ltd.
5+
6+
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
7+
except in compliance with the License. You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software distributed under the
12+
License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13+
either express or implied. See the License for the specific language governing permissions
14+
and limitations under the License.
15+
16+
Detail: https://github.com/Senparc/Senparc.CO2NET/blob/master/LICENSE
17+
18+
----------------------------------------------------------------*/
19+
#endregion Apache License Version 2.0
20+
21+
/*----------------------------------------------------------------
22+
Copyright (C) 2024 Senparc
23+
24+
文件名:TimeZoneConverter.cs
25+
文件功能描述:时区转换工具类
26+
27+
28+
创建标识:Senparc - 20240823
29+
30+
----------------------------------------------------------------*/
31+
32+
33+
using System;
34+
using System.Collections.Generic;
35+
using System.Linq;
36+
using System.Text;
37+
using System.Threading.Tasks;
38+
39+
namespace Senparc.CO2NET.Helpers
40+
{
41+
/// <summary>
42+
/// 时区转换工具类
43+
/// </summary>
44+
public static class TimeZoneConverter
45+
{
46+
private static readonly Dictionary<string, string> windowsToIana = new Dictionary<string, string>
47+
{
48+
{"Dateline Standard Time", "Etc/GMT+12"},
49+
{"UTC-11", "Etc/GMT+11"},
50+
{"Aleutian Standard Time", "America/Adak"},
51+
{"Hawaiian Standard Time", "Pacific/Honolulu"},
52+
{"Marquesas Standard Time", "Pacific/Marquesas"},
53+
{"Alaskan Standard Time", "America/Anchorage"},
54+
{"UTC-09", "Etc/GMT+9"},
55+
{"Pacific Standard Time (Mexico)", "America/Tijuana"},
56+
{"UTC-08", "Etc/GMT+8"},
57+
{"Pacific Standard Time", "America/Los_Angeles"},
58+
{"US Mountain Standard Time", "America/Phoenix"},
59+
{"Mountain Standard Time (Mexico)", "America/Chihuahua"},
60+
{"Mountain Standard Time", "America/Denver"},
61+
{"Central America Standard Time", "America/Guatemala"},
62+
{"Central Standard Time", "America/Chicago"},
63+
{"Easter Island Standard Time", "Pacific/Easter"},
64+
{"Central Standard Time (Mexico)", "America/Mexico_City"},
65+
{"Canada Central Standard Time", "America/Regina"},
66+
{"SA Pacific Standard Time", "America/Bogota"},
67+
{"Eastern Standard Time (Mexico)", "America/Cancun"},
68+
{"Eastern Standard Time", "America/New_York"},
69+
{"Haiti Standard Time", "America/Port-au-Prince"},
70+
{"Cuba Standard Time", "America/Havana"},
71+
{"US Eastern Standard Time", "America/Indianapolis"},
72+
{"Turks And Caicos Standard Time", "America/Grand_Turk"},
73+
{"Paraguay Standard Time", "America/Asuncion"},
74+
{"Atlantic Standard Time", "America/Halifax"},
75+
{"Venezuela Standard Time", "America/Caracas"},
76+
{"Central Brazilian Standard Time", "America/Cuiaba"},
77+
{"SA Western Standard Time", "America/La_Paz"},
78+
{"Pacific SA Standard Time", "America/Santiago"},
79+
{"Newfoundland Standard Time", "America/St_Johns"},
80+
{"Tocantins Standard Time", "America/Araguaina"},
81+
{"E. South America Standard Time", "America/Sao_Paulo"},
82+
{"SA Eastern Standard Time", "America/Cayenne"},
83+
{"Argentina Standard Time", "America/Buenos_Aires"},
84+
{"Greenland Standard Time", "America/Godthab"},
85+
{"Montevideo Standard Time", "America/Montevideo"},
86+
{"Magallanes Standard Time", "America/Punta_Arenas"},
87+
{"Saint Pierre Standard Time", "America/Miquelon"},
88+
{"Bahia Standard Time", "America/Bahia"},
89+
{"UTC-02", "Etc/GMT+2"},
90+
{"Mid-Atlantic Standard Time", "Atlantic/South_Georgia"},
91+
{"Azores Standard Time", "Atlantic/Azores"},
92+
{"Cape Verde Standard Time", "Atlantic/Cape_Verde"},
93+
{"UTC", "Etc/GMT"},
94+
{"GMT Standard Time", "Europe/London"},
95+
{"Greenwich Standard Time", "Atlantic/Reykjavik"},
96+
{"Sao Tome Standard Time", "Africa/Sao_Tome"},
97+
{"Morocco Standard Time", "Africa/Casablanca"},
98+
{"W. Europe Standard Time", "Europe/Berlin"},
99+
{"Central Europe Standard Time", "Europe/Budapest"},
100+
{"Romance Standard Time", "Europe/Paris"},
101+
{"Central European Standard Time", "Europe/Warsaw"},
102+
{"W. Central Africa Standard Time", "Africa/Lagos"},
103+
{"Jordan Standard Time", "Asia/Amman"},
104+
{"GTB Standard Time", "Europe/Bucharest"},
105+
{"Middle East Standard Time", "Asia/Beirut"},
106+
{"Egypt Standard Time", "Africa/Cairo"},
107+
{"E. Europe Standard Time", "Europe/Chisinau"},
108+
{"Syria Standard Time", "Asia/Damascus"},
109+
{"West Bank Standard Time", "Asia/Hebron"},
110+
{"South Africa Standard Time", "Africa/Johannesburg"},
111+
{"FLE Standard Time", "Europe/Kiev"},
112+
{"Israel Standard Time", "Asia/Jerusalem"},
113+
{"Kaliningrad Standard Time", "Europe/Kaliningrad"},
114+
{"Sudan Standard Time", "Africa/Khartoum"},
115+
{"Libya Standard Time", "Africa/Tripoli"},
116+
{"Namibia Standard Time", "Africa/Windhoek"},
117+
{"Arabic Standard Time", "Asia/Baghdad"},
118+
{"Turkey Standard Time", "Europe/Istanbul"},
119+
{"Arab Standard Time", "Asia/Riyadh"},
120+
{"Belarus Standard Time", "Europe/Minsk"},
121+
{"Russian Standard Time", "Europe/Moscow"},
122+
{"E. Africa Standard Time", "Africa/Nairobi"},
123+
{"Iran Standard Time", "Asia/Tehran"},
124+
{"Arabian Standard Time", "Asia/Dubai"},
125+
{"Astrakhan Standard Time", "Europe/Astrakhan"},
126+
{"Azerbaijan Standard Time", "Asia/Baku"},
127+
{"Russia Time Zone 3", "Europe/Samara"},
128+
{"Mauritius Standard Time", "Indian/Mauritius"},
129+
{"Saratov Standard Time", "Europe/Saratov"},
130+
{"Georgian Standard Time", "Asia/Tbilisi"},
131+
{"Volgograd Standard Time", "Europe/Volgograd"},
132+
{"Caucasus Standard Time", "Asia/Yerevan"},
133+
{"Afghanistan Standard Time", "Asia/Kabul"},
134+
{"West Asia Standard Time", "Asia/Tashkent"},
135+
{"Ekaterinburg Standard Time", "Asia/Yekaterinburg"},
136+
{"Pakistan Standard Time", "Asia/Karachi"},
137+
{"Qyzylorda Standard Time", "Asia/Qyzylorda"},
138+
{"India Standard Time", "Asia/Kolkata"},
139+
{"Sri Lanka Standard Time", "Asia/Colombo"},
140+
{"Nepal Standard Time", "Asia/Kathmandu"},
141+
{"Central Asia Standard Time", "Asia/Almaty"},
142+
{"Bangladesh Standard Time", "Asia/Dhaka"},
143+
{"Omsk Standard Time", "Asia/Omsk"},
144+
{"Myanmar Standard Time", "Asia/Rangoon"},
145+
{"SE Asia Standard Time", "Asia/Bangkok"},
146+
{"Altai Standard Time", "Asia/Barnaul"},
147+
{"W. Mongolia Standard Time", "Asia/Hovd"},
148+
{"North Asia Standard Time", "Asia/Krasnoyarsk"},
149+
{"N. Central Asia Standard Time", "Asia/Novosibirsk"},
150+
{"Tomsk Standard Time", "Asia/Tomsk"},
151+
{"China Standard Time", "Asia/Shanghai"},
152+
{"North Asia East Standard Time", "Asia/Irkutsk"},
153+
{"Singapore Standard Time", "Asia/Singapore"},
154+
{"W. Australia Standard Time", "Australia/Perth"},
155+
{"Taipei Standard Time", "Asia/Taipei"},
156+
{"Ulaanbaatar Standard Time", "Asia/Ulaanbaatar"},
157+
{"Aus Central W. Standard Time", "Australia/Eucla"},
158+
{"Transbaikal Standard Time", "Asia/Chita"},
159+
{"Tokyo Standard Time", "Asia/Tokyo"},
160+
{"North Korea Standard Time", "Asia/Pyongyang"},
161+
{"Korea Standard Time", "Asia/Seoul"},
162+
{"Yakutsk Standard Time", "Asia/Yakutsk"},
163+
{"Cen. Australia Standard Time", "Australia/Adelaide"},
164+
{"AUS Central Standard Time", "Australia/Darwin"},
165+
{"E. Australia Standard Time", "Australia/Brisbane"},
166+
{"AUS Eastern Standard Time", "Australia/Sydney"},
167+
{"West Pacific Standard Time", "Pacific/Port_Moresby"},
168+
{"Tasmania Standard Time", "Australia/Hobart"},
169+
{"Vladivostok Standard Time", "Asia/Vladivostok"},
170+
{"Lord Howe Standard Time", "Australia/Lord_Howe"},
171+
{"Bougainville Standard Time", "Pacific/Bougainville"},
172+
{"Russia Time Zone 10", "Asia/Srednekolymsk"},
173+
{"Magadan Standard Time", "Asia/Magadan"},
174+
{"Norfolk Standard Time", "Pacific/Norfolk"},
175+
{"Sakhalin Standard Time", "Asia/Sakhalin"},
176+
{"Central Pacific Standard Time", "Pacific/Guadalcanal"},
177+
{"Russia Time Zone 11", "Asia/Kamchatka"},
178+
{"New Zealand Standard Time", "Pacific/Auckland"},
179+
{"UTC+12", "Etc/GMT-12"},
180+
{"Fiji Standard Time", "Pacific/Fiji"},
181+
{"Chatham Islands Standard Time", "Pacific/Chatham"},
182+
{"UTC+13", "Etc/GMT-13"},
183+
{"Tonga Standard Time", "Pacific/Tongatapu"},
184+
{"Samoa Standard Time", "Pacific/Apia"},
185+
{"Line Islands Standard Time", "Pacific/Kiritimati"}
186+
};
187+
188+
/// <summary>
189+
/// 把 Windows 时区转换为 IANA 时区
190+
/// </summary>
191+
/// <param name="windowsZoneId"></param>
192+
/// <returns></returns>
193+
/// <exception cref="ArgumentException"></exception>
194+
public static string WindowsToIana(string windowsZoneId)
195+
{
196+
if (windowsToIana.ContainsKey(windowsZoneId))
197+
{
198+
return windowsToIana[windowsZoneId];
199+
}
200+
201+
throw new ArgumentException("Invalid Windows zone id");
202+
}
203+
}
204+
}

0 commit comments

Comments
 (0)