Skip to content

Commit 30d21d8

Browse files
committed
feat(utility): 添加基于时区的 Unix 时间戳转换方法
新增 TimeToSecondsWithTimeZone 和 TimeToMillisecondsWithTimeZone 公共方法,用于将指定 DateTime 转换为考虑当前设置时区偏移的 Unix 时间戳。同时添加了辅助的私有方法 DateTimeToUnixTimeSeconds 和 ConvertToUtc 以正确处理不同 DateTime.Kind 的转换逻辑,确保时间转换的准确性。
1 parent 7e20133 commit 30d21d8

1 file changed

Lines changed: 88 additions & 0 deletions

File tree

GameFrameX.Foundation.Utility/Time/TimerHelper.cs

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,94 @@ public static long UnixTimeMillisecondsWithTimeZone()
179179
return new DateTimeOffset(utcNow).ToUnixTimeMilliseconds() + (long)offset.TotalMilliseconds;
180180
}
181181

182+
/// <summary>
183+
/// 获取指定时间基于当前设置时区的 Unix 时间戳(秒级精度)。
184+
/// </summary>
185+
/// <param name="time">要转换的时间。</param>
186+
/// <returns>
187+
/// 返回一个 <see cref="long"/> 值,表示将指定时间视为 UTC 时间时的 Unix 时间戳 + 时区偏移。
188+
/// </returns>
189+
/// <remarks>
190+
/// 此方法会先将输入时间转换为 UTC(如果不是),然后加上当前设置时区的偏移量。
191+
/// 如果输入时间 Kind 为 Unspecified,则默认视为当前设置时区 (<see cref="CurrentTimeZone"/>) 的时间。
192+
/// </remarks>
193+
public static long TimeToSecondsWithTimeZone(DateTime time)
194+
{
195+
var utcTime = ConvertToUtc(time);
196+
var offset = CurrentTimeZone.GetUtcOffset(utcTime);
197+
return new DateTimeOffset(utcTime).ToUnixTimeSeconds() + (long)offset.TotalSeconds;
198+
}
199+
200+
/// <summary>
201+
/// 获取指定时间基于当前设置时区的 Unix 时间戳(毫秒级精度)。
202+
/// </summary>
203+
/// <param name="time">要转换的时间。</param>
204+
/// <returns>
205+
/// 返回一个 <see cref="long"/> 值,表示将指定时间视为 UTC 时间时的 Unix 时间戳 + 时区偏移。
206+
/// </returns>
207+
/// <remarks>
208+
/// 此方法会先将输入时间转换为 UTC(如果不是),然后加上当前设置时区的偏移量。
209+
/// 如果输入时间 Kind 为 Unspecified,则默认视为当前设置时区 (<see cref="CurrentTimeZone"/>) 的时间。
210+
/// </remarks>
211+
public static long TimeToMillisecondsWithTimeZone(DateTime time)
212+
{
213+
var utcTime = ConvertToUtc(time);
214+
var offset = CurrentTimeZone.GetUtcOffset(utcTime);
215+
return new DateTimeOffset(utcTime).ToUnixTimeMilliseconds() + (long)offset.TotalMilliseconds;
216+
}
217+
218+
/// <summary>
219+
/// 将 DateTime 转换为 Unix 时间戳(秒)
220+
/// 自动处理 DateTime.Kind
221+
/// Utc -> 使用 Zero 偏移
222+
/// Local -> 使用 Local 偏移
223+
/// Unspecified -> 使用 CurrentTimeZone 偏移
224+
/// </summary>
225+
private static long DateTimeToUnixTimeSeconds(DateTime time)
226+
{
227+
TimeSpan offset;
228+
if (time.Kind == DateTimeKind.Utc)
229+
{
230+
offset = TimeSpan.Zero;
231+
}
232+
else if (time.Kind == DateTimeKind.Local)
233+
{
234+
offset = TimeZoneInfo.Local.GetUtcOffset(time);
235+
}
236+
else
237+
{
238+
offset = CurrentTimeZone.GetUtcOffset(time);
239+
}
240+
241+
return new DateTimeOffset(time, offset).ToUnixTimeSeconds();
242+
}
243+
244+
/// <summary>
245+
/// 将时间转换为 UTC 时间。
246+
/// </summary>
247+
/// <param name="time">要转换的时间。</param>
248+
/// <returns>转换后的 UTC 时间。</returns>
249+
/// <remarks>
250+
/// - 如果 Kind 为 Utc,直接返回。
251+
/// - 如果 Kind 为 Local,转换为 UTC。
252+
/// - 如果 Kind 为 Unspecified,视为当前设置时区 (<see cref="CurrentTimeZone"/>) 的时间并转换为 UTC。
253+
/// </remarks>
254+
private static DateTime ConvertToUtc(DateTime time)
255+
{
256+
if (time.Kind == DateTimeKind.Utc)
257+
{
258+
return time;
259+
}
260+
261+
if (time.Kind == DateTimeKind.Local)
262+
{
263+
return time.ToUniversalTime();
264+
}
265+
266+
// Unspecified, assume CurrentTimeZone
267+
return TimeZoneInfo.ConvertTimeToUtc(time, CurrentTimeZone);
268+
}
269+
182270
/// <summary>
183271
/// 获取指定时间距离纪元时间的毫秒数。
184272
/// </summary>

0 commit comments

Comments
 (0)