Getting the proper date from forms that are day/month/year - javascript

When writing a new date object with a string, one can write it as:
var someDay = new Date("12/01/2012");
This equals December 1st 2012.
However, what if the user has to fill in a date on a website where the format isn't month/day/year, but day/month/year? How would one go about creating a date object with the correct date then?

If you are getting the data as a string from another website, then you need to know the format in which that website provides you the date. There is no way around this because D-M-Y and M-D-Y are indistinguishable; even Y-M-D would be indistinguishable if they used a two-digit format for the year.
This hasn't been tested at all, but at worst the general idea should solve your problem.
var pattern = /^(\d+)\b(\d+)\b(\d+)$/;
if (!pattern.test(dateString))
return null;
var matches = dateString.match(pattern);
if (siteUsesDMY)
return new Date(matches[2], matches[1]-1, matches[0]);
if (siteUsesMDY)
return new Date(matches[2], matches[0]-1, matches[1]);
...
Pattern: This pattern supports any numeric representation of the date, assuming it has a breaking character between each unit. If you need to support a website that doesn't have a breaking character, you would need a different pattern that matched that website's exact format (i.e.: site sends DDMMYYYY, then pattern would be /^(\d{2})(\d{2})(\d{4})$/).
Also fixed the month parameter in date creation, as I just remembered that JavaScript uses 0-11 for months.

Related

Removing (or allowing) ordinal characters from dynamic text with Date.parse();

I am building a self-depreciating list of dates and am using Date.parse() to convert rich text into a timestamp. Right now, we have a system where the user enters the date themselves, and I use a token on the backend to pull it through to that specific page.
I am trying to 'protect the user' from entering a wrong date format.
Currently, if they enter January 12th, 2016 it won't be able to parse and create a timestamp due to th. However, if they enter January 12, 2016 it can create a timestamp.
Is there a way to replace these ordinal numbers on a dynamic string? I've tried a simple jquery find/replace, but have had no luck with getting it to remove the ordinal date texts.
What I've tried:
$('.my-button').each(function() {
console.log($(this).text());
var text = $(this).text().replace('st, ', '');
$(this).text(text);
});
Any ideas on a solution, or a way to make Date.parse(): accept these extra characters?
For the simple case of removing an ordinal from a date string like "January 12th, 2016", you can use a regular expression like:
var re = /(\d{1,2})[a-z]{2}\b/i;
['January 12th, 2016','January 1st, 2016','January 2nd, 2016','20th February, 2015'].forEach(
function(s) {
document.write('<br>' + s.replace(re,'$1'));
}
);
However, parsing strings with Date.parse (and the Date constructor, they are equivalent for parsing) is strongly recommended against. Use a parser and define the format, do not leave it to chance.
There are libraries like moment.js, however it may be too big for your requirements. There are other dedicated parsers (check on GitHub), or if you only need to support one format, write one yourself. It only requires three or four of lines of code.

HTML Input type datetime-local setting the wrong time-zone

I've created an app that takes in HTML inputs and goes through JavaScript to create an event on a native calendar events. It takes the time from the <input type="datetime-local">, and it's putting in a different time because it's picking a different time zone. If I enter 1 o'clock PM as a time it will return 8 o'clock AM.
<input type="datetime-local" id="startDate" name="startDate">
And the JavaScript:
var startDate = new Date($("#startDate").val());
Any help would be awesome. I can post more code if needed.
The HTML5 datetime-local input type will give you a string value back, which contains the date and time in ISO8601 format, with minute precision, and without any time zone offset.
For example: 2014-07-12T01:00
The JavaScript date object is notoriously inconsistent when it comes to parsing dates from strings. In most implementations, when you provide a string like this, it erroneously assumes the value is in UTC. Therefore, the Date object you get back will be adjusted by the time zone offset from your local computer.
There are two approaches to work around the problem:
Option 1
Manipulate the string to a format that will likely be interpreted as local time by the Date object's parser. Specifically, replace the dashes (-) with forward slashes (/) and replace the T with a space.
var s = $("#startDate").val();
var startDate = new Date(s.replace(/-/g,'/').replace('T',' '));
Option 2
Use a library with more capable date parsing abilities. There are several available. One of the most popular is moment.js.
Moment.js has lots of options, but it just so happens that the default behavior is exactly what you need. So you can just pass the string to the moment constructor without any parameters.
var s = $("#startDate").val();
var startDate = moment(s).toDate();

Moment getting date attributes mistakenly

