Javascript date - Specify incoming date format (jQuery UI DateTimepicker) - javascript

I'm using custom plugin for jQuery UI datepicker - Timepicker
I have two fields, from and to input field, and need to check if to "is greater than" from. I have my custom onClose function (onClose: function(dateText, inst) {}), but the first parameter is value of input - a date string. But my date string is not in the "valid" JS datetime format so I'm not able to get Date object instance and compare.
It's dd.mm.yyyy hh:mm, e.g. 06.08.2012 12:00
I wonder if there is anything how to specify input string format, e.g.:
var date = new Date('dd.mm.yyyy hh:mm', dateText);
If not I'll have you parse it somehow...
Thanks for help in advance.

There is no such utility built in to JavaScript. If I were you I would match the date format with a regex and use the form of the Date constructor which accepts date parts:
function parseDate(str) {
var m = str.match(/^(\d\d)\.(\d\d)\.(\d{4}) (\d\d):(\d\d)$/);
return (m) ? new Date(m[3], m[2]-1, m[1], m[4], m[5]) : null;
}
Note that the month part is zero based (instead of one based, so January=0, hence the minux one). Also, note that the Number constructor is used to convert strings to numbers so you don't have to worry about numbers possibly prefixed with a zero being interpreted as octal as can happen with parseInt(...).

Related

Using Angular DateTime pipe programmatically for hh:mm:ss formats

