56

I would like to set the value of a datetime-local input with the current date and time. Right now I have an ugly solution that involves slicing the first 17 characters. In addition it sets the time in GMT instead of the local time. My code is as follows:

<input type="datetime-local" name="name" id="1234"> <script type="text/javascript"> var d = new Date(); var elem = document.getElementById("1234"); elem.value = d.toISOString().slice(0,16); </script> 

I have two problems with this code:

  1. Is there a way to convert from a Date to a legal value without manually slicing the string?
  2. I would like the string to be displayed in the datetime-local as DD/MM/YYYY, hh:mm (e.g. 05/11/2015, 14:10 it is 13:10 in GMT but I am in GMT+1 so I want to display 14:10). What is currently displayed is 05/11/2015, 01:10 PM. I would like to remove the PM and display in local time.

This might be an XY problem, so if I am doing it completely wrong and there is a better way to display datetime pickers in html, I would be happy to hear.

1

13 Answers 13

93

I ended up subtracting getTimezoneOffset minutes to adjust the toISOString value:

var now = new Date(); now.setMinutes(now.getMinutes() - now.getTimezoneOffset()); document.getElementById('dt').value = now.toISOString().slice(0,16);
<input id="dt" type="datetime-local" />

Sign up to request clarification or add additional context in comments.

4 Comments

I wish there was something more built-in to generate the format needed by a datetime-local input, but this answer works and is simple enough. Thanks!
Cool, the code is clean and easy to ready.
@Ninja Just like your commenty. XD
Btw: If your datetime-local input has step="1" set, and you want the value to not have its second cut out, replace the .slice(0,16) part with .replace(/\.\d\d\dZ/, "").
9

The following function will take a date object (e.g. new Date()) and will return a string correctly formatted for <input type='datetime-local'>.

const dateForDateTimeInputValue = date => new Date(date.getTime() + new Date().getTimezoneOffset() * -60 * 1000).toISOString().slice(0, 19) 

2 Comments

This is not always working because getTimezoneOffset it is using new Date instead of date. When date is from before of time switch and we calculate it after time switch offset will be incorrect. Eg. when give time is: 1645100310000, and current time is 1649067798571 calling dateForDateTimeInputValue(new Date(1645100310000)) will give us '2022-02-17T14:18:30' instead of correct one: '2022-02-17T13:18:30'
So the correct solution is: const dateForDateTimeInputValue = date => new Date(date.getTime() + date.getTimezoneOffset() * -60 * 1000).toISOString().slice(0, 19)
7

The toISOString function is responsible of converting your local date (new Date) into GMT.

If you don't want to use GMT then slice, you need to use the pure Date constructor and all of the getX functions, where X is (days, month, year...)

In addition, you'll need to extend the Number object with a function that will help you to return 01 instead of 1 for example, to preserve the dd/mm/yyyy, hh/mm format.

Let me call this prototype function AddZero

 <input type="datetime-local" name="name" id="1234"> <script type="text/javascript"> Number.prototype.AddZero= function(b,c){ var l= (String(b|| 10).length - String(this).length)+1; return l> 0? new Array(l).join(c|| '0')+this : this; }//to add zero to less than 10, var d = new Date(), localDateTime= [(d.getMonth()+1).AddZero(), d.getDate().AddZero(), d.getFullYear()].join('/') +', ' + [d.getHours().AddZero(), d.getMinutes().AddZero()].join(':'); var elem=document.getElementById("1234"); elem.value = localDateTime; </script> 

See this

5 Comments

Thanks for the answer. This prints the correct time as a string (05/11/2015, 14:36:30) but doesn't work as a value for a datetime-local
I am running my code on w3schools.com/htmL/…. If you copy paste your code there you will see it doesn't display properly.
Cool! What do you mean by datetime-local ? Unless I'm wrong, the local datetime is the date and time of your OS, when the runing browser is installed.
Yeah, when you run your code there it just displays null for me.
Thanks I will play around with it.
5

