Jak renderować DateTime w określonym formacie w ASP.NET MVC 3?

117

Jeśli moja klasa modelu ma właściwość typu, DateTimejak mogę ją renderować w określonym formacie - na przykład w formacie, który ToLongDateString()zwraca?

Próbowałem tego ...

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

... co zgłasza wyjątek, ponieważ wyrażenie musi wskazywać właściwość lub pole. I to...

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

... co nie zgłasza wyjątku, ale renderowane wyjście jest puste (chociaż valzawiera oczekiwaną wartość, jak mogłem zobaczyć w debugerze).

Dzięki za wskazówki z góry!

Edytować

ToLongDateStringto tylko przykład. Zamiast tego chcę użyć ToLongDateStringniestandardowej metody rozszerzenia DateTimei 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 "";
}

Więc myślę, że nie mogę użyć DisplayFormatatrybutu i DataFormatStringparametru we właściwościach ViewModel.

Slauma
źródło

Odpowiedzi:

159

Jeśli chcesz tylko wyświetlić datę w określonym formacie, zadzwoń:

@String.Format(myFormat, Model.MyDateTime)

Używanie @Html.DisplayFor(...)to po prostu dodatkowa praca, chyba że określasz szablon lub potrzebujesz czegoś, co jest oparte na szablonach, na przykład iteracja pliku IEnumerable<T>. Tworzenie szablonu jest dość proste i może również zapewnić dużą elastyczność. Utwórz folder w folderze widoków dla bieżącego kontrolera (lub folderu udostępnionych widoków) o nazwie DisplayTemplates. Wewnątrz tego folderu dodaj częściowy widok z typem modelu, dla którego chcesz zbudować szablon. W tym przypadku dodałem /Views/Shared/DisplayTemplatesi dodałem częściowy widok o nazwie ShortDateTime.cshtml.

@model System.DateTime

@Model.ToShortDateString()

A teraz możesz wywołać ten szablon za pomocą następującego wiersza:

@Html.DisplayFor(m => m.MyDateTime, "ShortDateTime")
Nick Larsen
źródło
Dzięki, wygląda to dobrze, a ten parametr szablonu („ShortDateTime”) rozwiązuje również problem, który opisałem w moim komentarzu do odpowiedzi ataddeini.
Slauma
3
Jeśli typ to „DateTime?” zamiast „DateTime” (@model DateTime?) ... szablon ciplay będzie obsługiwał wartości null lub not nullable. Nazwa pliku powinna pozostać „DateTime.cshtml”.
Romias
+1 Musiałem to skomentować, działało świetnie w mojej aplikacji! Dzięki!
Russell Christensen
Użycie @ Html.DisplayFor () nie jest dodatkową pracą, renderuje reprezentację html modelu, nawet bez szablonów ... nie należy się mylić ...
Cabuxa.Mapache
stackoverflow.com/questions/19920603/… zawiera kod, który jest pomocny w radzeniu sobie z wartościami zerowymi datetimes, o których wspomina @Romias.
Walter de Jong,
171

Możesz ozdobić swoją właściwość modelu widoku [DisplayFormat]atrybutem:

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

i Twoim zdaniem:

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

lub do wyświetlania wartości,

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

Inną możliwością, której nie polecam, jest użycie słabo wpisanego helpera:

@Html.TextBox("MyDate", Model.MyDate.ToLongDateString())
Darin Dimitrov
źródło
1
@Darin: Nie chcę elementu wejściowego, ale tylko statyczne wyjście tekstowe. Powinienem również wspomnieć, że rzeczywisty format jest tworzony przez niestandardową metodę rozszerzenia DateTime(ToLongDateString był tylko przykładem), więc jest mało prawdopodobne, żebym mógł go użyć DataFormatString.
Slauma
2
@Slauma, a może @Html.DisplayFor(x => x.MyDateTime). @NickLarsen to powód, dla którego należy używać modeli widoku. W moim przykładzie dekoruję model widoku tym atrybutem i widok jest już powiązany z danym widokiem, to jest jego cel.
Darin Dimitrov
1
@Slauma, OK, w tym przypadku możesz albo użyć niestandardowego szablonu wyświetlania, albo pozwolić, aby model widoku używał właściwości ciągu, a konwersja zostanie wykonana na warstwie mapowania podczas mapowania między modelem a modelem widoku (w ten sposób możesz nadal używaj tylko Html.DisplayFor w widoku).
Darin Dimitrov
5
@NickLarsen, nie, to jeden model widoku na widok. To dlatego, że ludzie popełniają ten błąd, i pytania takie jak Jak wykluczyć niektóre właściwości z walidacji w jednej akcji kontrolera, a nie w innej? są tak powszechne w SO.
Darin Dimitrov
1
Wracając do tego pytania rok później, zgadzam się z argumentem za jednym modelem na widok. Nadal uważam, że wszystko, co dotyczy opcji wyświetlania, należy do widoku, a nie do modelu.
Nick Larsen,
26

Proste, sformatowane dane wyjściowe wewnątrz modelu

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

lub w pętli foreach

@String.Format("{0:d}", item.CreatedOn)
odesuk
źródło
Wydaje się, że jest to string.Format
kopia
2
@PaulTyng ta odpowiedź była dla mnie jaśniejsza niż zaakceptowana odpowiedź, odesuk faktycznie pokazał format w pierwszym parametrze, który jako nowość mi pomaga.
Dan Beaulieu
1
Zgadzam się, to jest odpowiedź, która mi pomogła.
glenn garson
26

Używam następującego podejścia do formatu wbudowanego i wyświetlam właściwość daty z modelu.

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

