doeNET Framework 农历 ChineseLunisolarCalendar

C:Program Files (x86)MSBuild14.0Bincsc.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($"
 * 火车票预售期为:{preSaleDays}天

出行日期:{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("
按任意键退出...");
                    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}
");
                }
            }
        }
        Console.WriteLine($"
 * 火车票预售期为:{preSaleDays}天");
        Console.WriteLine($" * 今天可以预定 {FormatDate(DateTime.Now.AddDays(preSaleDays - 1))} 的火车票");
        Console.WriteLine(" * 输入 exit 可退出程序,输入 g 打开12306订票网站
");
        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($"
 * 例子:预售期{DefaultPreSaleDays}天,查看今天可以预定哪天火车票");
        Console.WriteLine($"   {appname} 60 now");
        Console.WriteLine("
 * 批处理:");
        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 readonly string[] DayOfToday = { "前天", "昨天", "今天", "明天", "后天" };

    private static string FormatDate(DateTime date, out ConsoleColor? consoleColor)
    {
        var d = (date.Date - DateTime.Now.Date).Days;
        var tip = d>=-2 && d<=2 ? $"({DayOfToday[d+2]})" : $"({DayOfWeek[(int) date.DayOfWeek]})";
        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)}";
    }        
}
原文地址:https://www.cnblogs.com/Bob-wei/p/5126365.html