Является ли объект даты Javascript всегда одним выходным? - PullRequest
182 голосов
/ 26 сентября 2011

В моем приложении Java Script у меня дата хранится в таком формате:

2011-09-24

Теперь, когда я пытаюсь использовать указанное выше значение для создания нового объекта Date (чтобы я мог получить дату вдругой формат), дата всегда возвращается один выходной.Смотрите ниже:

var doo = new Date("2011-09-24");
console.log(doo);

журналы:

Fri Sep 23 2011 20:00:00 GMT-0400 (Eastern Daylight Time)

Ответы [ 17 ]

193 голосов
/ 30 июля 2015

Есть несколько сумасшедших вещей, которые происходят с объектом JS DATE , который преобразует строки, например, рассмотрим следующую дату, которую вы указали

Примечание: Следующие примеры могут быть или не быть ONE DAY OFF в зависимости от ВАШ часовой пояс и текущее время.

new Date("2011-09-24"); // Year-Month-Day
// => Fri Sep 23 2011 17:00:00 GMT-0700 (MST) - ONE DAY OFF.

Однако, если мы изменим формат строки на Месяц-День-Год ...

new Date("09-24-2011");
=> // Sat Sep 24 2011 00:00:00 GMT-0700 (MST) - CORRECT DATE.

Еще один странный

new Date("2011-09-24");
// => Fri Sep 23 2011 17:00:00 GMT-0700 (MST) - ONE DAY OFF AS BEFORE.

new Date("2011/09/24"); // change from "-" to "/".
=> // Sat Sep 24 2011 00:00:00 GMT-0700 (MST) - CORRECT DATE.

Мы можем легко изменить дефис в вашей дате "2011-09-24" при создании новой даты

new Date("2011-09-24".replace(/-/g, '\/')); // => "2011/09/24".
=> // Sat Sep 24 2011 00:00:00 GMT-0700 (MST) - CORRECT DATE.

Чтоесли бы у нас была строка даты, например "2011-09-24T00: 00: 00"

new Date("2011-09-24T00:00:00");
// => Fri Sep 23 2011 17:00:00 GMT-0700 (MST) - ONE DAY OFF.

Теперь измените дефис на косая черта как и раньше;что происходит?

new Date("2011/09/24T00:00:00");
// => Invalid Date

Мне обычно приходится управлять форматом даты 2011-09-24T00: 00: 00 , поэтому я так и делаю.

new Date("2011-09-24T00:00:00".replace(/-/g, '\/').replace(/T.+/, ''));
// => Sat Sep 24 2011 00:00:00 GMT-0700 (MST) - CORRECT DATE.

ОБНОВЛЕНИЕ

Если вы предоставите отдельные аргументы конструктору Date, вы можете получить другие полезные выходные данные, как описано ниже

Примечание: аргументы могут быть типа Number или String.Я покажу примеры со смешанными значениями.

Получите первый месяц и день данного года

new Date(2011, 0); // Normal behavior as months in this case are zero based.
=> // Sat Jan 01 2011 00:00:00 GMT-0700 (MST)

Получите последний месяц и деньгод

new Date((2011 + 1), 0, 0); // The second zero roles back one day into the previous month's last day.
=> // Sat Dec 31 2011 00:00:00 GMT-0700 (MST)

Пример числа, строковые аргументы.Обратите внимание, что месяцем является март, потому что месяцы снова начинаются с нуля.

new Date(2011, "02"); 
=> // Tue Mar 01 2011 00:00:00 GMT-0700 (MST)

Если мы сделаем то же самое, но с нулевым днем, мы получим что-то другое.

new Date(2011, "02", 0); // again the zero roles back from March to the last day of February.
=> // Mon Feb 28 2011 00:00:00 GMT-0700 (MST)

При добавлении нулевого дня к любому аргументу год и месяц будет получен последний день предыдущего месяца.Если вы продолжите с отрицательными числами, вы можете продолжить откат на другой день

new Date(2011, "02", -1);
=> // Sun Feb 27 2011 00:00:00 GMT-0700 (MST)
84 голосов
/ 26 сентября 2011

Обратите внимание, что по восточному летнему времени установлено значение -4 hours и что часы в дату, когда вы возвращаетесь, равны 20.

20h + 4h = 24h

, то есть полуночи 2011-09-24.

Вы получаете правильную дату, вы просто никогда не указали правильный часовой пояс.

Если вам нужен доступ к значениям даты, вы можете использовать getUTCDate() или любой другойgetUTC*() функции :

var d,
    days;
