JS Date "Too many Recursions" - javascript

I have a piece of code to validate date ranges that Works in Chrome, but not in IE or Firefox.
I am using Kendo DateTimePicker to get the user dates. For example, if DateTo is an earlier date than DateFrom, DateFrom will be automatically change to the same date as DateTo.
if (dateFromEpochTime > dateToEpochTime) {
date = dateFrom.data("kendoDateTimePicker").value();
date.setHours(23);
date.setMinutes(59);
date.setSeconds(59);
dateTo.kendoDateTimePicker({
value: date,
format: "dd-MM-yyyy HH:mm:ss"
})
changedByCode = true;
}
} else {
if (dateFromEpochTime > dateToEpochTime) {
date = dateTo.data("kendoDateTimePicker").value();
date.setHours(00);
date.setMinutes(00);
date.setSeconds(00);
dateFrom.kendoDateTimePicker({
value: date,
format: "dd-MM-yyyy HH:mm:ss"
})
changedByCode = true;
}
}
This pieces of code that throw the exceptions(Too many recursions for Firefox and Out of stack space for IE) are:
dateTo.kendoDateTimePicker({ value: date, format: "dd-MM-yyyy HH:mm:ss" })
dateFrom.kendoDateTimePicker({ value: date, format: "dd-MM-yyyy HH:mm:ss" })
I cant quite figure out what goes wrong there.
P.s: Before the user presses Ok, I can change the dates as many times as I want and my function will correct them. After I press Ok and try to repeat the action things are breaking. Also, I am not including the same JavaScript file twice.

Related

javascript - how to get date format from string date

How can I get date format (for example: DD/MM/YYYY) from already formatted date (for example: 1/9/2021). Also can I somehow achieve not to swap US Date and NOT US Date (DD/MM/YYYY vs. MM/DD/YYYY).
I'm using Angular project (in case there is a Angular solution)
You can use moment.js to parse date like:
import moment from "moment";
const newDate = moment("1/9/2021", "MM/DD/YYYY").format("DD/MM/YYYY");
// newDate = 09/01/2021
The short answer is you can't reliably determine the format that a user inputs a date string based on system settings, even if you had access to them, because the user might input the value in a different format. E.g. in Britain it's common to use day/month/year, but if you check out the date on The Times newspaper you'll see something like "Sunday September 5 2021".
That's one reason why date pickers are used, however many users still prefer to enter dates manually and often find date pickers annoying.
Anyway, it seemed like a bit of fun to determine the localised format that Intl.DateTimeFormat produces for the default system language. This is of course totally unreliable, whatever. :-)
This works because formatToParts returns the parts in an array in the order associated with the language, along with the separators.
function getDateFormat(lang) {
let d = new Date(2021,0,20);
let format = new Intl.DateTimeFormat(lang,{
year: 'numeric',
month: 'numeric',
day: 'numeric'
}).formatToParts(d).reduce((acc,part) => {
acc += part.type == 'literal'? part.value : part.type;
return acc;
}, '');
return format;
}
['default',
'en-GB',
'en-US',
'en-CA',
'nl-BX',
'ar'].forEach(lang => {
let langDefault = lang == 'default'? new Intl.DateTimeFormat('default').resolvedOptions().locale : null;
console.log('Lang ' + lang + (langDefault? ' (' + langDefault + ')':'') +
' format ' + getDateFormat(lang) + '.');
});

Javascript date validation?

I have this validation in my code:
}
if(!$('#date').val() ) {
toastr.warning('Incomplete date field');
return;
}
How can i do a validation that my input #date could not be bigger than current date? or getdate() ?
i was traying
}
if(!$('#date').val() )> date.now {
toastr.warning('Check date');
return;
}
But it doesn´t work
Date.now() returns current timestamp (the number of milliseconds elapsed since January 1, 1970 00:00:00 UTC). It can be compared to another timestamp like this:
if (timestamp > Date.now()) {
toastr.warning('Check date');
return;
}
timestamp here needs to be obtained from the input value by converting the text to Date object. Date object supports several formats, see examples here.
Assuming #data input has value of 2021-12-31, timestamp will be 1640908800000 and Check date warning will be shown:
// $('#date').val() is '2020-11-20'
const dateObject = new Date($('#date').val());
const timestamp = dateObject.getTime();
// timestamp is 1640908800000
// Date.now() is 1605139119142
// 1640908800000 > 1605139119142
if (timestamp > Date.now()) {
toastr.warning('Check date');
return;
}
P.S. Please mind that JavaScript is case-sensitive, so Date is not the same as date.
P.P.S. Parsing dates (especially time) with Date object has many issues, so many libraries were created to do it in a reliable way. For example, MomentJS and date-fns.

