'assign javascript date to html5 datetime-local input

DOM:

<input id="myTextbox" type="datetime-local" />

Javascript (jQuery):

$('#myTextbox').val(new Date().toISOString());

Doesn't work. The format of input[type=datetime-local] is supposed to be ISO 8601, which is what javascript's Date.toISOString() returns.



Solution 1:[1]

http://www.w3schools.com/jsref/jsref_toisostring.asp:

The toISOString() method converts a Date object into a string, using the ISO standard.

The standard is called ISO-8601 and the format is: YYYY-MM-DDTHH:mm:ss.sssZ

While ISO 8601 has some flexibility, the format of javascript's Date's toISOString() is exactly as shown above.

The 'Z' at the end means this is a UTC date. So, this representation includes timezone information. (Javascript dates are naturally in UTC time since they are internally represented as milliseconds since epoch.)

The format of HTML5 input with type=datetime-local must be ...

The following parts, in exactly the following order:

  • A date.
  • The literal string "T".
  • A time.

Example:

1985-04-12T23:20:50.52

1996-12-19T16:39:57

http://www.w3.org/TR/html-markup/input.datetime-local.html

This is still ISO 8601, but stricter, and it does not allow a timezone to be specified.

Luckily, removing the timezone is as easy as removing the trailing 'Z'.

var isoStr = new Date().toISOString();
$('#myTextbox').val(isoStr.substring(0,isoStr.length-1));

Solution 2:[2]

Unfortunately, the previous answers did not work properly for me, because they suggest considering UTC time as my local time (which is, generally saying, incorrect).

For example, if my local time is 2021-03-10T01:50:55+0200, then date.toISOString() returns 2021-03-09T23:50:55Z, so I cannot just cut Z at the end, because for datetime-local I need local datetime 2021-03-10T01:50:55, NOT 2021-03-09T23:50:55.

So, the fixed code would be the following:

const d = new Date();
const dateTimeLocalValue = (new Date(d.getTime() - d.getTimezoneOffset() * 60000).toISOString()).slice(0, -1);
$('#myTextbox').val(dateTimeLocalValue);

That's why it works: we still use the trick of removing trailing "Z" from UTC's time format, but before doing it, we shift the time by our time zone offset (returning by date.getTimezoneOffset() in minutes) in the backward direction. After that, the shifted time, converted to UTC, provides the same date & time that our local. Of course, actually, the shifted time is a different moment, but we don't care as soon as its date & time in UTC matches our date & time in the local timezone.

With the example above, it works the following way:

  1. shift local time by timezone offset in opposite direction (e.g. if it was UTC+2, then we make even further from UTC): 2021-03-10T01:50:55+0200 -> 2021-03-10T03:50:55+0200 (by - date.getTimezoneOffset() * 60000, because 1 minute is 60000 milliseconds)
  2. return date&time values back by converting to UTC: 2021-03-10T03:50:55+0200 -> 2021-03-10T01:50:55Z (by .toISOString())
  3. remove trailing Z to get real local time with the suited format for <input type="datetime-local"> (by .slice(0, -1))

If someone needs back transformation, from input value to js Date, then we just need to do the same steps in the reverse order:

const dateTimeLocalValue = $('#myTextbox').val();
const fakeUtcTime = new Date(`${dateTimeLocalValue}Z`);
const d = new Date(fakeUtcTime.getTime() + fakeUtcTime.getTimezoneOffset() * 60000);
console.log(d);

Any questions are welcome)

Solution 3:[3]

Use $('#myTextbox')[0].valueAsNumber = new Date().getTime().

HTMLInputElement interface also has valueAsDate property, but type=datetime-local doesn't support it unfortunately.

https://html.spec.whatwg.org/C/#input-type-attr-summary

Solution 4:[4]

Date.toLocaleString can do the trick for you:

$('#myTextbox').val(new Date().toLocaleString("sv-SE", {
    year: "numeric",
    month: "2-digit",
    day: "2-digit",
    hour: "2-digit",
    minute: "2-digit",
    second: "2-digit"
}).replace(" ", "T"));

This will work even in browsers that don't support datatime-local like Firefox-desktop and Safari-desktop.

For more information on date-related-inputs to js-date conversions check this article that I wrote on the topic.

Solution 5:[5]

For me, I do like this:

const d = new Date()
element.value = `${d.toLocaleDateString().split("/").reverse().join("-")} ${d.toLocaleTimeString()}`

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Alexander Taylor
Solution 2 Maxim Georgievskiy
Solution 3
Solution 4
Solution 5 Evandro Uzeda