Làm thế nào để hiển thị DateTime ở một định dạng cụ thể trong ASP.NET MVC 3?


117

Nếu tôi có trong lớp mô hình của mình một thuộc tính kiểu, DateTimelàm cách nào tôi có thể hiển thị nó ở một định dạng cụ thể - ví dụ: trong định dạng ToLongDateString()trả về?

Tôi đã thử cái này ...

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

... mà ném ra một ngoại lệ vì biểu thức phải trỏ đến một thuộc tính hoặc trường. Và điều này...

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

... mà không ném ra một ngoại lệ, nhưng đầu ra được kết xuất là trống (mặc dù valchứa giá trị mong đợi, như tôi có thể thấy trong trình gỡ lỗi).

Cảm ơn các mẹo trước!

Biên tập

ToLongDateStringchỉ là một ví dụ. Những gì tôi thực sự muốn sử dụng thay vì ToLongDateStringlà một phương pháp mở rộng tùy chỉnh của DateTimeDateTime?:

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

Vì vậy, tôi nghĩ rằng tôi không thể sử dụng DisplayFormatthuộc tính và DataFormatStringtham số trên thuộc tính ViewModel.

Câu trả lời:


159

Nếu tất cả những gì bạn muốn làm là hiển thị ngày với một định dạng cụ thể, chỉ cần gọi:

@String.Format(myFormat, Model.MyDateTime)

Việc sử dụng @Html.DisplayFor(...)chỉ là công việc bổ sung trừ khi bạn đang chỉ định một mẫu hoặc cần sử dụng một cái gì đó được xây dựng trên các mẫu, như lặp lại một IEnumerable<T>. Tạo một mẫu đủ đơn giản và có thể cung cấp rất nhiều tính linh hoạt. Tạo một thư mục trong thư mục dạng xem của bạn cho bộ điều khiển hiện tại (hoặc thư mục dạng xem được chia sẻ) được gọi DisplayTemplates. Bên trong thư mục đó, thêm dạng xem từng phần với kiểu mô hình bạn muốn tạo mẫu. Trong trường hợp này, tôi đã thêm /Views/Shared/DisplayTemplatesvà thêm một chế độ xem từng phần được gọi là ShortDateTime.cshtml.

@model System.DateTime

@Model.ToShortDateString()

Và bây giờ bạn có thể gọi mẫu đó bằng dòng sau:

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

Cảm ơn, điều này có vẻ tốt và tham số mẫu này ("Thời gian ngắn") cũng giải quyết được vấn đề mà tôi đã mô tả trong nhận xét của mình cho câu trả lời ataddeini.
Slauma

3
Nếu loại là "DateTime?" thay vì "DateTime" (@model DateTime?) ... mẫu ciplay sẽ xử lý datetimes có thể nullable hoặc không nullable. Tên của tệp sẽ vẫn là "DateTime.cshtml".
Romias

+1 Đã phải nhận xét về điều này, hoạt động tuyệt vời trong ứng dụng của tôi! Cảm ơn!
Russell Christensen

Sử dụng @ Html.DisplayFor () không phải là việc làm thêm, nó ám đại diện html mô hình của, thậm chí không có mẫu .... không bị nhầm lẫn ...
Cabuxa.Mapache

stackoverflow.com/questions/19920603/… chứa mã hữu ích trong việc xử lý các đề cập về datetimes @Romias không có giá trị.
Walter de Jong

171

Bạn có thể trang trí [DisplayFormat]thuộc tính mô hình chế độ xem của mình bằng thuộc tính:

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

và theo quan điểm của bạn:

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

hoặc, để hiển thị giá trị,

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

Một khả năng khác, mà tôi không khuyến khích, là sử dụng một trình trợ giúp được đánh máy yếu:

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

1
@Darin: Tôi không muốn một phần tử đầu vào mà chỉ có đầu ra văn bản tĩnh. Tôi cũng nên đề cập rằng định dạng thực tế được tạo bởi một phương thức mở rộng tùy chỉnh của DateTime(ToLongDateString chỉ là một ví dụ), vì vậy không chắc rằng tôi có thể sử dụng DataFormatString.
Slauma

