Jump to content

get new value of type='date' field in its onchange event


ginerjm
Go to solution Solved by kicken,

Recommended Posts

I have a type='date' field in my html with an onchange call in it.  In the JS function that is triggered by this event I would like to get the newly-selected value and work with it but my JS line that grabs the value of the field is showing the old value still since the onchange apparently occurs before the system has actually updated the html element.

What do I have to reference to see the newly chosen date that hasn't made it to the html yet?

		new_dt = document.getElementById(dt_id).value;  // shows new value
		//alert("1 in changeDay with input of "+typeof new_dt+": "+new_dt);
		// confirms a string value of new date.
		dt_new = new Date(new_dt);	//converts str to date obj but wrong value

The code above reads in the new date value correctly.  But - when I attempt to convert that new string value to a date object I get a date that is one day earlier - typical JS logic I presume with 0-based date values.  What do I have to change in my last line of code to get a proper date value from the input string of line 1?

Edited by ginerjm
Link to comment
Share on other sites

Not my experience. Te value output in the "target" div is the new data value

<!DOCTYPE html>
<html lang="en">
<head>
<title>sample</title>
<meta charset="utf-8">
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script type='text/javascript'>

    $().ready(function() {
        $("#date1").change(function() {
            let d = $(this).val()
            
            let dobj = new Date(d)
            $("#target").html(dobj.toLocaleString())
        })
    })

</script>
</head>
<body>
    <h3>Date:</h3>
    <input type='date' id='date1' value='2023-02-24'>
    
    <h3>Changed date:</h3>
    <div id='target'>
    </div>
</body>
</html>

image.png.a8847033ea02f297c37b3a0bd689de49.png

  • Like 1
Link to comment
Share on other sites

Date inputs have a valueAsDate property you can use to get a pre-made Date object.  The date object you get will be set to the midnight of the selected date UTC.  When you convert that to string, it will be in whatever the browser's local timezone is, which is probably why you're seeing the day before.

https://jsfiddle.net/vzhqxdsp/

 

  • Like 1
Link to comment
Share on other sites

Kicken - so you're saying to use valueAsDate instead of value when I get the input from the html field.  So here's my new code:

		new_dt = document.getElementById(dt_id).valueAsDate;  // shows new value
		//alert("1 in changeDay with input of "+typeof new_dt+": "+new_dt);
				// confirms a string value of new date.
		dt_new = new Date(new_dt);	//converts str to date obj but wrong value

Same result.   

The problem is how to catch the newly chosen date from the calendar pop-up that the type='date' brings up.  It is not 2/24/23 here in the usa and I am clicking on 2/25 in the calendar.  When I click it away the JS code pops up and immediately shows me the 2/24 date still and not the date I selected - 2/25.  That is what I'm trying to figure out.  How to get the 'new' date value (which shows up on-screen once my JS code finishes) instead of the old one.

Link to comment
Share on other sites

1 hour ago, ginerjm said:

Kicken - so you're saying to use valueAsDate instead of value when I get the input from the html field

That was only part of what I said.  I also said:

1 hour ago, kicken said:

The date object you get will be set to the midnight of the selected date UTC. When you convert that to string, it will be in whatever the browser's local timezone is, which is probably why you're seeing the day before.

Your issue isn't with getting the wrong value back.  Your issue is time zones.  When you select 2/25, date you get represents 2023-02-25 00:00:00 UTC but when you're displaying that, you are displaying it in whatever your local timezone is, which for me, is Eastern Standard Time.  When converting that time from UTC to Eastern standard time you get a value of 2023-02-04 19:00:00 EST.

If you check the fiddle I link, it shows you both the UTC value and your local value when you choose a date.

 

Link to comment
Share on other sites

Ok - here is my code and the output I am seeing.

		new_dt = document.getElementById(dt_id).valueAsDate;  // shows new value
		alert("1 in changeDay with input value of "+typeof new_dt+": "+new_dt);
		dt_new = new Date(new_dt);	//converts str to date obj but wrong value
		alert("2 in changeDay dt_new is "+ typeof dt_new + ": " +dt_new);
		dt_val = dt_new.toString();
		alert("3 in changeDay dt_val is "+typeof dt_val+": "+dt_val);
		document.getElementById(day_fld).value = dt_val.substring(0, 3);

Alert 1 shows:

     1 in changeDay with input value of object: Fri Feb 24 2023 19:00:00 GMT-0500 (Eastern Standard Time)

When my datepicker was popped up I chose to move the date from 2/24 to 2/25.  I do understand why the time shows as 19:00 but the date is not what I expect but I am guessing it is the "pre" value and not the "post" value of the whole onchange process.

