.NET saving date in dd/MM/yyyy format in HttpPost - c#

Unlike the U.S.A ... most other countries uses the dd/MM/yyyy format (from smallest to biggest). However, .NET naturally takes in date in MM/dd/yyyy format.
I have an input that accepts a datetime, and the user will want to type in the date in dd/MM/yyyy format, let's say they type in 30/1/2017 ... but when that date is posted in the backend, it becomes unrecognized.. or it becomes reversed (1/2/2017 becomes 2/1/2017).
[HttpPost]
public ActionResult Save(DateTime date) // user entered 1/2/2017 from front-end
{
date.ToString("dd/MM/yyyy"); // this becomes 2/1/2017
}
Is there some kind of global setting to reverse this recognization of date in .NET? I would not like to manually switch dates from front-end because that seems like alot of work and alot of places to do it from.

You'd be better off setting the culture on the thread or in the controller initialization, or in the routing. There are a couple of answers in this question that show several excellent ways to do it.
The point is, the Thread.CurrentCulture controls the formatting of date/time and currency, among other cool things...so you can focus on the real solution, and leave all the trivial work to the framework.

DateTime.ParseExact is one of the shots you can try.
You need to specify culture, and then parse the date:
CultureInfo provider = CultureInfo.InvariantCulture;
DateTime.ParseExact("01/02/2017", "dd/MM/yyyy", provider);
DateTime.ParseExact("01/02/2017", "MM/dd/yyyy", provider);
If you will show output, the first one will be [01.02.2017 00:00:00] and the seccond [02.01.2017 00:00:00]
Your solution does not work, because when you are getting the data, it's probalbly get with the same American format of "MM/dd/yyyy"

DateTime isn't a good idea for serialisation/deserialisation like that because of stuff like this, or timezones. Rather than trying to hack it such that it works, avoid it altogether by sending it as a Unix timestamp (or similar things, like strings with timezone info that you then parse), and then turn it into a DateTime on your end.
You can follow this answer and cater it to your purposes like so:
[HttpPost]
public ActionResult Save(double timestamp)
{
var date = new DateTime(1970,1,1,0,0,0,0,System.DateTimeKind.Utc).AddSeconds( timestamp );
}
This isn't ideal, but there must be a way to automate it. Be aware your front-end will need to send it as a normal Unix timestamp (Javascript, for example, uses a timestamp in milliseconds instead of seconds.) and as UTC. This also avoids timezone issues.

If you will going to use this format conversion multiple times, why not to use a Helper Method ?
Like this c# console aplication exemple:
static void Main(string[] args)
{
DateTime mydate = new DateTime(2017, 04, 08);
string myValue = convertDate(mydate);
Console.WriteLine(myValue);
Console.ReadKey();
}
private static string convertDate(DateTime dateToConvert)
{
return string.Format("{0:MM/dd/yyyy}", dateToConvert);
}

Related

Best way to validate a date string in C#

I was trying to validate a date read from app.config file using DateTime.TryParse() method. However, it returned true when the input was "12/05/201". This was actually a typo, and should have been, "12/05/2018". When I stepped through the code it automatically converted the date to "12/05/0201" and returned true. However when I used DateTime.TryParseExact(), it correctly returned false for the above input. So, should we always use DateTime.TryParseExact()? I am little confused because earlier I used use DateTime.TryParse() whenever I had to validate a date string! Both the code is given below:
Boolean isValidStartDate = DateTime.TryParse(startDate, out DateTime startDateVerified);
CultureInfo enUS = new CultureInfo("en-US");
Boolean isValidStartDate = DateTime.TryParseExact(startDate,"MM/dd/yyyy",enUS, DateTimeStyles.None, out DateTime startDateVerified);
Thanks
The year 201 being invalid is business logic - if you want to have logical safeguards on your imported data (and you should), do them explicitly. With C# you can easily add an extension method to DateTime if you want, something like
public static DateTime ParseDateWithSanity(this DateTime, string date)
{
dt = DateTime.Parse(date);
if dt.Year < 1900
{
throw BadInputException()
}
}
Best way to Validate date depends upon the use case and input data source and its formate
DateTime.TryParse is parsed using formatting information in the current DateTimeFormatInfo object so let's say if you use TryParse "12/05/201" it will return the parsed data according to your current culture settings. Which is "12/05/0201" ie in date format "MM/DD/YYYY"
Its always good practice to specify date formate and culture variance while parsing date and use TryParseExact instead of TryParse
(Note: To know about current culture settings you can look for a member of classes CultureInfo.DefaultThreadCurrentCulture and CultureInfo.DefaultThreadCurrentUICulture)

Set DateTime format

