Javascript equivalent to .NET's DateTime.Parse - c#

I'm trying to build a validator that will work with .NET's DefaultModelBinder of using DateTime.Parse to convert a string from the form post to a DateTime. I don't want to have to wait until a date has been posted to the server for it to realize it was a bad date.
Currently jquery.validate uses the following code to validate date fields:
// http://docs.jquery.com/Plugins/Validation/Methods/date
date: function(value, element) {
return this.optional(element) || !/Invalid|NaN/.test(new Date(value));
}
However, due to Javascript's terrible Date parser, this:
275481/69/100089
Will evaluate as valid, to Sep. 12, 275760.
While on the other hand, this:
11-19-2013
Will evaluate as invalid.
Of course, I understand that C#'s DateTime.Parse() takes things like culture (localization) and leap year into account, and I could live with assuming a fixed (US) culture, and allowing "02-29-2013" on the client and kick it out at the server (ideally not, but it's acceptable).
But I can't believe someone hasn't put together a better date validator to work with C#'s DateTime.Parse() logic.
Maybe someone has, I just haven't found it -- which is why I'm posting here.
And I know I have several ways to go about this -- from incredibly simple (less accurate) to incredibly complex (more accurate), but I'm hoping someone has already gone down this road and found the sweet spot.

Datejs seems pretty robust to me. Its parse function supports over 150 cultures:
Date.parse("February 20th 1973")
And in case you need to parse a date string that is not valid in the current culture you can use the parseExact function:
// The Date of 15-Oct-2004
Date.parseExact("10/15/2004", ["M/d/yyyy", "MMMM d, yyyy"]);

In all honesty, your best bet is to perform an AJAX hit, and ask your ASP.net web-server to parse the string and return a Javascript date.
Javascript libraries easily get confused with different locales, e.g.:
GET /ParseDate.ashx?dateStaring=06/01/34 4:53:05 غ.و&locale=ar-SA
Which gets really complicated because:
"6/1/34" = November 19, 2012
The .NET framework, with Windows behind it, has support for a lot of different locales.