Alert 2 shows:

   2 in changeDay dt_new is object: Fri Feb 24 2023 19:00:00 GMT-0500 (Eastern Standard Time)

I am interpreting this output to be showing the original value of the date field since it is not the date that I clicked on in the calendar window.  I tried to change the value from 2/24 to 2/25.  But now I have a date object and not a string only thing is that it is the wrong date. 

Alert 3 shows:

    3 in changeDay dt_val is string: Fri Feb 24 2023 19:00:00 GMT-0500 (Eastern Standard Time)

Now the process is done and the date field shows the new date as desired.  My issue is that the JS code never shows me a date of 2/25 which I need since my logic is trying to show the name of the Day for each date that is displayed.  So instead of changing my day field from Fri to Sat it uses the wrong date value to determine what the Day should be, hence it remains as Fri instead of being altered to Sat.  As you can see (and wonder about) the last line of my code is simply pulling the day name off of the beginning of the result string and placing it on the page but since my code never sees 2/25 it gets the wrong day.

******************

Ok - I figured out what to do with the link you provided.  Don't understand why UTC and Local are now a concern.  I can certainly see why they are different values but since it is early in the day here in EST I don't now why UTC value is 2/25 already.

Edited by ginerjm
Link to comment
Share on other sites

15 minutes ago, ginerjm said:

I can certainly see why they are different values but since it is early in the day here in EST I don't now why UTC value is 2/25 already.

The current time of day is not relevant. The date object you get from the input is set to midnight.  EST is UTC - 5 hours.  (2023-02-25 00:00:00) - (5 hours) = (2023-02-24 19:00:00).

 

Link to comment
Share on other sites

Ok - How does this look as a solution?  Corny but since it is only for me in my location it works.

        new_dt = document.getElementById(dt_id).value;  // shows new value
        new_dt = new_dt + ' 05:00:00';
I simply grabbed the basic 'value' and appended 5 hours to it and now my calcluation comes out correct.

Link to comment
Share on other sites

Javascript (like php) doesn't do date-only values, there is always an associated time and timezone.  The date object you get from the input is created with the specified date at midnight UTC.  You can use the UTC related functions to get back that date, but if you use the non-utc functions then the information you get back is translated to whatever the local timezone is first.  Since EST is behind UTC, that means rolling back to a late hour on the previous day.

If you want a date object with the selected date in the local timezone, you'll need to generate it yourself.  One way is to create a new date object with a timestamp that has been adjusted by the timezone offset. https://jsfiddle.net/0dvn71e3/

//Calculate offset to local timezone
const adjustment = ((new Date()).getTimezoneOffset()*60*1000);
//Create a new date object with the offset applied.
const cs = new Date(df.getTime() + adjustment);

 

Link to comment
Share on other sites

It looks bad.  It's the equivalent of someone having a calculation where they are adding 2+3 and getting 4, and deciding to "fix" that by adding 1 to it.

Your examples all seem contrived and it's still not clear to me reading this thread, what the "why" is here, because you are manipulating, copying and re-creating variables in various ways, and yet you stated earlier all you care about is getting a "day".  I'm not sure what that means.

UTC exists for a reason.  Locale conversions exist for a reason.  I've had this conversation with other people in the past who seem to have the same complaint about this, but in general, it's a simple concept:  your 2/25 is not necessarily my 2/25 depending on the timezone we live in.  For that reason people synchronize their servers to UTC time zone, and store dates in utc.  The built ins at the OS level across the board are based on UTC.  

It seems like you are choosing to ignore what both Barand and Kicken have been trying to teach you.   

  • Figure out if you have a UTC or a "locale specific (ie. your timezone)" datetime.
  • If it's UTC, and you are making a copy, but you want that copy to be locale specific, make sure you are keeping that in mind.

 

Link to comment
Share on other sites

Well if someone has a true solution why not show me?

I have an input tag with type='date'.  I have PHP logic that looks at that date and derives the 'day' that it represents and puts it into a separate field to show a complete date and day pair when the data is sent to the client.  But when I click on the calendar to alter that date value I need some JS to make that day field keep up with the new date value.

I figured this out because I am by no means a JS pro.  I know enough to usually get by.  This obviously is not one of those times.  So show me how you would do it.

Link to comment
Share on other sites

@ginerjm:

Quote

I have PHP logic that looks at that date and derives the 'day' that it represents and puts it into a separate field to show a complete date and day pair when the data is sent to the client

Why?  You are storing either a date or datetime in a database, right?  If that is the case, then your extract certainly doesn't need to depend on a redundant database column, when your extract can just compute that during the process to send the data to the client.

Perhaps we are also missing content on your environment.