This is my solution to make it work with timestamps:

 function timestampToDatetimeInputString(timestamp) { const date = new Date((timestamp + _getTimeZoneOffsetInMs())); // slice(0, 19) includes seconds return date.toISOString().slice(0, 19); } function _getTimeZoneOffsetInMs() { return new Date().getTimezoneOffset() * -60 * 1000; } document.getElementById('dt').value = timestampToDatetimeInputString(Date.now()); 
<input id="dt" type="datetime-local" />

Comments

4

Since ES6(?) you can use .valueAsDate property:

const dateInput = document.querySelector('#date-input') const localDt =_=> // return local Date time { let now = new Date() now.setMinutes(now.getMinutes() - now.getTimezoneOffset()) now.setSeconds(0) // remove seconds now.setMilliseconds(0) // remove milliseconds return now } // usage : dateInput.valueAsDate = localDt() // init date value 
<input type="datetime-local" id="date-input" >

4 Comments

After clicking Run code snippet I got Uncaught InvalidStateError: Failed to set the 'valueAsDate' property on 'HTMLInputElement': This input element does not support Date values.
Chrome 114. I seems like valueAsDate only works on date inputs in chrome. Tested in firefox and it works there.
@nezu ... indeed, it no longer works with Chrome... strange, it seems to me that I tested this code on chrome in 2021! it looks like a case of regression. PS: I mainly use FireFoxb (and chromium for some testing)
2

Leaning on others'...

<input id="myDateTime" type="datetime-local"> <script> var dateString = "7/15/20 7:9:00 PM" if (dateString !== "") { var dateVal = new Date(dateString); var day = dateVal.getDate().toString().padStart(2, "0"); var month = (1 + dateVal.getMonth()).toString().padStart(2, "0"); var hour = dateVal.getHours().toString().padStart(2, "0"); var minute = dateVal.getMinutes().toString().padStart(2, "0"); var sec = dateVal.getSeconds().toString().padStart(2, "0"); var ms = dateVal.getMilliseconds().toString().padStart(3, "0"); var inputDate = dateVal.getFullYear() + "-" + (month) + "-" + (day) + "T" + (hour) + ":" + (minute) + ":" + (sec) + "." + (ms); $("#myDateTime").val(inputDate); } </script> 

The value assigned to the input.val() MUST have every digit placeholder filled in YYYY-MM-DDThh:mm:ss.mss - see Proper format for datetime-local value

Comments

1

as Mdn said there is problem with client side time like this

function setValue(element, date) { var isoString = date.toISOString() element.value = isoString.substring(0, (isoString.indexOf("T")|0) + 6|0); } setValue(document.querySelector("#timelocal"), new Date())
<!--midnight of January 1st, 10000: the exact time of Y10K--> <input type="datetime-local" id="timelocal"/>

then you should always add

new Date().getTimezoneOffset() * 60 * 1000 

when you assign value to this element and minus when u read its value

function setValue(element, date) { date = new Date(date.getTime() - new Date().getTimezoneOffset() * 60 * 1000) var isoString = date.toISOString() element.value = isoString.substring(0, (isoString.indexOf("T")|0) + 6|0); } var el = document.querySelector("#timelocal"); setValue(el, new Date()) var correctDate = new Date( el.valueAsNumber + new Date().getTimezoneOffset() * 60 * 1000); console.log(correctDate.toString())
<input type="datetime-local" id="timelocal"/>

Comments

1

In 2023, it still doesn't have a native solution to format time elegantly. However, I can compose the format that datetime-local wants, YYYY-mm-ddTHH:MM.

  • YYYY-mm-dd is the date
  • T is the seperator of date and time
  • HH:MM is for the hours and minutes

We convert a Date object and then assign it to the input's value.

const convertToDateTimeLocalString = (date) => { const year = date.getFullYear(); const month = (date.getMonth() + 1).toString().padStart(2, "0"); const day = date.getDate().toString().padStart(2, "0"); const hours = date.getHours().toString().padStart(2, "0"); const minutes = date.getMinutes().toString().padStart(2, "0"); return `${year}-${month}-${day}T${hours}:${minutes}`; } const currentTime = new Date() document.getElementById('1234').value = convertToDateTimeLocalString(currentTime) 

toISOString only shows the UTC time and other toLocaleString series methods are difficult and mysterious to be customized so I don't like to use them.

Comments

0

example :

 <TextField variant="standard" style={{width:"50%"}} //type='datetime-local' type='datetime-local' InputLabelProps={{ shrink: true }} defaultValue={new Date().toISOString().substring(0, (new Date().toISOString().indexOf("T")|0) + 6|0)} /> 

Comments

0

This might be overkill. If you want only what the OP asked for, jump to the last line, input.valueAsNumber...

/** * Store the given date and time into the given input element. * Everything will be displayed in local time, similar to dateAndTime.toString(). * * Going the other way is easy: `new Date(input.value)`. * @param input This should be set to "datetime-local". * @param dateAndTime The date and time to load into the input. */ export function loadDateTimeLocal(input : HTMLInputElement, dateAndTime : Date, truncateTo : "minutes" | "seconds" | "milliseconds" = "milliseconds") { // The element will remember this value. // If you store a time like '2021-12-08T14:23:01.001', the display and the editor will show seconds and milliseconds. // If you store a time like '2021-12-08T14:23:01.000' or '2021-12-08T14:23:01', the display and the editor will show seconds but not milliseconds. // If you store a time like '2021-12-08T14:23:00.000' or '2021-12-08T14:23', the display and the editor will show neither seconds nor milliseconds. // Changing the time using the GUI will not change which fields are displayed. // Note: Rounding or truncating will only remove fields, not add them. // If you want to display "14:23:00.000", and you want the user to be able to set the seconds via the GUI, I don't think that's possible. // Note: I didn't see this documented anywhere. I learned this by experimenting with Chrome. let truncateBy : number; switch (truncateTo) { case "minutes": { truncateBy = dateAndTime.getSeconds() * 1000 + dateAndTime.getMilliseconds(); break; } case "seconds": { truncateBy = dateAndTime.getMilliseconds(); break; } case "milliseconds" : { truncateBy = 0; break; } default: { throw new Error("wtf"); } } // This is conversion is surprisingly hard to do. Advice from MDN and others failed miserably. input.valueAsNumber = (+dateAndTime) - (dateAndTime.getTimezoneOffset() * 60000) - truncateBy; } 

Comments

0

I've just created a function to format new Date local time zone into datetime to insert it into mysql registry

const dateTime = new Date(); const dateTimeFormat = (dateTime) => { const localDateTime = dateTime.toLocaleString('en-GB') const dateTimeArray = localDateTime.split(',') const date = dateTimeArray[0].split('/').reverse().join('-') const time = dateTimeArray[1] return date + ' ' + time } 

Comments

-2

Replace this line

elem.value = d.toISOString().slice(0,16); 

with

elem.value = d.toLocaleString(); 

This will still print "am/pm" at the end but it takes care of the time adjustment to local values.

1 Comment

This does not work on an input with type datetime-local
-4

Personally i used :

<input type="datetime-local" name="name" id="1234" value="<?php echo date('Y-m-d');echo 'T';echo date (H);echo ':';echo date(i);?>"> 

2 Comments

only voting you down since this is in php, OP tags reference html, javascript and datetime object
I use PHP, also this solution for me works, thx

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.