views:

1743

answers:

4

Hello,

I'm struggling myself trying to find an easy way to change the DateTime format for my Table field.

I have a Model called Article with a field called releaseDate that is a DateTime

I managed to do it (visually) by converting the

Article.releaseDate.ToString("dd/MM/yy")

but the thing is when I try to submit a date with this format from the create action it returns an error telling the the format is wrong.

Any easy way to change the default ("MM/dd/yy") to ("dd/MM/yy")?

Thanks in advance

A: 

The View will eventually be rendered in HTML, and since HTML is text-based, you might as well just take the consequence and make the releaseData property a string instead of a DateTime.

That would also have the added benefit that you don't have to invoke methods (ToString) from your Views.

If you need to round-trip the value (i.e. submit it) you will need to parse it in any case, because it will arrive in the web request as a string. Such parsing can be done in a custom ModelBinder if the DefaultModelBinder doesn't fit the bill.

Mark Seemann
-1 Isn't the point of MVC to separate the model, data access and presentation layers? The model should contain releaseDate as a DateTime as it is holding a date time value regardless of how it is displayed. Let the default model binders do their job for output and input conversion.
David G
@DaveG: The Model in this case would be a ViewModel, which should do whatever it takes to make the View as passive as possible. It could encapsulate the real Domain Model which would obviously have the releaseDate represented as a DateTime, but the point is exactly that the Domain Model should not be concerned with presentation.
Mark Seemann
Yes, but the OP already stated they were using an Article type from the existing Model. If you created a specific ViewModel type with the releaseData property as a string how would you reuse that accross different Views? What would happen if one view was editable for example with a date format of dd/MM/yyyy but another view was non editable with a display label of the format MMMM dd, yyyy. You would have to create another ViewModel for each view. Not very DRY.
David G
@DaveG: It is pretty widely accepted these days that you should not bind Views directly to Domain Models - neither in ASP.NET MVC, WPF or any other technology. Once that is established, we can subsequently discuss how to apply the DRY principle.
Mark Seemann
I never said it SHOULD be binded directly to the domain model, that's a different discussion, but ludicco is binding directly. My point is simply releaseDate should be a DateTime value even in your separate ViewModel type, not a String, and let your View handle the displaying of the date.
David G
+3  A: 

Yep. It sure is mate :)

try changing the current thread's CULTURE. By default, it takes the system's OS. but u can override that.

check this out...

Thread.CurrentThread.CurrentCulture = new CultureInfo("en-GB");
Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-GB");

Here's a good post explaining ....

HTH.

Pure.Krome
Thanks for you answer Pure.Krome, As I was looking to change all the app defaults maybe the web.config solution from Dave seemed to be the straight forward one.
ludicco
no probs :) glad u got your answer :)
Pure.Krome
A: 

Your problem here is that since the compiler only sees two digits/two digits/two digits in both cases, it has no way to know that you want day/month/year instead of month/day/year until it tries to actually casts, and notices that your value for the month is >= 12.

You could solve this by splitting the date on /, and throwing in the arguments in the "correct" order to the compiler, like so:

string[] dateParts = input.Split("/");
int day; int month; int year;

// You could use a boolean variable here to double-check that all casts are successful
Int32.TryParse(dateParts[0], out day);
Int32.TryParse(dateParts[1], out month);
Int32.TryParse(dateParts[2], out year);

var output = new DateTime(year, month, day);

If you put this in a separate function you could use it like this to support both formats:

DateTime releaseDate;
try
{
    // will throw exception if input is not in the default format
    releaseDate = new DateTime(input);
}
catch (InvalidFormatException ex)
{
    releaseDate = GetDateTimeFromNonStandardInput(input);
}
catch 
{
    throw; // or do whatever error handling you feel like.
}

Personally, I'd write the GetDateTimeFromNonStandardInput() as an extension method to the DateTime class.

Tomas Lycken
+4  A: 

You could change the culture information on a page by page basis by including

<%@ Page UICulture="en" Culture="en-GB" %>

or globally across all pages by adding to your web.config

<globalization uiCulture="en" culture="en-GB" />

Both will change the DateTime model binding to dd/MM/yyyy so no conversion is necessary.

See this question for more information

The code equivalent is

CultureInfo.CurrentUICulture.DateTimeFormat
 = CultureInfo.CurrentCulture.DateTimeFormat
 = new CultureInfo( "en-GB", false ).DateTimeFormat;
David G
Thanks a Lot Dave web.config solution solved my problem quickly
ludicco