Ввод даты в консольном приложении

96
04 июля 2021, 22:20

Пишу программу в С#, которая предполагает простое анкетирование пользователей с последующем выводом данных.

Как правильно организовать в консольном приложении C# получение от пользователя данных о дате его рождения?

Answer 1

Сделайте метод, который в цикле опрашивает ввод, пока не будет введено правильное значение:

DateTime inputDoB()
{
    DateTime dob; // date of birth
    string input;
    do
    {
        Console.WriteLine("Введите дату рождения в формате дд.ММ.гггг (день.месяц.год):");
        input = Console.ReadLine();
    }
    while (!DateTime.TryParseExact(input, "dd.MM.yyyy", null, DateTimeStyles.None, out dob));
    return dob;
}

Использование:

var dob = inputDoB();

Можно задать произвольный формат вводимой даты. Например, "d.M.yyyy", что позволит вводить дату в виде 1.4.2017.

Answer 2

Всё зависит от ваших требований, если достаточно простого ручного ввода, то можно воспользоваться одним из ответов, присланных ранее.

Если вы реализуете консольный графический интерфейс, можно придумать что-то наподобие такого:

class ConsoleDatePicker
{
    public int Left { get; set; }
    public int Top { get; set; }
    public DateTime SelectedDate { get; set; }
    public ConsoleDatePicker(int left, int top)
    {
        Left = left;
        Top = top;
        SelectedDate = DateTime.Today;
    }
    public ConsoleDatePicker() : this(0, 0) { }
    string[] months = { "янв", "фев", "мар", "апр", "май", "июн", "июл", "авг", "сен", "окт", "ноя", "дек" };
    public void Show()
    {
        int oldLeft = Console.CursorLeft, oldTop = Console.CursorTop;
        ShowFrame();
        ShowMonth();
        ShowCursor();
        Console.SetCursorPosition(oldLeft, oldTop);
    }
    void ShowFrame()
    {
        Console.SetCursorPosition(Left, Top);
        Console.Write("╔══════════════════════╗");
        Console.SetCursorPosition(Left, Top + 1);
        Console.Write("║                      ║");
        Console.SetCursorPosition(Left, Top + 2);
        Console.Write("╟──────────────────────╢");
        for (int topAdd = 3; topAdd <= 15; ++topAdd)
        {
            Console.SetCursorPosition(Left, Top + topAdd);
            Console.Write("║                      ║");
        }
        Console.SetCursorPosition(Left, Top + 16);
        Console.Write("╚══════════════════════╝");
    }
    void ShowMonth()
    {
        Console.SetCursorPosition(Left, Top + 1);
        Console.Write($"║       {months[SelectedDate.Month - 1]} {SelectedDate.Year:0000}       ║");
        string[,] days = new string[6, 7];
        int week = 0;
        int dayOfWeek = (int)FirstDayOfMonth(SelectedDate).DayOfWeek - 1;
        if (dayOfWeek == -1) dayOfWeek = 6;
        int daysInMonth = LastDayOfMonth(SelectedDate).Day;
        for (int day = 1; day <= daysInMonth; ++day)
        {
            days[week, dayOfWeek] = $"{day,2}";
            ++dayOfWeek;
            if (dayOfWeek == 7)
            {
                ++week;
                dayOfWeek = 0;
            }
        }
        for (int row = 0; row < 6; ++row)
            for (int column = 0; column < 7; ++column)
            {
                Console.SetCursorPosition(Left + 2 + column * 3, Top + 4 + row * 2);
                Console.Write(days[row, column] ?? "  ");
            }
    }
    void ShowCursor()
    {
        int column = (int)SelectedDate.DayOfWeek - 1;
        if (column == -1) column = 6;
        int row = (SelectedDate.Day + (int)FirstDayOfMonth(SelectedDate).DayOfWeek - 2) / 7;
        Console.SetCursorPosition(Left + 1 + column * 3, Top + 3 + row * 2);
        Console.Write("┌──┐");
        Console.SetCursorPosition(Left + 1 + column * 3, Top + 4 + row * 2);
        Console.Write("│");
        Console.SetCursorPosition(Left + 4 + column * 3, Top + 4 + row * 2);
        Console.Write("│");
        Console.SetCursorPosition(Left + 1 + column * 3, Top + 5 + row * 2);
        Console.Write("└──┘");
    }
    void EraseCursor()
    {
        int column = (int)SelectedDate.DayOfWeek - 1;
        if (column == -1) column = 6;
        int row = (SelectedDate.Day + (int)FirstDayOfMonth(SelectedDate).DayOfWeek - 2) / 7;
        Console.SetCursorPosition(Left + 1 + column * 3, Top + 3 + row * 2);
        Console.Write("    ");
        Console.SetCursorPosition(Left + 1 + column * 3, Top + 4 + row * 2);
        Console.Write(" ");
        Console.SetCursorPosition(Left + 4 + column * 3, Top + 4 + row * 2);
        Console.Write(" ");
        Console.SetCursorPosition(Left + 1 + column * 3, Top + 5 + row * 2);
        Console.Write("    ");
    }
    DateTime FirstDayOfMonth(DateTime date)
    {
        return new DateTime(date.Year, date.Month, 1);
    }
    DateTime LastDayOfMonth(DateTime date)
    {
        return FirstDayOfMonth(date.AddMonths(1)).AddDays(-1);
    }
    public DateTime GetDate()
    {
        int oldLeft = Console.CursorLeft, oldTop = Console.CursorTop;
        bool cursorVisible = Console.CursorVisible;
        Console.CursorVisible = false;
        ConsoleKeyInfo key;
        do
        {
            Console.SetCursorPosition(oldLeft, oldTop);
            key = Console.ReadKey();
            DateTime newDate = SelectedDate;
            if (key.Key == ConsoleKey.RightArrow) newDate = SelectedDate.AddDays(1);
            if (key.Key == ConsoleKey.LeftArrow) newDate = SelectedDate.AddDays(-1);
            if (key.Key == ConsoleKey.DownArrow) newDate = SelectedDate.AddDays(7);
            if (key.Key == ConsoleKey.UpArrow) newDate = SelectedDate.AddDays(-7);
            if (newDate != SelectedDate)
            {
                EraseCursor();
                bool changeMonth = newDate.Month != SelectedDate.Month;
                SelectedDate = newDate;
                if (changeMonth) ShowMonth();
                ShowCursor();
            }
        }
        while (key.Key != ConsoleKey.Enter);
        Console.CursorVisible = cursorVisible;
        Console.SetCursorPosition(oldLeft, oldTop);
        return SelectedDate;
    }
}

