Используя JavaScript, непросто установить значение ввода html типа datetime-local.
document.getElementById("dateInput").valueAsNumber = new Date("Thu Mar 30 2023 12:54:17 GMT+0000 (UTC)").valueOf();
Следующее не работает, если вы не находитесь в часовом поясе UTC. valueAsNumber принимает числовое представление даты и времени, но не преобразует числовое представление UTC в местный часовой пояс.
document.getElementById("dateInput").valueAsDate = new Date("Thu Mar 30 2023 12:54:17 GMT+0000 (UTC)");
Следующее возвращает «Uncaught DOMException: не удалось установить свойство valueAsDate для HTMLInputElement: этот элемент ввода не поддерживает значения даты».
document.getElementById("dateInput").value = "Thu Mar 30 2023 12:54:17 GMT+0000 (UTC)";
Следующее возвращает «Указанное значение «Четверг, 30 марта 2023 г., 12:54:17 по Гринвичу + 0000 (UTC)» не соответствует требуемому формату. Формат — «гггг-ММ-ддЧч: мм», за которым следует необязательный «: ss». " или ":ss.SSS""
let date = new Date("Thu Mar 30 2023 12:54:17 GMT+0000 (UTC)");
const formatDate = (date) => {
return date.getFullYear() + "-" + (date.getMonth()+1).toString().padStart(2, '0') + "-" + date.getDate() + "T" + date.getHours().toString().padStart(2, '0') + ":" + date.getMinutes().toString().padStart(2, '0');
}
document.getElementById("dateInput").value = formatDate(date);
Ниже показано, как это будет реализовано. Я разместил этот вопрос/ответ, чтобы избавить кого-то еще от необходимости найти это решение.
Почему бы просто не использовать .toISOString()
???
toISOString находится в формате UTC. Когда вы устанавливаете значение ввода типа datetime-local
, оно предполагает местное время, поэтому с toISOString вы непреднамеренно сместите время на разницу между местным временем и UTC.
Если вы собираетесь использовать вывод Date.prototype.toString, вам следует проанализировать строку и создать временную метку, соответствующую вашей цели. Только название месяца нужно преобразовать в число, остальное, что вам нужно, находится в строке без изменений.
См. Date.toISOString(), но местное время вместо UTC, чтобы напрямую использовать объект Date.
Ниже приведен пример разбора вывода Date.prototype.toString и его переформатирования.
/* Reformat timestamp in Date#toString format to ISO 8601 local
* i.e. without offset.
*
* @param {string} s - timestamp in ddd MMM DD YYYY HH:mm:ss format
* default is current date
* @returns {string} timestamp reformatted as YYYY-MM-DDTHH:mm:ss
*/
function reformatDateAsISO(s = new Date().toString()) {
let pad = n => (n < 10? '0':'') + n;
let months = [,'Jan','Feb','Mar','Apr','May','Jun',
'Jul','Aug','Sep','Oct','Non','Dec'];
let [day, mon, date, year, time, rest] = s.split(' ');
return `${year}-${pad(months.indexOf(mon))}-${date}T${time}`;
}
["Thu Mar 30 2023 12:54:17 GMT+0000 (UTC)",
new Date().toString()
].forEach(s => console.info(s + '\n' + reformatDateAsISO(s)));
Спасибо за ответ. Да, я полагаю, что эта функция также достигает цели. Однако зачем изобретать велосипед, анализируя строки даты, сгенерированные из toString(), когда вызов new Date уже делает это за нас с помощью Date.parse()? Кроме того, у строк есть функция padStart, так зачем вы создаете для нее функцию?
@ bchr02— 1. Потому что вопрос «…используя строку даты, сгенерированную из Date.prototype.toString()». Если вы просто хотите использовать дату, см. это дубликат, см. второй абзац. 2. Потому что. ;-)
вы правы, мой вопрос был неправильно сформулирован. Я исправил это через редактирование. Но до сих пор этот точный вопрос не задавался и на него не давался ответ. Упомянутая вами ссылка дает ответ, который содержит информацию о часовом поясе, которая не может быть интерпретирована входным значением datetime-local html.
Если вы собираетесь использовать вывод Date.prototype.toString, вам следует проанализировать строку и создать временную метку, соответствующую вашей цели. Только название месяца нужно преобразовать в число, остальное, что вам нужно, находится в строке без изменений. См. Date.toISOString(), но местное время вместо UTC, чтобы напрямую использовать объект Date.