Объединение даты и времени списка

#c# #linq

#c# #linq

Вопрос:

Я получаю ошибку, приведенную ниже. Код работает нормально, когда число равно 1, но когда я использую string .присоединяюсь и пытаюсь преобразовать начальную дату, я получаю эту ошибку? Есть ли лучший способ отформатировать этот список?

The string was not recognized as a valid DateTime. There is an unknown word starting at index 0.

  static void Main(string[] args)
        {
            try
            {
                List<Meeting> Meeting = new List<Meeting>();
                List<MeetingDates> ListOfMeetingDates = new List<MeetingDates>();
                ListOfMeetingDates.Add(new MeetingDates() { MeetingDatesId = 1, StartDate= "11-1-2020"});
                ListOfMeetingDates.Add(new MeetingDates() { MeetingDatesId = 2, StartDate = "11-2-2020" });
                ListOfMeetingDates.Add(new MeetingDates() { MeetingDatesId = 3, StartDate = "11-3-2020" });
                Meeting.Add(new Meeting() { Meetingid = 1, MeetingName="a",ListOfMeetingDates= ListOfMeetingDates });
                var listOfMeetings = Meeting
                    .Select(x => new MeetingViewModel
                    {
                        MeetingName = x.MeetingName,
                        MeetingDate = GetDateRangeFormatted(x.ListOfMeetingDates)
                     }).ToList();

            }
            catch (Exception ex)
            {
                ex.ToString();
            }
        }
        private static string GetDateRangeFormatted(IEnumerable<MeetingDates> meetingDates)
        {
            if (meetingDates.Count() == 0)
                return "";
            if (meetingDates.Count() == 1)
                return Convert.ToDateTime(meetingDates.First().StartDate).ToString("MMMM dd yyyy");
            return string.Join(" - ", Convert.ToDateTime(meetingDates.Select(d => d.StartDate).ToString()).ToString("MMMM dd yyyy"));
        }
        class Meeting
        {
            public int Meetingid { get; set; }
            public string MeetingName { get; set; }

            public List<MeetingDates> ListOfMeetingDates { get; set; }
        }
        class MeetingDates
        {
            public int MeetingDatesId { get; set; }
            public string StartDate { get; set; }
        }
        class MeetingViewModel
        {
            public string MeetingName { get; set; }
            public string MeetingDate { get; set; }
        }
 

Комментарии:

1. только что система была построена, и я не хотел ничего менять

2. Не используйте Convert. ToDateTime .. и остановитесь со всеми операциями от строки до даты к строке до даты.. просто укажите даты и время, потому что «11-3-2020» — это либо 3 ноября, либо 11 марта, в зависимости от того, где находится компьютер, но new DateTime(2020,3,11) не ошибается и не зависит от настроек культуры.. он начинается как datetime и, таким образом, может существовать всю свою жизнь, пока вы не отформатируете его в строку непосредственно перед отображением

3. Проблема в вашей string.Join строке. Порядок, в котором вы вызываете Convert.ToDateTime vs meetingDates.Select , обратный. Есть ли какая-то конкретная причина, по которой ваши свойства даты являются string , а не DateTime или DateTimeOffset ?

4. Я не уверен в причине, по которой я не могу ее изменить

5. Не могли бы вы уточнить? Почему ты не можешь это изменить? Откуда берутся данные?

Ответ №1:

Вы можете попытаться изменить код из:

 return string.Join(" - ", Convert.ToDateTime(meetingDates.Select(d => d.StartDate).ToString()).ToString("MMMM dd yyyy"));
 

Для:

 var dates = meetingDates.Select(d => new {dt = Convert.ToDateTime(d.StartDate).ToString("MMMM dd yyyy")}).ToList();
        return string.Join(" - ", dates.Select(s => s.dt));
 

Это должно сработать, но было бы лучше использовать тип DateTime для дат

Ответ №2:

Короткий ответ

Эта строка:

 return string.Join(" - ", Convert.ToDateTime(meetingDates.Select(d => d.StartDate).ToString()).ToString("MMMM dd yyyy"));
 

Должно быть написано так:

 return string.Join(" - ", meetingDates.Select(d => Convert.ToDateTime(d.StartDate).ToString("MMMM dd yyyy")));
 

Несколько советов

При отладке ошибки в сложном, составном операторе, подобном этому, разбейте его на отдельные части. Если вы сделаете это с вашим исходным оператором, вы получите следующее:

 var step1 = meetingDates.Select(d => d.StartDate);
var step2 = step1.ToString();
var step3 = Convert.ToDateTime(step2);
var step4 = step3.ToString("MMMM dd yyyy");
var step5 = string.Join(" - ", step4);  
return step5;
 

Если проблема не возникает у вас сразу после того, как вы это сделали, используйте IntelliSense в VisualStudio для проверки каждого шага. В этом случае обратите внимание, что тип step1 является an IEnumerable<string> . Когда вы вызываете ToString это, вы получаете строку «System.Linq.Enumerable SelectListIterator`2[Запрос пользователя даты собраний, система.Строка]». Когда вы передаете это значение Convert.ToDateTime , вы получаете исключение.

Длинный ответ

Как упоминалось в нескольких комментариях, вы действительно хотите избежать работы с датами в строках, если это возможно. При работе с датами вам может потребоваться знать языковой стандарт / культуру. Например, «11-3-2020» может означать «3 ноября 2020 года» или «11 марта 2020 года», в зависимости от локали. При работе со временем также необходимо учитывать часовой пояс.

Это поможет лучше понять общую картину. Данные, с которыми вы работаете, изначально были созданы чем-то и помещены в базу данных. В идеале вы хотели бы преобразовать и сохранить даты так, чтобы они были представлены в вашей модели EF в виде двоичного DateTime или DateTimeOffset . Если вы действительно не можете это контролировать, то лучший способ преобразовать строки в даты — использовать DateTime.Синтаксический анализ или дата-время.Синтаксический анализ завершается.