Как отобразить DateTime в определенном формате в ASP.NET MVC 3?

117

Если в моем классе модели есть свойство типа, DateTimeкак я могу отобразить его в определенном формате - например, в формате, который ToLongDateString()возвращается?

Я пробовал это ...

@Html.DisplayFor(modelItem => item.MyDateTime.ToLongDateString())

... который вызывает исключение, потому что выражение должно указывать на свойство или поле. И это...

@{var val = item.MyDateTime.ToLongDateString();
  Html.DisplayFor(modelItem => val);
}

... который не вызывает исключения, но выводимый результат пуст (хотя и valсодержит ожидаемое значение, как я мог видеть в отладчике).

Заранее спасибо за советы!

редактировать

ToLongDateStringэто только пример. На самом деле я хочу использовать вместо этого ToLongDateStringсобственный метод расширения DateTimeи DateTime?:

public static string FormatDateTimeHideMidNight(this DateTime dateTime)
{
    if (dateTime.TimeOfDay == TimeSpan.Zero)
        return dateTime.ToString("d");
    else
        return dateTime.ToString("g");
}

public static string FormatDateTimeHideMidNight(this DateTime? dateTime)
{
    if (dateTime.HasValue)
        return dateTime.Value.FormatDateTimeHideMidNight();
    else
        return "";
}

Итак, я думаю, что не могу использовать DisplayFormatатрибут и DataFormatStringпараметр в свойствах ViewModel.

Slauma
источник

Ответы:

159

Если все, что вы хотите сделать, это отобразить дату в определенном формате, просто позвоните:

@String.Format(myFormat, Model.MyDateTime)

Использование @Html.DisplayFor(...)- это просто дополнительная работа, если вы не указываете шаблон или вам нужно использовать что-то, построенное на шаблонах, например повторение файла IEnumerable<T>. Создать шаблон достаточно просто, но он также может обеспечить большую гибкость. Создайте папку в папке представлений для текущего контроллера (или папки общих представлений) с именем DisplayTemplates. Внутри этой папки добавьте частичный вид с типом модели, для которого вы хотите создать шаблон. В этом случае я добавил /Views/Shared/DisplayTemplatesи добавил частичное представление под названием ShortDateTime.cshtml.

@model System.DateTime

@Model.ToShortDateString()

И теперь вы можете вызвать этот шаблон со следующей строкой:

@Html.DisplayFor(m => m.MyDateTime, "ShortDateTime")
Ник Ларсен
источник
Спасибо, выглядит хорошо, и этот параметр шаблона ("ShortDateTime") также решает проблему, которую я описал в моем комментарии к ответу ataddeini.
Slauma
3
Если тип - «DateTime?» вместо «DateTime» (@model DateTime?) ... шаблон ciplay будет обрабатывать дату и время, допускающие или не допускающие значения NULL. Имя файла должно оставаться «DateTime.cshtml».
Romias 02
+1 Пришлось это прокомментировать, у меня приложение отлично поработало! Спасибо!
Рассел Кристенсен,
Использование @ Html.DisplayFor () не является дополнительной работой, оно отображает html-представление модели даже без шаблонов .... не путайте ...
Cabuxa.Mapache
stackoverflow.com/questions/19920603/… содержит код, который полезен при работе с датами, допускающими значение NULL, о которых упоминает @Romias.
Вальтер де Йонг,
171

Вы можете украсить свойство модели представления [DisplayFormat]атрибутом:

[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", 
               ApplyFormatInEditMode = true)]
public DateTime MyDateTime { get; set; }

и на ваш взгляд:

@Html.EditorFor(x => x.MyDate)

или, для отображения значения,

@Html.DisplayFor(x => x.MyDate)

Другой вариант, который я не рекомендую, - это использовать слабо типизированный помощник:

