Это намного проще, если вы используете jQuery:
$("#mydiv").scrollTop($("#mydiv")[0].scrollHeight);
До появления спецификации 5-го издания метод Date.parse
был полностью зависимым от реализации (new Date(string)
эквивалентен Date.parse(string)
кроме последнего возвращает число, а не Date
). В спецификации 5-го издания было добавлено требование о поддержке упрощенного (и немного неправильного) ISO-8601 , но кроме этого было требование no для того, что Date.parse
/ new Date(string)
должны принять иное, чем то, что они должны были принять любой вывод Date # toString (не сказав, что это было).
Как и в ECMAScript 2017 (издание 8), реализации необходимо было проанализировать их вывод для Дата # toString и Дата # toUTCString , но формат этих строк не был указан.
Начиная с ECMAScript 2019 (версия 9) формат для Дата # toString и Дата # toUTCString указана как (соответственно):
предоставление еще 2 форматов, которые Date.parse должны корректно анализировать в новых реализациях (отмечая, что поддержка не является вездесущей и несовместимые реализации будут оставаться в использовании в течение некоторого времени).
Я бы рекомендовал, чтобы строки даты обрабатывались вручную, а конструктор даты Date использовался с аргументами года, месяца и дня, чтобы избежать двусмысленность:
// parse a date in yyyy-mm-dd format
function parseDate(input) {
var parts = input.split('-');
// new Date(year, month [, day [, hours[, minutes[, seconds[, ms]]]]])
return new Date(parts[0], parts[1]-1, parts[2]); // Note: months are 0-based
}
Есть какой-то метод безумия. Как правило, если браузер может интерпретировать дату как ISO-8601, он будет. «2005-07-08» попадает в этот лагерь, и поэтому он анализируется как UTC. «8 июля 2005» не может, и поэтому он анализируется по местному времени.
Подробнее см. JavaScript и даты, What Mess! .
Хотя CMS верна , что передача строк в метод разбора, как правило, небезопасна, новая спецификация ECMA-262 5th Edition (aka ES5) в разделе 15.9.4.2 предлагает что Date.parse()
фактически должны обрабатывать даты в формате ISO. В старой спецификации не было такого требования. Конечно, старые браузеры и некоторые современные браузеры по-прежнему не обеспечивают эту функциональность ES5.
Ваш второй пример не является неправильным. Это указано в UTC, что подразумевается Date.prototype.toISOString()
, но отображается в вашем локальном часовом поясе.
Оба правильные, но они интерпретируются как даты с двумя разными часовыми поясами. Итак, вы сравнили яблоки и апельсины:
// local dates
new Date("Jul 8, 2005").toISOString() // "2005-07-08T07:00:00.000Z"
new Date("2005-07-08T00:00-07:00").toISOString() // "2005-07-08T07:00:00.000Z"
// UTC dates
new Date("Jul 8, 2005 UTC").toISOString() // "2005-07-08T00:00:00.000Z"
new Date("2005-07-08").toISOString() // "2005-07-08T00:00:00.000Z"
Я удалил вызов Date.parse()
, так как он автоматически используется для строкового аргумента. Я также сравнивал даты с использованием формата ISO8601 , чтобы вы могли визуально сравнивать даты между вашими местными датами и датами UTC. Время разговора составляет 7 часов, что является разницей в часовом поясе и почему ваши тесты показывают две разные даты.
Другим способом создания этих же локальных / UTC-дат будет:
new Date(2005, 7-1, 8) // "2005-07-08T07:00:00.000Z"
new Date(Date.UTC(2005, 7-1, 8)) // "2005-07-08T00:00:00.000Z"
Но я по-прежнему настоятельно рекомендую Moment.js , который как простой, но мощный :
// parse string
moment("2005-07-08").format() // "2005-07-08T00:00:00+02:00"
moment.utc("2005-07-08").format() // "2005-07-08T00:00:00Z"
// year, month, day, etc.
moment([2005, 7-1, 8]).format() // "2005-07-08T00:00:00+02:00"
moment.utc([2005, 7-1, 8]).format() // "2005-07-08T00:00:00Z"
Во время недавнего опыта написания JS-переводчика я много боролся с внутренней работой дат ECMA / JS. Итак, я полагаю, что я брошу свои 2 цента здесь. Надеемся, что совместное использование этого материала поможет другим с любыми вопросами о различиях между браузерами в том, как они обрабатывают даты.
Все реализации хранят свои значения даты внутри себя как 64-разрядные номера которые представляют собой миллисекунды с 01.01.1970 UTC (GMT - это то же самое, что и UTC). Даты, возникающие после 1/1/1970 00:00:00
, являются положительными числами, а даты предшествуют отрицательным.
Поэтому следующий код дает точный результат во всех браузерах.
Date.parse('1/1/1970');
В моей временной зоне ( EST), результат составляет 18000000, потому что это то, сколько мс составляет 5 часов (это всего 4 часа в летние месяцы). Значение будет отличаться в разных часовых поясах. Все основные браузеры делают это одинаково.
Вот и все. Несмотря на то, что в форматах входных строк есть некоторые отклонения, которые основные браузеры будут анализировать как даты, они по существу интерпретируют их одинаково с часовыми поясами и летней экономией. Один из них - формат ISO 8601. Это единственный формат, специально описанный в спецификации ECMA-262 v.5. Для всех других строковых форматов интерпретация зависит от реализации. По иронии судьбы, это формат, в котором браузеры могут отличаться. Ниже приведен сравнительный вывод Chrome vs Firefox для 1/1/1970 на моей машине с использованием формата строки ISO 8601.
Date.parse('1970-01-01T00:00:00Z'); // Chrome: 0 FF: 0
Date.parse('1970-01-01T00:00:00-0500'); // Chrome: 18000000 FF: 18000000
Date.parse('1970-01-01T00:00:00'); // Chrome: 0 FF: 18000000
toString
для соответствия моему входному значению, если я не укажу альтернативный часовой пояс, который я никогда не делаю. Отсутствие спецификатора должно предполагать местный вход времени. Но здесь ситуация ухудшается, FF обрабатывает краткую форму формата ISO 8601 («YYYY -MM-DD ") по-разному, чем обрабатывает длинную форму (« YYYY-MM-DDTHH: mm: ss: sssZ ») без каких-либо логических причин. Вот результат из FF с длинными и короткими форматами даты ISO без спецификатора часового пояса.
Date.parse('1970-01-01T00:00:00'); // 18000000
Date.parse('1970-01-01'); // 0
Итак, чтобы ответить на вопрос первоначального вопросчика, "YYYY-MM-DD"
- это короткая форма ISO 8601 "YYYY-MM-DDTHH:mm:ss:sssZ"
. Таким образом, это интерпретируется как время UTC, тогда как другое интерпретируется как локальное. Вот почему,
console.log(new Date(Date.parse("Jul 8, 2005")).toString());
console.log(new Date(Date.parse("2005-07-08")).toString());
console.log(new Date(Date.parse("Jul 8, 2005")).toString());
console.log(new Date(Date.parse("2005-07-08T00:00:00")).toString());
Нижняя строка - это строка синтаксического анализа. Единственная строка ISO 8601, которую вы можете безопасно анализировать в браузерах, - это длинная форма. И ВСЕГДА используйте спецификатор «Z». Если вы это сделаете, вы можете спокойно перемещаться между локальным и UTC.
console.log(new Date(Date.parse("2005-07-08T00:00:00Z")).toString());
К счастью, большинство современных браузеров другие форматы ввода одинаково, включая наиболее часто используемые форматы «1/1/1970» и «1/1/1970 00:00:00 AM». Все следующие форматы (и другие) рассматриваются как локальный ввод времени во всех браузерах и конвертируются в UTC перед хранением. Таким образом, они совместимы с кросс-браузером. Выходной код этого кода во всех браузерах в моем часовом поясе одинаковый.
console.log(Date.parse("1/1/1970"));
console.log(Date.parse("1/1/1970 12:00:00 AM"));
console.log(Date.parse("Thu Jan 01 1970"));
console.log(Date.parse("Thu Jan 01 1970 00:00:00"));
console.log(Date.parse("Thu Jan 01 1970 00:00:00 GMT-0500"));
. На стороне вывода все браузеры переводили часовые пояса одинаково, но они обрабатывать строковые форматы по-разному. Вот функции toString
и то, что они выводят. Обратите внимание на то, что функции toUTCString
и toISOString
выводят на моей машине 5:00 AM.
Конвертирует с UTC в локальное время перед печатью
- toString
- toDateString
- toTimeString
- toLocaleString
- toLocaleDateString
- toLocaleTimeString
Прямая печать сохраненного времени UTC
- toUTCString
- toISOString
In Chrome
toString Thu Jan 01 1970 00:00:00 GMT-05:00 (Eastern Standard Time)
toDateString Thu Jan 01 1970
toTimeString 00:00:00 GMT-05:00 (Eastern Standard Time)
toLocaleString 1/1/1970 12:00:00 AM
toLocaleDateString 1/1/1970
toLocaleTimeString 00:00:00 AM
toUTCString Thu, 01 Jan 1970 05:00:00 GMT
toISOString 1970-01-01T05:00:00.000Z
In Firefox
toString Thu Jan 01 1970 00:00:00 GMT-05:00 (Eastern Standard Time)
toDateString Thu Jan 01 1970
toTimeString 00:00:00 GMT-0500 (Eastern Standard Time)
toLocaleString Thursday, January 01, 1970 12:00:00 AM
toLocaleDateString Thursday, January 01, 1970
toLocaleTimeString 12:00:00 AM
toUTCString Thu, 01 Jan 1970 05:00:00 GMT
toISOString 1970-01-01T05:00:00.000Z
Я обычно не используйте формат ISO для ввода строки. Единственный раз, когда использование этого формата полезно для меня, - это когда даты нужно сортировать как строки. Формат ISO можно сортировать как есть, а другие - нет. Если у вас есть совместимость с несколькими браузерами, укажите либо часовой пояс, либо используйте совместимый строковый формат.
Код new Date('12/4/2013').toString()
проходит через следующее внутреннее псевдопреобразование:
"12/4/2013" -> toUCT -> [storage] -> toLocal -> print "12/4/2013"
Надеюсь, этот ответ был полезен.
Согласно http://blog.dygraphs.com/2012/03/javascript-and-dates-what-mess.html формат «yyyy / mm / dd» решает обычные проблемы , Он говорит: «Придерживайтесь« YYYY / MM / DD »для строк даты, когда это возможно. Это универсально поддерживается и недвусмысленно. В этом формате все времена являются локальными». Я установил тесты: http://jsfiddle.net/jlanus/ND2Qg/432/ Этот формат: + избегает двусмысленности порядка дня и месяца, используя порядок ymd и 4-значный год + избегает UTC против локальной проблемы, не соответствующей формату ISO, с помощью косой черты + danvk, dygraphs , говорит, что этот формат хорош во всех браузерах.
Ниже приведен короткий гибкий фрагмент, который преобразует строку datetime в безопасном для кросс-браузера стиле, как nicel, подробно описанный @ drankin2112.
var inputTimestamp = "2014-04-29 13:00:15"; //example
var partsTimestamp = inputTimestamp.split(/[ \/:-]/g);
if(partsTimestamp.length < 6) {
partsTimestamp = partsTimestamp.concat(['00', '00', '00'].slice(0, 6 - partsTimestamp.length));
}
//if your string-format is something like '7/02/2014'...
//use: var tstring = partsTimestamp.slice(0, 3).reverse().join('-');
var tstring = partsTimestamp.slice(0, 3).join('-');
tstring += 'T' + partsTimestamp.slice(3).join(':') + 'Z'; //configure as needed
var timestamp = Date.parse(tstring);
Ваш браузер должен предоставить тот же результат временной метки, что и Date.parse
с:
(new Date(tstring)).getTime()
Используйте moment.js для синтаксического анализа дат:
var caseOne = moment("Jul 8, 2005", "MMM D, YYYY", true).toDate();
var caseTwo = moment("2005-07-08", "YYYY-MM-DD", true).toDate();
Третий аргумент определяет строгий разбор (доступно с 2.3.0). Без него moment.js также может давать неверные результаты.
Эта библиотека синтаксического анализа веса должна решить все подобные проблемы. Мне нравится библиотека, потому что ее довольно легко расширить.
Пример синтаксического анализа:
var caseOne = Date.parseDate("Jul 8, 2005", "M d, Y");
var caseTwo = Date.parseDate("2005-07-08", "Y-m-d");
И форматирование обратно в строку (вы заметите, что оба случая дают точно такой же результат):
console.log( caseOne.dateFormat("M d, Y") );
console.log( caseTwo.dateFormat("M d, Y") );
console.log( caseOne.dateFormat("Y-m-d") );
console.log( caseTwo.dateFormat("Y-m-d") );
Другое решение состоит в создании ассоциативного массива с форматом даты и последующим переформатированием данных.
Этот метод полезен для даты, отформатированной беспорядочным способом.
Пример:
mydate='01.02.12 10:20:43':
myformat='dd/mm/yy HH:MM:ss';
dtsplit=mydate.split(/[\/ .:]/);
dfsplit=myformat.split(/[\/ .:]/);
// creates assoc array for date
df = new Array();
for(dc=0;dc<6;dc++) {
df[dfsplit[dc]]=dtsplit[dc];
}
// uses assc array for standard mysql format
dstring[r] = '20'+df['yy']+'-'+df['mm']+'-'+df['dd'];
dstring[r] += ' '+df['HH']+':'+df['MM']+':'+df['ss'];
Ответ на принятый ответ от CMS верен, я только что добавил некоторые функции:
// parse a date time that can contains spaces, dashes, slashes, colons
function parseDate(input) {
// trimes and remove multiple spaces and split by expected characters
var parts = input.trim().replace(/ +(?= )/g,'').split(/[\s-\/:]/)
// new Date(year, month [, day [, hours[, minutes[, seconds[, ms]]]]])
return new Date(parts[0], parts[1]-1, parts[2] || 1, parts[3] || 0, parts[4] || 0, parts[5] || 0); // Note: months are 0-based
}
Date.parse
не вел себя с форматами даты в Великобритании по какой-то причине, я не мог работать – Ben 23 July 2012 в 11:59return new Date(parts[0], parts[1] - 1, parts[2], parts[3], parts[4], parts[5]);
Отлично работает, спасибо! – Richard Rout 13 February 2013 в 22:57