C:\Program Files (x86)\MSBuild\14.0\Bin\csc.exe test.cs
# test.cs
using System; using System.Diagnostics; using System.Globalization; using System.IO; class Program { private static readonly ConsoleColor DefaultForegroundColor = Console.ForegroundColor; private static readonly int DefaultPreSaleDays = 60; private static readonly string WebSite = "http://www.12306.cn"; private static int Main(params string[] args) { var preSaleDays = 0; if (args.Length > 0) { if (!int.TryParse(args[0], out preSaleDays)) { ShowHelpAndExit(1); //第一个参数错误 } else if (args.Length > 1) { DateTime argsDate; //出行日期 if (args[1].Trim().Equals("now", StringComparison.OrdinalIgnoreCase)) { argsDate = DateTime.Now.AddDays(preSaleDays - 1); //出行日期为now的话,计算出今天可预订的出行日期 } else if (!DateTime.TryParse(args[1], out argsDate)) { ShowHelpAndExit(2); //第二个参数错误 } Console.WriteLine($"\n * 火车票预售期为:{preSaleDays}天\n\n出行日期:{FormatDate(argsDate)}"); OutputBookingDay(preSaleDays, argsDate); //输出预售日期 var paused = true; if (args.Length > 2) { if (args[2].Trim().Equals("nopause", StringComparison.OrdinalIgnoreCase)) { paused = false; //第三个参数为 nopause 则不暂停直接退出,用于配合命令提示符 } } if (paused) { Console.Write("\n按任意键退出..."); Console.ReadKey(true); } Environment.Exit(0); //正常退出 } } else { Console.WriteLine("计算从哪天起应该购买预售火车票"); //未带参数,输出标题 Console.WriteLine(); } if (preSaleDays <= 0) { Console.Write($"火车票预售期(缺省为{DefaultPreSaleDays}天):"); var input = Console.ReadLine()?.Trim(); //手动输入预售期 InputToExit(input); if (!int.TryParse(input, out preSaleDays) || preSaleDays <= 0) { preSaleDays = DefaultPreSaleDays; //输入错误,预售期设置为缺省天数 ConsoleCursorRelativeLine(-1); //光标移动到上一行行首。 var point = ConsoleCursorGetCurrentPosition(); if (point != null) { ConsoleCursorFillLines(point.Value.Top, point.Value.Top, ‘ ‘); //清除光标所在行的显示字符(用空格填充) Console.Write($"火车票预售期(缺省为{DefaultPreSaleDays}天):{preSaleDays}\n"); } } } Console.WriteLine($"\n * 火车票预售期为:{preSaleDays}天"); Console.WriteLine($" * 今天可以预定 {FormatDate(DateTime.Now.AddDays(preSaleDays - 1))} 的火车票"); Console.WriteLine(" * 输入 exit 可退出程序,输入 g 打开12306订票网站\n"); while (true) { Console.Write("出行日期:"); //输入出行日期 var input = Console.ReadLine()?.Trim(); InputToExit(input); //若输入exit则退出 if (input != null && input.Equals("g", StringComparison.OrdinalIgnoreCase)) { Process.Start(WebSite); //输入g打开12306网站 Console.WriteLine($"正在打开 {WebSite}"); } else { DateTime dest; if (DateTime.TryParse(input, out dest)) { ConsoleCursorRelativeLine(-1); var point = ConsoleCursorGetCurrentPosition(); if (point != null) { ConsoleCursorFillLines(point.Value.Top, point.Value.Top, ‘ ‘); //清除前一行显示字符 Console.WriteLine($"出行日期:{FormatDate(dest)}"); //更新输出日期 } OutputBookingDay(preSaleDays, dest); } else { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("输入错误"); //显示输出错误 Console.ForegroundColor = DefaultForegroundColor; ConsoleCursorRelativeLine(-3); //光标向上移动3行 var point = ConsoleCursorGetCurrentPosition(); if (point != null) { ConsoleCursorFillLines(point.Value.Top, point.Value.Top + 1, ‘ ‘); } } } Console.WriteLine(); } } static void InputToExit(string input) { if (input.Equals("exit", StringComparison.OrdinalIgnoreCase)) { Environment.Exit(0); //用户退出 } } static void ShowHelp() { //帮助提示 var appname = Path.GetFileName(Environment.GetCommandLineArgs()[0]); Console.WriteLine(" * 参数格式:"); Console.WriteLine($" {appname} <火车票预售期>"); Console.WriteLine($" {appname} <火车票预售期> <出行日期> [nopause]"); Console.WriteLine($" {appname} <火车票预售期> now [nopause]"); Console.WriteLine($"\n * 例子:预售期{DefaultPreSaleDays}天,查看今天可以预定哪天火车票"); Console.WriteLine($" {appname} 60 now"); Console.WriteLine("\n * 批处理:"); Console.WriteLine($" {appname} 60 now nopause|Find \"出行日期:\""); Console.WriteLine(); } static void ShowHelpAndExit(int exitcode) { ShowHelp(); //显示帮助提示然后按任意键退出 Console.Write("按任意键退出..."); Console.ReadKey(true); Environment.Exit(exitcode); //返回错误码(errorlevel) } static string FormatDate(DateTime date) { ConsoleColor? cc; return FormatDate(date, out cc); //格式化日期 } private static readonly string[] DayOfWeek = { "周日", "周一", "周二", "周三", "周四", "周五", "周六" }; private static string FormatDate(DateTime date, out ConsoleColor? consoleColor) { var d = (date.Date - DateTime.Now.Date).Days; string tip; switch (d) { case -2: tip = "(前天)"; break; case -1: tip = "(昨天)"; break; case 0: tip = "(今天)"; break; case 1: tip = "(明天)"; break; case 2: tip = "(后天)"; break; default: tip = $"({DayOfWeek[(int) date.DayOfWeek]})"; break; } consoleColor = d >= 0 ? ConsoleColor.Green : ConsoleColor.Yellow; var chinaCalendarString = ConvertToChineseLunisolarCalendar(date); return $"{date:yyyy-M-d}{tip}{chinaCalendarString}"; } private static void OutputBookingDay(int days, DateTime destDate) { var date = destDate.AddDays(-days + 1); ConsoleColor? cc; var formattedDest = FormatDate(date, out cc); Console.ForegroundColor = DefaultForegroundColor; Console.Write("预售日期:"); //用缺省前景色显示“预售日期:”这几个字 if (cc.HasValue) { Console.ForegroundColor = cc.Value; //更换前景色 } Console.WriteLine(formattedDest); //按格式输出预售日期 Console.ForegroundColor = DefaultForegroundColor; //还原缺省前景色 } private static void ConsoleCursorRelativeLine(int rows) { //将ConsoleCursor操作封装成方法,加入try语句,防止在非控制台下输出造成异常,下同 try { var t = Console.CursorTop + rows; //相对行号 Console.SetCursorPosition(0, t); //移动光标到相对行 } catch { // ignored } } private static void ConsoleCursorFillLines(int startLine, int endLine, char @char) { var d = endLine - startLine + 1; if (d > 0) { var consoleCursorGetCurrentPosition = ConsoleCursorGetCurrentPosition(); if (consoleCursorGetCurrentPosition != null) { var point = consoleCursorGetCurrentPosition.Value; Console.SetCursorPosition(0, startLine); //光标移动到起始行 Console.Write(new string(@char, Console.BufferWidth*d)); //用字符填满指定行数(d) Console.SetCursorPosition(point.Left, point.Top); //返回光标原来的位置 } } } private static Point? ConsoleCursorGetCurrentPosition() { try { return new Point(Console.CursorLeft, Console.CursorTop); //返回光标位置 } catch { // ignored } return null; //失败 } private struct Point { public readonly int Left; public readonly int Top; public Point(int left, int top) { Left = left; Top = top; } } private static readonly ChineseLunisolarCalendar ChinaCalendar = new ChineseLunisolarCalendar(); private static readonly string[] M1 = { "正月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "腊月" }; private static readonly string[] D1 = { "初", "十", "廿", "三" }; private static readonly string[] D2 = { "一", "二", "三", "四", "五", "六", "七", "八", "九" }; private static readonly string[] D3 = { "初十", "二十", "三十" }; private static string CcDay(int d) { var dd = d%10; return dd == 0 ? $"{D3[d/10-1]}" : $"{D1[d/10]}{D2[dd-1]}"; } private static string CcMonth(int y, int m) { var leapMonth = 0; if (ChinaCalendar.IsLeapYear(y)) { for (int i = 1; i <= m; i++) { if (ChinaCalendar.IsLeapMonth(y, i)) { leapMonth = i; break; } } if (m == leapMonth) { return $"闰{M1[m - 2]}"; } if (leapMonth > 0) { return $"{M1[m - 2]}"; } } return $"{M1[m - 1]}"; } private static string ConvertToChineseLunisolarCalendar(DateTime date) { if (date > ChinaCalendar.MaxSupportedDateTime || date < ChinaCalendar.MinSupportedDateTime) { return ""; } var y = ChinaCalendar.GetYear(date); var m = ChinaCalendar.GetMonth(date); // 1~13 var d = ChinaCalendar.GetDayOfMonth(date); // 1~31 return $"{CcMonth(y, m)}{CcDay(d)}"; } }
时间: 2024-11-15 20:50:47