@@ -223,5 +223,121 @@ public void UnixTimeWithTimeZone_ShouldIncludeOffset()
223223 // 允许误差在 100 毫秒内
224224 Assert . True ( Math . Abs ( diffMilliseconds - 28800000 ) <= 100 , $ "Expected diff 28800000, but got { diffMilliseconds } ") ;
225225 }
226+
227+ /// <summary>
228+ /// 测试 TimeToSecondsWithTimeZone 和 TimeToMillisecondsWithTimeZone 方法
229+ /// </summary>
230+ [ Fact ]
231+ public void TimeToWithTimeZone_ShouldHandleDifferentKinds ( )
232+ {
233+ var offset = TimeSpan . FromHours ( 8 ) ;
234+ var customTimeZone = TimeZoneInfo . CreateCustomTimeZone ( "Test+8" , offset , "Test+8" , "Test+8" ) ;
235+ TimerHelper . SetTimeZone ( customTimeZone ) ;
236+
237+ var nowUtc = DateTime . UtcNow ;
238+ var nowLocal = DateTime . Now ; // System Local
239+ // 构造一个 Unspecified 时间,假设它就是 CurrentTimeZone 下的时间
240+ var nowZone = TimeZoneInfo . ConvertTimeFromUtc ( nowUtc , customTimeZone ) ; // Kind is Unspecified
241+
242+ // 1. Test UTC input
243+ // 预期:UTC 时间戳 + 8 小时
244+ var expectedSeconds = new DateTimeOffset ( nowUtc ) . ToUnixTimeSeconds ( ) + 28800 ;
245+ var actualSecondsUtc = TimerHelper . TimeToSecondsWithTimeZone ( nowUtc ) ;
246+ Assert . Equal ( expectedSeconds , actualSecondsUtc ) ;
247+
248+ // 2. Test Unspecified input (assumed as CurrentTimeZone)
249+ // nowZone 是 UTC+8 的时间,转回 UTC 应该是 nowUtc
250+ // 所以结果应该和上面一样
251+ var actualSecondsZone = TimerHelper . TimeToSecondsWithTimeZone ( nowZone ) ;
252+ Assert . Equal ( expectedSeconds , actualSecondsZone ) ;
253+
254+ // 3. Test System Local input
255+ // TimerHelper should convert System Local to UTC, then apply CurrentTimeZone offset
256+ // So result should still be same absolute moment + 8 hours
257+ // 注意:如果 System Local 和 UTC 转换有微小差异(如 tick 精度),可能会有一点点误差,但在秒级应该是相等的
258+ var actualSecondsLocal = TimerHelper . TimeToSecondsWithTimeZone ( nowLocal ) ;
259+ // nowLocal 和 nowUtc 代表同一时刻(理想情况下)
260+ // 允许 1 秒误差
261+ Assert . True ( Math . Abs ( actualSecondsLocal - expectedSeconds ) <= 1 ) ;
262+ }
263+
264+ /// <summary>
265+ /// 测试扩展的 Day/Week/Month/Year 的 WithTimeZone 方法
266+ /// </summary>
267+ [ Fact ]
268+ public void ExtendedMethods_ShouldIncludeOffset ( )
269+ {
270+ var offset = TimeSpan . FromHours ( 8 ) ;
271+ var customTimeZone = TimeZoneInfo . CreateCustomTimeZone ( "Test+8" , offset , "Test+8" , "Test+8" ) ;
272+ TimerHelper . SetTimeZone ( customTimeZone ) ;
273+
274+ long offsetSeconds = ( long ) offset . TotalSeconds ;
275+
276+ // 1. Test Day
277+ var todayStandard = TimerHelper . GetTodayStartTimestamp ( ) ;
278+ var todayWithZone = TimerHelper . GetTodayStartTimestampWithTimeZone ( ) ;
279+ Assert . Equal ( offsetSeconds , todayWithZone - todayStandard ) ;
280+
281+ // 2. Test Week
282+ var weekStandard = TimerHelper . GetWeekStartTimestamp ( ) ;
283+ var weekWithZone = TimerHelper . GetWeekStartTimestampWithTimeZone ( ) ;
284+ Assert . Equal ( offsetSeconds , weekWithZone - weekStandard ) ;
285+
286+ // 3. Test Month
287+ var monthStandard = TimerHelper . GetMonthStartTimestamp ( ) ;
288+ var monthWithZone = TimerHelper . GetMonthStartTimestampWithTimeZone ( ) ;
289+ Assert . Equal ( offsetSeconds , monthWithZone - monthStandard ) ;
290+
291+ // 4. Test Year
292+ var yearStandard = TimerHelper . GetYearStartTimestamp ( ) ;
293+ var yearWithZone = TimerHelper . GetYearStartTimestampWithTimeZone ( ) ;
294+ Assert . Equal ( offsetSeconds , yearWithZone - yearStandard ) ;
295+
296+ // 5. Test specific date (Month End)
297+ var now = DateTime . UtcNow ;
298+ var monthEndStandard = TimerHelper . GetEndTimestampOfMonth ( now ) ;
299+ var monthEndWithZone = TimerHelper . GetEndTimestampOfMonthWithTimeZone ( now ) ;
300+ Assert . Equal ( offsetSeconds , monthEndWithZone - monthEndStandard ) ;
301+ }
302+
303+ [ Fact ]
304+ public void AllWithTimeZoneMethods_ShouldIncludeOffset ( )
305+ {
306+ var offset = TimeSpan . FromHours ( 8 ) ;
307+ var customTimeZone = TimeZoneInfo . CreateCustomTimeZone ( "Test+8" , offset , "Test+8" , "Test+8" ) ;
308+ TimerHelper . SetTimeZone ( customTimeZone ) ;
309+ long offsetSeconds = ( long ) offset . TotalSeconds ;
310+ var now = DateTime . UtcNow ;
311+
312+ // Day
313+ Assert . Equal ( offsetSeconds , TimerHelper . GetTodayStartTimestampWithTimeZone ( ) - TimerHelper . GetTodayStartTimestamp ( ) ) ;
314+ Assert . Equal ( offsetSeconds , TimerHelper . GetTodayEndTimestampWithTimeZone ( ) - TimerHelper . GetTodayEndTimestamp ( ) ) ;
315+ Assert . Equal ( offsetSeconds , TimerHelper . GetStartTimestampOfDayWithTimeZone ( now ) - TimerHelper . GetStartTimestampOfDay ( now ) ) ;
316+ Assert . Equal ( offsetSeconds , TimerHelper . GetEndTimestampOfDayWithTimeZone ( now ) - TimerHelper . GetEndTimestampOfDay ( now ) ) ;
317+ Assert . Equal ( offsetSeconds , TimerHelper . GetTomorrowStartTimestampWithTimeZone ( ) - TimerHelper . GetTomorrowStartTimestamp ( ) ) ;
318+ Assert . Equal ( offsetSeconds , TimerHelper . GetTomorrowEndTimestampWithTimeZone ( ) - TimerHelper . GetTomorrowEndTimestamp ( ) ) ;
319+
320+ // Week
321+ Assert . Equal ( offsetSeconds , TimerHelper . GetWeekStartTimestampWithTimeZone ( ) - TimerHelper . GetWeekStartTimestamp ( ) ) ;
322+ Assert . Equal ( offsetSeconds , TimerHelper . GetWeekEndTimestampWithTimeZone ( ) - TimerHelper . GetWeekEndTimestamp ( ) ) ;
323+ Assert . Equal ( offsetSeconds , TimerHelper . GetStartTimestampOfWeekWithTimeZone ( now ) - TimerHelper . GetStartTimestampOfWeek ( now ) ) ;
324+ Assert . Equal ( offsetSeconds , TimerHelper . GetEndTimestampOfWeekWithTimeZone ( now ) - TimerHelper . GetEndTimestampOfWeek ( now ) ) ;
325+ Assert . Equal ( offsetSeconds , TimerHelper . GetNextWeekStartTimestampWithTimeZone ( ) - TimerHelper . GetNextWeekStartTimestamp ( ) ) ;
326+ Assert . Equal ( offsetSeconds , TimerHelper . GetNextWeekEndTimestampWithTimeZone ( ) - TimerHelper . GetNextWeekEndTimestamp ( ) ) ;
327+
328+ // Month
329+ Assert . Equal ( offsetSeconds , TimerHelper . GetStartTimestampOfMonthWithTimeZone ( now ) - TimerHelper . GetStartTimestampOfMonth ( now ) ) ;
330+ Assert . Equal ( offsetSeconds , TimerHelper . GetEndTimestampOfMonthWithTimeZone ( now ) - TimerHelper . GetEndTimestampOfMonth ( now ) ) ;
331+ Assert . Equal ( offsetSeconds , TimerHelper . GetNextMonthStartTimestampWithTimeZone ( ) - TimerHelper . GetNextMonthStartTimestamp ( ) ) ;
332+ Assert . Equal ( offsetSeconds , TimerHelper . GetNextMonthEndTimestampWithTimeZone ( ) - TimerHelper . GetNextMonthEndTimestamp ( ) ) ;
333+ Assert . Equal ( offsetSeconds , TimerHelper . GetMonthStartTimestampWithTimeZone ( ) - TimerHelper . GetMonthStartTimestamp ( ) ) ;
334+ Assert . Equal ( offsetSeconds , TimerHelper . GetMonthEndTimestampWithTimeZone ( ) - TimerHelper . GetMonthEndTimestamp ( ) ) ;
335+
336+ // Year
337+ Assert . Equal ( offsetSeconds , TimerHelper . GetYearStartTimestampWithTimeZone ( ) - TimerHelper . GetYearStartTimestamp ( ) ) ;
338+ Assert . Equal ( offsetSeconds , TimerHelper . GetYearEndTimestampWithTimeZone ( ) - TimerHelper . GetYearEndTimestamp ( ) ) ;
339+ Assert . Equal ( offsetSeconds , TimerHelper . GetStartTimestampOfYearWithTimeZone ( now ) - TimerHelper . GetStartTimestampOfYear ( now ) ) ;
340+ Assert . Equal ( offsetSeconds , TimerHelper . GetEndTimestampOfYearWithTimeZone ( now ) - TimerHelper . GetEndTimestampOfYear ( now ) ) ;
341+ }
226342 }
227343}
0 commit comments