2
@Slauma, thế còn @Html.DisplayFor(x => x.MyDateTime). @NickLarsen đó là lý do tại sao nên sử dụng các mô hình chế độ xem. Trong ví dụ của tôi, tôi trang trí mô hình khung nhìn bằng thuộc tính này và một khung nhìn đã được gắn với một khung nhìn nhất định, đó là mục đích của nó.
Darin Dimitrov

1
@Slauma, OK, trong trường hợp này, bạn có thể sử dụng mẫu hiển thị tùy chỉnh hoặc để mô hình xem của bạn sử dụng thuộc tính chuỗi và chuyển đổi sẽ được thực hiện ở lớp ánh xạ khi bạn ánh xạ giữa mô hình và mô hình xem (theo cách này bạn có thể vẫn chỉ sử dụng Html.DisplayFor trong chế độ xem).
Darin Dimitrov

5
@NickLarsen, không, đó là một mô hình xem cho mỗi chế độ xem. Chính vì mọi người mắc lỗi này nên các câu hỏi như Làm cách nào để loại trừ một số thuộc tính khỏi xác thực trong một hành động của bộ điều khiển chứ không phải hành động khác? rất phổ biến trên SO.
Darin Dimitrov

1
Trở lại câu hỏi này một năm sau, tôi đồng ý với lập luận cho một mô hình cho mỗi quan điểm. Tuy nhiên, tôi vẫn nghĩ rằng bất cứ điều gì liên quan đến các lựa chọn hiển thị đều thuộc về chế độ xem chứ không phải mô hình.
Nick Larsen

26

Đầu ra được định dạng đơn giản bên trong mô hình

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

hoặc trong vòng lặp foreach

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

Có vẻ như là một bản sao của câu trả lời được chấp nhận sử dụngstring.Format
Paul Tyng

2
@PaulTyng câu trả lời này đối với tôi rõ ràng hơn câu trả lời được chấp nhận, odesuk thực sự đã hiển thị định dạng trong tham số đầu tiên, với tư cách là một người mới, giúp tôi.
Dan Beaulieu

1
Tôi đồng ý, đây là câu trả lời đã giúp tôi.
glenn garson

26

Tôi sử dụng cách tiếp cận sau để định dạng nội tuyến và hiển thị thuộc tính ngày tháng từ mô hình.

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

Nếu không, khi điền TextBox hoặc Editor, bạn có thể làm như @Darin đề xuất, trang trí thuộc tính bằng một [DisplayFormat]thuộc tính.


Đây là giải pháp mà tôi đang tìm kiếm!
Envil

Đây là giải pháp mà tôi đang tìm kiếm!
Raihan Ridoy

9

Nếu tất cả các DateTimeloại của bạn được hiển thị giống nhau, bạn có thể sử dụng DateTimemẫu hiển thị tùy chỉnh .

Trong thư mục Chế độ xem của bạn, hãy tạo một thư mục có tên "DisplayTemplates" trong thư mục chế độ xem cụ thể của bộ điều khiển của bạn hoặc trong thư mục "Chia sẻ" (các thư mục này hoạt động tương tự như các phần tử).

Bên trong, hãy tạo một tệp có tên DateTime.cshtmllấy DateTimetên @modelvà mã cách bạn muốn hiển thị ngày của mình:

@model System.DateTime
@Model.ToLongDateString()

Bây giờ bạn chỉ có thể sử dụng điều này trong chế độ xem của mình và nó sẽ hoạt động:

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

Miễn là bạn tuân theo quy ước thêm nó vào thư mục "DisplayTemplates" và đặt tên tệp phù hợp với loại mà bạn đang hiển thị, MVC sẽ tự động sử dụng điều đó để hiển thị giá trị của bạn. Điều này cũng hoạt động để chỉnh sửa kịch bản bằng "EditorTemplates".

