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.

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")

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())

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)

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.


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 .


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.


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")%>

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; }


0

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


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

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.


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


-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.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.