Come eseguire il rendering di un DateTime in un formato specifico in ASP.NET MVC 3?


117

Se nella mia classe modello ho una proprietà di tipo, DateTimecome posso renderla in un formato specifico, ad esempio nel formato che ToLongDateString()restituisce?

Ho provato questo ...

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

... che genera un'eccezione perché l'espressione deve puntare a una proprietà o a un campo. E questo...

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

... che non genera un'eccezione, ma l'output renderizzato è vuoto (sebbene valcontenga il valore atteso, come ho potuto vedere nel debugger).

Grazie per i suggerimenti in anticipo!

modificare

ToLongDateStringè solo un esempio. Quello che voglio effettivamente usare invece di ToLongDateStringè un metodo di estensione personalizzato di DateTimee 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 "";
}

Quindi, penso di non poter utilizzare l' DisplayFormatattributo e il DataFormatStringparametro nelle proprietà ViewModel.

Risposte:


159

Se tutto ciò che vuoi fare è visualizzare la data con un formato specifico, chiama:

@String.Format(myFormat, Model.MyDateTime)

L'utilizzo @Html.DisplayFor(...)è solo un lavoro extra a meno che non si specifichi un modello o sia necessario utilizzare qualcosa basato su modelli, come l'iterazione di un file IEnumerable<T>. La creazione di un modello è abbastanza semplice e può fornire anche molta flessibilità. Crea una cartella nella cartella delle viste per il controller corrente (o la cartella delle viste condivise) chiamata DisplayTemplates. All'interno di quella cartella, aggiungi una vista parziale con il tipo di modello per il quale desideri creare il modello. In questo caso ho aggiunto /Views/Shared/DisplayTemplatese aggiunto una vista parziale chiamata ShortDateTime.cshtml.

@model System.DateTime

@Model.ToShortDateString()

E ora puoi chiamare quel modello con la seguente riga:

@Html.DisplayFor(m => m.MyDateTime, "ShortDateTime")

Grazie, questo sembra buono, e questo parametro del modello ("ShortDateTime") risolve anche il problema che avevo descritto nel mio commento alla risposta ataddeini.
Slauma

3
Se il tipo è "DateTime?" invece di "DateTime" (@model DateTime?) ... il modello di cifratura gestirà datetimes nullable o non nullable. Il nome del file dovrebbe rimanere "DateTime.cshtml".
Romias

+1 Ho dovuto commentare questo, ha funzionato alla grande nella mia applicazione! Grazie!
Russell Christensen

Use @ Html.DisplayFor () non è un lavoro extra, rende la rappresentazione html del modello, anche senza modelli .... non essere confuso ...
Cabuxa.Mapache

stackoverflow.com/questions/19920603/… contiene codice utile per gestire i datetimes nullable menzionati da @Romias.
Walter de Jong

171

Puoi decorare la proprietà del tuo modello di visualizzazione con l' [DisplayFormat]attributo:

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

e secondo te:

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

oppure, per visualizzare il valore,

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

Un'altra possibilità, che non consiglio, è usare un helper debolmente digitato:

@Html.TextBox("MyDate", Model.MyDate.ToLongDateString())

1
@Darin: non voglio un elemento di input, ma solo un output di testo statico. Dovrei anche menzionare che il formato effettivo viene creato da un metodo di estensione personalizzato di DateTime(ToLongDateString era solo un esempio), quindi è improbabile che possa usare DataFormatString.
Slauma

2
@Slauma, che ne dici @Html.DisplayFor(x => x.MyDateTime). @ NickLarsen è per questo che dovrebbero essere usati i modelli di visualizzazione. Nel mio esempio decoro il modello di visualizzazione con questo attributo e una vista è già collegata a una data vista, questo è il suo scopo.
Darin Dimitrov

1
@Slauma, OK, in questo caso potresti utilizzare un modello di visualizzazione personalizzato o fare in modo che il tuo modello di visualizzazione utilizzi una proprietà stringa e la conversione verrà eseguita al livello di mappatura quando esegui la mappatura tra il modello e il modello di visualizzazione (in questo modo potresti ancora utilizzare solo Html.DisplayFor nella vista).
Darin Dimitrov

5
@ NickLarsen, no, è un modello di visualizzazione per visualizzazione. È perché le persone commettono questo errore che domande come Come escludo alcune proprietà dalla convalida in un'azione del controller e non in un'altra? sono così comuni su SO.
Darin Dimitrov

1
Tornando a questa domanda un anno dopo, sono d'accordo con l'argomento per un modello per vista. Penso ancora che tutto ciò che riguarda le scelte di visualizzazione appartenga alla vista e non al modello.
Nick Larsen

26

Semplice output formattato all'interno del modello

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

o nel ciclo foreach

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

Sembra un duplicato della risposta accettata dell'usostring.Format
Paul Tyng