d = new Date('2011-09-24');
days = ['Sun', 'Mon', 'Tues', 'Wed', 'Thurs', 'Fri', 'Sat'];
console.log(days[d.getUTCDay()]);
64 голосов
/ 28 января 2013

Для нормализации даты и устранения нежелательного смещения (проверено здесь: https://jsfiddle.net/7xp1xL5m/):

var doo = new Date("2011-09-24");
console.log(  new Date( doo.getTime() + Math.abs(doo.getTimezoneOffset()*60000) )  );
// Output: Sat Sep 24 2011 00:00:00 GMT-0400 (Eastern Daylight Time)

Это также выполняет то же самое и относится к @tpartee (проверено здесь: https://jsfiddle.net/7xp1xL5m/1/):

var doo = new Date("2011-09-24");
console.log( new Date( doo.getTime() - doo.getTimezoneOffset() * -60000 )  );
25 голосов
/ 26 сентября 2011

Если вы хотите получить 0 часов некоторой даты в местном часовом поясе, передайте отдельные части даты конструктору Date.

new Date(2011,08,24); // month value is 0 based, others are 1 based.
24 голосов
/ 16 января 2016

Просто хочу добавить, что очевидно добавление пробела в конце строки будет использовать UTC для создания.

new Date("2016-07-06")
> Tue Jul 05 2016 17:00:00 GMT-0700 (Pacific Daylight Time)

new Date("2016-07-06 ")
> Wed Jul 06 2016 00:00:00 GMT-0700 (Pacific Daylight Time)

Изменить: Это не рекомендуемое решение, просто альтернативный ответ. Пожалуйста, не используйте этот подход, так как очень неясно, что происходит. Есть несколько способов, которыми кто-то может рефакторировать это случайно, вызывая ошибку.

17 голосов
/ 26 сентября 2011

Я считаю, что это связано с настройкой часового пояса. Дата, которую вы создали, по Гринвичу, а по умолчанию - полночь, но ваш часовой пояс - EDT, поэтому он вычитает 4 часа. Попробуйте это, чтобы проверить:

var doo = new Date("2011-09-25 EDT");
11 голосов
/ 26 сентября 2011

Ваша проблема связана именно с часовым поясом. Обратите внимание на часть GMT-0400 - то есть вы на 4 часа отстали от GMT. Если вы добавите 4 часа к отображаемой дате / времени, вы получите ровно полночь 2011/09/24. Вместо этого используйте метод toUTCString(), чтобы получить строку GMT:

var doo = new Date("2011-09-24");
console.log(doo.toUTCString());
5 голосов
/ 26 января 2015

Это через меня за петлю, +1 на ответ zzzBov.Вот полное преобразование даты, которая работала для меня, используя методы UTC:

//myMeeting.MeetingDate = '2015-01-30T00:00:00'

var myDate = new Date(myMeeting.MeetingDate);
//convert to JavaScript date format
//returns date of 'Thu Jan 29 2015 19:00:00 GMT-0500 (Eastern Standard Time)' <-- One Day Off!

myDate = new Date(myDate.getUTCFullYear(), myDate.getUTCMonth(), myDate.getUTCDate());
//returns date of 'Fri Jan 30 2015 00:00:00 GMT-0500 (Eastern Standard Time)' <-- Correct Date!
4 голосов
/ 26 сентября 2011

Это означает 2011-09-24 00:00:00 GMT, и, поскольку вы находитесь на GMT -4, это будет 20:00 в предыдущий день.

Лично я получаю 2011-09-24 02:00:00, потому что я живу на GMT +2.

4 голосов
/ 06 сентября 2016

Это, вероятно, не очень хороший ответ, но я просто хочу поделиться своим опытом с этой проблемой.

Мое приложение глобально использует utc date с форматом 'YYYY-MM-DD', в то время как средство выбора датыплагин, который я использую, принимает только дату js, мне трудно рассмотреть как utc, так и js.Поэтому, когда я хочу передать отформатированную дату «ГГГГ-ММ-ДД» в свой указатель даты, я сначала преобразовываю ее в формат «ММ / ДД / ГГГГ», используя moment.js или все, что вам нравится, и дата, отображаемая на устройстве выбора даты, теперьправильный.Для вашего примера

var d = new Date('2011-09-24'); // d will be 'Fri Sep 23 2011 20:00:00 GMT-0400 (EDT)' for my lacale
var d1 = new Date('09/24/2011'); // d1 will be 'Sat Sep 24 2011 00:00:00 GMT-0400 (EDT)' for my lacale

Видимо d1 - это то, что я хочу.Надеюсь, это будет полезно для некоторых людей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...