I am trying to get functionality - if the user entered date is less than the current date I need to show an error message on the screen, I implemented the following code which is working fine in my local system date but not working in other time zones. Can anyone please help in getting this.
I need to use only javascript or jquery. I was not supposed to use other libraries.
dateFormat = function(value, event) {
let newValue = value.replace(/[^0-9]/g, '').replace(/(\..*)\./g, '$1');
const dayOrMonth = (index) => index % 2 === 1 && index < 4;
// on delete key.
if (!event.data) {
return value;
}
return newValue.split('').map((v, i) => dayOrMonth(i) ? v '/' : v).join('');
}
checkStart = function(value) {
var newDate = new Date().toISOString();
var inputDate = new Date(value).toISOString();
var today = new Date(newDate).setHours(0,0,0,0);
var userDate = new Date(inputDate).setHours(0,0,0,0);
if(userDate < today) {
$('#error-msg3').show();
$('#startDate').val('');
} else {
$('#error-msg3').hide();
}
}
<input type="tel" maxlength="10" id="startDate" name="startDate" placeholder="mm/dd/yyyy"
oninput="this.value = dateFormat(this.value, event)" onblur="checkStart(this.value)" required/>
<span id="error">Start date should not be lesser than the current date.</span>
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
Server and Db May run on a different timezone, (UTC preferred ) and when you sen date as a string it doesn't have any timezone there instead it is just a string.
Try sending it as a timestamp or UTC date string So that server and db will automatically convert it to their timzone and store it. and when any user fetch it from other time zone it will automatically converts to their timezone (but you store string it will just be treated as a string everywhere)
let d = new Date()
console.log(d.getTime())
//or get utc string
console.log(d.toUTCString())
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
Send this value to your server (API)
CodePudding user response:
Your code runs entirely on the client so timezone is irrelevant.
In the OP there is:
var newDate = new Date().toISOString();
...
var today = new Date(newDate).setHours(0,0,0,0);
The conversion of Date to string to Date to number is inefficient and unnecessary. The following is equivalent:
let today = new Date().setHours(0,0,0,0);
Similarly for inputDate:
var inputDate = new Date(value).toISOString();
...
var userDate = new Date(inputDate).setHours(0,0,0,0);
is equivalent to:
let userDate = new Date(value).setHours(0,0,0,0);
All calculations are local so timezone is irrelevant. Also see Why does Date.parse give incorrect results?
Attempting to control user input using script is always fraught as there are many cases that are either impossible or impractical to code around. The use of a tel input for Dates is an example. The whole issue can be avoided by using a date input and setting a min value to today. Then users can't select a date before today and your issue is solved, e.g.
window.onload = function() {
let dateEl = document.getElementById('dateInput');
dateEl.min = new Date().toLocaleString('en-CA', {year:'numeric', month:'2-digit', day:'2-digit'});
}
<input id="dateInput" type="date">
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
If you are comparing the date sent by the user to a date on the server, then user system clock accuracy and timezone may be an issue, but that isn't explained in the OP.
If that is an issue, then you need to ask another question on that specific topic.
If you really want to manually control the input date and show an error message when invalid dates are selected, then parse the value from the date input and compare it to the start of today and go from there:
// Parse YYYY-MM-DD as local
function parseYMDLocal(s) {
let [Y, M, D] = s.split(/\D/);
return new Date(Y, M-1, D);
}
// Check if date in YYYY-MM-DD format is before today
function isBeforeToday(d) {
return parseYMDLocal(d) < new Date().setHours(0,0,0,0);
}
function checkValue() {
let errEl = document.getElementById('errEl');
errEl.textContent = '';
console.log(typeof this.value);
if (isBeforeToday(this.value)) {
errEl.textContent = 'Date must be today or later';
} else {
// do something else
}
}
window.onload = function() {
document.getElementById('dateInp').addEventListener('blur', checkValue, false);
}
#errEl {color: red}
<input id="dateInp" type="date"><span id="errEl"></span>
<iframe name="sif4" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>