Wie rendere ich eine DateTime in einem bestimmten Format in ASP.NET MVC 3?

117

Wenn ich in meiner Modellklasse eine Eigenschaft vom Typ habe, DateTimewie kann ich sie in einem bestimmten Format rendern - zum Beispiel in dem Format, das ToLongDateString()zurückgibt?

Ich habe es versucht ...

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

... was eine Ausnahme auslöst, da der Ausdruck auf eine Eigenschaft oder ein Feld verweisen muss. Und das...

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

... was keine Ausnahme auslöst, aber die gerenderte Ausgabe ist leer (obwohl sie valden erwarteten Wert enthält, wie ich im Debugger sehen konnte).

Vielen Dank für Tipps im Voraus!

Bearbeiten

ToLongDateStringist nur ein Beispiel. Was ich eigentlich anstelle von verwenden möchte, ToLongDateStringist eine benutzerdefinierte Erweiterungsmethode von DateTimeund 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 "";
}

Daher kann ich das DisplayFormatAttribut und den DataFormatStringParameter in den ViewModel-Eigenschaften nicht verwenden.

Slauma
quelle

Antworten:

159

Wenn Sie nur das Datum in einem bestimmten Format anzeigen möchten, rufen Sie einfach an:

@String.Format(myFormat, Model.MyDateTime)

Die Verwendung @Html.DisplayFor(...)ist nur zusätzliche Arbeit, es sei denn, Sie geben eine Vorlage an oder müssen etwas verwenden, das auf Vorlagen basiert, z. B. das Iterieren einer IEnumerable<T>. Das Erstellen einer Vorlage ist einfach genug und bietet auch viel Flexibilität. Erstellen Sie in Ihrem Ansichtsordner einen Ordner für den aktuellen Controller (oder freigegebenen Ansichtsordner) mit dem Namen DisplayTemplates. Fügen Sie in diesem Ordner eine Teilansicht mit dem Modelltyp hinzu, für den Sie die Vorlage erstellen möchten. In diesem Fall habe ich /Views/Shared/DisplayTemplateseine Teilansicht namens hinzugefügt und hinzugefügtShortDateTime.cshtml .

@model System.DateTime

@Model.ToShortDateString()

Und jetzt können Sie diese Vorlage mit der folgenden Zeile aufrufen:

@Html.DisplayFor(m => m.MyDateTime, "ShortDateTime")
Nick Larsen
quelle
Danke, das sieht gut aus und dieser Vorlagenparameter ("ShortDateTime") löst auch das Problem, das ich in meinem Kommentar zur Antwort von ataddeini beschrieben hatte.
Slauma
3
Wenn der Typ "DateTime?" Ist. Anstelle von "DateTime" (@model DateTime?) ... verarbeitet die Ciplay-Vorlage nullfähige oder nicht nullbare Datumsangaben. Der Dateiname sollte "DateTime.cshtml" bleiben.
Romias
+1 Musste dies kommentieren, hat in meiner Bewerbung super funktioniert! Vielen Dank!
Russell Christensen
Use @ Html.DisplayFor () ist keine zusätzliche Arbeit, es rendert die HTML-Darstellung des Modells, auch ohne Vorlagen .... nicht verwirrt sein ...
Cabuxa.Mapache
stackoverflow.com/questions/19920603/… enthält Code, der beim Umgang mit nullbaren Datumsangaben hilfreich ist, die @Romias erwähnt.
Walter de Jong
171

Sie können Ihre Ansichtsmodelleigenschaft mit dem folgenden [DisplayFormat]Attribut dekorieren :

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

und aus Ihrer Sicht:

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

oder zur Anzeige des Wertes

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

Eine andere Möglichkeit, die ich nicht empfehle, ist die Verwendung eines schwach typisierten Helfers:

