วิธีการแสดง DateTime ในรูปแบบเฉพาะใน ASP.NET MVC 3


117

หากฉันมีคุณสมบัติประเภทหนึ่งในคลาสโมเดลDateTimeฉันจะแสดงผลในรูปแบบเฉพาะได้อย่างไรตัวอย่างเช่นในรูปแบบที่ToLongDateString()ส่งคืน

ฉันได้ลองสิ่งนี้ ...

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

... ซึ่งแสดงข้อยกเว้นเนื่องจากนิพจน์ต้องชี้ไปที่คุณสมบัติหรือฟิลด์ และนี่...

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

... ซึ่งไม่ได้ทำให้เกิดข้อยกเว้น แต่เอาต์พุตที่แสดงผลนั้นว่างเปล่า (แม้ว่าจะvalมีค่าที่คาดหวังอย่างที่ฉันเห็นในดีบักเกอร์)

ขอบคุณสำหรับเคล็ดลับล่วงหน้า!

แก้ไข

ToLongDateStringเป็นเพียงตัวอย่างเท่านั้น สิ่งที่ฉันต้องการใช้แทนToLongDateStringคือวิธีการขยายที่กำหนดเองของDateTimeและ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 "";
}

ดังนั้นฉันคิดว่าฉันไม่สามารถใช้DisplayFormatแอตทริบิวต์และDataFormatStringพารามิเตอร์บนคุณสมบัติ ViewModel ได้

คำตอบ:


159

หากสิ่งที่คุณต้องการทำคือแสดงวันที่ในรูปแบบเฉพาะเพียงโทร:

@String.Format(myFormat, Model.MyDateTime)

การใช้@Html.DisplayFor(...)เป็นเพียงงานพิเศษเว้นแต่คุณจะระบุเทมเพลตหรือจำเป็นต้องใช้สิ่งที่สร้างขึ้นจากเทมเพลตเช่นการทำซ้ำIEnumerable<T>ไฟล์. การสร้างเทมเพลตนั้นง่ายเพียงพอและสามารถให้ความยืดหยุ่นได้มากเช่นกัน สร้างโฟลเดอร์ในมุมมองของคุณโฟลเดอร์สำหรับตัวควบคุมปัจจุบัน (หรือวิวที่ใช้ร่วมกันโฟลเดอร์) DisplayTemplatesที่เรียกว่า ภายในโฟลเดอร์นั้นให้เพิ่มมุมมองบางส่วนด้วยประเภทโมเดลที่คุณต้องการสร้างเทมเพลต ในกรณีนี้ผมเพิ่มและเพิ่มมุมมองบางส่วนที่เรียกว่า/Views/Shared/DisplayTemplatesShortDateTime.cshtml

@model System.DateTime

@Model.ToShortDateString()

และตอนนี้คุณสามารถเรียกเทมเพลตนั้นด้วยบรรทัดต่อไปนี้:

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

ขอบคุณสิ่งนี้ดูดีและพารามิเตอร์เทมเพลตนี้ ("ShortDateTime") ช่วยแก้ปัญหาที่ฉันได้อธิบายไว้ในความคิดเห็นของฉันสำหรับคำตอบ ataddeini
Slauma

3
หากเป็นประเภท "DateTime?" แทนที่จะเป็น "DateTime" (@model DateTime?) ... เทมเพลต ciplay จะจัดการวันที่ที่เป็นโมฆะหรือไม่เป็นค่าว่างได้ ชื่อไฟล์ควรเป็น "DateTime.cshtml"
Romias

+1 ต้องแสดงความคิดเห็นเกี่ยวกับสิ่งนี้ใช้งานได้ดีในแอปพลิเคชันของฉัน! ขอบคุณ!
Russell Christensen

Use @ Html.DisplayFor () ไม่ใช่งานพิเศษ แต่แสดงการแสดง html ของโมเดลแม้ว่าจะไม่มีเทมเพลตก็ตาม ... อย่าสับสน ...
Cabuxa.Mapache

stackoverflow.com/questions/19920603/…มีรหัสที่เป็นประโยชน์ในการจัดการกับเวลาที่เป็นโมฆะที่ @Romias กล่าวถึง
Walter de Jong

171

คุณสามารถตกแต่งคุณสมบัติโมเดลมุมมองของคุณด้วย[DisplayFormat]แอตทริบิวต์:

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

และในมุมมองของคุณ:

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

หรือสำหรับการแสดงค่า

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

ความเป็นไปได้อีกอย่างที่ฉันไม่แนะนำคือการใช้ตัวช่วยที่พิมพ์ผิด:

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

1
@ ดาริน: ฉันไม่ต้องการองค์ประกอบอินพุต แต่มีเพียงเอาต์พุตข้อความคงที่ ฉันควรพูดถึงว่ารูปแบบจริงถูกสร้างขึ้นโดยวิธีการขยายที่กำหนดเองของDateTime(ToLongDateString เป็นเพียงตัวอย่างเท่านั้น) ดังนั้นจึงไม่น่าที่ฉันจะสามารถDataFormatStringใช้ได้
Slauma

