using System; using System.Collections.Generic; using System.Globalization; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Threading; using AxCopilot.SDK; namespace AxCopilot.Handlers; public class DateCalcHandler : IActionHandler { private static readonly string[] DateFormats = new string[5] { "yyyy-MM-dd", "yyyy/MM/dd", "yyyyMMdd", "MM/dd/yyyy", "dd-MM-yyyy" }; public string? Prefix => "date"; public PluginMetadata Metadata => new PluginMetadata("DateCalc", "날짜 계산 · D-day · 타임스탬프 변환", "1.0", "AX"); public Task> GetItemsAsync(string query, CancellationToken ct) { string text = query.Trim(); DateTime now = DateTime.Now; List list = new List(); if (string.IsNullOrWhiteSpace(text)) { string value = now.ToString("dddd", new CultureInfo("ko-KR")); list.Add(Item($"{now:yyyy-MM-dd} ({value})", $"{now:HH:mm:ss} · {now:yyyy-MM-dd}")); list.Add(Item($"유닉스 타임스탬프: {new DateTimeOffset(now).ToUnixTimeSeconds()}", "현재 시각의 Unix epoch")); list.Add(Item($"올해 {now.DayOfYear}일째 / 남은 일: {(new DateTime(now.Year, 12, 31) - now).Days}일", $"ISO 주차: {ISOWeek.GetWeekOfYear(now)}주")); return Task.FromResult((IEnumerable)list); } Match match = Regex.Match(text, "^([+-])(\\d+)([dDwWmMyY])$"); if (match.Success) { int num = ((match.Groups[1].Value == "+") ? 1 : (-1)); int num2 = int.Parse(match.Groups[2].Value) * num; string text2 = match.Groups[3].Value.ToLowerInvariant(); if (1 == 0) { } DateTime dateTime = text2 switch { "d" => now.AddDays(num2), "w" => now.AddDays(num2 * 7), "m" => now.AddMonths(num2), "y" => now.AddYears(num2), _ => now, }; if (1 == 0) { } DateTime value2 = dateTime; string value3 = value2.ToString("dddd", new CultureInfo("ko-KR")); int days = (value2.Date - now.Date).Days; string subtitle = ((days >= 0) ? $"오늘로부터 {days}일 후" : $"오늘로부터 {Math.Abs(days)}일 전"); list.Add(Item($"{value2:yyyy-MM-dd} ({value3})", subtitle)); return Task.FromResult((IEnumerable)list); } if (Regex.IsMatch(text, "^\\d{10,13}$") && long.TryParse(text, out var result)) { long seconds = ((result > 9999999999L) ? (result / 1000) : result); DateTime localDateTime = DateTimeOffset.FromUnixTimeSeconds(seconds).LocalDateTime; string value4 = localDateTime.ToString("dddd", new CultureInfo("ko-KR")); list.Add(Item($"{localDateTime:yyyy-MM-dd HH:mm:ss} ({value4})", $"Unix {result} → 로컬 시간")); return Task.FromResult((IEnumerable)list); } if (text.Equals("unix", StringComparison.OrdinalIgnoreCase) || text.Equals("to unix", StringComparison.OrdinalIgnoreCase)) { long value5 = new DateTimeOffset(now).ToUnixTimeSeconds(); list.Add(Item($"{value5}", $"현재 시각 ({now:yyyy-MM-dd HH:mm:ss}) → Unix 타임스탬프")); return Task.FromResult((IEnumerable)list); } if (DateTime.TryParseExact(text, DateFormats, CultureInfo.InvariantCulture, DateTimeStyles.None, out var result2)) { string value6 = result2.ToString("dddd", new CultureInfo("ko-KR")); int days2 = (result2.Date - now.Date).Days; if (1 == 0) { } string text3 = ((days2 > 0) ? $"D-{days2} (앞으로 {days2}일)" : ((days2 != 0) ? $"D+{Math.Abs(days2)} ({Math.Abs(days2)}일 지남)" : "오늘")); if (1 == 0) { } string subtitle2 = text3; list.Add(Item($"{result2:yyyy-MM-dd} ({value6})", subtitle2)); return Task.FromResult((IEnumerable)list); } list.Add(new LauncherItem("날짜 형식을 인식할 수 없습니다", "예: +30d, -100d, 2026-12-25, 1711584000, unix", null, null, null, "\ue7ba")); return Task.FromResult((IEnumerable)list); } private static LauncherItem Item(string title, string subtitle) { return new LauncherItem(title, subtitle + " · Enter로 복사", null, title, null, "\ue823"); } public Task ExecuteAsync(LauncherItem item, CancellationToken ct) { object data = item.Data; string text = data as string; if (text != null && !string.IsNullOrWhiteSpace(text)) { try { Application current = Application.Current; if (current != null) { ((DispatcherObject)current).Dispatcher.Invoke((Action)delegate { Clipboard.SetText(text); }); } } catch { } } return Task.CompletedTask; } }