@Html.TextBox("MyDate", Model.MyDate.ToLongDateString())
Darin Dimitrov
quelle
1
@Darin: Ich möchte kein Eingabeelement, sondern nur statische Textausgabe. Ich sollte auch erwähnen, dass das tatsächliche Format durch eine benutzerdefinierte Erweiterungsmethode von erstellt wurde DateTime(ToLongDateString war nur ein Beispiel), so dass es unwahrscheinlich ist, dass ich es verwenden kann DataFormatString.
Slauma
2
@ Slauma, wie wäre es @Html.DisplayFor(x => x.MyDateTime). @NickLarsen das ist der Grund, warum Ansichtsmodelle verwendet werden sollten. In meinem Beispiel dekoriere ich das Ansichtsmodell mit diesem Attribut und eine Ansicht ist bereits an eine bestimmte Ansicht gebunden, das ist ihr Zweck.
Darin Dimitrov
1
@Slauma, OK, in diesem Fall können Sie entweder eine benutzerdefinierte Anzeigevorlage verwenden oder Ihr Ansichtsmodell eine Zeichenfolgeeigenschaft verwenden lassen. Die Konvertierung erfolgt auf der Zuordnungsebene, wenn Sie zwischen dem Modell und dem Ansichtsmodell zuordnen (auf diese Weise können Sie dies tun) Verwenden Sie immer noch nur Html.DisplayFor in der Ansicht.
Darin Dimitrov
5
@ NickLarsen, nein, es ist ein Ansichtsmodell pro Ansicht. Weil Leute diesen Fehler machen, stellen sich Fragen wie Wie kann ich einige Eigenschaften in einer Controller-Aktion von der Validierung ausschließen und nicht in einer anderen? sind so häufig auf SO.
Darin Dimitrov
1
Ein Jahr später komme ich auf diese Frage zurück und stimme dem Argument für ein Modell pro Ansicht zu. Ich denke immer noch, dass alles, was mit den Anzeigeoptionen zu tun hat, in die Ansicht und nicht in das Modell gehört.
Nick Larsen
26

Einfache formatierte Ausgabe innerhalb des Modells

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

oder in der foreach-Schleife

@String.Format("{0:d}", item.CreatedOn)
odesuk
quelle
Scheint wie ein Duplikat der akzeptierten Antwort vonstring.Format
Paul Tyng
2
@PaulTyng diese Antwort war für mich klarer als die akzeptierte Antwort, odesuk zeigte tatsächlich das Format im ersten Parameter, was mir als Neuling hilft.
Dan Beaulieu
1
Ich stimme zu, das ist die Antwort, die mir geholfen hat.
Glenn Garson
26

Ich verwende den folgenden Ansatz, um das Inline-Format zu verwenden und eine Datumseigenschaft aus dem Modell anzuzeigen.

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

Andernfalls könnten Sie beim Auffüllen einer TextBox oder eines Editors wie von @Darin vorgeschlagen das Attribut mit einem [DisplayFormat]Attribut dekorieren .

Steven
quelle
Dies ist die Lösung, die ich suche!
Envil
Dies ist die Lösung, nach der ich gesucht habe!
Raihan Ridoy
9

Wenn alle Ihre DateTimeTypen auf dieselbe Weise gerendert werden, können Sie eine benutzerdefinierte DateTimeAnzeigevorlage verwenden.

Erstellen Sie in Ihrem Ansichtsordner einen Ordner mit dem Namen "DisplayTemplates", entweder unter Ihrem Controller-spezifischen Ansichtsordner oder unter dem Ordner "Shared" (diese funktionieren ähnlich wie Partials).

Erstellen Innerhalb einer Datei mit dem Namen DateTime.cshtml, der nimmt DateTimedie wie @modelund Code , wie Sie Ihr Datum machen möchten:

@model System.DateTime
@Model.ToLongDateString()

Jetzt können Sie dies einfach in Ihren Ansichten verwenden und es sollte funktionieren:

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

Solange Sie der Konvention folgen, sie dem Ordner "DisplayTemplates" hinzuzufügen und die Datei so zu benennen, dass sie dem von Ihnen angezeigten Typ entspricht, verwendet MVC diese automatisch, um Ihre Werte anzuzeigen. Dies funktioniert auch zum Bearbeiten von Szenarien mit "EditorTemplates".

Hier finden Sie weitere Informationen zu Vorlagen .

