Comment rendre un DateTime dans un format spécifique dans ASP.NET MVC 3?

117

Si j'ai dans ma classe de modèle une propriété de type, DateTimecomment puis-je la rendre dans un format spécifique - par exemple dans le format qui ToLongDateString()renvoie?

J'ai essayé ça ...

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

... qui lève une exception car l'expression doit pointer vers une propriété ou un champ. Et ça...

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

... qui ne lève pas d'exception, mais la sortie rendue est vide (bien qu'elle valcontienne la valeur attendue, comme j'ai pu le voir dans le débogueur).

Merci pour les conseils à l'avance!

Éditer

ToLongDateStringn'est qu'un exemple. Ce que je souhaite utiliser à la place, ToLongDateStringc'est une méthode d'extension personnalisée de DateTimeet 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 "";
}

Donc, je pense que je ne peux pas utiliser l' DisplayFormatattribut et le DataFormatStringparamètre sur les propriétés ViewModel.

Slauma
la source

Réponses:

159

Si tout ce que vous voulez faire est d'afficher la date avec un format spécifique, appelez simplement:

@String.Format(myFormat, Model.MyDateTime)

L'utilisation @Html.DisplayFor(...)est juste un travail supplémentaire à moins que vous ne spécifiiez un modèle ou que vous deviez utiliser quelque chose qui est construit sur des modèles, comme l'itération d'un IEnumerable<T>. La création d'un modèle est assez simple et peut également offrir beaucoup de flexibilité. Créez un dossier dans votre dossier de vues pour le contrôleur actuel (ou le dossier de vues partagées) appelé DisplayTemplates. Dans ce dossier, ajoutez une vue partielle avec le type de modèle pour lequel vous souhaitez créer le modèle. Dans ce cas, j'ai ajouté /Views/Shared/DisplayTemplateset ajouté une vue partielle appelée ShortDateTime.cshtml.

@model System.DateTime

@Model.ToShortDateString()

Et maintenant, vous pouvez appeler ce modèle avec la ligne suivante:

@Html.DisplayFor(m => m.MyDateTime, "ShortDateTime")
Nick Larsen
la source
Merci, cela semble bon, et ce paramètre de modèle ("ShortDateTime") résout également le problème que j'avais décrit dans mon commentaire à la réponse ataddeini.
Slauma
3
Si le type est "DateTime?" au lieu de "DateTime" (@model DateTime?) ... le modèle ciplay gérera les datetimes Nullable ou non Nullable. Le nom du fichier doit rester "DateTime.cshtml".
Romias
+1 J'ai dû commenter cela, a très bien fonctionné dans mon application! Merci!
Russell Christensen
Use @ Html.DisplayFor () n'est pas un travail supplémentaire, il rend la représentation html du modèle, même sans modèles .... ne soyez pas confus ...
Cabuxa.Mapache
stackoverflow.com/questions/19920603/… contient du code qui est utile pour traiter les dates-heures Nullable @Romias mentionne.
Walter de Jong
171

Vous pouvez décorer votre propriété de modèle de vue avec l' [DisplayFormat]attribut:

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

et à votre avis:

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

ou, pour afficher la valeur,

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

Une autre possibilité, que je ne recommande pas, est d'utiliser un assistant faiblement typé:

@Html.TextBox("MyDate", Model.MyDate.ToLongDateString())
Darin Dimitrov
la source
1
@Darin: Je ne veux pas d'élément d'entrée, mais uniquement une sortie de texte statique. Je dois également mentionner que le format réel est créé par une méthode d'extension personnalisée de DateTime(ToLongDateString n'était qu'un exemple), il est donc peu probable que je puisse utiliser DataFormatString.
Slauma
2
@Slauma, que diriez-vous @Html.DisplayFor(x => x.MyDateTime). @NickLarsen c'est la raison pour laquelle les modèles de vue doivent être utilisés. Dans mon exemple, je décore le modèle de vue avec cet attribut et une vue est déjà liée à une vue donnée, c'est son but.
Darin Dimitrov
1
@Slauma, OK, dans ce cas, vous pouvez soit utiliser un modèle d'affichage personnalisé, soit demander à votre modèle de vue d'utiliser une propriété de chaîne et la conversion sera effectuée au niveau de la couche de mappage lorsque vous mappez entre le modèle et le modèle de vue (de cette façon, vous pouvez utilisez toujours uniquement Html.DisplayFor dans la vue).
Darin Dimitrov
5
@NickLarsen, non, c'est un modèle de vue par vue. C'est parce que les gens font cette erreur que des questions telles que Comment exclure certaines propriétés de la validation dans une action de contrôleur et pas sur une autre? sont si courants sur SO.
Darin Dimitrov
1
Revenant à cette question un an plus tard, je suis d'accord avec l'argument d'un modèle par vue. Je pense toujours que tout ce qui concerne les choix d'affichage appartient à la vue et non au modèle.
Nick Larsen
26

Sortie formatée simple à l'intérieur du modèle

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

ou dans la boucle foreach

@String.Format("{0:d}", item.CreatedOn)
odesuk
la source
Semble être un double de la réponse acceptée de l'utilisationstring.Format
Paul Tyng
2
@PaulTyng cette réponse était plus claire pour moi que la réponse acceptée, odesuk a en fait montré le format dans le premier paramètre, ce qui, en tant que newb, m'aide.
Dan Beaulieu
1
Je suis d'accord, c'est la réponse qui m'a aidé.
glenn garson
26