W przeciwnym razie, wypełniając TextBox lub Editor, możesz zrobić tak, jak sugerował @Darin, ozdobić atrybut [DisplayFormat]atrybutem.

Steven
źródło
To jest rozwiązanie, którego szukam!
Envil
To jest rozwiązanie, którego szukałem!
Raihan Ridoy
9

Jeśli wszystkie DateTimetypy są renderowane w ten sam sposób, możesz użyć niestandardowego DateTimeszablonu wyświetlania.

W folderze Widoki utwórz folder o nazwie „DisplayTemplates” albo w folderze widoków specyficznych dla kontrolera, albo w folderze „Shared” (działają one podobnie do częściowych).

Wewnątrz utwórz plik o nazwie, DateTime.cshtmlktóry przyjmuje DateTimejako @modelkod i kod, w jaki sposób chcesz renderować swoją datę:

@model System.DateTime
@Model.ToLongDateString()

Teraz możesz po prostu użyć tego w swoich widokach i powinno działać:

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

Tak długo, jak będziesz przestrzegać konwencji dodawania go do folderu „DisplayTemplates” i nazwania pliku tak, aby pasował do wyświetlanego typu, MVC automatycznie użyje tego do wyświetlenia twoich wartości. Działa to również w przypadku edycji scenariuszy przy użyciu „EditorTemplates”.

Oto więcej informacji na temat szablonów .

ataddeini
źródło
Dzięki, właśnie go przetestowałem i działa dobrze, jeśli typ jest naprawdę DateTime. Jednak mam kilka właściwości DateTime dopuszczających wartość null. Próbowałem utworzyć drugi plik w DisplayTemplatesfolderze, o nazwie NullableDateTime.cshtmli wewnątrz: @using MyHelpers @model System.DateTime? @Model.MyCustomExtension()Oto MyCustomExtensionmetoda rozszerzenia na DateTime?. Jednak pojawia się wyjątek, gdy DateTime? pole jest naprawdę puste, co oznacza, że ​​słownik wymaga elementu modelu, DateTimektóry nie jest pusty. Czy istnieje sposób na zdefiniowanie DisplayTemplate dla DateTime dopuszczającej wartość null?
Slauma
@Slauma: Hmm, dobre pytanie. Prawdopodobnie NullableDateTime.cshtmltrzymałbym się i zastosował podejście, które zasugerował @NickLarsen i którego używa @Html.DisplayFor(m => m.MyDateTime, "NullableDateTime").
ataddeini
Nie musisz jawnie dodawać nazwy szablonu, jeśli szablon DateTime.cshtml jest ustawiony jako „@model DateTime?” zamiast „DateTime”. W ten sposób wszystkie daty (dopuszczalne lub nie) są obsługiwane przez ten sam szablon ...
Romias,
7

Preferuję zachowanie szczegółów formatowania w widoku, a nie w modelu widoku. Więc w MVC4 / Razor:

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

odniesienie do formatu datetime: http://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.71).aspx

Następnie mam powiązany z nim Datepicker JQuery, który umieszcza datę w innym formacie ... doh!

Wygląda na to, że muszę ustawić format DatePicker na to samo formatowanie.

Więc przechowuję System.Globalizationformatowanie w atrybucie data- * i zbieram je podczas konfigurowania

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

A oto kiepska część: formaty .net i datepicker nie pasują, więc potrzebne jest hakowanie:

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

to trochę słabe, ale powinno obejmować wiele przypadków.

philn5d
źródło
Pierwsze 3 linijki są najważniejsze :) Przykład i link do definicji formatu
Borik
2

pracuje dla mnie

<%=Model.MyDateTime.ToString("dd-MMM-yyyy")%>
numerah
źródło
To pytanie oczywiście dotyczy silnika widoku brzytwy, odpowiedziałeś w innym języku.
Rhys Bevilaqua
2

Miałem ostatnio ten sam problem.

Odkryłem, że po prostu zdefiniowanie DataType jako daty w modelu działa również (przy użyciu podejścia Code First)

[DataType(DataType.Date)]
public DateTime Added { get; set; }
Vladislav Bolshakov
źródło
1

możesz to zrobić @item.Date.Value.Tostring("dd-MMM-yy");

Saurabh Solanki
źródło
0

jeśli chcę tylko wyświetlić datę w krótkim formacie, po prostu używam @ Model.date.ToShortDateString () i wyświetla datę w

Marcianin
źródło
0

Jeśli chcesz tylko wyświetlić datę w określonym formacie, zadzwoń:

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

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

Spowoduje to następujący format,

26-Apr-2013

04/26/13
Kailas Mane
źródło
Co się stanie, jeśli @ Model.LeadDate == null?
Bimal Das
0

będzie to wyświetlane w dd/MM/yyyyformacie w Twoim widoku

Z uwagi:

zamiast DisplayForużywać tego kodu

<td>

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

</td

sprawdza również, czy wartość jest pusta w kolumnie daty, jeśli prawda, wyświetli Date is Empty lub rzeczywistą sformatowaną datę z kolumny.

Nadzieja pomaga komuś.

shaijut
źródło
0
@{
  string datein = Convert.ToDateTime(item.InDate).ToString("dd/MM/yyyy");        
  @datein
}
wesley7
źródło
0

W MVC5 użyłbym, jeśli twój model to data i godzina

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

Lub jeśli twój model zawiera właściwość datetime

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

Oto oficjalne znaczenie formatów:

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

Jose Ortega
źródło
-2

Tylko View File Adjust w ten sposób. Możesz tego spróbować.

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

item.transdateto jest twój DateTimetyp danych.

Martine Chang
źródło