Bagaimana cara membuat DateTime dalam format tertentu di ASP.NET MVC 3?

117

Jika saya memiliki di kelas model saya properti tipe DateTimebagaimana saya bisa membuatnya dalam format tertentu - misalnya dalam format yang ToLongDateString()mengembalikan?

Saya sudah mencoba ini ...

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

... yang memunculkan pengecualian karena ekspresi harus mengarah ke properti atau bidang. Dan ini...

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

... yang tidak memunculkan pengecualian, tetapi keluaran yang diberikan kosong (meskipun valberisi nilai yang diharapkan, seperti yang saya lihat di debugger).

Terima kasih atas tip sebelumnya!

Sunting

ToLongDateStringhanyalah sebuah contoh. Apa yang sebenarnya ingin saya gunakan sebagai ganti ToLongDateStringmetode ekstensi ubahsuaian DateTimedan 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 "";
}

Jadi, saya rasa saya tidak dapat menggunakan DisplayFormatatribut dan DataFormatStringparameter pada properti ViewModel.

Slauma
sumber

Jawaban:

159

Jika yang ingin Anda lakukan hanyalah menampilkan tanggal dengan format tertentu, panggil saja:

@String.Format(myFormat, Model.MyDateTime)

Menggunakan @Html.DisplayFor(...)hanyalah pekerjaan tambahan kecuali Anda menentukan template, atau perlu menggunakan sesuatu yang dibangun di atas template, seperti iterasi file IEnumerable<T>. Membuat template cukup sederhana, dan dapat memberikan banyak fleksibilitas juga. Buat folder di folder tampilan Anda untuk pengontrol saat ini (atau folder tampilan bersama) yang dipanggil DisplayTemplates. Di dalam folder itu, tambahkan tampilan parsial dengan tipe model yang Anda inginkan untuk membuat template. Dalam hal ini saya menambahkan /Views/Shared/DisplayTemplatesdan menambahkan tampilan parsial yang disebut ShortDateTime.cshtml.

@model System.DateTime

@Model.ToShortDateString()

Dan sekarang Anda dapat memanggil template itu dengan baris berikut:

@Html.DisplayFor(m => m.MyDateTime, "ShortDateTime")
Nick Larsen
sumber
Terima kasih, ini terlihat bagus, dan parameter template ini ("ShortDateTime") juga memecahkan masalah yang saya jelaskan dalam komentar saya untuk jawaban ataddeini.
Slauma
3
Jika jenisnya adalah "DateTime?" bukannya "DateTime" (@model DateTime?) ... template ciplay akan menangani datetimes nullable atau tidak nullable. Nama file harus tetap "DateTime.cshtml".
Romias
+1 Harus mengomentari ini, bekerja dengan baik di aplikasi saya! Terima kasih!
Russell Christensen
Gunakan @ Html.DisplayFor () bukan pekerjaan tambahan, ini membuat representasi html model, bahkan tanpa templat .... jangan bingung ...
Cabuxa.Mapache
stackoverflow.com/questions/19920603/… berisi kode yang berguna untuk menangani waktu yang dapat dibatalkan yang disebutkan @Romias.
Walter de Jong
171

Anda dapat menghias properti model tampilan Anda dengan [DisplayFormat]atribut:

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

dan menurut pandangan Anda:

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

atau, untuk menampilkan nilai,

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

Kemungkinan lain, yang tidak saya rekomendasikan, adalah menggunakan helper yang diketik lemah:

@Html.TextBox("MyDate", Model.MyDate.ToLongDateString())
Darin Dimitrov
sumber
1
@Darin: Saya tidak ingin elemen input, tetapi hanya output teks statis. Saya juga harus menyebutkan bahwa format sebenarnya dibuat dengan metode ekstensi kustom DateTime(ToLongDateString hanyalah sebuah contoh), jadi sepertinya saya tidak dapat menggunakannya DataFormatString.
Slauma
2
@Slauma, bagaimana kalau @Html.DisplayFor(x => x.MyDateTime). @NickLarsen itulah alasan mengapa model tampilan harus digunakan. Dalam contoh saya, saya menghias model tampilan dengan atribut ini dan tampilan sudah terikat dengan tampilan tertentu, itulah tujuannya.
Darin Dimitrov
1
@Slauma, OK, dalam hal ini Anda dapat menggunakan template tampilan ubahsuaian atau meminta model tampilan Anda menggunakan properti string dan konversi akan dilakukan di lapisan pemetaan saat Anda memetakan antara model dan model tampilan (dengan cara ini Anda bisa masih hanya menggunakan Html.DisplayFor dalam tampilan).
Darin Dimitrov
5
@NickLarsen, tidak, itu satu model tampilan per tampilan. Karena orang membuat kesalahan inilah maka pertanyaan seperti Bagaimana cara mengecualikan beberapa properti dari validasi dalam satu tindakan pengontrol dan bukan yang lain? sangat umum di SO.
Darin Dimitrov
1
Kembali ke pertanyaan ini setahun kemudian, saya setuju dengan argumen untuk satu model per tampilan. Saya masih berpikir apa pun yang berhubungan dengan pilihan tampilan termasuk dalam tampilan dan bukan modelnya.
Nick Larsen
26

Keluaran berformat sederhana di dalam model

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

atau di loop depan

@String.Format("{0:d}", item.CreatedOn)
odesuk
sumber
Sepertinya duplikat dari jawaban penggunaan yang diterimastring.Format
Paul Tyng
2
@PaulTyng jawaban ini lebih jelas bagi saya daripada jawaban yang diterima, odesuk sebenarnya menunjukkan format di parameter pertama yang, sebagai newb, membantu saya.
Dan Beaulieu
1
Saya setuju, inilah jawaban yang membantu saya.
glenn garson
26