2
@PaulTyng questa risposta è stata più chiara per me della risposta accettata, odesuk ha effettivamente mostrato il formato nel primo parametro che, come newb, mi aiuta.
Dan Beaulieu

1
Sono d'accordo, questa è la risposta che mi ha aiutato.
glenn garson

26

Uso il seguente approccio al formato inline e visualizzo una proprietà della data dal modello.

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

Altrimenti quando si popola una casella di testo o un editor si potrebbe fare come suggerito da @Darin, decorando l'attributo con un [DisplayFormat]attributo.


Questa è la soluzione che sto cercando!
Envil

Questa è la soluzione che stavo cercando!
Raihan Ridoy

9

Se tutti i DateTimetipi vengono visualizzati allo stesso modo, puoi utilizzare un DateTimemodello di visualizzazione personalizzato .

Nella cartella Views creare una cartella denominata "DisplayTemplates" nella cartella delle visualizzazioni specifiche del controller o nella cartella "Shared" (funzionano in modo simile ai partials).

All'interno crea un file denominato DateTime.cshtmlche prende DateTimecome @modele il codice come vuoi rendere la tua data:

@model System.DateTime
@Model.ToLongDateString()

Ora puoi semplicemente usarlo nelle tue visualizzazioni e dovrebbe funzionare:

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

Fintanto che segui la convenzione di aggiungerlo alla cartella "DisplayTemplates" e denominare il file in modo che corrisponda al tipo che stai visualizzando, MVC lo utilizzerà automaticamente per visualizzare i tuoi valori. Funziona anche per modificare gli scenari utilizzando "EditorTemplates".

Ecco alcune informazioni in più sui modelli .


Grazie, l'ho appena testato e funziona bene se il tipo è davvero DateTime. Tuttavia ho alcune proprietà DateTime nullable. Ho provato a creare un secondo file nella DisplayTemplatescartella, chiamato NullableDateTime.cshtmle all'interno: @using MyHelpers @model System.DateTime? @Model.MyCustomExtension()Ecco MyCustomExtensionun metodo di estensione su DateTime?. Tuttavia ottiene un'eccezione quando un DateTime? field è davvero nullo e mi dice che il dizionario richiede un elemento del modello di tipo DateTimeche non è nullo. C'è un modo per definire un DisplayTemplate per un DateTime nullable?
Slauma

@Slauma: Hmm, bella domanda. Probabilmente continuerei a NullableDateTime.cshtmlutilizzare l'approccio suggerito e utilizzato da @NickLarsen @Html.DisplayFor(m => m.MyDateTime, "NullableDateTime").
ataddeini

Non è necessario aggiungere esplicitamente il nome del modello se il modello DateTime.cshtml è impostato come "@model DateTime?" invece di "DateTime". In questo modo tutte le date (nullable o meno) sono gestite dallo stesso modello ...
Romias

7

La mia preferenza è mantenere i dettagli di formattazione con la vista e non con il viewmodel. Quindi in MVC4 / Razor:

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

riferimento al formato datetime: http://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.71).aspx

Quindi ho un datepicker JQuery associato ad esso, e quello ha inserito la data in un formato diverso ... doh!

Sembra che sia necessario impostare il formato del datepicker sulla stessa formattazione.

Quindi memorizzo la System.Globalizationformattazione in un attributo data- * e la raccolgo durante la configurazione del file

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

Ed ecco la parte schifosa: i formati di .net e datepicker non corrispondono, quindi è necessario l'hackery:

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

è un po 'debole, ma dovrebbe coprire molti casi.


Le prime 3 righe sono le più importanti :) Esempio e collegamento alla definizione del formato
Borik

2

per me va bene

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

Questa domanda ovviamente sta usando il motore di visualizzazione del rasoio, hai risposto usando una lingua diversa.
Rhys Bevilaqua

2

Ha avuto lo stesso problema di recente.

Ho scoperto che anche la semplice definizione di DataType come Date nel modello funziona (utilizzando l'approccio Code First)

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


0

se voglio solo visualizzare la data in formato breve, uso solo @ Model.date.ToShortDateString () e stampa la data in


0

Se tutto ciò che vuoi fare è visualizzare la data con un formato specifico, chiama:

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

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

Risulterà nel seguente formato,

26-Apr-2013

04/26/13

Cosa succederà se @ Model.LeadDate == null?
Bimal Das

0

questo verrà visualizzato in dd/MM/yyyyformato nella tua vista

In vista:

invece di DisplayForusare questo codice

<td>

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

</td

controlla anche se il valore è nullo nella colonna della data, se è vero, verrà visualizzata la data è vuota o la data formattata effettiva dalla colonna.

La speranza aiuta qualcuno.


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


-2

Visualizza solo la regolazione del file in questo modo. Puoi provare questo.

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

item.transdateè il tuo DateTimetipo di dati.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.