This functionality is working fine in Chrome... But not IE or FF.
I am trying to validate two fields that take the value of MonthName YearNumber (see screenshot).
I am using Date.parse() to get miliseconds, then compare if Start Date <= End Date.
function IsStartEndDtError(StartDt, EndDt) {
//convert dates to miliseconds to compare if one is greater than other
var StartDtMili = Date.parse(StartDt);
var EndDtMili = Date.parse(EndDt);
if (StartDtMili <= EndDtMili) {
return false;
}
else {
return true;
}
}
What appears in Firebug:
Since the format your date is in isn't universally supported you can try a library like Date.js:
Date.parse("November 2012")
// returns: Thu Nov 01 2012 00:00:00 GMT+0000 (GMT)
If you don't want another library you can manually replace the month names with numbers and create a new date string.
Ecmascript does not seem to support full month names, if you look at "Section 15.9.1.15 Date Time String Format" in the spec.
In Firefox:
new Date("November 2012")
// Invalid Date
new Date("2012-11")
// Thu Nov 01 2012 00:00:00 GMT+0000 (GMT)
The second date format should be standardized across browsers, the first isn't.
11 1999, November 1999 are not parsable formats. You either need to use a date library that is more flexible with its input formats, or process your input and identify the parts in it:
function IsStartEndDtError(StartDt, EndDt) {
var months = {
January: 0,
February: 1,
...
};
//convert dates to miliseconds to compare if one is greater than other
var StartDtMili = (new Date(StartDt.split(" ")[1], month[StartDt.split(" ")[0]])).getTime();
var EndDtMili = (new Date(EndDt.split(" ")[1], month[EndDt.split(" ")[0]])).getTime();
if (StartDtMili <= EndDtMili) {
return false;
}
else {
return true;
}
}
Related
I receive Date in 3 formats from different APIs
UTC format: 2014-01-01T00:00:00.000Z (String)
GMTformat: Thu, 29 Nov 2018 17:30:56 GMT (String)
unixTimeStamp: 1558606726 (number)
Also the UTC format sometimes might not have Z in the end so the normal parsing will give a time difference.
function formatDate(dateString) {
var dateTime, utcFormatRegex, zeroHourOffsetRegex;
// Some APIs return a Date in standard ISO UTC format may not have Z at the end
utcFormatRegex = /^\d{4}-\d{2}-\d{2}T.*$/;
zeroHourOffsetRegex = /^.*Z$/;
if (utcFormatRegex.test(dateString) && !zeroHourOffsetRegex.test(dateString)) {
dateString+='Z';
}
dateTime = new Date(dateString);
}
Given that there are parsing functions for all of the different formats, i need a function that determines which parsing function we should be using based on a regex and parse it accordingly. If regex is not the ideal solution then how can i approach this?
What I'm getting at is there should probably be a more robust solution than 'if there isn't a Z then add one' to get it to parse through the single date time parser. What if we get another date time format that doesn't play nicely with a Z on the end? We'll be making multiple changes at that point in time.
Using a regular expression is OK, but you need to test strictly for the formats you're expecting. If you get something you don't expect, throw an error. It's one of the failings of current built–in parsers is that there's no way to specify strict parsing, e.g. where a format is supplied and the parser throws an error if the input string doesn't match.
There are libraries that can help, a search will reveal quite a few.
But if you only have to support the 3 formats in the OP, something like the following may suit:
/* Return a Date where the input may be:
** string: ISO 8601 timestamp that should be treated as UTC
** whether it has a trailing Z or not
** string: Timestamp in the format (using moment.js tokens):
** ddd, DD MMM YYYY HH:mm:ss GMT
** nunber: UNIX time value, seconds since 1970-01-01 UTC
*/
function toDate(value) {
// Parse the string & fail early if it fails
let d = new Date(value);
// Throw error if couldn't parse value
if (isNaN(d.getTime())) {
throw 'Invalid timestamp: ' + value;
}
// Otherwise, do the work
let days = 'Sun Mon Tue Wed Thu Fri Sat'.split(' ');
let months = 'Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec'.split(' ');
// Test for time value first as that's the easiest
if (typeof value == 'number' && !isNaN(value)) {
return new Date(value * 1000);
// Test for ISO 8601 next
} else if (/^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d\.\d\d\dZ?$/.test(value)) {
return new Date(/Z$/.test(value)? value : value + 'Z');
// Test for random format
} else if (/^[a-z]{3}, \d?\d [a-z]{3} \d{4} \d\d:\d\d:\d\d GMT$/i.test(value)) {
let b = value.split(/ |:/);
if (days.includes(b[0].substr(0,3)) && months.includes(b[2])) {
let x = new Date(Date.UTC(
b[3], // year
months.indexOf(b[2]), // month, zero indexed
b[1], // day
b[4], b[5], b[6] // hh:mm:ss
));
// Check value was a valid date, only need to check some parts
if (x.getUTCFullYear() == b[3] &&
x.getUTCDate() == b[1] &&
x.getUTCHours() == b[4] &&
x.getUTCSeconds() == b[6]) {
return x;
} else {
throw 'Invalid timestamp: ' + value;
}
}
// Throw error as must be unknown format
} else {
throw 'Unknown format: ' + value;
}
}
// Minimal testing
var isoString0 = '2014-01-01T00:00:00.000Z',
isoString1 = '2014-01-01T00:00:00.000', // no Z, parse as UTC anyway
randomString = 'Thu, 29 Nov 2018 17:30:56 GMT',
unixTimeValue = 1558606726, // Assume seconds
invalidDate0 = '2018-02-29T00:00:00.000Z', // no 29 Feb in 2018, fail built-in parse
invalidDate1 = 'Thu, 29 Feb 2018 17:30:56 GMT', // no 29 Feb in 2018, fail manual parse
invalidFormat = '6/6/2019'; // Unknown format
[isoString0, isoString1, randomString, unixTimeValue, invalidDate0,
invalidDate1, invalidFormat].forEach(s => {
var result;
try {
result = toDate(s);
console.log(s + ' =>\n' + result.toISOString());
} catch (e) {
console.log(e);
}
});
I have following datetime value in a json :
Fri Jan 22 2016 14:34:38 GMT-0500
I would like to display something like "January 22, 2016"
How could I achieve this in javascript. I have JQuery, Extjs libraries available.
Try creating object having properties of abbreviated months, values of full month, using for..in loop , String.prototype.slice(), String.prototype.replace()
var months = {
"Jan":"January",
"Feb":"February",
"Mar":"March",
"Apr":"April",
"May":"May",
"Jun":"June",
"Jul":"July",
"Aug":"August",
"Sep":"September",
"Oct":"October",
"Nov":"November",
"Dec":"December"
};
var date = "Fri Jan 22 2016 14:34:38 GMT-0500";
// extract "Jan 22 2016" from `date`
var d = date.slice(4, -18);
for (var prop in months) {
if (new RegExp(prop).test(d)) {
// replace abbreviated month with full month name
d = d.replace(prop, months[prop]);
// replace day with day followed by comma `,` character
d = d.replace(/(\d{2})(?=\s)/, "$1,")
}
}
document.body.textContent = d
This question is addressed to the same question of yours. You can use the functions shown here to construct the date string as you want.
// This could be any Date String
var str = "Fri Feb 08 2013 09:47:57 GMT +0530 (IST)";
var date = new Date(str);
This will then give you access to all the Date functions (MDN)
For example:
var day = date.getDate(); //Date of the month: 2 in our example
var month = date.getMonth(); //Month of the Year: 0-based index, so 1 in our example
var year = date.getFullYear() //Year: 2013
Extract date and time from string using Javascript
Found this crazy method here, but worked!
Converting milliseconds to a date (jQuery/JS)
Here is the fiddle that i'v done
https://jsfiddle.net/Ripper1992/hj6L2Lvz/
var now = new Date("Fri Jan 22 2016 14:34:38 GMT-0500");
alert(now.customFormat( "#MMMM# #DD#, #YYYY#" ) );
customFormat is the function called to get each part of the Data, parse and replace based on the #MMMM# or #DD# or #SS# defined by the user.
And here is the complete function with the documentation
http://phrogz.net/JS/FormatDateTime_JS.txt
I have a jQuery datepicker tool returning back a maximum and a minimum date.
The dates are to filter out results from an array. I use jQuery.grep to filter based on the date. For some reason, while >= will work, <= only returns less than.
// Function to filter based on date minimum
function filterListGreaterThan(filter, list, min){
var result = jQuery.grep(list, function (obj){
return new Date(obj[filter]) >= min;
});
return result;
};
function filterListLessThan(filter, list, max){
var result = jQuery.grep(list, function (obj){
return new Date(obj[filter]) <= max;
});
return result;
};
So if i put in Nov 1, 2013 - Nov 5, 2013 it will only return Nov 1 - Nov 4... and I have no idea why.
Edit: Mac gave me the correct answer. When comparing the dates jQuery Sets the time to midnight. So even though I had it searching on the correct day it was not looking past midnight. This is the Corrected function:
// Function to filter based on date maximum
function filterListLessThan(filter, list, max){
var result = jQuery.grep(list, function (obj){
//add time to date because jQuery sets the time at 00:00:00
max.setHours(23,59,59);
return new Date(obj[filter]) <= max;
})
return result;
};
It seems the problem is likely due to the max date having a time component set to 00:00 AM - all items in the array occurring on the max date are probably being filtered out because they occur some time after 00:00 AM.
To fix this, the best approach is either to change the max date to have a time component of 11:59:59 PM, or to set the max date to 00:00 AM the following day and use a less-than (rather than a less-than-or-equal).
Not entirely sure I understand what you are trying to do, so apologies if this is not what you need but if you just want to filter an array of dates I'd try something like below.
You need to make sure you are comparing a Date object with another Date object and that the values in your array are formatted so as to make a valid Date object.
I'm not sure how that jQuery function works but using vanilla javascript I would do something like this to filter dates:
var list = ['2013,10,01','2013,10,02','2013,10,03','2013,10,04','2013,10,05',
'2013,10,06'];
function filterListGreaterThan(list, min_date){
var filtered_dates = [];
for(var i=0; i < list.length; i++){
var parts = list[i].split(','),
test_date = new Date(parts[0],parts[1],parts[2]);
if(test_date >= min_date){
filtered_dates.push(test_date);
}
}
return filtered_dates;
}
var min_date = new Date('2013','10','04'),
dates = filterListGreaterThan2(list, min_date);
console.log(dates);
//RETURNS:
//Mon Nov 04 2013 00:00:00 GMT+0000 (GMT Standard Time)
//Tue Nov 05 2013 00:00:00 GMT+0000 (GMT Standard Time)
//Wed Nov 06 2013 00:00:00 GMT+0000 (GMT Standard Time)
//
In the following date conversion after converting back the long integer The date says october instead of september
var date = 2013-09-23 18:31
startdate = getTimeStamp(date); //1382533260000
Now
t=1382533260000
rt = new Date(t)
//Wed Oct 23 2013 18:31:00 GMT+0530 (India Standard Time)
function getTimeStamp(strDate) {
var a1=strDate.split(" ");
var d1=a1[0].split("-");
var t1=a1[1].split(":");
var dtObj = new Date(d1[0],d1[1],d1[2],t1[0],t1[1]);
return dtObj.getTime();
}
In JavaScript, month numbers are numbered 0-11.
If you're parsing from components like this into the Date constructor you'll have to subtract one from the number:
function getTimeStamp(strDate) {
var a1=strDate.split(" ");
var d1=a1[0].split("-");
var t1=a1[1].split(":");
var dtObj = new Date(d1[0],d1[1] - 1,d1[2],t1[0],t1[1]);
return dtObj.getTime();
}
Months are zero-based, so January is zero, February is one, etc..
So you need to use d1[1]-1 in your new Date() constructor.
Javascript month parameter starts from 0 upto 11 so, passing 8 means september
var exampleDate='23-12-2010 23:12:00';
I want to convert above string into a date and have tried a couple things:
var date = new Date(exampleDate); //returns invalid Date
var date1 = Date.parse(exampleDate); //returns NAN
This code is running fine in IE and Opera, but date is returning me an invalid Date and date1 is returning NAN in Firefox. What should I do?
The string in your example is not in any of the standard formats recognized by browsers. The ECMAScript specification requires browsers to be able to parse only one standard format:
The format is as follows: YYYY-MM-DDTHH:mm:ss.sssZ
This format includes date-only forms:
YYYY
YYYY-MM
YYYY-MM-DD
It also includes time-only forms with an optional time zone offset appended:
THH:mm
THH:mm:ss
THH:mm:ss.sss
Also included are “date-times” which may be any combination of the above.
If the String does not conform to that format the function may fall back to any
implementation-specific heuristics or implementation-specific date formats. Unrecognizable Strings or dates
containing illegal element values in the format String shall cause Date.parse to return NaN.
So in your example, using 2010-12-23T23:12:00 is the only string guaranteed to work. In practice, most browsers also allow dates of the format DD Month YYYY or Month DD, YYYY, so strings like 23 Dec 2010 and Dec 23, 2010 could also work.
Above format is only supported in IE and Chrome.
so try with another formats. following are some formats and there supporting browsers.
<script type="text/javascript">
//var dateString = "03/20/2008"; // mm/dd/yyyy [IE, FF]
var dateString = "2008/03/20"; // yyyy/mm/dd [IE, FF]
// var dateString = "03-20-2008"; // mm-dd-yyyy [IE, Chrome]
// var dateString = "March 20, 2008"; // mmmm dd, yyyy [IE, FF]
// var dateString = "Mar 20, 2008"; // mmm dd, yyyy [IE, FF]
// Initalize the Date object by passing the date string variable
var myDate = new Date(dateString);
alert(myDate);
</script>
You could parse it manually with a regular expression then call the date constructor with the date elements, as such:
var parseDate = function(s) {
var re = /^(\d\d)-(\d\d)-(\d{4}) (\d\d):(\d\d):(\d\d)$/;
var m = re.exec(s);
return m ? new Date(m[3], m[2]-1, m[1], m[4], m[5], m[6]) : null;
};
var dateStr = '23-12-2010 23:12:00';
parseDate(dateStr).toString(); //=> Thu Dec 23 2010 23:12:00 GMT-0800
JavaScript should support conversion at least from the following dateStrings:
* yyyy/MM/dd
* MM/dd/yyyy
* MMMM dd, yyyy
* MMM dd, yyyy
Try with:
var exampleDate='12/23/2010 23:12:00';
var date = new Date(exampleDate);
Use datejs and this code:
var exampleDate='23-12-2010 23:12:00';
var myDate = Date.parseExact(exampleDate, 'dd-MM-yyyy hh:mm:ss');
myDate should be a correctly constructed Date object.
Just use in this format:
var exampleDate='2010-12-23 23:12:00';
#casablanca has a good answer but it's been 10+ years and this still has a lot of weight in Google so I thought I'd update with a new answer.
TL;DR
// Use an ISO or Unix time string to generate `Month DD, YYYY`
const newDate = new Date('23-12-2010')
const simpleDate = `${newDate.toLocaleString('en-us', { month: 'long' } )} ${newDate.getDate()}, ${newDate.getFullYear()}`
// yields: December, 23 2010 (if you want date suffix, read until the end)
Background: Dates come in a lot of formats, but you're mostly going to receive:
An ISO 8601 format date (YYYY-MM-DDTHH:mm:ss.sssZ) where Z is a UTC timezone offset. You might also get a subset of this (ie, YYYY-MM-DD)
Unix timestamp format date (1539734400), where the number is literally the total amount of milliseconds since the beginning of Unix time, Jan 1st 1970.
Basics: JS has a built-in Date prototype that accepts ISO 8601 and derivatives (of just time or just date). You can instantiate with new Date and return a date object OR you can use the Date.parse() method to return a Unix timestamp.
const dateObj = new Date('23-12-2010:23:12:00') // returns date object
const dateDateOnly = new Date('23-12-2010') // returns date object
const dateTimeOnly = new Date('23:12:00') // returns date object
const dateString = Date.parse('23-12-2010:23:12:00') // returns Unix timestamp string
You can also break the date into 7 parameters: the year, the month (starting from 0), the day, the hour, the minutes, seconds and milliseconds with the time zone offset - NOTE, I've used the multi-params approach only once in my career. Since I'm in Texas I get, UTC-5 (Central Time) when I run the following:
const dateByParam = new Date(2021, 2, 26, 13, 50, 13, 30) // Fri Mar 26 2021 13:50:13 GMT-0500 (Central Daylight Time)
New-ish Stuff toLocaleString: Typically, the return from the Date object is still pretty dense like our last example (Fri Mar 26 2021 13:50:13 GMT-0500 (Central Daylight Time) so additional methods have been added to help developers.
Typically with a date, I want something like March 21st, 2021 - the day and year have been easy to get for a long time:
// Assuming myDate is a JS Date object...
myDate.getDate() // date on the calendar, ie 22
myDate.getDay() // day of the week, where 0 means Sunday, 1 means monday, etc
myDate.getFullYear() // 4 digit year, ie, 2021
But I've always had to build a function to turn getDay into January, February, March, not anymore. toLocaleString() gives you some new superpowers. You can pass it two params, a string for region (ie, en-us) and an object with what you want back (ie, { month: 'long' }). This helps internationalize the response, if need be.
// Again, assuming myDate is a JS Date object...
myDate.toLocaleString('en-us', { month: 'long' } ) // March
Date Suffix I've still seen no built-in way to get the suffix for a date, like th, st, so I built this utility function that uses the modulus % operator to check the divisor of each day number and apply the right suffix (aimed at an American audience but might be the same elsewhere?).
/**
* setDateSuffix()
*
* Desc: Takes two digit date, adds 'st', 'nd', 'rd', etc
*
* #param { integer } num - a number date
*/
export const setDateSuffix = (num) => {
const j = num % 10,
k = num % 100
if (j === 1 && k !== 11) {
return num + "st";
}
if (j === 2 && k !== 12) {
return num + "nd";
}
if (j === 3 && k !== 13) {
return num + "rd";
}
return num + "th";
}
Altogether now.. Long winded way of getting here, but if I am given an ISO or Unix date and I want Month DDth, YYYY, this is what I run:
// setDateSuffix IS NOT PART OF BUILT-IN JS!
const newDate = new Date('23-12-2010')
const simpleDate = `${newDate.toLocaleString('en-us', { month: 'long' } )} ${setDateSuffix(newDate.getDate())}, ${newDate.getFullYear()}`
// yields: December 23rd, 2010
Note - all of this will likely change, hopefully for the better, when temporal becomes a reality in JS: https://github.com/tc39/proposal-temporal. Look forward to somebody's 2030 update of this post!