I'm trying use DatePipe for HH:MM:SS (or any other documented formats) just as I've used DecimalPipe for monetary values.
However, passing my logic a format such as hh:mm:ss my values immediately turn to 07:00:00.
time = 'hh:mm:ss';
val = '1:02'; // user entered value
invalids = new RegExp('[^0-9:]{0,6}', 'g'); // time chars only
replaced = String(val).replace(invalids, ''); // remove non-hhmmss characters
let value = this.datePipe.transform(replaced, time); // format the value
console.log(value); // '07:00:00' why!?
Here is the repro in StackBlitz:67
How can I get the component to accept those predefined formats to force the input value?
Angular DatePipe's input is typed as any, but actually requires a Date, or miliseconds, or ISO formatted string which you are not giving it.
https://angular.io/api/common/DatePipe#input-value
value any The date expression: a Date object, a number (milliseconds
since UTC epoch), or an ISO string
(https://www.w3.org/TR/NOTE-datetime).
The data you are passing in does not meet that criteria so it's probably not going to work for you use case unless you can modify it before sending to datePipe.

Why moment(date).isValid() returns wrong result

when I check the following date it returns true result, Why?
const value = "3";
if (moment(new Date(value), "DD-MM-YYYY HH:mm", true).isValid()) // true
{ }
or
const value = "3";
if (moment(new Date(value)).isValid()) // true
{ }
That is because new Date("3") is valid date and
console.log(new Date("3"))
This is one of those cases that shows you need to sanitize your date strings and should not depend on the native parser, unless you are sure your strings have already been validated and are conformant.
ECMA-262 Date(value) constructor specs
Date.parse
If the String does not conform to that format the function may fall back to any implementation-specific heuristics or implementation-specific date formats.
So it's not conformant to "Date Time String Format", which requires the string to start with "YYYY", so it goes to an implementation specific parsing that is similar to the rules for above, but using the form: "MM-DD-YYYY".
The purpose of using strict mode (setting third argument of moment() to true) is to let moment do the string parsing and determine if it fits the formats that you provide (to for example avoid unexpected parsing behavior like this). If you use Date() to parse, you are no longer using moment's strict mode to validate the string fits your required format.
let value = "3";
function checkDate(value){
console.log(value,
moment(value, "DD-MM-YYYY HH:mm", true).isValid() ? 'valid' : 'invalid')
}
value = "01-01-2011 11:22"
checkDate(value)
value = "01-01-2011 11:22Z"
checkDate(value)
value = "3"
checkDate(value)
value = new Date("3").toString()
checkDate(value)
value = new Date('INVALID DATE')
checkDate(value)
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.25.3/moment-with-locales.min.js" integrity="sha256-8d6kI5cQEwofkZmaPTRbKgyD70GN5mDpTYNP9YWhTlI=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.28/moment-timezone-with-data.js" integrity="sha256-O1PdKrSbpAYWSBteb7yX/CMmHhu3US31mtCbsryGwaY=" crossorigin="anonymous"></script>
If you don't need to validate the date string (for example to prevent unexpected parsing behavior), don't need to worry about non-modern browsers, and really just need to parse conforming Date strings and format to basic string formats, you could just use native Date() with Intl.DateTimeFormat or Date.prototype.toLocaleString.
TL;DR the way you are using it right now implies that you don't actually need moment
Because 3 is a valid Date, the Date also supports only the year or only month format.
If you try new Date("YYYY") --> It's a valid date
If you try new Date("MM") --> It's a valid format
So, for new Date("{1 to 12}") It will accept
For new Date("{13 to 31}") It's invalid
Also, from new Date("{32 to 49}") It considers as year, for two digits it will add the current century that is (2000 + number you specified), for e.g.
new Date("32") is the year 2032 and for new Date("{50 to 99}") it adds in the previous century i.e. (1900 + number you specified), for e.g. new Date("99") is the year "1999"
For three-digit, till "100000" on-wards it's pretty straightforward what input it is will be a year, for e.g. new Date("100") is year 100 and new Date("100000") is the year 100000. The rest are invalid.
The above is valid as of today, instead of taking care of the above information it's always advisable to use Null, NaN, and Undefined values where the date field is not present

Specific date format and optional time included with moment.js

Team,
I have got a Typescript method like below.
public getDateDisplayFormat(dateFormat: string, displayTime: boolean): string {
}
The "dateFormat" parameter can be of any with/without date format like MM/DD/YYYY or DD/MM/YYYY or DD/MM/YY HH:mmss Z or MM/DD/YY HH:mmss Z or any other valid formats.
But based on the displayTime parameter I need to add/remove time value in the date.
I tried L and LLT formats but those are giving just MM/DD/YYYY irrespective of my date format.
The dateFormat is dynamic based on the client and so I cannot change it from DD/MM into MM/DD.
So, my dateFormat which is passed should remain same but only the time portion should add/remove in the format.
Please suggest how I can achieve this.
Thanks in advance.
Try this
public getDateDisplayFormat(dateFormat: string, displayTime: boolean): string {
let format = dateFormat.substr(0,str.indexOf(' ')); //get the format by splitting the string on first space. Date goes at index 0, rest goes at index 1.
if(displayTime){
//if format length is greater than 1, it means that dateFormat had both date and time format so return it, else, append time format and return it.
dateTime = format.length > 1 ? dateFormat : format[0] + "your time format";
return dateTime;
}
// if time format is not needed just return the date format.
return format[0];
}

Formating date from milliseconds to this format: DD/MM/YYYY hh:mm:ss (US time locale) using native JS

I need to format this value in milliseconds "1543325996" to date like this "18/01/1970, 11:42:05 PM". I've already got the right result using 'toLocaleTimeString' function, but this result has String type. I need exactly Date type.
function dateFormat(date) {
var formDate = new Date(+date).toLocaleDateString("en-GB");
var formTime = new Date(+date).toLocaleTimeString("en-US");
var concatDate = (formDate + ", " + formTime);
// here I've got error 'Invalid Date'. I know that it's a wrong way, but don't know what to do.
var newDate = new Date(concatDate);
return newDate;
}
but this returns error "Invalid Date". Is there another way to convert String to Date?
...but this result has String type. I need exactly Date type.
Date objects don't have a format. Formatting is intrinsically a textual thing (e.g., string).
If you want Dates, then new Date(+date) is giving you that. There's nothing further required. Later, at some point, if you want to display that date in a textual form, use toLocaleDateString or Intl.DateTimeFormat or similar to format them in the way you want them formatted. But not until/unless you need to convert them to text (a string).

momentjs isValid is returning false when it should be true and visa versa

Using HTML, javascript and jQuery I am importing a date from MS excel using "xlsx.full.min.js". I have set the date field in MS Excel to text so MS Excel does not change its format when exported. Once imported I then parse the table created to validate each field. To validate the date field I use:
var dateFormat = 'DD/MM/YYYY';
alert("$(this).text(): " + $(this).text());
alert(moment(moment($(this).text()).format(dateFormat),dateFormat,true).isValid());
When the MS Excel date field contains "13/12/2018" false is returned. When the MS Excel date field contains "12/13/2018" true is returned. Both these values are displayed in the alert so I know they are being passed correctly.
As I have set the date format to "DD/MM/YYYY" why does that format fail and "MM/DD/YYYY" pass?
MomentJS converts the date from string into its object before performing operations on it. If format is not specified, it assumes default formats. The parse operation is explained here: https://momentjs.com/docs/#/parsing/string/
So, in your case you have to pass the dateformat while moment object is created. Like this:
var dateFormat = "DD/MM/YYYY";
moment("12/13/2018",dateFormat).isValid() //will return false
moment("13/12/2018",dateFormat).isValid() //will return true
Update:
MomentJS allows date to be parsed even if the specified date contains other characters apart from the format. For eg., "1A/2B/2018" will be considered as a valid date as "1/2/2018".
Inorder to avoid that, and check the format and date to match exactly, moment object should be passed an additional boolean to enable strict mode.
moment("1A/2B/2018", dateFormat).isValid() //will return true
moment("1A/2B/2018", dateFormat, true).isValid() //will return false

Categories