Parsowanie daty w formacie DD-MM-RRRR

0

Treść:
Napisać program, który pobierze datę w formacie DD-MM-RRRR, z której pobierze miesiąc i wyświetli jego nazwę słownie.

Kod:

 Console.WriteLine("Podaj datę w formacie |dzień,miesiąc,rok| : ");
 string n;
 n = Console.ReadLine();
 string miesiac;

 miesiac = n.Substring(3, 2);
           
            if (miesiac == "01")
                Console.Write("luty");
            else if (miesiac == "02")
                Console.Write("styczeń");
            else if (miesiac == "03")
                Console.Write("marzec");
            else if (miesiac == "04")
                Console.Write("kwiecien");
            else if (miesiac == "05")
                Console.Write("maj");
            else if (miesiac == "06")
                Console.Write("czerwiec");
            else if (miesiac == "07")
                Console.Write("lipiec");
            else if (miesiac == "08")
                Console.Write("sierpień");
            else if (miesiac == "09")
                Console.Write("wrzesień");
            else if (miesiac == "10")
                Console.Write("pazdziernik");
            else if (miesiac == "11")
                Console.Write("listopad");
            else if (miesiac == "12")
                Console.Write("grudzień");
                
      if (miesiac[1] > 2 || miesiac[0] > 1)
            {
                Console.WriteLine("Nie ma takiego miesiąca");
            }

Chciałbym zoptymalizować ten program. Nie chce mieć tylu if tylko pętle. Próbowałem z foreach() albo for ale zawsze były potrzebne te if

Czy istnieje jakaś metoda z Klasy Array lub String która zamienia datę na tekst?

Albo w chwili wczytywania zmiennej "n" mogę zmienić typ zmiennej na datę?

Z góry dzięki:)

1

Stwórz tablice miesiecy.
nastepnie możesz swoje dane wejsciowe rozłączyć (??) (chodzi mi o split) na podstawie "-"
Dzieki temu będziesz mógł wziąć sobie odpowiedni index za pomocą Miesiace[miesiac +1] wczesniej tylko walidacja.
dzieki splitowi będziesz miał to w jednej polu w tablicy wiec walidacja sprowadzi się do sprawdzenia czy miesiąc jest 1> i <12

PS. Przy tak dużej konstrukcji powinienś już raczej użyć instrukcji switch

3

Jak sobie wyobrażasz zastąpienie warunku logicznego pętlą? Podpowiem: nie da się.

Jest kilka opcji innego podejścia do tematu.

1a) Zamiast masy ifów możesz zrobić switch:

switch (miesiac)
{
    case "01": Console.WriteLine("Styczeń"); break;
    // ...
    default:
      Console.WriteLine("Nie ma takiego miesiąca");
      break;
   
}

1b)

            Console.WriteLine(month switch
            {
                "01" => "Styczeń",
                // ...
                _ => "Nie ma takiego miesiąca"
            });
  1. Słownik
           var month = "01";
            var monthNames = new Dictionary<string, string>()
            {
                { "01", "styczeń" },
                { "02", "lucień" },
                // ...
            };

            Console.WriteLine(monthNames.ContainsKey(month) ? monthNames[month] : "Nieprawidłowy miesiąc");

3a) Użyj istniejacych narzędzi

            if (int.TryParse(month, out var intMonth) && intMonth >= 1 && intMonth <= 12)
            {
                var mfi = new System.Globalization.DateTimeFormatInfo(); // lub new CultureInfo("PL").DateTimeFormat lub CultureInfo.CurrentCulture.DateTimeFormat
                Console.WriteLine(mfi.GetMonthName(intMonth));
            }
            else
                Console.WriteLine("...");

3b) jak w 3a, ale wnętrze warunku to

    var monthName = new DateTime(2000, intMonth, 1).ToString("MMMM", CultureInfo.CurrentCulture);
    Console.WriteLine(mfi.GetMonthName(intMonth));
  1. 3b w nieco bardziej cywilizowany sposób:
        private string GetMonthName(int month)
        {
            if (month >= 1 && month <= 12)
                return CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(month);
            throw new ArgumentOutOfRangeException(nameof(month));
        }

        private string GetMonthName(string monthNumber)
        {
            if (int.TryParse(monthNumber, out var intMonth))
                return GetMonthName(intMonth);
            throw new ArgumentOutOfRangeException(nameof(monthNumber));
        }

        private bool TryGetMonthName(string monthNumber, out string monthName)
        {
            monthName = default;
            try {
                monthName = GetMonthName(monthNumber);
                return true;
            }
            catch { return false; }
        }

i wywołanie

            var month = "01";
            Console.WriteLine(TryGetMonthName(month, out var monthName) ? monthName : "Nieprawidłowy miesiąc");
4

Jak już nauczysz się tablic, struktur kontrolnych to info - nie rób tak. Operacje na datach, parsowanie, ToString etc. są już w bibliotece standardowej, np.

Console.WriteLine(DateTime.Now.ToString("dd MMMM yyyy", System.Globalization.CultureInfo.GetCultureInfo("pl-PL"))); // 08 listopada 2022
4
ŁF napisał(a):

Jak sobie wyobrażasz zastąpienie warunku logicznego pętlą? Podpowiem: nie da się.

a jednak:

            bool x=true;
            if(x) do_something();
            while(x) { do_something(); break; }
            for(bool f=true;(x)&&(f);f=false) do_something();

Ale nie powtarzać tego ani w domu ani na produkcji!

1
Zygwryd napisał(a):

Treść:
Napisać program, który pobierze datę w formacie DD-MM-RRRR, z której pobierze miesiąc i wyświetli jego nazwę słownie.

Kod:

 Console.WriteLine("Podaj datę w formacie |dzień,miesiąc,rok| : ");

Troszkę uspokój myślenie.
Póki co, to sam proponujesz userowi przecinki

1 użytkowników online, w tym zalogowanych: 0, gości: 1