Я использую date-fns для возврата некоторых значений, как показано ниже:
import { format, formatDistance } from "date-fns";
var date = new Date("2019-03-06 00:00:00");
console.info(format(new Date(date), "dd MMM, y"));
Он отлично работает в Chrome и возвращается We Mar, y
Но возвращает Invalid Date в Safari.
Я полагаю, это потому, что дата ("2019-03-06 00:00:00") не в формате ISO 8601. Но это формат, который я получаю от конечной точки. Есть ли возможность преобразовать это в правильный формат и заставить его работать в Safari?
Возможно: "2019-03-06 00:00:00".split(" ").join("T")



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Я вижу две проблемы:
Вы полагаетесь на нестандартный формат ввода при первом анализе даты.
Вы передаете Date конструктору Date, что заставляет его преобразовать дату в строку, а затем проанализировать строку.
Я бы проанализировал его только один раз и использовал стандартный формат даты/времени при вызове new Date в первый раз:
import { format, formatDistance } from "date-fns";
var date = new Date("2019-03-06T00:00:00");
// Note -----------------------^
console.info(format(date, "dd MMM, y"));
// No `new Date` ^
Обратите внимание, что ваша строка будет проанализирована как местное время (в движках JavaScript, соответствующих спецификациям¹), поскольку она включает в себя временную часть строки. К сожалению, это изменилось после того, как формат был добавлен в ES2015, обновлен в ES2016, но где он закончился:
When the UTC offset representation is absent, date-only forms are interpreted as a UTC time and date-time forms are interpreted as a local time.
Поскольку ваша строка не имеет смещения UTC (без Z или +00:00 или подобных) и имеет время, она анализируется по местному времени. (Опять же, на движках JavaScript, соответствующих спецификациям¹).
Я рекомендую либо не анализировать строки даты с помощью встроенного объекта Date, либо убедиться, что у вас всегда есть индикатор часового пояса в строке, если вы это делаете.
¹ РобГ указал, что Safari анализирует new Date("2019-03-06T00:00:00") как UTC. К сожалению, это Жук в JavaScriptCore, движке JavaScript от Apple. Это влияет не только на Safari, но и на Chrome на iOS (и, возможно, на любой другой браузер iOS; я тестировал Brave, Opera и Dolphin), поскольку Chrome должен использовать JavaScriptCore вместо своего обычного V8 на iOS, потому что приложения не могут выделять исполняемую память, поэтому механизмы JIT нельзя использовать на iOS. Но команда V8 сделала версия V8 только для интерпретатора, поэтому, возможно, Chrome (и Brave) на iOS будет обновлен, чтобы использовать его, если он будет достаточно быстрым.
Есть ли способ преобразовать "2019-03-06 00:00:00" в "2019-03-06T00:00:00", поскольку я не контролирую то, что получаю от API?
@ user1012181 - Замена строки: theDate = theDate.replace(/ /g, "T");. Вы захотите проверить, предназначено ли то, что предоставляет вам API, для UTC или местного времени. Если это UTC, добавьте Z в конце: theDate = theDate.replace(/ /g, "T") + "Z";.
Спасибо, я проверю это
"… анализируется по местному времени.". Нет, синтаксический анализатор Safari не работает, new Date("2019-03-06T00:00:00") анализируется как UTC. :-(
@RobG - "(в браузерах, соответствующих спецификациям)" :-) (Но я вижу, что у меня этого нет в обоих местах.) Я удивлен, что Safari еще не соответствует спецификации, тьфу. Вот почему я не анализирую даты как строки без часового пояса.
@RobG - Тьфу, это еще хуже: это не Сафари как таковой (конечно), это JavaScriptCore, поэтому он влияет на Safari, а также на Chrome на iOS (поскольку Chrome должен использовать АО на iOS, потому что приложения не могут выделять исполняемую память -- но в какой-то момент они могут использовать вместо этого режим только интерпретатора V8). Раздражает В самом деле то, что формат, определяемый спецификацией не (mm/dd/yyyy HH:MM:SS), надежно анализируется как местное время для разных движков (и локалей, несмотря на то, что он специфичен для США): jsfiddle.net/tjcrowder/ojmh3fsv/2Вздох
Удивительно, но я не смог найти отчет об ошибке, поэтому я добавил один.
Система сообщений об ошибках Safari довольно удручающая. Я сообщил о некоторых ошибках несколько лет назад, насколько я знаю, они не исправлены. Начиная с ECMAScript 2015, при передаче объекта Date конструктор больше не выполняет операцию date -> string -> date, он просто принимает значение времени. :-) Я все еще люблю использовать new Date(+date).
Простым ответом на это может быть преобразование даты в отметку времени и значение и передача ее в format
import { format, formatDistance } from "date-fns";
var date = new Date("2019-03-06").getTime();
console.info(format(new Date(date), "dd MMM, y"));
Почему вы дважды анализируете дату?