@Html.TextBox("MyDate", Model.MyDate.ToLongDateString())
Дарин Димитров
источник
1
@Darin: Мне не нужен элемент ввода, а нужен только статический текст. Я также должен упомянуть, что фактический формат создается специальным методом расширения DateTime(ToLongDateString был только примером), поэтому маловероятно, что я смогу использовать DataFormatString.
Slauma
2
@Slauma, как насчет @Html.DisplayFor(x => x.MyDateTime). @NickLarsen - вот почему следует использовать модели просмотра. В моем примере я украшаю модель представления этим атрибутом, и представление уже привязано к данному представлению, это его цель.
Дарин Димитров
1
@Slauma, ОК, в этом случае вы можете либо использовать настраиваемый шаблон отображения, либо использовать в своей модели представления строковое свойство, и преобразование будет выполняться на слое сопоставления при сопоставлении модели и модели представления (таким образом вы могли бы по-прежнему используйте только Html.DisplayFor в представлении).
Дарин Димитров
5
@NickLarsen, нет, это одна модель представления на представление. Именно из-за того, что люди совершают эту ошибку, возникает вопрос: как исключить некоторые свойства из проверки в одном действии контроллера, а не в другом? так распространены на SO.
Дарин Димитров
1
Возвращаясь к этому вопросу годом позже, я согласен с аргументом в пользу одной модели на представление. Я все еще думаю, что все, что связано с выбором дисплея, относится к виду, а не к модели.
Ник Ларсен,
26

Простой форматированный вывод внутри модели

@String.Format("{0:d}", model.CreatedOn)

или в цикле foreach

@String.Format("{0:d}", item.CreatedOn)
odesuk
источник
Похоже на дубликат принятого ответа об использованииstring.Format
Пол Тынг
2
@PaulTyng этот ответ был для меня более ясным, чем принятый ответ, odesuk фактически показал формат в первом параметре, который, как новичок, мне помогает.
Дэн Больё
1
Я согласен, это тот ответ, который мне помог.
Гленн
26

Я использую следующий подход для встроенного формата и отображения свойства даты из модели.

@Html.ValueFor(model => model.MyDateTime, "{0:dd/MM/yyyy}")

В противном случае при заполнении TextBox или Editor вы могли бы сделать как предложил @Darin, украсив атрибут [DisplayFormat]атрибутом.

Стивен
источник
Это решение, которое я ищу!
Envil
Это решение, которое я искал!
Райхан Ридой
9

Если все ваши DateTimeтипы отображаются одинаково, вы можете использовать настраиваемый DateTimeшаблон отображения.

В папке представлений создайте папку с именем «DisplayTemplates» либо в папке конкретных представлений вашего контроллера, либо в папке «Общие» (они работают аналогично частичным).

Внутри создайте файл с именем, DateTime.cshtmlкоторый принимает DateTimeв качестве @modelкода и код того, как вы хотите отобразить дату:

@model System.DateTime
@Model.ToLongDateString()

Теперь вы можете просто использовать это в своих представлениях, и он должен работать:

@Html.DisplayFor(mod => mod.MyDateTime)

Пока вы следуете соглашению о добавлении его в папку «DisplayTemplates» и присваивании имени файлу в соответствии с отображаемым вами типом, MVC будет автоматически использовать это для отображения ваших значений. Это также работает для сценариев редактирования с использованием «EditorTemplates».

Вот еще немного информации о шаблонах .

ataddeini
источник
Спасибо, только что протестировал и работает нормально, если тип действительно DateTime. Однако у меня есть несколько свойств DateTime, допускающих значение NULL. Я попытался создать второй файл в DisplayTemplatesпапке с именем NullableDateTime.cshtmlи внутри: @using MyHelpers @model System.DateTime? @Model.MyCustomExtension()ЗдесьMyCustomExtension метод расширения DateTime?. Однако возникает исключение, когда DateTime? field действительно имеет значение null, что говорит мне, что для словаря требуется элемент модели, тип DateTimeкоторого не равен нулю. Есть ли способ определить DisplayTemplate для DateTime, допускающего значение NULL?
Slauma
@Slauma: Хм, хороший вопрос. Я бы, наверное, придерживалсяNullableDateTime.cshtml и использовал подход, который предложил и использовал @NickLarsen @Html.DisplayFor(m => m.MyDateTime, "NullableDateTime").
ataddeini
Вам не нужно явно добавлять имя шаблона, если ваш шаблон DateTime.cshtml установлен как "@model DateTime?" вместо DateTime. Таким образом, все даты (обнуляемые или нет) обрабатываются одним и тем же шаблоном ...
Ромиас
7