Right way:

  • Server uses UTC
  • Database uses UTC
  • Always store datetime values as UTC
  • Queries/display take into account client/enduser locale when presented.

Yet it is not unusual to see people say:  well I'm in albany, NY, so let me set up the system with the database to be based on the EST timezone, and then all the dates/datetimes will be what i want to see (in my local timezone).  Unfortunately that creates a mess of potential confusion, and is not best practice, but if that's your reality, perhaps that is part of the underlying issue.  

Link to comment
Share on other sites

Requinex - I appreciate your response and I tried it but the answer that it gives me is simply a number - the day value of my new date.  That is not what I am seeking.  I am trying to get the day name such as Mon, Tue....

 

Gizmola - Yes I have a date stored in my db.  My timezone is America/New York.  Whatever that means to you I don't know.  I write things for me and my friends that we use locally, so that time works for us.  My current issue has nothing to do with timezones and such.  All that I am trying to get using JS is the day (Mon, Tue...) from the new date that the datepicker calendar provides and I don't have the right JS knowledge apparently to derive that from the value of my date field when it is changed.  I am not storing it.  I am just trying to place a literal on the input form to help recognize what day the current date references.

I didn't know there could be so much discussion on right and wrong over this little problem.

Link to comment
Share on other sites

2 hours ago, ginerjm said:

My current issue has nothing to do with timezones and such

Except, it absolutely does.  You're getting the "wrong date" because of timezone issues, not because the change event is late or somehow using the previous value.

You've been given a few ways to get the selected date as you're expecting.

  1. Use the UTC date/month/year functions and build the date yourself.
  2. Adjust the date object by the timezone offset.
  3. Extract the date from the UTC string.

Pick one and roll with it.

 

Link to comment
Share on other sites

Nothing I've seen has helped me resolve this issue.

And WHY is it a timezone issue?  I'm not playing with timezones.  It has been set (php wise?) at America New York always.  Why does the datepicker bring it into play?  If I was just using it to alter the date it does it just fine.  The problem is the event handlers make it difficult.

I have an html input tag of type=date.  I want to capture some event when the user (me) clicks on the field and chooses a new date from the pop-up calendar.  When I select a new date I want to get the day (Mon,Tue....) of the new date and set another field with it.  That is all.   Show me how please.

You guys/gals have seen me on these forums for a few years now.  I"m pretty good at doing the PHP thing and sometimes JS.  This issue is something that has me struggling and nothing I've seen so far here has been clear to me.  Sorry but that's the way it is.  I would completely get rid of my current code if someone would just show me how simple it could be.

Kicken - you say I've been shown 3 ways to resolve it.  Well, I'm not seeing it.  Sorry if I'm seeming stupid but it just isn't coming to me.

Link to comment
Share on other sites

  • Solution
1 hour ago, ginerjm said:

Why does the datepicker bring it into play?

Because the javascript Date object parses the date you pick as YYYY-MM-DD 00:00:00 UTC.  If you use any of the non-utc methods of that date object to access the details of that selected time, it gives you those details in your local timezone (EST) which is -5 hours from UTC (thus, the previous day).

1 hour ago, ginerjm said:

When I select a new date I want to get the day (Mon,Tue....) of the new date and set another field with it

I was thinking you wanted the full date (m/d/Y) value not the day of the week, but either way the solutions are essentially the same.

//1. Extract the day from the generated UTC String
console.log(input.valueAsDate.toUTCString().substring(0,3));

//2. Map the day to a string via numeric index (0=Sunday)
console.log(['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'][input.valueAsDate.getUTCDay()]);

//3. Create a new date object adjusted for the timezone offset, then do the above but with the local functions
const adjustment = ((new Date()).getTimezoneOffset()*60*1000);
const cs = new Date(input.valueAsDate.getTime() + adjustment);

console.log(cs.toString().substring(0,3));
console.log(['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'][cs.getDay()]);
Link to comment
Share on other sites

The thing is, time zones seem like a simple thing until you start to run into them in code - then they turn into the actual, true, legitimate, and complete devil. I have somehow over the last three or four jobs I've had turned into the dude that fixes the time zone issues and I can say that each and every time has been a monumental pain in the ass for different reasons.

It may not look like you're having a time zone issue, but as kicken has pointed out - it is.

I have found https://momentjs.com a bit easier to deal with than straight JS Date(), but you still have to be cognizant of the time zone.

Link to comment
Share on other sites

2 hours ago, ginerjm said:

What do I do with a "console.log" instruction?

console.log is just for debugging, it shows the value in the browser's developer console, similar to doing a var_dump in php to see a variable on the page.

Edited by kicken
Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.