I'm trying to determine if a string is a number or a date.
Here is my code:
this._getFieldFormat = (value) => {
// check if is date
let d = new Date(value);
if (!isNaN( d.getTime() ) ) {
return 'date';
}
// check if is boolean
// isNaN(false) = false, false is a number (0), true is a number (1)
if(typeof value === 'boolean'){
return 'boolean';
}
// check if a string is a number
if(!isNaN(value)){
return 'number';
}
return typeof value;
};
It works for a date like: 2016-04-19T23:09:10.208092Z.
The problem is that 1 look to be a valid date (Wed Dec 31 1969 16:00:00 GMT-0800 (PST)) and isNaN(new Date()) is return false (a date is a number).
Any idea on how to get out of this loop?
So what is happening is called coercion. Since javascript is dynamic typing when you give it two different types the js engine tries to coerce one of the types into something reasonable or what it thought you meant.
For instance:
isNan("37"); is false because "37" is converted to the number 37
isNaN(new Date()) is return false (a date is a number)
It converted Date to a number so this is correct.
However, invalid values in date strings not recognized as ISO format as defined by ECMA-262 may or may not result in NaN, depending on the browser and values provided
So
new Date('23/25/2014'); // NON-ISO string with invalid date values
So this will return NaN in all browsers that comply with ES5 and later.
Also to do a stricter check you can use:
Number.isNan(new Date()); // This should return true
So to recap make sure the date conform to the ISO standard or it will be NaN and use the stricter check. Hope this helps.
In general and from a Javascript design point of view, however, I don't think you can do it by design. Any number between 8640000000000000 and the earliest date in terms of a number -8640000000000000 can be converted to date (represented as time in milliseconds from 01 January, 1970 UTC).
Therefore, any number not falling is this range cannot be a date. And any number falling in range would be a valid date or a number and you gotta use context to determine if you want to interpret it as a number or a date.
You could however do a naive implementation to test if number is a valid date or not, but that's the best you can do, without context.
Determining whether a date is a number or not can be a bit easier. Because a human-readable representation of date will return true by isNaN() thereby determining that it's definitely not a number. Then you would go on and check if that string is a date or not, which you already did in your function.
Related
Given a date :
const date = new Date();
console.log(date.valueOf()); // print numeric value : 1587644687189
Any documentation mentions that valueOf() is an inbuilt function in JavaScript which is used to get the number of milliseconds between 1 January 1970 00:00:00 UTC and the given date.
How this function is implemented on a Date object ?
Date instances are always based on a timestamp value, a number that measures milliseconds from a fixed point in time. The .valueOf() function simply returns that number. The function does not have to compute the number of milliseconds; it always has that as effectively a private internal property.
Calling the various mutator functions like .setMonth() etc will update that timestamp value. That process is where interesting work is done, such as taking into account daylight savings time and other complexities of calendar math.
Any object can have a .valueOf():
console.log(5 + { valueOf: () => 6 }); // 11
It can also be placed on the prototype, as is the case with Date objects.
I have a date with the format 2017-03-29T06:45:00.000Z, how do I check if it is equal or less to the date and time now?
If I check with
var currentTime = new Date();
if("2017-03-29T06:45:00.000Z" <= currentTime){
its not right since current date is in the format Wed Mar 29 2017 08:59:18 GMT+0200(CEST)
Any input appreciated, thanks
You are trying to compare a string to a Date Object. Because the two data types do not match, javascript tries to compare them by their value and calls currentTime.valueOf(). This evaluates to a integer like 1490781568805. Javascript then tries to compare the string to the evaluated integer. The result is different than you might expect, because the individual char codes of the string are compared to the integer.
"2017-03-29T06:45:00.000Z" <= new Date() // string compared to the Date object
"2017-03-29T06:45:00.000Z" <= new Date().valueOf() // javascript trying get a value for the date object
"2017-03-29T06:45:00.000Z" <= 1490781568805 // evaluates to false
You can just parse your date string to a Date object using Date.parse()
Date.parse("2017-03-29T06:45:00.000Z") <= new Date() // two Date objects are compared
I'm doing an app, and I encounter this problem, I thought comparing dates will be that easy but it's not. My condition inside if works well if the dates are of the same year, but if the value is like the value given below, it doesn't the result becomes true which should be false. So how do I properly compare this date format I have?
startDate.toLocaleDateString() has a value of 12/24/2016
endDate.toLocaleDateString() has a value of 01/03/2017
if(startDate.toLocaleDateString() > endDate.toLocaleDateString())
{
//do this
}
else
{
//do this
}
You could compare Date directly, because it uses EPOCH time, which is comparable.
Creates a JavaScript Date instance that represents a single moment in time. Date objects are based on a time value that is the number of milliseconds since 1 January, 1970 UTC.
if (startDate > endDate) {
It uses Date#valueOf
The valueOf() method returns the primitive value of a Date object.
and returns
The number of milliseconds between 1 January 1970 00:00:00 UTC and the given date.
I have the following code :
var fomattedDate = moment(myDate).format("L");
Sometimes moment(myDate).format("L") returns "Invalid date", I want to know if there is a way to prevent that and return an empty string instead.
TL;DR
If your goal is to find out whether you have a valid date, use Moment's isValid:
var end_date_moment, end_date;
jsonNC.end_date = jsonNC.end_date.replace(" ", "T");
end_date_moment = moment(jsonNC.end_date);
end_date = end_date_moment.isValid() ? end_date_moment.format("L") : "";
...which will use "" for the end_date string if the date is invalid.
Details
There are two very different things going on here.
First:
0000-00-00T00:00:00 is an invalid date. There's no month prior to January (which is month #1 in that format), nor a day of a month prior to day #1. So 0000-00-00 makes no sense.
0000-01-01T00:00:00 would be valid — and moment("0000-01-01T00:00:00").format("L") happily returns "01/01/0000" for it.
If you use a valid date (such as your 2015-01-01T00:00:00 example), the code is fine.
Second:
console.log(Object.prototype.toString.call(end_date));
It returns [object String] even with a valid date, so the if condition doesn't working in my case.
Of course it does: format returns a string, and you're using format to get end_date.
If you want to know if a MomentJS object has an invalid date, you can check like this:
if (theMomentObject.isValid()) {
// It has as valid date
} else {
// It doesn't
}
If you want to know if a Date object has an invalid date:
if (!isNaN(theDateObject)) {
// It has as valid date
} else {
// It doesn't
}
...because isNaN will coerce the date to its primitive form, which is the underlying number of milliseconds since Jan 1 1970 00:00:00 GMT, and when a date has an "invalid" date, the number it contains is NaN. So isNaN(theDateObject) is true when the date is invalid.
How do you validate timestamp using javascript and timestamp to accept multiple formats
e.g. YYYY-MM-DD HH:mm:ss.S, YYYY-MM-DD HH:mm:ss AM/PM.
You can validate if a string is a valid timestamp like this:
var valid = (new Date(timestamp)).getTime() > 0;
var valid = (new Date('2012-08-09')).getTime() > 0; // true
var valid = (new Date('abc')).getTime() > 0; // false
Revisiting this answer after many years, validating dates can still be challenging. However, some of the argument is that the built in parser accepts a number of input format, many of which have little relevance.
The question here is to validate a timestamp of multiple formats, and unless the date parser can help you, there is a need to convert the timestamp into a generic format that is comparable. How to convert into this format depends on the format of the input, and in case of incompatible inputs, a tailored conversion algorithm will have to be developed.
Either use the built in date parser, as described above, otherwise, you will have to parse the input manually, and validate it accordingly.
The solution of #Jørgen is nice but if you have a date before January 1, 1970 your timestamp will be a negative number but also a valid timestamp.
function isValidTimestamp(_timestamp) {
const newTimestamp = new Date(_timestamp).getTime();
return isNumeric(newTimestamp);
}
function isNumeric(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
The numeric validation I took from the following SO answer.
For example:
isValidTimestamp('12/25/1965') // true
Every valid number is a timestamp. If it satisfies the condition of valid integer number then it will also satisfy the condition of the valid timestamp.
Timestamp = The number of milliseconds since 1970/01/01
var d = Date.parse(your_timestamp);
d should be a valid number and not NaN.
ref: http://www.w3schools.com/jsref/jsref_parse.asp
You can't generically parse a date string without knowing beforehand what the format is, or at least that it is one of a limited number of formats.
If the date component is always in ISO8601 format (yyyy-mm-dd) and the time is either 24hr or 12hr with AM or PM, you should be able to easily split off the time, look for AM or PM, then treat the time as 12 or 24hr depending on whether it's present or not.
Timezones must be specified as either UTC (Z) or hours +/-UTC, abbreviations such as EST are ambiguous (and not standardised).
by using new Date().getTime(); you can do this
and doing something like this
var getDate="12-12-2012";
var myDate=getDate.split("-");
var getDate=myDate[1]+"/"+myDate[0]+"/"+myDate[2];
alert(new Date(getDate).getTime());
/**
* Determine whether string is timestamp
*
* #example
*
* isTimestamp('1606205966448'); // true
* isTimestamp(1606205966448); // true
* isTimestamp('1606205966448qwe'); // false
* isTimestamp('2020-11-24T08:19:26.448Z'); // false
*
* #param {string|number} n
* #returns {boolean}
*/
function isTimestamp(n) {
const parsed = parseFloat(n);
return !Number.isNaN(parsed) && Number.isFinite(parsed) && /^\d+\.?\d+$/.test(n);
}
export default isTimestamp;
Warning! The answer from Jørgen doesn't work before 1970.
getTime will return NaN (Not a Number) when it's not a valid date so we'll just use the built-in function isNaN to check, and inverse the value with !.
!isNaN(new Date("1969-02-13").getTime())
Working with dates can be a hassle. It's recommended to use libraries that are battle-tested. Something like date-fns or similar.