using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace TestConsoleApp { internal class Program { static void Main(string[] args) { var dt1 = new DateTime(2026, 3, 29, 4, 0, 0); var dt2 = new DateTime(2026, 3, 29, 6, 0, 0); var dt3 = new DateTime(2026, 3, 29, 14, 0, 0); var dnt1 = DateAndTime.GetNow("", dt1); var dnt2 = DateAndTime.GetNow("", dt2); var dnt3 = DateAndTime.GetNow("", dt3); Console.WriteLine(string.Format("{0:yyyy-MM-dd} {1:yyyy-MM-dd} {2} {3:yyyy-MM-dd} {4}", dnt1.TwWorkDate, dnt1.TwCalendarDate, dnt1.TwTime, dnt1.LocalDate, dnt1.LocalTime)); Console.WriteLine(string.Format("{0:yyyy-MM-dd} {1:yyyy-MM-dd} {2} {3:yyyy-MM-dd} {4}", dnt2.TwWorkDate, dnt2.TwCalendarDate, dnt2.TwTime, dnt2.LocalDate, dnt2.LocalTime)); Console.WriteLine(string.Format("{0:yyyy-MM-dd} {1:yyyy-MM-dd} {2} {3:yyyy-MM-dd} {4}", dnt3.TwWorkDate, dnt3.TwCalendarDate, dnt3.TwTime, dnt3.LocalDate, dnt3.LocalTime)); Console.WriteLine("按 ENTER 結束"); Console.ReadLine(); } } /// /// 30 小時制的日期類別 /// public class DateAndTime { /// /// 台灣工作日期 /// public DateTime TwWorkDate; /// /// 台灣日曆日期 /// public DateTime TwCalendarDate; /// /// 台灣時間 /// public string TwTime; /// /// 當地日期 /// public DateTime LocalDate; /// /// 當地時間 /// public string LocalTime; /// /// 時區名稱 /// public string TimezoneName; /// /// 時區ID /// public string TimeZoneID; public DateAndTime(DateTime twWorkDate, DateTime twCalendarDate, string twTime, DateTime localDate, string localTime, string timezoneName, string timezoneID) : base() { this.TwWorkDate = twWorkDate; this.TwCalendarDate = twCalendarDate; this.TwTime = twTime; this.LocalDate = localDate; this.LocalTime = localTime; TimezoneName = timezoneName; TimeZoneID = timezoneID; } public static DateTime 轉換時區(string 時區, DateTime 日期, string 時間) { // 解析30小時制(小時可能 >= 24,表示跨入隔日凌晨) var parts = 時間.Split(':'); var timeSpan = new TimeSpan(int.Parse(parts[0]), int.Parse(parts[1]), int.Parse(parts[2])); var sourceTime = 日期.Date.Add(timeSpan); if (string.IsNullOrEmpty(時區) || string.Compare(時區, "Taipei Standard Time") == 0) { return sourceTime; } // 重要:將 Kind 設為 Unspecified sourceTime = DateTime.SpecifyKind(sourceTime, DateTimeKind.Unspecified); // 轉換到目標時區 var sourceZone = TimeZoneInfo.FindSystemTimeZoneById("Taipei Standard Time"); var targetZone = TimeZoneInfo.FindSystemTimeZoneById(時區); var utcTime = TimeZoneInfo.ConvertTimeToUtc(sourceTime, sourceZone); var targetTime = TimeZoneInfo.ConvertTimeFromUtc(utcTime, targetZone); return targetTime; } public static DateAndTime GetNow(string bpeno, DateTime twNow) { string timezoneID = "Pacific Standard Time"; string timezoneName = "美西"; var twCalendarDate = twNow.Date; var twWorkDate = twNow.Date; var localNow = 轉換時區(timezoneID, twNow.Date, twNow.ToString("HH:mm:ss")); var localDate = localNow.Date; var twHourOffset = 0; var localHourOffset = 0; // 06:00 之前算前一天 if (twNow.TimeOfDay < new TimeSpan(6, 0, 0)) { twWorkDate = twWorkDate.AddDays(-1); twHourOffset = 24; } if (localNow.TimeOfDay < new TimeSpan(6, 0, 0)) { localDate = localDate.AddDays(-1); localHourOffset = 24; } return new DateAndTime( twWorkDate, twCalendarDate, string.Format("{0:00}:{1:00}:{2:00}", twNow.TimeOfDay.Hours + twHourOffset, twNow.TimeOfDay.Minutes, twNow.Second), localDate, string.Format("{0:00}:{1:00}:{2:00}", localNow.TimeOfDay.Hours + localHourOffset, localNow.TimeOfDay.Minutes, localNow.Second), timezoneName, timezoneID ); } public static DateAndTime GetNow(string bpeno) { var twNow = DateTime.UtcNow.AddHours(8); return GetNow(bpeno, twNow); } } }