J'utilise l'approche suivante pour le format en ligne et affiche une propriété de date à partir du modèle.

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

Sinon, lors du remplissage d'une zone de texte ou d'un éditeur, vous pouvez faire comme @Darin suggéré, décorer l'attribut avec un [DisplayFormat]attribut.

Steven
la source
C'est la solution que je recherche!
Envil
C'est la solution que je recherchais!
Raihan Ridoy
9

Si tous vos DateTimetypes sont rendus de la même manière, vous pouvez utiliser un DateTimemodèle d'affichage personnalisé .

Dans votre dossier Views, créez un dossier nommé «DisplayTemplates» soit sous le dossier de vues spécifiques de votre contrôleur, soit sous le dossier «Shared» (ceux-ci fonctionnent comme des partiels).

À l'intérieur, créez un fichier nommé DateTime.cshtmlqui prend DateTimecomme @modelcode et comment vous voulez rendre votre date:

@model System.DateTime
@Model.ToLongDateString()

Maintenant, vous pouvez simplement l'utiliser dans vos vues et cela devrait fonctionner:

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

Tant que vous suivez la convention de l'ajouter au dossier "DisplayTemplates" et de nommer le fichier pour qu'il corresponde au type que vous affichez, MVC l'utilisera automatiquement pour afficher vos valeurs. Cela fonctionne également pour l'édition de scénarios à l'aide de "EditorTemplates".

Voici quelques informations supplémentaires sur les modèles .

ataddeini
la source
Merci, je viens de le tester et cela fonctionne bien si le type est vraiment DateTime. Cependant, j'ai quelques propriétés DateTime nullables. J'ai essayé de créer un deuxième fichier dans le DisplayTemplatesdossier, appelé NullableDateTime.cshtmlet dans: @using MyHelpers @model System.DateTime? @Model.MyCustomExtension()Voici MyCustomExtensionune méthode d'extension sur DateTime?. Cependant, il obtient une exception quand un DateTime? field est vraiment nul, ce qui me dit que le dictionnaire nécessite un élément de modèle de type DateTimequi n'est pas nul. Existe-t-il un moyen de définir un DisplayTemplate pour un DateTime nullable?
Slauma
@Slauma: Hmm, bonne question. Je m'en tiendrai probablement à NullableDateTime.cshtmlet utiliserais l'approche suggérée et utilisée par @NickLarsen @Html.DisplayFor(m => m.MyDateTime, "NullableDateTime").
ataddeini
Vous n'avez pas besoin d'ajouter explicitement le nom du modèle si votre modèle DateTime.cshtml est défini sur "@model DateTime?" au lieu de "DateTime". De cette façon, toutes les dates (nullables ou non) sont gérées par le même modèle ...
Romias
7

Ma préférence est de conserver les détails de mise en forme avec la vue et non avec le modèle de vue. Donc dans MVC4 / Razor:

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

référence au format datetime: http://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.71).aspx

Ensuite, j'ai un datepicker JQuery lié à lui, et qui met la date dans un format différent ... doh!

Il semble que je doive définir le format du sélecteur de date sur le même format.

Je stocke donc le System.Globalizationformatage dans un attribut data- * et je le collecte lors de la configuration du

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

Et voici la partie désagréable: les formats de .net et de datepicker ne correspondent pas, donc le piratage est nécessaire:

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

c'est un peu faible, mais devrait couvrir de nombreux cas.

philn5d
la source
Les 3 premières lignes sont les plus importantes :) Exemple et lien vers la définition du format
Borik
2

travaille pour moi

<%=Model.MyDateTime.ToString("dd-MMM-yyyy")%>
numerah
la source
Cette question utilise évidemment le moteur de vue rasoir, vous avez répondu en utilisant une langue différente.
Rhys Bevilaqua
2

J'ai eu le même problème récemment.

J'ai découvert que la simple définition de DataType comme Date dans le modèle fonctionne également (en utilisant l'approche Code First)

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

tu peux faire comme ça @item.Date.Value.Tostring("dd-MMM-yy");

Saurabh Solanki
la source
0

si je veux juste afficher la date au format court, j'utilise simplement @ Model.date.ToShortDateString () et il imprime la date dans

Marcianin
la source
0

Si tout ce que vous voulez faire est d'afficher la date avec un format spécifique, appelez simplement:

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

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

Il en résultera le format suivant,

26-Apr-2013

04/26/13
Crinière de Kailas
la source
Que se passera-t-il si @ Model.LeadDate == null?
Bimal Das
0

cela s'affichera au dd/MM/yyyyformat dans votre vue

En vue:

au lieu d' DisplayForutiliser ce code

<td>

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

</td

il vérifie également si la valeur est nulle dans la colonne de date, si elle est vraie, elle affichera la date est vide ou la date mise en forme réelle de la colonne.

L'espoir aide quelqu'un.

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

Dans MVC5, j'utiliserais, si votre modèle est le datetime

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

Ou si votre modèle contient la propriété du datetime

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

Voici la signification officielle des formats:

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

José Ortega
la source
-2

Seulement voir le fichier Ajuster comme ça. Vous pouvez essayer ceci.

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

item.transdatece sont vos DateTimedonnées de type.

Martine Chang
la source