Đây là một số thông tin thêm về các mẫu .


Cảm ơn, tôi vừa thử nghiệm nó và nó hoạt động tốt nếu loại thực sự là DateTime. Tuy nhiên, tôi có một số thuộc tính DateTime nullable. Tôi đã cố gắng tạo tệp thứ hai trong DisplayTemplatesthư mục, được gọi NullableDateTime.cshtmlvà bên trong: @using MyHelpers @model System.DateTime? @Model.MyCustomExtension()Đây MyCustomExtensionlà một phương thức mở rộng đang bật DateTime?. Tuy nhiên nó nhận được một ngoại lệ khi DateTime? trường thực sự là null cho tôi biết rằng từ điển yêu cầu một phần tử mô hình của loại DateTimekhông phải là null. Có cách nào để xác định một DisplayTemplate cho một DateTime nullable không?
Slauma

@Slauma: Hmm, câu hỏi hay. Tôi có thể sẽ gắn bó với NullableDateTime.cshtmlvà sử dụng phương pháp mà @NickLarsen đã đề xuất và sử dụng @Html.DisplayFor(m => m.MyDateTime, "NullableDateTime").
ataddeini

Bạn không cần thêm tên của mẫu một cách rõ ràng nếu mẫu DateTime.cshtml của bạn được đặt là "@model DateTime?" thay vì "DateTime". Bằng cách đó tất cả các Ngày (nullable hay không) được xử lý bởi cùng một mẫu ...
Romias

7

Sở thích của tôi là giữ các chi tiết định dạng với chế độ xem chứ không phải với chế độ xem. Vì vậy, trong MVC4 / Razor:

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

tham chiếu định dạng datetime: http://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.71).aspx

Sau đó, tôi có một trình chọn ngày của JQuery bị ràng buộc với nó và đó là ngày ở định dạng khác ... doh!

Có vẻ như tôi cần đặt định dạng của trình chọn ngày thành cùng một định dạng.

Vì vậy, tôi đang lưu trữ System.Globalizationđịnh dạng trong thuộc tính data- * và thu thập nó khi thiết lập

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

Và đây là một phần tệ hại: định dạng của .net và datepicker không khớp với nhau, vì vậy cần có hack:

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

đó là loại yếu, nhưng sẽ bao gồm rất nhiều trường hợp.


Đầu 3 dòng này là quan trọng nhất :) Ví dụ và liên kết đến Format Definition
Borik

2

làm việc cho tôi

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

Câu hỏi này rõ ràng là sử dụng công cụ xem dao cạo, bạn đã trả lời bằng một ngôn ngữ khác.
Rhys Bevilaqua

2

Đã gặp vấn đề tương tự gần đây.

Tôi phát hiện ra rằng chỉ cần xác định DataTypeNgày trong mô hình cũng hoạt động (sử dụng phương pháp Code First)

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


0

nếu tôi chỉ muốn hiển thị ngày ở định dạng ngắn, tôi chỉ cần sử dụng @ Model.date.ToShortDateString () và nó in ngày tháng ở dạng


0

Nếu tất cả những gì bạn muốn làm là hiển thị ngày với một định dạng cụ thể, chỉ cần gọi:

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

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

Nó sẽ dẫn đến định dạng sau,

26-Apr-2013

04/26/13

Điều gì sẽ xảy ra nếu @ Model.LeadDate == null?
Bimal Das

0

cái này sẽ hiển thị ở dd/MM/yyyyđịnh dạng trong Chế độ xem của bạn

Đang xem:

thay vì DisplayForsử dụng mã này

<td>

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

</td

nó cũng kiểm tra xem giá trị có rỗng trong cột ngày không, nếu đúng thì nó sẽ hiển thị Ngày trống hoặc ngày được định dạng thực tế từ cột.

Hy vọng sẽ giúp ai đó.


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


-2

Chỉ View File Điều chỉnh như thế này. Bạn có thể thử điều này.

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

item.transdatenó là DateTimedữ liệu kiểu của bạn .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.