Подтвердить что ты не робот

Дата Javascript недействительна для iOS

Я работаю над iOS-приложением на основе Phonegap, которое уже сделано для Android. Следующие строки отлично работают для Android, но не для iOS. Почему?

var d = new Date("2015-12-31 00:00:00");
console.log(d.getDate() + '. ' + d.getMonth() + ' ' + d.getFullYear();

Результат для Android:

31.11 2015

Результат на iOS:

NaN. NaN NaN

Откуда возникает разница?

4b9b3361

Ответ 1

Ваша строка даты не в формате, указанном для работы с new Date. Единственный формат в спецификации - это упрощенная версия ISO-8601, но она была добавлена только в ES5, и поэтому поддержка может быть без изменений. Ваша строка не в этом формате, но она действительно близка.

Если вы измените пространство на T, вы будете в спецификации:

var dateString = "2015-12-31 00:00:00";
var d = new Date(dateString.replace(' ', 'T'));

(Я предполагаю, что вы на самом деле не используете строковый литерал, следовательно, вызов replace.)

Обратите внимание, что в спецификации ES5 произошла ошибка, которая была исправлена в ES2015 (ES6): что происходит, когда в строке нет индикатора часового пояса. В стандарте ISO-8601 ни один индикатор не означает "местное время", но в спецификации ES5 указано, что по умолчанию используется значение Z (UTC - ошибочно, GMT). Они исправили это в спецификации ES2015, но, к сожалению, некоторые движки JavaScript следовали спецификации ES5, а другие - ISO-8601 (а теперь и ES2015). Но подождите, это становится еще хуже: использование локального времени для строк, которые только что содержат даты, оказалось проблематичным для существующего кода (и на самом деле TC39 действительно пытается не нарушать существующий код), поэтому в ES2016 им пришлось изменить его снова, чтобы сказать: Строка только для даты, интерпретируйте ее как UTC, но если это строка даты/времени, интерпретируйте ее как местное время.

Так что со всеми этими развлечениями и играми, для надежной поддержки кросс-браузеров, вы должны включить индикатор часового пояса, потому что в противном случае вы не знаете, будет ли он интерпретироваться как UTC или местное время. Вы можете использовать Z для GMT или + / - а затем HH:MM чтобы задать смещение. (Сокращения, такие как CST, не допускаются, так как для них нет стандарта.)

Если они еще не поддерживают это, то почти всеобщая поддержка для YYYY/MM/DD HH:MM:SS (интерпретируется как местное время), даже если она не указана. Так:

var dateString = "2015-12-31 00:00:00";
var d = new Date(dateString.replace(/-/g, '/'));

Ответ 2

Я не могу сказать, почему. Может быть, потому что iOS не поддерживает функцию Javascript Date, а также Android или поддерживает другой формат?

Но я могу дать вам обходное решение:

var s = "2015-12-31 00:00:00".split(" ")[0].split("-"),
    d = new Date( s[0], s[1], s[2], 0, 0, 0 );

console.log(d);

var s = "2015-12-31 00:00:00".replace(/[ :]/g, "-").split("-"),
    d = new Date( s[0], s[1], s[2], s[3], s[4], s[5] );

console.log(d);

Ответ 3

Решение, которое работает как для IOS, так и для Android, и позволяет избежать манипуляции со строками, когда оно не требуется,

let fullDate = "1991-03-29 00:00:00";
let date = new Date(fullDate);

// In case its IOS, parse the fulldate parts and re-create the date object.
if(Number.isNaN(date.getMonth())) {
  let arr = fullDate.split(/[- :]/);
  date = new Date(arr[0], arr[1]-1, arr[2], arr[3], arr[4], arr[5]);
}

Ответ 4

Попробуйте с var d = new Date("2015/12/31 00:00:00"); Работает для меня.

Ответ 5

Также

var d = new Date("2015/12/31T00:00:00");

работает для меня :)

Спасибо @dda