39

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.

6 Answers 6

27

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)

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

1 Comment

Here's a little helper I created using your code const getDateString = (date?: Date) => {const newDate = date ? new Date(date) : new Date();return new Date(newDate.getTime() - newDate.getTimezoneOffset() * 60000).toISOString().slice(0, -1);};
18

Update: this answer may set the date incorrectly (off by one day) based on your local time zone and time of day. See Maxim's answer for an explanation and a correct solution.

--

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

4 Comments

upvoted int32_t's answer but i'm using this for compatibility with firefox, which doesn't support datetime-local.
Wow, I searched for wayy too long for this simple fix. This should be the accepted answer.
Note that new Date().toISOString() changes the timestamp accordingly to the current timezone, which might need tweaking too
This answer assumes my local timezone is UTC and is not working for any other timezone. It's simply wrong, sorry. See the answer stackoverflow.com/a/66558369/2988107 from Maxim for the correct answer.
11

Date.toLocaleString can do the trick for you, as the Swedish locale sv-SE is (at the moment) almost matching the format you expect, just replace the space with a "T":

$('#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.

3 Comments

If that link is to your work, be sure to point that out, or this answer could be reported as spam...
Thanks @HereticMonkey for pointing this out, I updated the answer
Please note that locales including "sv-SE" (Swedish) may change their preferred datetime formats at any time. There is a proposal to create a stable locale with ISO-like formatting but it is still Stage 1: github.com/tc39/proposal-stable-formatting
5

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/multipage/input.html#input-type-attr-summary

3 Comments

ah yes, $('#myTextbox')[0].valueAsNumber = new Date().getTime(); works!
at least in google chrome, this does not work: $('#myTextbox')[0].valueAsDate = new Date(); Uncaught InvalidStateError: Failed to set the 'valueAsDate' property on 'HTMLInputElement': This input element does not support Date values.
This will set the time according to UTC not local time
2
$('#myTextbox').val(new Date().toISOString().slice(0,-8));

However, it will use UTC time, which may not be what you expect. If you want to use local time, then you have to compose it by yourself. (Nice job javascript)

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}:00`;
}

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

1 Comment

Note: To produce a json schema compatible date-time, one must add const seconds = date.getSeconds().toString().padStart(2, "0");, return ${year}-${month}-${day}T${hours}:${minutes}:${seconds} and set the html input's step attribute to "1".
-1

For me, I do like this:

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

1 Comment

Depending on your locale, you might not have /, nor parameters in the order you expect.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.