I have the following code -
DateTime timeStamp;
timeStamp = System.Convert.ToDateTime(y.InnerText);
Where y.InnerText is 11/03/2013 11:35:24.
However this is breaking my import statement as it the database is looking for the format -
2013-03-11 11:35:24
How can I set the format of the DateTime object?
How can I set the format of the DateTime object?
You can't. DateTime values don't have formats, any more than int or double values do. When you want to convert them to/from strings, that's where you specify any formatting information.
Instead, you should use parameterized SQL and avoid converting the DateTime value back into a string in the first place. This is a general best practice - don't include values in your SQL string; parameterized SQL has multiple benefits:
It avoids SQL injection attacks
It avoids conversion issues like this one
It keeps your code (SQL) separate from your data (parameter values)
I would also suggest that instead of using Convert.ToDateTime, you specify your expected format when parsing. For example:
timeStamp = DateTime.ParseExact(y.InnerText,
"dd/MM/yyyy HH:mm:ss",
CultureInfo.InvariantCulture);
Basically, the two rules I try to apply are:
Avoid performing any conversions where you don't have to. If you make sure that every system uses the right data types as far as possible, you often don't need to make any conversions at all.
Where you do need to convert to/from string representations, be very explicit about the representation you want to consume/produce. For machine-readable values, that should usually use the invariant culture and possibly a custom date/time format. For human-readable values, that should usually use the user's culture and a standard date/time format.
I use this step
Convert to DateTime.
Use ToString(); function
Example :
DateTime myDateTime = DateTime.Now;
string myDateTimeString = myDateTime.ToString("yyyy-MM-dd hh:mm:ss");
if you are passing datetime to sql database try with yourdatetime.ToString("yyyy/MM/dd") format this will work for you.
and one more thing you can add a datetime format for your Applicaton culture. so this will treat you datetime format at you desire.
using System;
using System.Globalization;
using System.Threading;
namespace test {
public static class Program {
public static void Main() {
CultureInfo culture = (CultureInfo)CultureInfo.CurrentCulture.Clone();
culture.DateTimeFormat.ShortDatePattern = "yyyy/MM/dd HH:mm:ss";
culture.DateTimeFormat.LongTimePattern = "";
Thread.CurrentThread.CurrentCulture = culture;
Console.WriteLine(DateTime.Now);
}
}
}
Basically Date does not have a format. If the database parameter/field is Datetime type you should be fine passing as a Date type. It is not a good idea to pass date as a string.
However, if that something you have to deal with, then you better pass the Date in a none culture specific date format (ISO8601 or ISO) in a parameterised query. Otherwise you could have problems with database servers in different culture settings.
For example, for sql server, it is safe (in conversion) to pass date time in ISO8601 as;
'yyyy-mm-ddThh:mi:ss.mmm' //(no spaces)
you can use ToString convertion to 2013-03-11 11:35:24
DateTime timeStamp;
timeStamp = System.Convert.ToDateTime(y.InnerText).ToString("yyyy-MM-dd HH:mm:ss");
And what if you just override your ToString() method of your DateTime object?
Wouldn't you be able then to choose the format you want and every time it is used, it will be formatted in the way you want it without being bothered by it.
This is just a thought so I don't know if there are better solutions or not.
You can then use the properties year, month, day, to build it like you want.
Something like:
public override ToString(){
return this.Year + "-" + this.Month + "-" + this.Day;
}
Greetings

Checking if valid date in C# not working properly

I am using the following function to determine whether input string is valid date or not.
public static bool IsDate(string date)
{
DateTime Temp;
if (DateTime.TryParse(date, out Temp))
return true;
else
return false;
}
Problem is when I give input "1997-09" then it returns true. I want it to check complete date like "1997-08-12"
And no there is no fix date format. Input could also be "19-Feb-2012"
And no there is no fix date format. Input could also be "19-Feb-2012"
There must be, otherwise it's nonesense. If you haven't defined how your system must behave you'd better stop coding and take a moment to define it.
You could use the TryParseExact method which allows you to specify one or more formats you would like to handle.
one easy condition you can add:
public static bool IsDate(string date)
{
DateTime Temp;
return(DateTime.TryParse(date, out Temp)&&date.Length>=10)
}
You should establish list of a correct date formats and then check with DateTime.TryParseExact, something like this:
string format = "yyyy-MM-dd";
DateTime dateTime;
if (DateTime.TryParseExact(dateString, format, CultureInfo.InvariantCulture,
DateTimeStyles.None, out dateTime))
Use DateTime.TryParse, you can specify the format then, more here. http://msdn.microsoft.com/en-us/library/9h21f14e.aspx
To resolve this you should define a datetime-format in your applicaiton.
On any webpage you go, if you see a compilation form, you probabbly will will see some date field too, and near it something like:
DD-MM-YYYY, or MM/DD/YY, or somethign else .
Define for your application format, make it esplicit for the user and check on correctness according to your format.
Just an hypothetic example:
say user inserted a date and you store it into the string like DD-MM-YYYY, one of possible choice could be simply say :
if(dateTimeUserString.Split('-').Length < 3)
//not valid string !
I repeat, this is just an example you should choose more appropriate way for your application.
DateTime.TryParse does have an overload that takes an IFormatProvider to allow specification of custom formats. You may need to define multiple IFormatPrividers to check the various strings you may expect as valid.
Also, rather than the if/else, you could also shorten your code a bit by
return DateTime.TryParse(date, out Temp);
You can return result of parsing directly:
public static bool IsDate(string value)
{
DateTime date;
return DateTime.TryParse(value, out date);
}
And it works with formats you have provided (at least when current culture "en-US").
Your code will run just fine and check the given date string if it can be a valid date using all of the current culture's date formats including this 19-Feb-2012 or 1997-09 of yours or even 19 february.
This makes you flexible in date input.
But if flexibility is not what your are looking for then try to parse for one or more specific formats using TryParseExact.