I'm trying to use MomentJS to support dates handling in my application. However, I'm facing a problem with date manipulation.
The files are loaded in this order:
<script src="/javascripts/modules/moment/moment.min.js"></script>
<script src="/javascripts/modules/moment/moment-timezone.min.js"></script>
<script src="/javascripts/modules/moment/moment-timezone-data.js"></script>
<script src="/javascripts/modules/moment/moment-with-langs.min.js"></script>
Now in somepart of my JS code I change the moment language to FR or PT.
moment.lang('fr');
Both languages validade a date as "DD/MM/YYYY" instead of american pattern. So I expect moment
to validate a date following the country date pattern passed.
Then 12/10/2014 must be: day (12), month (09), year (2014), but it is returning always american pattern instead of the correct one.
I'm getting the date properties as:
console.log("DAY: " + moment(textDate).date());
console.log("MONTH: " + moment(textDate).month());
console.log("YEAR: " + moment(textDate).year());
where textDate is my date taken from a text input.
## EDIT ##
I know I can pass the pattern to Moment. I.e:
moment(textDate, 'DD/MM/YYYY');
In the case of my application I'm using like this:
moment(textDate, '<%=lingua.general.time.pDate%>');
However, it suppose to work automatically, don't it? Of course if you already have needed language packages as well. So the previous way I mentioned before should Works, whatever.
If you don't pass any formatting arguments, moment will let your browser do the parsing (with the exception of a full ISO timestamp).
To tell moment to do the parsing, and to use the localized short date format associated with the language, pass an L as the format string:
moment(textDate, 'L')
See in the docs:
Parsing using #String+Format
The display formats. Scroll down to "Localized formats". (The parser uses the same format strings)
Also, not related to your question, but moment-with-langs already includes a copy of moment.js, so you don't need both scripts.

Trying to parse date using new Date(). but keep getting wrong results

I am trying to parse a date string i get from php through ajax call(which is irrelevant for now) using new Date().
however i keep getting wrong results.
My string is 2013-05-09 20:56:17
When i do
var something = new Date("2013-05-09 20:56:17");
alert(something.getMonth());
It keeps alerting 0
In my opinion for some reason new date cant parse this string.
Is there a way to specify the date format for new Date() in JS ?
My current solution is to import php's: date() and strtotime() and use them :
alert(date('m', strtotime("2013-05-09 20:56:17")));
This works however I have to use external js lib and I am pretty sure there is a better JS way to achieve that.
If you use slashes instead of hyphens, it works:
var something = new Date("2013/05/09 20:56:17");
alert(something.getMonth());
It's easy enough to replace any hyphens in a string with slashes first if you need to (say, if you were getting the date string from somewhere else):
var something = new Date("2013-05-09 20:56:17");
something = something.replace('-', '/');
It seems JavaScript's Date constructor doesn't recognize date formats with hyphens, or at least not that particular format.
Choose a different format specifier in PHP for your ajax dates. The format you expect and the format expected by the javascript are different.
var something = new Date("2013-05-09T20:56:17");
Note the 'T' which appears as a literal separator and marks the beginning of time per ISO 8601
Reference for various [browser] javascript date formats
W3 DateTime
Microsoft IE DateTime
Mozilla [Firefox] DateTime
Google DateJs
And lastly, the PHP date format specifier list:
PHP Date
PHP DateTime
Note the 'DATE_ISO8601'; but I suggest not using that at this time. Instead use 'DATE_ATOM' which may produce a date format more widely supported (comments suggest it makes iPhones happier and no issues with other browsers).
To use it in PHP:
$something = new DateTime('NOW');
echo $something->format('c');
echo $something->format(DateTime::ATOM);

JavaScript validate existence of date

I have a date in the format YYMMDD. Is there anyway I can validate it in JavaScript?
By validation I don't mean easier things like length, characters etc but rather if the date exists in real life.
I'm hoping there is a faster / better way than breaking it in 3 chunks of 2 characters and checking each individually.
Thank you.
try to convert it to a date and if it fails, you get the dreaded NaN then you know it is not a valid date string? Not Pretty but it should work
var myDate = new Date(dateString);
// should write out NaN
document.write("Date : " + myDate);
You date string would have to be in a valid format for javascript I don't think what you have in your question YYMMDD is supported
The format YYMMDD is not supported by Javascript Date.parse so you have to do some processing of it like breaking it in parts.
I would suggest building a function that splits it in 3 2 char strings and then builds an american style date
MM/DD/YY and try to parse that with Date.parse.
If it returns anything but NaN then its a valid date.
The Date parser in JavaScript is pretty useless. The actual formats it accepts vary greatly across browsers; the only formats guaranteed to work by the ECMAScript standard are whatever formats the implementation's toString and toUTCString methods produce. In ECMAScript Fifth Edition you will also get ISO-8166 format, which is nearer to your format but still not quite.
So, the best solution is usually to parse it yourself.
var y= parseInt(s.slice(0, 2), 10)+2000;
var m= parseInt(s.slice(2, 4), 10)-1;
var d= parseInt(s.slice(4, 6), 10);
var date= new Date(Date.UTC(y, m, d));
Now you've got a Date object representing the input date in UTC. But that's not enough, because the Date constructor allows bogus months like 13 or days like 40, wrapping around. So to check the given day was a real day, convert back to year/month/day and compare:
var valid= date.getUTCFullYear()===y && d.getUTCMonth()===m && d.getUTCDate()===d;

Categories

Resources