2
@ สล่ามาไง@Html.DisplayFor(x => x.MyDateTime). @NickLarsen นั่นคือเหตุผลที่ควรใช้โมเดลมุมมอง ในตัวอย่างของฉันฉันตกแต่งโมเดลมุมมองด้วยแอตทริบิวต์นี้และมุมมองเชื่อมโยงกับมุมมองที่กำหนดแล้วนั่นคือวัตถุประสงค์
Darin Dimitrov

1
@Slauma ตกลงในกรณีนี้คุณสามารถใช้เทมเพลตการแสดงผลที่กำหนดเองหรือให้โมเดลมุมมองของคุณใช้คุณสมบัติสตริงและการแปลงจะทำที่เลเยอร์การแมปเมื่อคุณแมประหว่างโมเดลและโมเดลมุมมอง (วิธีนี้คุณสามารถทำได้ ยังคงใช้เฉพาะ Html.DisplayFor ในมุมมอง)
Darin Dimitrov

5
@NickLarsen ไม่เป็นแบบจำลองการดูหนึ่งครั้งต่อการดู เป็นเพราะผู้คนทำผิดนี้จึงตั้งคำถามเช่นฉันจะแยกคุณสมบัติบางอย่างออกจากการตรวจสอบความถูกต้องในการดำเนินการของคอนโทรลเลอร์หนึ่งตัวได้อย่างไร เป็นเรื่องธรรมดาใน SO
Darin Dimitrov

1
กลับมาที่คำถามนี้ในอีกหนึ่งปีต่อมาฉันเห็นด้วยกับข้อโต้แย้งสำหรับหนึ่งรุ่นต่อการดู ฉันยังคงคิดว่าสิ่งใดก็ตามที่เกี่ยวข้องกับตัวเลือกการแสดงผลอยู่ในมุมมองไม่ใช่โมเดลอย่างไรก็ตาม
Nick Larsen

26

เอาต์พุตที่จัดรูปแบบอย่างง่ายภายในโมเดล

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

หรือใน foreach loop

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

ดูเหมือนจะซ้ำกับคำตอบที่ยอมรับในการใช้string.Format
Paul Tyng

2
@PaulTyng คำตอบนี้ชัดเจนสำหรับฉันมากกว่าคำตอบที่ยอมรับ odesuk แสดงรูปแบบในพารามิเตอร์แรกซึ่งในฐานะที่เป็น newb ช่วยฉันได้
Dan Beaulieu

1
ฉันเห็นด้วยนี่คือคำตอบที่ช่วยฉัน
glenn garson

26

ฉันใช้แนวทางต่อไปนี้ในการจัดรูปแบบอินไลน์และแสดงคุณสมบัติวันที่จากแบบจำลอง

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

มิฉะนั้นเมื่อเติมกล่องข้อความหรือตัวแก้ไขคุณสามารถทำได้เหมือนที่ @Darin แนะนำให้ตกแต่งแอตทริบิวต์ด้วย[DisplayFormat]แอตทริบิวต์


นี่คือทางออกที่ฉันกำลังมองหา!
Envil

นี่คือทางออกที่ฉันกำลังมองหา!
Raihan Ridoy

9

หากทุกDateTimeประเภทของคุณแสดงผลในลักษณะเดียวกันคุณสามารถใช้ไฟล์DateTimeเทมเพลตการแสดงผลที่ได้

ในโฟลเดอร์ Views ของคุณให้สร้างโฟลเดอร์ชื่อ "DisplayTemplates" ภายใต้โฟลเดอร์มุมมองเฉพาะของคอนโทรลเลอร์ของคุณหรือภายใต้โฟลเดอร์ "แชร์" (ซึ่งทำงานคล้ายกับบางส่วน)

ภายในสร้างไฟล์ชื่อDateTime.cshtmlที่ใช้DateTimeเป็น@modelรหัสและวิธีที่คุณต้องการแสดงวันที่ของคุณ:

@model System.DateTime
@Model.ToLongDateString()

ตอนนี้คุณสามารถใช้สิ่งนี้ในมุมมองของคุณและควรใช้งานได้:

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

ตราบเท่าที่คุณทำตามหลักการเพิ่มลงในโฟลเดอร์ "DisplayTemplates" และตั้งชื่อไฟล์ให้ตรงกับประเภทที่คุณกำลังแสดง MVC จะใช้โดยอัตโนมัติเพื่อแสดงค่าของคุณ นอกจากนี้ยังใช้ได้กับการแก้ไขสถานการณ์โดยใช้ "EditorTemplates"

นี่คือบางส่วนข้อมูลเพิ่มเติมเกี่ยวกับแม่


