#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
vsmeetingDates.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.Синтаксический анализ или дата-время.Синтаксический анализ завершается.