Format a date using the current thread culture Vs double digits for month and day?

I want to display some rows of data on a web page where one column is a DateTime.
I want the date format to be displayed based on the current thread culture.
Right now, I'm doing this (dt is a DateTime):
string s = dt.ToString(Thread.CurrentThread.CurrentCulture.DateTimeFormat);
It's working well, however, on some culture, months and days are represented as only one digit (hours too), for example:
8/8/2011 8:57:59 AM
I would like the date to be displayed like this:
08/08/2011 08:57:59 AM
It would be easier to read (and prettier) when there's a list of rows.
I saw that there's a String.format method I could use, but that makes the current culture irrelevant.
Is there a way to achieve what I'm trying to do?
The solution provided here might be useful.
I see only a single solution - you should obtain the current culture display format, patch it so that it meets your requirement and finally format your DateTime value using the patched format string.
Make a custom culture.
Base it on the current thread culture.
Modify the settings you want to override.
Then either set it back into the thread as the culture or use it temporarily during the format operation.
We currently do this to format all dates in an internationally unambiguous form ddMMMyyyy where MMM is only English three-letter abbreviations, yet obey local numeric formatting rules ./, etc.
The relevant properties to override would be here.
If you want to show it based on the current culture, then what is the problem? If you want a specific format, you have to specify that.
string text = myDateTime.ToString("{0:[your format]}");
I believe this defaults to the server format - but what if you try specifying "u" as the format code which will put the year first then I think two digits.
You can use
String.Format("{0:dd/MM/yyyy hh:MM PM ", yourDatetime)
The date separator / (slash) and time sepatator : (colon) will be rewritten to characters defined in the current DateTimeForma­tInfo.DateSepa­rator and DateTimeForma­tInfo.TimeSepa­rator.
EDIT: Forgot to add object param needed to the string.format
using System.Globalization;
private static CultureInfo defaultCulture = new CultureInfo("nl-NL");
public static CultureInfo GetCurrentCulture()
{
List<CultureInfo> badCultures = new List<CultureInfo>();
badCultures.Add(new CultureInfo("en-US"));
if (badCultures.Contains(System.Threading.Thread.CurrentThread.CurrentCulture))
return defaultCulture;
return System.Threading.Thread.CurrentThread.CurrentCulture;
}

Problem with DateTime datatype

I have problem with the DateTime data type. Through a textbox I want to add person dateofbirth. As there is no date datatype in C# i am forced to use the DateTime datatype, but while converting TxtDateofBirth to DateTime i am getting an error, "String was not recognized as a valid DateTime." Here is my conversion the code. I kept this code in add event.
DateTime dateofbirth = Convert.ToDateTime(TxtDateOfBirth.Text);
What should I do?
Thanks,
Masum
Use DateTime.ParseExact with a format string which only specifies the date part.
Alternatively, as this is user input, use DateTime.TryParseExact so you don't need to catch an exception if the user has entered a bad date:
using System;
class Test
{
static void Main()
{
TestParsing("24/10/2009");
TestParsing("flibble");
}
static void TestParsing(string text)
{
DateTime dt;
if (DateTime.TryParseExact(text, "d", null, 0, out dt))
{
Console.WriteLine("Parsed to {0}", dt);
}
else
{
Console.WriteLine("Bad date");
}
}
}
Note that the format string "d" means "short date format" (see the "standard date and time form at strings" and "custom date and time format strings" pages in MSDN). "null" means "use the current culture" - so the above works for me in the UK, but you'd need to make the string "10/24/2009" in the US. You could specify a particular culture if you don't want to use the thread's current default. 0 means the default date and time style. Look at the MSDN page for more information.
Alternatively , use a mask so that users can only enter valid dates. (See the c# section under examples on the link given)
There is hardly anything one could add to Jon's answers, but in this case I'd like to make a point:
Try to understand that your problem is not because of the DateTime datatype but because your date string does not match the expected format (based on regional settings/thread culture) that the DateTime constructor.
You say that you are "forced" to use the DateTime datatype. You should keep in mind that Dates should always be treated as Dates. I've seen too many developers fall into the trap of using dates as strings (and performing split/search operations) rather than using DateTime because they feel that the latter is too complicated.

Categories