DateTimeขอบคุณฉันเพิ่งผ่านการทดสอบมันและมันทำงานได้ดีถ้าประเภทที่เป็นจริง อย่างไรก็ตามฉันมีคุณสมบัติ DateTime ที่เป็นโมฆะ ฉันพยายามสร้างไฟล์ที่สองในDisplayTemplatesโฟลเดอร์ชื่อNullableDateTime.cshtmlและภายใน: @using MyHelpers @model System.DateTime? @Model.MyCustomExtension()นี่MyCustomExtensionคือวิธีการขยายบนDateTime?. อย่างไรก็ตามจะได้รับข้อยกเว้นเมื่อ DateTime? ฟิลด์เป็นโมฆะจริง ๆ โดยบอกฉันว่าพจนานุกรมต้องการองค์ประกอบแบบจำลองDateTimeที่ไม่เป็นโมฆะ มีวิธีกำหนด DisplayTemplate สำหรับ DateTime ที่เป็นโมฆะหรือไม่?
Slauma

@Slauma: อืมเป็นคำถามที่ดี ผมก็อาจจะติดกับNullableDateTime.cshtmlและใช้วิธีการที่ @NickLarsen @Html.DisplayFor(m => m.MyDateTime, "NullableDateTime")ปัญหาและการใช้งาน
ataddeini

คุณไม่จำเป็นต้องเพิ่มชื่อของเทมเพลตอย่างชัดเจนหากเทมเพลต DateTime.cshtml ของคุณตั้งค่าเป็น "@model DateTime?" แทน "DateTime" ด้วยวิธีนี้วันที่ทั้งหมด (เป็นโมฆะหรือไม่) จะถูกจัดการโดยเทมเพลตเดียวกัน ...
Romias

7

ความชอบของฉันคือเก็บรายละเอียดการจัดรูปแบบด้วยมุมมองไม่ใช่ดูโมเดล ดังนั้นใน MVC4 / Razor:

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

การอ้างอิงรูปแบบวันที่และเวลา: http://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.71).aspx

จากนั้นฉันมี JQuery datepicker ที่ผูกไว้และนั่นคือวันที่ในรูปแบบอื่น ... doh!

ดูเหมือนว่าฉันต้องตั้งค่ารูปแบบของ datepicker ให้เป็นรูปแบบเดียวกัน

ดังนั้นฉันจึงจัดเก็บการSystem.Globalizationจัดรูปแบบในแอตทริบิวต์ data- * และรวบรวมเมื่อตั้งค่าไฟล์

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

และนี่คือส่วนที่น่ารังเกียจ: รูปแบบของ. net และ datepicker ไม่ตรงกันดังนั้นจึงจำเป็นต้องมีการแฮ็กเกอร์:

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

เป็นเรื่องที่อ่อนแอ แต่ควรครอบคลุมหลายกรณี


3 บรรทัดแรกมีความสำคัญที่สุด :) ตัวอย่างและลิงก์ไปยังนิยามรูปแบบ
Borik

2

เหมาะกับฉัน

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

เห็นได้ชัดว่าคำถามนี้ใช้เครื่องมือดูมีดโกนคุณได้ตอบกลับโดยใช้ภาษาอื่น
Rhys Bevilaqua

2

มีปัญหาเดียวกันเมื่อเร็ว ๆ นี้

ฉันค้นพบว่าการกำหนดDataTypeเป็นวันที่ในโมเดลก็ใช้ได้เช่นกัน (โดยใช้วิธี Code First)

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


0

หากฉันต้องการแสดงวันที่ในรูปแบบสั้น ๆ ฉันแค่ใช้ @ Model.date ToShortDateString () และพิมพ์วันที่ใน


0

หากสิ่งที่คุณต้องการทำคือแสดงวันที่ในรูปแบบเฉพาะเพียงโทร:

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

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

จะส่งผลในรูปแบบต่อไปนี้

26-Apr-2013

04/26/13

จะเกิดอะไรขึ้นถ้า @ Model.LeadDate == null?
Bimal Das

0

สิ่งนี้จะแสดงในdd/MM/yyyyรูปแบบในมุมมองของคุณ

ในมุมมอง:

แทนที่จะDisplayForใช้รหัสนี้

<td>

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

</td

นอกจากนี้ยังตรวจสอบว่าค่าเป็นโมฆะในคอลัมน์วันที่หรือไม่หากเป็นจริงจะแสดงวันที่ว่างเปล่าหรือวันที่จัดรูปแบบจริงจากคอลัมน์

ความหวังช่วยใครบางคน



0

ใน MVC5 ฉันจะใช้ถ้ารุ่นของคุณเป็นวันที่และเวลา

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

หรือหากโมเดลของคุณมีคุณสมบัติของวันที่และเวลา

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

นี่คือความหมายอย่างเป็นทางการของรูปแบบ:

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


-2

ดูไฟล์เท่านั้นปรับแบบนี้ คุณอาจลองทำเช่นนี้

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

item.transdateเป็นข้อมูลDateTimeประเภทของคุณ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.