Saya menggunakan pendekatan berikut untuk format inline dan menampilkan properti tanggal dari model.

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

Jika tidak, saat mengisi TextBox atau Editor, Anda dapat melakukan seperti yang disarankan @Darin, menghias atribut dengan [DisplayFormat]atribut.

Steven
sumber
Ini adalah solusi yang saya cari!
Envil
Ini adalah solusi yang saya cari!
Raihan Ridoy
9

Jika semua DateTimejenis Anda dirender dengan cara yang sama, Anda dapat menggunakan DateTimetemplate tampilan kustom .

Dalam folder Views Anda, buat folder bernama "DisplayTemplates" baik di bawah folder views spesifik pengontrol Anda, atau di bawah folder "Shared" (ini berfungsi mirip dengan parsial).

Dalam membuat sebuah file bernama DateTime.cshtmlyang mengambil DateTimesebagai @modeldan kode bagaimana Anda ingin membuat kencan Anda:

@model System.DateTime
@Model.ToLongDateString()

Sekarang Anda bisa menggunakan ini dalam pandangan Anda dan itu akan berfungsi:

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

Selama Anda mengikuti konvensi untuk menambahkannya ke folder "DisplayTemplates" dan menamai file agar sesuai dengan jenis yang Anda tampilkan, MVC akan secara otomatis menggunakannya untuk menampilkan nilai Anda. Ini juga berfungsi untuk mengedit skenario menggunakan "EditorTemplates".

Berikut beberapa informasi lebih lanjut tentang template .

ataddeini
sumber
Terima kasih, saya baru saja mengujinya dan berfungsi dengan baik jika tipenya benar-benar DateTime. Namun saya memiliki beberapa properti DateTime nullable. Saya mencoba membuat file kedua di DisplayTemplatesfolder, disebut NullableDateTime.cshtmldan di dalam: @using MyHelpers @model System.DateTime? @Model.MyCustomExtension()Berikut MyCustomExtensionadalah metode ekstensi di DateTime?. Namun itu mendapatkan pengecualian ketika DateTime? field benar-benar null yang memberi tahu saya bahwa kamus membutuhkan elemen model tipe DateTimeyang bukan null. Apakah ada cara untuk mendefinisikan DisplayTemplate untuk DateTime nullable?
Slauma
@Slauma: Hmm, pertanyaan bagus. Saya mungkin akan tetap NullableDateTime.cshtmlmenggunakan dan menggunakan pendekatan yang disarankan dan digunakan @NickLarsen @Html.DisplayFor(m => m.MyDateTime, "NullableDateTime").
ataddeini
Anda tidak perlu menambahkan nama template secara eksplisit jika template DateTime.cshtml Anda disetel sebagai "@model DateTime?" bukannya "DateTime". Dengan cara itu semua Tanggal (nullable atau tidak) ditangani oleh template yang sama ...
Romias
7

Preferensi saya adalah mempertahankan detail pemformatan dengan tampilan dan bukan model tampilan. Jadi di MVC4 / Razor:

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

referensi format waktu: http://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.71).aspx

Kemudian saya memiliki datepicker JQuery yang terikat padanya, dan itu menempatkan tanggal dalam format yang berbeda ... doh!

Sepertinya saya perlu mengatur format datepicker ke format yang sama.

Jadi saya menyimpan System.Globalizationpemformatan dalam atribut data- * dan mengumpulkannya saat menyiapkan

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

Dan inilah bagian yang sial: format .net dan datepicker tidak cocok, jadi peretasan diperlukan:

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

itu agak lemah, tetapi harus mencakup banyak kasus.

philn5d.dll
sumber
3 baris pertama adalah yang paling penting :) Contoh dan tautan ke Definisi Format
Borik
2

bekerja untuk saya

<%=Model.MyDateTime.ToString("dd-MMM-yyyy")%>
numerah
sumber
Pertanyaan ini jelas-jelas menggunakan mesin tampilan pisau cukur, Anda telah membalasnya dengan bahasa lain.
Rhys Bevilaqua
2

Mengalami masalah yang sama baru-baru ini.

Saya menemukan bahwa hanya dengan mendefinisikan DataType sebagai Date dalam model juga berfungsi (menggunakan pendekatan Code First)

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

kamu bisa melakukan seperti ini @item.Date.Value.Tostring("dd-MMM-yy");

Saurabh Solanki
sumber
0

jika saya hanya ingin menampilkan tanggal dalam format singkat saya hanya menggunakan @ Model.date.ToShortDateString () dan mencetak tanggal dalam

Marcianin
sumber
0

Jika yang ingin Anda lakukan hanyalah menampilkan tanggal dengan format tertentu, panggil saja:

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

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

Ini akan menghasilkan format berikut,

26-Apr-2013

04/26/13
Kailas Mane
sumber
Apa yang akan terjadi jika @ Model.LeadDate == null?
Bimal Das
0

ini akan ditampilkan dalam dd/MM/yyyyformat di View Anda

Dalam penglihatan:

alih-alih DisplayFormenggunakan kode ini

<td>

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

</td

itu juga memeriksa apakah nilainya null di kolom tanggal, jika benar maka itu akan menampilkan Tanggal Kosong atau tanggal diformat aktual dari kolom.

Harapan membantu seseorang.

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

Di MVC5 saya akan menggunakan, jika model Anda adalah datetime

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

Atau jika model Anda berisi properti datetime

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

Berikut arti resmi dari Format:

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

Jose Ortega
sumber
-2

Hanya Lihat File Sesuaikan seperti ini. Anda dapat mencoba ini.

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

item.transdateitu adalah DateTimetipe data Anda.

Martine Chang
sumber