Задать номер месяца по его названию. C#

272
14 марта 2018, 03:48

Имеется ComboBox, который хранит месяца года в текстовом формате. Как можно записать номер месяца в DataTime?

Там где происходит добавление месяцев в список, нужный мне номер месяца сохранить сразу не могу, так как нужен выбор пользователя.

for (int i = 1; i <= 12; i++)
{
   cmbMonth.Items.Add(now.ToString("MMMM"));
   now = now.AddMonths(1);
   cmbMonth.Text = DateTime.Now.ToString("MMMM");
}

Нужно из cmbMonth.Text получить название месяца, что бы записать полноценную дату выбранную пользователем. Но так-как месяца хранятся в виде текста, возникли проблемы. Как можно решить? (Писать цикл с месяцами и их номерами не вариант, так как текст месяца в ComboBox зависит от языка системы)

Answer 1

Для перевода из String в DataTime есть пара хороших методов Parse и ParseExact. Вот второй и подойдет для данной задачи!

Суть следующая - Вы ему даете 3 аргумента:

  1. string, где есть значения связанные со временем (будь то время, дата, месяц или еще что).
  2. Некая маска, по которой метод ParseExact поймет, что находится в пункте 1.
  3. Культура пользователя или указанная заранее.

Напишу пример к вашей задаче:

var m = "Декабрь";
DateTime dd = DateTime.ParseExact(m, "MMMM", System.Globalization.CultureInfo.CurrentCulture);
Console.WriteLine(dd);

Как видим я задал 3 параметра - месяц (декабрь), маска (полный формат месяца) и культура (текущая культура пользователя).

Результатом программа выдаст:

01.12.2018 0:00:00

Надеюсь это решит вашу проблему. Удачи!

Answer 2

Небольшой пример работы с комбобоксом, где в качестве элемента будет не строка, а наш класс.

class MyForm : Form
{
    public MyForm()
    {
        var cb = new ComboBox();
        var currMonth = DateTime.Now.AddDays(-DateTime.Now.Day + 1);
        for (var i = 0; i < 12; i++)
        {
            var dt = currMonth.AddMonths(i);
            cb.Items.Add(new MonthItem { Id = dt.Month, Text = dt.ToString("MMMM") });
        }
        cb.DisplayMember = "Text";
        cb.SelectedIndexChanged += (sender, args) =>
        {
            var m = (cb.SelectedItem as MonthItem);
            if (m != null)
            {
                MessageBox.Show($"Selected {m.Text} with ID = {m.Id}");
            }
        };
        this.Controls.Add(cb);
    }
    private class MonthItem
    {
        public int Id { get; set;}
        public string Text { get; set;}
    }
}

И как результат

Answer 3

Вероятно, лучше хранить в комбобоксе непосредственно значения DateTime. При этом настроить формат комбобокса для отображения в желаемом виде.

Значение cmbKuu.Text достаточно установить один раз, вынеся его из цикла. Кроме того, следует предусмотреть тот почти невероятный случай, когда между выполнением двух операторов произойдёт смена месяца на компьютере, в результате чего в cmbKuu может оказаться следующий месяц. Поэтому не вызываем DateTime.Now дважды.

var now = DateTime.Now;
cmbMonth.FormattingEnabled = true;
cmbMonth.FormatString = "MMMM";
cmbKuu.Text = now.ToString("MMMM");
for (int i = 1; i <= 12; i++)
{
    cmbMonth.Items.Add(now);
    now = now.AddMonths(1);
}

Теперь в обработчике события можно получить выбранное значение DateTime и использовать его свойства.

private void CmbMonth_SelectedIndexChanged(object sender, EventArgs e)
{
    var dateTime = (DateTime)cmbMonth.SelectedItem;
    // используем dateTime.Month
}
READ ALSO
Вызов конструктора наследуемого типа C#

Вызов конструктора наследуемого типа C#

ЗдравствуйтеУ меня есть вопрос, возможно ли вызвать конструктор объекта, если точно не знаешь какого он типа? От одного базового класса наследуются...

266
GetHashCode() и Equals() в Hashtable

GetHashCode() и Equals() в Hashtable

Имеется следующий код:

187
Написание текста в чат игры [требует правки]

Написание текста в чат игры [требует правки]

Тема такая: Нужно в игровой чат написать сообщение

218