Instead of trying to find two Datetime implementations (one for JS and another for C#) that have similar validation and parsing, have you considered having the client 1)use its own library to validate the date and 2)parse and reformat the date to a C# friendly format?
This would allow you to use DateJS to get a very flexible front end for date inputs, make it easier to deal with the client side culture, and let your server side deal with a fixed format.

Have you tried passing your string into the constructor?
Here's a sample from https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date
var birthday = new Date("December 17, 1995 03:24:00");

Related

Why is DateTime.TryParse() returning true for the culture "en-NZ" when MMddyyyy is passed in?

I have the following code:
DateTime.TryParse("06-28-2012", new System.Globalization.CultureInfo("en-NZ"),
System.Globalization.DateTimeStyles.AssumeLocal, out date);
I'm not sure why this is returning true since if I go into my Regional Settings in Windows, I only see the following date formats under short date:
d/MM/yyyy
d/MM/yy
dd/MM/yy
d.MM.yy
yyyy-MM-dd
So then why is a short date format like MM-dd-yyyy returning true? Shouldn't it return false?
I'm using this similar post as a source: DateTime c# parsing
Important:
Please note that I also have my regional settings set to use English (New Zealand) and chose
yyyy-MM-dd as my short date format.
Having your short date format set to yyyy-MM-dd is the cause of this behavior (I do not know if that the standard in New Zealand, but New Zealand's short date is set to d/MM/yyyy on my computer). I do not know if Dot Net, or the underlying Windows APIs are to blame, but it seems like it's smart enough to understand that the 4-digits part represents the year, and after that it just preserves the month-day order (Note that calling DateTime.TryParse("28-06-2012") will actually fail).
You can try using ParseExact, but be warned that will fail on a slightest change of the string (for example, when using a dot or a slash as a separator, instead of a dash.
In my opinion, it's probably best to leave the behavior as is, as it can handle more cases, but if you really must check if a date string was in a specified (yet flexible) format, Regex is the best option. For example Regex.IsMatch("2012/06/28", #"[0-9][0-9][0-9][0-9][./\\][0-9][0-9]?[./\\][0-9][0-9]?"); should suit your needs, while still allowing some flexibility.
You could try DateTime.ParseExact
Could you execute and post the result from the code below?
System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat.ShortDatePattern;
System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat.DateSeparator;

DateTime.Parse can format unusual format strings?

I was looking at a code in an application (Someone else wrote it),on some cases it worked fine and on some cases it gave exceptions,it was actually converting strings in datetime,here is the code
//5000 is the year,but what about "1" is it month or day ?,if its month
//then what about the day ?
DateTime time = DateTime.Parse("1.5000");//1.5000 doesn't looks a date to me ?
time.ToString();//returns "1/1/5000 12:00:00 AM"
//where as if I give this string to DateTime.Parse();
time = DateTime.Parse("2341.70");
//FormatException was unhandled
//String was not recognized as a valid DateTime.
A Confusing thought
How does this string "3.5000" (it matches the 1.5000 pattern) evaluates , does this means 3-3-5000 or 1-3-5000 ,the format is ambiguous its unclear and confusing !
My questions are,
What kind of formats can DateTime.Parse expects ?
Whats happening in the code above ?
Suggestions to improve the code ?
Many people have commented on the possible reasons for the parse that you have seen being successful but your question seems to have several separate parts...
1. What kind of formats can DateTime.Parse expects ?
DateTime.Parse has been written to be as inclusive as possible. Pretty much anything that it can find someway to make into a DateTime it will do its best to do so which means in addition to the usual familiar yyyy-MM-dd type formats more strange ones like M.yyyy or yyyy.M and so on.
2. Whats happening in the code above ?
That is very complicated because the DateTime.Parse method is itself very complicated. You can probably fidn the source code out there somewhere but the complexity made it very hard for me to follow. Without being able to give precise details I'm going to answer this the same as above. What is happening is that the framework is trying its best to give you a date back and not throw an exception. The date it gives is the best guess as to what you meant.
3. Suggestions to improve the code ?
It sounds like if you are getting parse exceptions that you are passing dates in formats that are unexpected. Without knowing what those inputs are its hard to say. Two things could improve your code though. Making sure a single consistent date format is used and then using DateTime.ParseExact to ensure that it conforms to the right format. You will remove all ambiguity this way but you will sacrifice flexibility.
The second option is to use DateTime.TryParse. This will attempt to parse your date and then return a boolean saying whether it succeeded or not. If successful the date parse will be returned in a ref parameter. This won't make your code any better at recognising unknown date formats but will let your code know when such an unparsable format crops up and you can deal with it (eg by providing user feedback reporting the wrong format and suggesting a correct one, or just by logging it or something else).
What the best method is depends mostly on where your input is coming from. If it is user input then I'd go with the second option. If it is automated input then you probably want to make sure your input is standardized and then use the first option. Of course circumstances always vary so this is not a hard and fast rule. :)
In regards to "2. Whats happening in the code above ?":
In some cultures, the date separator is a dot instead of a slash. So for example 13.12.2013 is a valid date (2013-12-13) in the format "dd.MM.yyyy". Now by whatever design choice, the day part in this example is not mandatory and if left out, is automatically filled with 1. So parsing 12.2013 would result in 2013-12-01. And therefore it's easy to see how 1.5000 would become 5000-01-01. 2341.70 can not be parsed, because 2341 is not a valid month. - So in this case 1.5000 is a "valid" date in the format M.yyyy.

How to validate string is correct date time

I have some data picked up from an excel file.
I want to validate that the user has entered a valid date time string. I have tried to use DateTime.Parse method but found that certain values seem to be accepted.
For example,
If I submit 3.3 as a date time this is accepted by the DateTime.Parse method as a valid date time and outputs 03/03/2012 00:00:00
I want to want to block this. Only allowing the user to enter correctly formatted date times.
So for example a user could supply 03/03/2012 or 03/03/2012 12:30:00 but not values like 01022012 or 3.3.2012
Any Ideas?
You want to use DateTime.ParseExact or DateTime.TryParseExact
This allows you do parse from a date format string of your choice.
http://msdn.microsoft.com/en-us/library/system.datetime.tryparseexact.aspx
Examples here:-
http://msdn.microsoft.com/en-us/library/ms131044.aspx
You can use RegEx to to this. Something like this should help #"\d{2}/\d{2}/\d{4}(\s+\d{2}\:\d{2}\:\d{2})?"
You can handle it on the client side with various jquery plugin/functions like this or a simple Google search can return many other useful results.
if you want to handle it on the server side, (I am not sure on what project you are working) but depending over it you can write your own method/use Regex or Data Annotation MVC.
If you are still having trouble try adding few details about your project such as Language, Architecture etc. that would help more in providing the right solution.
Hope it helps. Thankyou

Time (DateTime) Format Conditionally Show Minutes

The jquery FullCalendar plugin has a neat format for time.
If it the time is 7:00pm, the format shows up as 7p.
If it the time is 7:30am, the format shows up as 7:30a.
Question: Is there any way to use standard formatting to accomplish this with c# sharp? Obviously I can create logic to do this myself, but I'm hoping there is a format string that will accopmlish this.
ie (doesn't work):
MyDateTime.ToString("h{:mm}t");
Formatting strings do not have conditionals - there is no way to specify a condition within a format string.
You will need to use a standard if and format accordingly.
if(MyDateTime.Minutes == 0)
{
return MyDateTime.ToString("h");
}
return MyDateTime.ToString"h:mmt");
Or, in one line:
return MyDateTime.ToString((MyDateTime.Minutes == 0)?"h":"h:mmt");
No, there's nothing like this within the built-in .NET date/time formatting. You'll have to write the code yourself.
(I haven't seen anything similar for dates and times in other date/time libraries, to be honest. I've seen conditional formatting for periods, but that's a different matter. The only exception to this is "fractional seconds" which can be expressed such that they're removed - including the decimal point - if the time is a whole number of seconds.)

Is there an API to convert from "YYYYMMDDHHMMSS.UUUUUU-TZO" format to C# DateTime?

Example: "20080807144334.410187-180" (-180 means GMT minus three hours. Rio de Janeiro in this case.)
That string format is returned when I query file creation/change/access times via WMI (that is not totally working; see here). I guess I could parse it the idiot way, extracting year, month etc. from the string positions. But I'd like not to reinvent the wheel. System.DateTime's constructors don't handle that format. Should I go on and do it the idiot way or is there something better?
You should be able to use DateTime.ParseExact or .TryParseExact to give it the specific format to use when parsing.
However, I don't think you can get it to read your time zone in that format (though I can't actually figure out how to get it to read a time zone in any format).
The rest of it would look like this:
DateTime.ParseExact("20080807144334.410187", "yyyyMMddHHmmss.ffffff", System.Globalization.CultureInfo.InvariantCulture)
You should take a look at the DateTime.TryParseExact method. It'll let you pass in your format that you're converting from.
http://msdn.microsoft.com/en-us/library/system.datetime.tryparseexact.aspx

Categories