Як візуалізувати 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.

Відповіді:


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.
Слаума

3
Якщо тип "DateTime?" замість "DateTime" (@model DateTime?) ... шаблон шаблону ciplay буде обробляти зведені чи не зведені дати. Ім'я файлу має залишатися "DateTime.cshtml".
Роміас

+1 Довелося прокоментувати це, чудово працював у моїй програмі! Дякую!
Рассел Крістенсен

Використання @ Html.DisplayFor () не є додатковою роботою, воно відображає html-представлення моделі, навіть без шаблонів .... не плутайте ...
Cabuxa.Mapache

stackoverflow.com/questions/19920603/… містить код, який корисний для боротьби з незмінними датами часу @ Roomias згадує.
Вальтер де Йонг

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.
Слаума

2
@Slauma, як щодо @Html.DisplayFor(x => x.MyDateTime). @ NickLarsen саме тому слід використовувати моделі перегляду. У своєму прикладі я прикрашаю модель перегляду цим атрибутом, і подання вже прив’язане до заданого виду, це його мета.
Дарин Димитров

1
@Slauma, добре, у цьому випадку ви можете або скористатися спеціальним шаблоном відображення, або ваша модель подання використовувати властивість рядка, і перетворення буде здійснено на шарі відображення, коли ви збираєтеся між моделлю та моделлю перегляду (таким чином, ви могли б все ще використовуйте лише Html.DisplayFor у перегляді).
Дарин Димитров

5
@ NickLarsen, ні, це одна модель перегляду на перегляд. Через те, що люди роблять цю помилку, виникають такі запитання, як я можу виключити деякі властивості з перевірки в одній дії контролера, а не в іншій? такі поширені на SO.
Дарин Димитров

1
Повернувшись до цього питання через рік, я погоджуюся з аргументом щодо однієї моделі за перегляд. Я все ще думаю, що все, що стосується вибору дисплея, належить до перегляду, а не моделі.
Нік Ларсен

26

Простий відформатований вихід всередині моделі

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

або в передній петлі

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

Схоже, дублікат прийнятої відповіді про використанняstring.Format
Пол Тайнг

2
@PaulTyng ця відповідь була для мене зрозумілішою, ніж прийнята відповідь, Одесук фактично показав формат у першому парамі, який як новачок допомагає мені.
Дан Болье

1
Я згоден, це відповідь, яка мені допомогла.
glenn garson

26

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

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

Інакше під час заселення TextBox або редактора ви могли б зробити так, як запропонував @Darin, прикрасивши атрибут [DisplayFormat]атрибутом.


Це рішення, яке я шукаю!
Енвіл

Це рішення, яке я шукав!
Райхан Рідой

9

Якщо всі ваші DateTimeтипи відображаються однаково, ви можете використовувати власний DateTimeшаблон відображення.

У своїй папці Views створіть папку під назвою "DisplayTemplates" або під папкою певних переглядів у вашому контролері, або під папкою "Спільні" (вони працюють аналогічно партіям).

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

@model System.DateTime
@Model.ToLongDateString()

Тепер ви можете просто використовувати це у своїх поглядах, і це має працювати:

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

Поки ви будете дотримуватися конвенції щодо додавання його до папки "DisplayTemplates" та присвоєння ім'я файлу відповідно до типу, який відображається, MVC автоматично використовуватиме його для відображення значень. Це також працює для редагування сценаріїв за допомогою "EditorTemplates".

Ось додаткова інформація про шаблони .


Дякую, я щойно перевірив це, і він чудово працює, якщо тип справді є DateTime. Однак у мене є кілька зведених властивостей DateTime. Я спробував створити другий файл у DisplayTemplatesпапці, що називається NullableDateTime.cshtmlта всередині: @using MyHelpers @model System.DateTime? @Model.MyCustomExtension()Ось MyCustomExtensionметод розширення на DateTime?. Однак він отримує виняток, коли DateTime? поле насправді є нульовим, підказуючи мені, що для словника потрібен елемент типу, DateTimeякий не є нульовим. Чи є спосіб визначити DisplayTemplate для змінної DateTime?
Слаума

@Slauma: Хм, гарне запитання. Можливо, я б дотримувався NullableDateTime.cshtmlта використовував підхід, який запропонував @NickLarsen та використовував @Html.DisplayFor(m => m.MyDateTime, "NullableDateTime").
ataddeini

Вам не потрібно явно додавати назву шаблону, якщо для вашого шаблона DateTime.cshtml встановлено значення "@model DateTime?" замість "DateTime". Таким чином усі дати (зведені чи ні) обробляються одним і тим же шаблоном ...
Romias

7

Моя перевага - тримати деталі форматування з видом, а не з переглядом. Так у MVC4 / Razor:

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

посилання на формат дати: http://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.71).aspx

Тоді у мене прив’язаний добірчик дат JQuery, і ця дата ставиться у іншому форматі ... так!

Виглядає так, що мені потрібно встановити формат датчика на той самий формат.

Тому я зберігаю 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")
    });
});

це якась слабка, але має охоплювати багато випадків.


Перші 3 рядки найважливіші :) Приклад та посилання на визначення формату
Борік

2

працює для мене

<%=Model.MyDateTime.ToString("dd-MMM-yyyy")%>

Це питання, очевидно, використовується за допомогою механізму перегляду бритви, ви відповіли іншою мовою.
Rhys Bevilaqua

2

З тією ж проблемою були нещодавно.

Я виявив, що просто визначення DataType як Date у моделі також працює (використовуючи Code First)

[DataType(DataType.Date)]
public DateTime Added { get; set; }


0

якщо я просто хочу відобразити дату в короткому форматі, я просто використовую @ Model.date.ToShortDateString () і друкує дату в


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

він також перевіряє, чи значення стовпця недійсне, якщо воно є істинним, то воно буде відображати Дата порожньо або фактично відформатовану дату зі стовпця.

Надія комусь допомагає.


0
@{
  string datein = Convert.ToDateTime(item.InDate).ToString("dd/MM/yyyy");        
  @datein
}


-2

Переглянути лише налаштування файлів, як це. Ви можете спробувати це.

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

item.transdateце ваш DateTimeтип даних.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.