Beejee
Beejee

Reputation: 2016

Textbox for DateTime wrong format

I know this is one of the most frequently asked questions. I had the solution to this but my current project is driving me nuts. I use the exact same code and still the result is different.

This is the code I normally use to format my dates:

@Html.TextBoxFor(m => m.DateOfAgenda, "{0:dd/MM/yyyy}")

Normally this should result in 07/10/2014 but for some reason it results in 07-10-2014 When I test it in another project the code above works as expected.

As a test I compared the results of the follow lines:

@Html.TextBoxFor(m => m.DateOfAgenda, "{0:dd/MM/yyyy}")
/* result: 07-10-2014*/
@Html.TextBoxFor(m => m.DateOfAgenda)
/* result: 7-10-2014 00:00:00*/

So my code seems to work partially only the '-' won't be replaced by '/' Does somebody know how to handle this once and for all?

EDIT

I have custom code setting the Culture. It uses the route to set it to a specific culture (default is 'nl') When I put the code below in comments everything seems to work. But I need this part to load my resources (label text, errors, ...).

var language = handler.RequestContext.RouteData.Values["language"];

if (language != null)
{
    Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(language.ToString());
    Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(language.ToString());
}

To be more specific this line breaks the format

Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(language.ToString());

Does anybody know why? I would expect that {0:dd/MM/yyyy} has priority because it is explicitly set. Funny part is that the / is just translated to -. When I use {0:dd//MM//yyyy} it results in 19--10--2014.

EDIT

Sorry for my late response but I couldn't find the time to try this out. So basically the problem was the culture and my format settings.

@Html.TextBoxFor(m => m.DateOfAgenda, "{0:dd/MM/yyyy}")

The '/' still gets replaced by the divider specified by your culture. My culture was set to 'nl' but by default this results in 'nl-nl' where they use '-' as date separator. I live in Belgium 'nl-be' and here we use '/'. The could have set my culture or change the format. The code below did the trick.

@Html.TextBoxFor(m => m.DateOfAgenda, "{0:dd'/'MM'/'yyyy}")

Upvotes: 7

Views: 3083

Answers (4)

user1364100
user1364100

Reputation:

Model page

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

View Page

@Html.EditorFor(model => model.DateOfAgenda)

Upvotes: 0

user1364100
user1364100

Reputation:

View Page

@Html.TextBoxFor(m => m.DateOfAgenda, new { Value = Model.DateOfAgenda.ToString("dd/MM/yyyy")});

Upvotes: 0

user3559349
user3559349

Reputation:

This appears to be by design. TextBoxFor sets the value as per the following code snippet

string attemptedValue = (string)htmlHelper.GetModelStateValue(fullName, typeof(string));
tagBuilder.MergeAttribute("value", attemptedValue ?? ((useViewData) ? htmlHelper.EvalString(fullName, format) : valueParameter), isExplicitValue);

which calls the EvalString method of HtmlHelper

internal string EvalString(string key, string format)
{
  return Convert.ToString(ViewData.Eval(key, format), CultureInfo.CurrentCulture);
}

which calls the Eval method of ViewDataDictionary

public string Eval(string expression, string format)
{
  object value = Eval(expression);
  return FormatValueInternal(value, format);
}

internal static string FormatValueInternal(object value, string format)
{
  ....
  return String.Format(CultureInfo.CurrentCulture, format, value);
}

So the value uses the format of the current culture. I presume this is because the DefaultModelBinder use the current culture info to parse the string representation of the date back to a DateTime (if you were able to override it, it would not bind unless you created a custom model binder.

Upvotes: 1

Tim Schmelter
Tim Schmelter

Reputation: 460038

I'm not that familiar with ASP.NET MVC, but if you don't specify a format, your current culture's DateTimeFormat is used. Also, / is a special format specifier in .NET which means "replace me with the current DateTimeFormats date-separator which seems to be -.

So you should provide CultureInfo.InvariantCulture or mask the format specifier by using \\/instead:

@Html.TextBoxFor(m => m.DateOfAgenda, "{0:dd\\/MM\\/yyyy}")

or by using the character literal '/':

@Html.TextBoxFor(m => m.DateOfAgenda, "{0:dd'/'MM'/'yyyy}")

Read: The "/" Custom Format Specifier

Upvotes: 5

Related Questions