Использовать можно так:

        ConsoleDatePicker cdp = new ConsoleDatePicker(5, 5);
        cdp.Show();
        DateTime date = cdp.GetDate();
        Console.WriteLine("Вы выбрали {0:d}", date);

Еще один вариант для использования в консольном GUI, более простой, менее громоздкий и, скорее всего, более удобный. Без использования псевдографики, поэтому не зависит от используемой кодовой страницы (хотя в разных культурах представление даты должно быть разным dd.MM.yyyy/yyyy-MM-dd - при желании реализуете самостоятельно).

class ConsoleDatePickerMini
{
    public int Left { get; }
    public int Top { get; }
    public DateTime SelectedDate { get; private set; }
    public ConsoleDatePickerMini(int left, int top, DateTime date)
    {
        Left = left;
        Top = top;
        SelectedDate = date;
    }
    public ConsoleDatePickerMini(int left, int top) : this(left, top, DateTime.Today) { }
    public ConsoleDatePickerMini() : this(0, 0) { }
    public void Show()
    {
        int oldLeft = Console.CursorLeft, oldTop = Console.CursorTop;
        ShowDate();
        Console.SetCursorPosition(oldLeft, oldTop);
    }
    public DateTime GetDate()
    {
        int oldLeft = Console.CursorLeft, oldTop = Console.CursorTop;
        bool cursorVisible = Console.CursorVisible;
        Console.CursorVisible = false;
        int f = 0;
        ConsoleKeyInfo key;
        do
        {
            ShowCursor(f);
            Console.SetCursorPosition(oldLeft, oldTop);
            key = Console.ReadKey();
            if (key.Key == ConsoleKey.RightArrow) f = (f + 1) % 3;
            if (key.Key == ConsoleKey.LeftArrow) f = (f + 2) % 3;
            if (key.Key == ConsoleKey.UpArrow ||
                key.Key == ConsoleKey.DownArrow)
            {
                int additive = key.Key == ConsoleKey.UpArrow ? 1 : -1;
                if (f == 0) SelectedDate = SelectedDate.AddDays(additive);
                else if (f == 1) SelectedDate = SelectedDate.AddMonths(additive);
                else if (f == 2) SelectedDate = SelectedDate.AddYears(additive);
            }
            ShowDate();
        }
        while (key.Key != ConsoleKey.Enter);
        Console.CursorVisible = cursorVisible;
        Console.SetCursorPosition(oldLeft, oldTop);
        return SelectedDate;
    }
    void ShowDate()
    {
        Console.SetCursorPosition(Left, Top);
        Console.Write("          ");
        Console.SetCursorPosition(Left, Top + 1);
        Console.Write(SelectedDate.ToString("dd.MM.yyyy"));
        Console.SetCursorPosition(Left, Top + 2);
        Console.Write("          ");
    }
    void ShowCursor(int field)
    {
        int offset = new[] { 1, 4, 9 }[field]; // или по хакерски: int offset = (field + 1) * (field + 1);
        Console.SetCursorPosition(Left + offset, Top);
        Console.Write("+");
        Console.SetCursorPosition(Left + offset, Top + 2);
        Console.Write("-");
    }
}

Использование аналогично предыдущему. Выглядит так:

Answer 3

Попробуйте так:

Console.WriteLine("Введите дату рождения в формате (DD.MM.YYYY): \n");
string input = Console.ReadLine();
string[] split = input.Split('.');
double day = Double.Parse(split[0]);
double month = Double.Parse(split[1]);
double year = Double.Parse(split[2]);
READ ALSO
Формирование сообщения рукопожатия

Формирование сообщения рукопожатия

На странице спецификации протокола BitTorrent, сказано, что сообщение рукопожатия, должно быть отправлено первым, после подключенияИ указано...

104
Последовательность нажатия клавиш

Последовательность нажатия клавиш

Как выполнить открытие формы, после нажатия определенной последовательности клавиш (стрелок) на клавиатуре? Прошу предоставить пример кода,...

77
Задать авторазмер UserControl передаваемого в TabPage

Задать авторазмер UserControl передаваемого в TabPage

Есть отдельный UserControl, который я передаю в TabPage и юзаю его в TabControl

84
Множественное использование UserControl

Множественное использование UserControl

Работаю с WPF с применением паттерна MVVMСтолкнулся с проблемой, создал UserControl(далее UC) один общий который будет несколько раз использоваться:

123