-1

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>
  • Are you storing date in DB ? how you are storing it, also how you are sending it to server – sojin Oct 29 '21 at 05:22
  • I have update my above code, I'm converting user entered date format to mm/dd/yyyy and sending it to server through form action url – user10742586 Oct 29 '21 at 05:29
  • If your code uses jQuery, include it as a library in the snippet otherwise it will just throw errors. Why are you using an input type tel for a date? Even if jQuery is included, the script doesn't seem to do anything useful. – RobG Oct 29 '21 at 05:57

2 Answers2

0

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())

Send this value to your server (API)

sojin
  • 2,158
  • 1
  • 10
  • 18
  • If I use in this way, will that be work for any timzone ? **var newDate = new Date().toUTCString(); var inputDate = new Date(value).toUTCString(); var today = new Date(newDate).setHours(0,0,0,0); var userDate = new Date(inputDate).setHours(0,0,0,0);** – user10742586 Oct 29 '21 at 06:32
  • In your time zone time will be (0,0,0) but in another time zone, of course, the time will be different, as you know like if it is 12 AM in your time zone it will be 3 AM in some other. there is no sense by making 0,0,0 for all time zones – sojin Oct 29 '21 at 06:37
  • But if I do the code in this way, it is allowing me to enter the yesterday's date as well which should actually need to display an error message. **var today = new Date().toUTCString(); var userDate = new Date(value).toUTCString(); if(userDate < today) { $('#error').show(); $('#startDate').val(''); } else { $('#error').hide(); }** – user10742586 Oct 29 '21 at 06:48
  • Check whether date is past or not before sending it to the server. many solutions for this available in google and StackOverflow search for it – sojin Oct 29 '21 at 07:04
  • The OP code is running entirely on the client, so server timezone is irrelevant. – RobG Oct 29 '21 at 07:11
  • No, he is storing timezone in the server, and others from different timezones are reading it from a server. so it should be a date object or time stamp. not a formated date string that is what I am saying – sojin Oct 29 '21 at 07:16
  • It may well be that the date on the client is different to the date on the server, but that isn't mentioned at all in the OP. Nothing in the OP's code hints at that. It simply compares system and user input dates in a way that makes timezones irrelevant. – RobG Oct 29 '21 at 09:50
0

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">

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>
RobG
  • 142,382
  • 31
  • 172
  • 209