ataddeini
quelle
Danke, ich habe es gerade getestet und es funktioniert gut, wenn der Typ wirklich ist DateTime. Ich habe jedoch einige nullfähige DateTime-Eigenschaften. Ich habe versucht, eine zweite Datei in dem DisplayTemplatesOrdner zu erstellen , genannt NullableDateTime.cshtmlund innerhalb von: @using MyHelpers @model System.DateTime? @Model.MyCustomExtension()Hier MyCustomExtensionist eine Erweiterungsmethode für DateTime?. Es kommt jedoch zu einer Ausnahme, wenn eine DateTime? Feld ist wirklich null und sagt mir, dass das Wörterbuch ein Modellelement vom Typ benötigt, DateTimedas nicht null ist. Gibt es eine Möglichkeit, eine DisplayTemplate für eine nullfähige DateTime zu definieren?
Slauma
@ Slauma: Hmm, gute Frage. Ich würde mich wahrscheinlich an den von NullableDateTime.cshtml@NickLarsen vorgeschlagenen und verwendeten Ansatz halten @Html.DisplayFor(m => m.MyDateTime, "NullableDateTime").
Ataddeini
Sie müssen den Namen der Vorlage nicht explizit hinzufügen, wenn Ihre DateTime.cshtml-Vorlage auf "@model DateTime?" anstelle von "DateTime". Auf diese Weise werden alle Daten (nullbar oder nicht) von derselben Vorlage behandelt ...
Romias
7

Ich bevorzuge es, die Formatierungsdetails mit der Ansicht und nicht mit dem Ansichtsmodell beizubehalten. Also in MVC4 / Razor:

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

Referenz zum Datum / Uhrzeit-Format: http://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.71).aspx

Dann habe ich einen JQuery-Datepicker daran gebunden, und das gibt das Datum in einem anderen Format an ... doh!

Sieht so aus, als müsste ich das Format des Datepickers auf dieselbe Formatierung einstellen.

Also speichere ich die System.GlobalizationFormatierung in einem data- * Attribut und sammle sie beim Einrichten des

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

Und hier ist der blöde Teil: Die Formate von .net und Datepicker stimmen nicht überein, daher ist Hackery erforderlich:

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

Das ist etwas schwach, sollte aber viele Fälle abdecken.

philn5d
quelle
Die ersten 3 Zeilen sind am wichtigsten :) Beispiel und Link zur Formatdefinition
Borik
2

funktioniert bei mir

<%=Model.MyDateTime.ToString("dd-MMM-yyyy")%>
Numerah
quelle
Diese Frage verwendet offensichtlich die Razor View Engine. Sie haben in einer anderen Sprache geantwortet.
Rhys Bevilaqua
2

Hatte vor kurzem das gleiche Problem.

Ich habe festgestellt, dass das einfache Definieren von DataType als Datum im Modell ebenfalls funktioniert (unter Verwendung des Code First-Ansatzes).

[DataType(DataType.Date)]
public DateTime Added { get; set; }
Vladislav Bolshakov
quelle
1

Sie können so tun @item.Date.Value.Tostring("dd-MMM-yy");

Saurabh Solanki
quelle
0

Wenn ich das Datum nur im Kurzformat anzeigen möchte, verwende ich einfach @ Model.date.ToShortDateString () und es druckt das Datum in

Marcianin
quelle
0

Wenn Sie nur das Datum in einem bestimmten Format anzeigen möchten, rufen Sie einfach an:

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

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

Es ergibt sich folgendes Format:

26-Apr-2013

04/26/13
Kailas Mähne
quelle
Was passiert, wenn @ Model.LeadDate == null ist?
Bimal Das
0

Dies wird dd/MM/yyyyin Ihrer Ansicht im Format angezeigt

Im Hinblick auf:

anstatt DisplayFordiesen Code zu verwenden

<td>

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

</td

Außerdem wird geprüft, ob der Wert in der Datumsspalte null ist. Wenn true, wird Datum leer oder das tatsächlich formatierte Datum in der Spalte angezeigt.

Hoffnung hilft jemandem.

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

In MVC5 würde ich verwenden, wenn Ihr Modell das Datum / die Uhrzeit ist

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

Oder wenn Ihr Modell die Eigenschaft datetime enthält

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

Hier ist die offizielle Bedeutung der Formate:

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

Jose Ortega
quelle
-2

Nur Datei anzeigen So anpassen. Sie können dies versuchen.

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

item.transdateEs sind Ihre DateTimeTypdaten.

Martine Chang
quelle