Я предпочитаю сохранять детали форматирования с представлением, а не с моделью представления. Итак, в MVC4 / Razor:

@Html.TextBoxFor(model => model.DateTime, "{0:d}");

Ссылка на формат datetime: http://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.71).aspx

Затем у меня есть привязанный к нему JQuery datepicker, и он помещает дату в другом формате ... doh!

Похоже, мне нужно установить формат datepicker в такое же форматирование.

Поэтому я сохраняю System.Globalizationформатирование в атрибуте data- * и собираю его при настройке

@Html.TextBoxFor(
    model => model.DateTime.Date, 
    "{0:d}", 
    new 
    { 
        @class = "datePicker", 
        @data_date_format=System.Globalization.CultureInfo
                          .CurrentUICulture.DateTimeFormat.ShortDatePattern 
    }));

И вот отстой: форматы .net и datepicker не совпадают, поэтому требуется хакерство:

$('.datePicker').each(function(){
    $(this).datepicker({
        dateFormat:$(this).data("dateFormat").toLowerCase().replace("yyyy","yy")
    });
});

это слабовато, но должно охватывать множество случаев.

philn5d
источник
Первые 3 строки являются наиболее важными :) Пример и ссылка на определение формата
Борик
2

работает для меня

<%=Model.MyDateTime.ToString("dd-MMM-yyyy")%>
numerah
источник
Этот вопрос, очевидно, использует механизм просмотра бритвы, вы ответили на другом языке.
Rhys Bevilaqua 08
2

Недавно была такая же проблема.

Я обнаружил, что простое определение DataType как Date в модели также работает (с использованием подхода Code First)

[DataType(DataType.Date)]
public DateTime Added { get; set; }
Владислав Большаков
источник
1

ты можешь сделать это @item.Date.Value.Tostring("dd-MMM-yy");

Саураб Соланки
источник
0

если я просто хочу отобразить дату в коротком формате, я просто использую @ Model.date.ToShortDateString (), и он печатает дату в

Marcianin
источник
0

Если все, что вы хотите сделать, это отобразить дату в определенном формате, просто позвоните:

@Model.LeadDate.ToString("dd-MMM-yyyy")

@Model.LeadDate.ToString("MM/dd/yy")

Это приведет к следующему формату,

26-Apr-2013

04/26/13
Кайлас Мане
источник
Что будет, если @ Model.LeadDate == null?
Бимал Дас
0

это будет отображаться в dd/MM/yyyyформате в вашем представлении

Ввиду:

вместо DisplayForиспользования этого кода

<td>

@(item.Startdate.HasValue ? item.Startdate.Value.ToString("dd/MM/yyyy") : "Date is Empty")

</td

он также проверяет, является ли значение null в столбце даты, если оно истинно, то будет отображаться Date is Empty или фактическая отформатированная дата из столбца.

Надежда кому-то помогает.

shaijut
источник
0
@{
  string datein = Convert.ToDateTime(item.InDate).ToString("dd/MM/yyyy");        
  @datein
}
wesley7
источник
0

В MVC5 я бы использовал, если ваша модель - datetime

string dt = Model.ToString("dd/MM/yyy"); 

Или, если ваша модель содержит свойство datetime

string dt = Model.dateinModel.ToString("dd/MM/yyy"); 

Вот официальное значение форматов:

https://msdn.microsoft.com/en-us/library/8kb3ddd4(v=vs.110).aspx

Хосе Ортега
источник
-2

Только Просмотр файла Отрегулируйте так. Вы можете попробовать это.

@Html.FormatValue( (object)Convert.ChangeType(item.transdate, typeof(object)), 
                            "{0: yyyy-MM-dd}")

item.transdateэто DateTimeданные вашего типа.

Мартина Чанг
источник