momentjs for only time value

I use momentjs to work with date and time
let dateAndTime = moment(component.props.data.value, moment.ISO_8601);
let date = '',
time = '';
if (dateAndTime) {
if (moment(dateAndTime, 'YYYY-MM-DD', true).isValid()) {
date = moment(dateAndTime).format('YYYY-MM-DD');
}
if (moment(dateAndTime, 'HH:mm', true).isValid()) {
time = moment(dateAndTime).format('HH:mm');
}
}
this code works just fine if component.props.data.value contains date and time like 2018-05-22 14:45 or if it contains only date like 2018-05-22. The problem is sometimes component.props.data.value contains only time like 14:45, so moment(component.props.data.value, moment.ISO_8601) doesn't create moment object and code below doesn't execute. Is there any way to handle case only for time?
You can use moment(String, String[]), as the docs says:
If you don't know the exact format of an input string, but know it could be one of many, you can use an array of formats.
This is the same as String + Format, only it will try to match the input to multiple formats.
Your first line of code could be like the following:
let dateAndTime = moment(component.props.data.value, [moment.ISO_8601, 'HH:mm']);

Javascript compare two datetimes

I need to compare two datetimes. Format of datetimes is: DD-MM-YYYY hh:mm:ss.
Here is my code:
expirationDate = someDate;
var now = moment().format("DD-MM-YYYY hh:mm:ss");
if(moment(expirationDate).isBefore(now)){
console.log("Past");
} else {
console.log("Future");
}
for this datetimes it work great:
Now: 07-12-2017 11:15:09
Expiration date: 07-12-2017 10:14:10
it return Past
but for this it doesn't work:
Now: 07-12-2017 11:15:03
Expiration date: 15-12-2016 05:59:00
it return Future
I've also tried with if (Date.parse(expireDate) < Date.parse(now)) it also doesn't work properly.
Does anyone know where is the problem or is there any other way to compare two datetimes?
You need to specify the format of the date string.
if (moment().isAfter(moment(expirationDate, 'DD-MM-YYYY HH:mm:ss'))) {
console.log("Past");
} else {
console.log("Future");
}

Plotly.js setting timezone for type:"date"

I'm working on a graph to display a status over time. All the data is in unix formatting. I display the data in my title using javascript (new Date(data)).toUTCString. This is the same data used for the graph but the graph is running 1 hour early. Image
Here is my layout config:
layout = {
"showlegend": true,
"title": new Date(min).toUTCString() + " to " + new Date(max).toUTCString(),
"xaxis": {
"autorange": true,
"range": [
min,
max
],
"title": "Time",
"type": "date" //if I change this to scatter, I get the unix values
}
}
Plotly.newPlot('graphMain', temp, layout); //temp contains the arrays
I'm currently residing in Austria (UTC+01:00).
Anyone have an idea for this?
Plotly doesn't currently support timezones.
You might want to use something like moment.js timezone if you need to precompute datetime to a local timezone or to UTC. Or you can do it manually if you like.
Today, I think Plotly.js still doesn't support timezones, or at least I couldn't find it. This is how I solved it, but, please, if you have a better solution I'd be glad to hear about!
I suppose the original format of the dates is yyyy-mm-ddTHH:MM:SSZ, then you change the format using the function in https://stackoverflow.com/a/74341794/11692632, which gets the timezone of the pc.
function fmt(date, format = 'YYYY-MM-DD hh:mm:ss') {
const pad2 = (n) => n.toString().padStart(2, '0');
//These functions get the date from the browser timezone, in my case 'Europe/Madrid'
const map = {
YYYY: date.getFullYear(),
MM: pad2(date.getMonth() + 1),
DD: pad2(date.getDate()),
hh: pad2(date.getHours()),
mm: pad2(date.getMinutes()),
ss: pad2(date.getSeconds()),
};
return Object.entries(map).reduce((prev, entry) => prev.replace(...entry), format);
}
> date = '2022-12-15T10:00:00Z'
'2022-12-15T10:00:00Z'
> newDate = new Date(date)
2022-12-15T10:00:00.000Z
> fmt(new Date(date))
'2022-12-15 11:00:00'
NOTE, of course, if you are using unix time, it would also work
> date = 1671100918000
1671100918000
> newDate = new Date(date)
2022-12-15T10:41:58.000Z
> newDate.toLocaleString('se-SE', { timeZone: 'Europe/Madrid' })
'2022-12-15 11:41:58'
So, if my array of dates is dates, to translate the dates to my timezone you should do:
> const tz_dates=dates.map(date=>fmt(new Date(date)))

Categories

Resources