У меня есть веб-страница с тремя раскрывающимися списками для дня, месяца и года. Если я использую конструктор JavaScript Date, который принимает числа, я получаю объект Date для моего текущего часового пояса:
new Date(xiYear, xiMonth, xiDate)
Укажите правильную дату, но он считает, что это время по Гринвичу + 01:00 из-за перехода на летнее время.
Проблема здесь в том, что я затем передаю этот Date методу Ajax, и когда дата десериализуется на сервере, она конвертируется в GMT и, таким образом, теряется час, который перемещает день назад на единицу.
Теперь я мог бы просто передать день, месяц и год индивидуально в метод Ajax, но, похоже, должен быть лучший способ.
Принятый ответ указал мне в правильном направлении, однако само использование setUTCHours() изменилось:
Apr 5th 00:00 GMT+01:00
к
Apr 4th 23:00 GMT+01:00
Затем мне также пришлось установить дату, месяц и год UTC, чтобы получить
Apr 5th 01:00 GMT+01:00
чего я и хотел.



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


Я не верю, что это возможно - нет возможности установить часовой пояс для объекта Date после его создания.
И в каком-то смысле это имеет смысл - концептуально (если, возможно, не в реализации); на http://en.wikipedia.org/wiki/Unix_timestamp (выделено мной):
Unix time, or POSIX time, is a system for describing instants in time, defined as the number of seconds elapsed since midnight Coordinated Universal Time (UTC) of Thursday, January 1, 1970.
После того, как вы построите его, он будет представлять определенную точку в «реальном» времени. Часовой пояс имеет значение только тогда, когда вы хотите преобразовать эту абстрактную временную точку в удобочитаемую строку.
Таким образом, имеет смысл изменить только фактическое время, которое Date представляет в конструкторе. К сожалению, кажется, что нет способа передать явный часовой пояс - и вызываемый вами конструктор (возможно, правильно) переводит ваши «локальные» временные переменные в GMT, когда он сохраняет их канонически, поэтому нет возможности использовать конструктор int, int, int для времени по Гринвичу.
С другой стороны, тривиально просто использовать конструктор, который вместо этого принимает String. Вам даже не нужно преобразовывать числовой месяц в строку (по крайней мере, в Firefox), поэтому я надеялся, что наивная реализация сработает. Однако после тестирования он успешно работает в Firefox, Chrome и Opera, но не работает в Konqueror («Недействительная дата»), Safari («Недействительная дата») и IE («NaN»). Я полагаю, у вас есть просто поисковый массив для преобразования месяца в строку, например:
var months = [ '', 'January', 'February', ..., 'December'];
function createGMTDate(xiYear, xiMonth, xiDate) {
return new Date(months[xiMonth] + ' ' + xiDate + ', ' + xiYear + ' 00:00:00 GMT');
}
Если нет возможности «установить часовой пояс для объекта Date после его создания», подразумеваете ли вы, что есть способ установить часовой пояс для создаваемого объекта Date в виде? Не похоже, что дата js - это «тонкая обертка вокруг нескольких секунд с начала эпохи» - похоже, это количество секунд плюс часовой пояс.
@Anthony, он может использовать только часовой пояс клиента. Javascript может выполнять локальные операции с utc и обратно, но доступа к базе данных часовых поясов нет. Например, он не может сказать вам время в Мехико, когда вы находитесь в Сан-Диего.
любой пробег в
var d = new Date(xiYear, xiMonth, xiDate).toLocaleString();
Похоже, это помогает мне (один часовой пояс от GMT), но, поскольку «локаль» не обязательно связана с часовым поясом, я бы не стал на это полагаться.
используя .setUTCHours(), можно было бы фактически устанавливать даты в формате UTC, что позволило бы вам использовать время UTC во всей системе.
Однако вы не можете установить его с помощью UTC в конструкторе, если вы не укажете строку даты.
Используя new Date(Date.UTC(year, month, day, hour, minute, second)), вы можете создать объект Date из определенного времени UTC.
Синтаксис «новая дата (Date.UTC (...))» позволяет вам создать дату, которая является эквивалент относительно даты в формате UTC с точки зрения момента времени, который она представляет, но это не то же самое - у нее есть другой часовой пояс (кроме UTC).
Имейте в виду, что при использовании «Дата» значение «месяц» находится в диапазоне от 0 до 11 (а не от 1 до 12). Я продолжал получать смещение часового пояса на 2 часа (хотя оно должно было быть на 1 час), и мне потребовались часы, чтобы выяснить, что причина в неправильном месяце.
Это отличный ответ. Но я использую библиотеку [datepicker ui], которая использует новую дату во многих местах. Все, что я хочу, это установить часовой пояс UTC, и каждая дата соответствует новому часовому поясу. Я удивлен, что в Javascript для этого нет ничего.
Ничто не мешает вам взять «часовой пояс» как отдельный параметр и обработать его самостоятельно. Объект Date i js всегда представлен как «местное» время, вы можете просто установить его из другого часового пояса, но toString () по-прежнему будет показывать его как соответствующее местное время.
@SanjeevKumarDangi JavaScript имеет все необходимое для этого, [datepicker ui] использует его неправильно (он работает только с местным временем, поэтому страдает от ошибок летнего времени в зависимости от местного часового пояса и времени, установленного в объекте даты). У большинства сборщиков свиданий, с которыми вы столкнетесь, одни и те же проблемы.
@ jishi - объекты Date основаны на значении времени UTC, а не на местном времени. Однако метод Date.prototype.toString по умолчанию будет использовать значения местного времени отображать.
@RobG И конструктор, и отдельные сеттеры также основаны на местном времени. В этом случае не имеет значения, как обрабатывается внутреннее представление времени. Он хотел создать объект Date ИЗ времени в формате UTC (возможно, из переменной сервера), поэтому я не понимаю, к чему вы клоните.
@ Энтони: "но это не то же самое время" неверно. Он представляет собой точно такой же момент времени, единственная разница - смещение часового пояса.
@ jishi - я попадаю на "Объект Date i js всегда представлен как «местное» время.", что неверно. Внутреннее значение времени объекта Date - UTC согласно спецификация языка. Смещение часового пояса используется для отображения местного времени.
Если вам нужен объект даты с заданной строкой даты stackoverflow.com/questions/948532/…
Я считаю, что вам нужна функция createDateAsUTC (сравните с convertDateToUTC)
function createDateAsUTC(date) {
return new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds()));
}
function convertDateToUTC(date) {
return new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds());
}
Я поражен ясностью и полезностью его ответов. Не знал, что работа с датами Javascript была таким кошмаром до сегодняшнего дня: S
Не могли бы объяснить разницу между ними? Первый преобразует date в часовой пояс UTC, а второй вроде не делает ничего полезного? (возвращает ту же дату, что и date)
Я понял: первый возвращает дату в часовом поясе UTC с буквальными значениями даты местного времени. Второй возвращает дату в местном часовом поясе, но со значениями даты в формате UTC.
Этот подход является одной из реализаций шаблона, называемого «сдвиг эпохи», который предназначен для перемещения эпохи (то есть на основе UTC) в ту, которая смещена на текущее смещение часового пояса. К сожалению, хотя это часто встречается, этот подход ошибочен. Объект JavaScript Date всегда будет отражать эпоху unix на основе UTC и часовой пояс местный. Симптом становится очевидным, когда вы вызываете toString для полученного объекта даты и по-прежнему видите местный часовой пояс, даже если вы ожидали, что он будет в формате UTC.
Это также может вызвать ошибки в значениях времени около перехода на летнее время местного часового пояса. Короче говоря, смещение эпохи (через любую реализацию) не работает с объектом JavaScript Date. Другой способ увидеть это здесь заключается в том, что Date.UTC ожидает значений на основе UTC, и вы вводите ему значения местного времени, и наоборот, с помощью конструктора Date.
Эти функции помогли мне преобразовать метку времени Unix на стороне клиента, поэтому спасибо автору
чувак, я искал ответ на этот вопрос около 5 часов, большое спасибо!
@MattJohnson Я считаю, что этот метод вполне приемлем, если вы понимаете, что любые даты, с которыми вы работаете, всегда устанавливаются на TZ среды. Если вы хотите хранить даты в формате UTC, вам необходимо иметь четкое разделение между датами со сдвигом эпохи / без сдвига и обрабатывать соответственно.
@AlbertEngelB - как вы думаете, как лучше всего хранить даты в формате UTC, избегая метода смены эпох?
Если вы хотите иметь дело с немного другой, но связанной проблемой создания объекта Javascript Date из года, месяца, дня, ..., включая часовой пояс - то есть, если вы хотите преобразовать строку в Date - тогда вы, по-видимому, Придется танцевать до безумия сложный танец:
// parseISO8601String : string -> Date
// Parse an ISO-8601 date, including possible timezone,
// into a Javascript Date object.
//
// Test strings: parseISO8601String(x).toISOString()
// "2013-01-31T12:34" -> "2013-01-31T12:34:00.000Z"
// "2013-01-31T12:34:56" -> "2013-01-31T12:34:56.000Z"
// "2013-01-31T12:34:56.78" -> "2013-01-31T12:34:56.780Z"
// "2013-01-31T12:34:56.78+0100" -> "2013-01-31T11:34:56.780Z"
// "2013-01-31T12:34:56.78+0530" -> "2013-01-31T07:04:56.780Z"
// "2013-01-31T12:34:56.78-0330" -> "2013-01-31T16:04:56.780Z"
// "2013-01-31T12:34:56-0330" -> "2013-01-31T16:04:56.000Z"
// "2013-01-31T12:34:56Z" -> "2013-01-31T12:34:56.000Z"
function parseISO8601String(dateString) {
var timebits = /^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2})(?::([0-9]*)(\.[0-9]*)?)?(?:([+-])([0-9]{2})([0-9]{2}))?/;
var m = timebits.exec(dateString);
var resultDate;
if (m) {
var utcdate = Date.UTC(parseInt(m[1]),
parseInt(m[2])-1, // months are zero-offset (!)
parseInt(m[3]),
parseInt(m[4]), parseInt(m[5]), // hh:mm
(m[6] && parseInt(m[6]) || 0), // optional seconds
(m[7] && parseFloat(m[7])*1000) || 0); // optional fraction
// utcdate is milliseconds since the epoch
if (m[9] && m[10]) {
var offsetMinutes = parseInt(m[9]) * 60 + parseInt(m[10]);
utcdate += (m[8] === '+' ? -1 : +1) * offsetMinutes * 60000;
}
resultDate = new Date(utcdate);
} else {
resultDate = null;
}
return resultDate;
}
То есть вы создаете «время в формате UTC», используя дату без часового пояса (чтобы вы знали, в какой локали она находится, а именно «локаль» UTC, и по умолчанию она не является локальной), а затем вручную применяете указанное смещение часового пояса.
Было бы неплохо, если бы кто-то действительно имел мысль об объекте даты Javascript более, ооо, пяти минут ....
спасибо за отличную функцию! единственное, что я хотел бы изменить, это добавить поддержку двоеточия в смещении часового пояса. var timebits = / ^ ([0-9] {4}) - ([0-9] {2}) - ([0-9] {2}) T ([0-9] {2}) :( [0-9] {2}) (? :: ([0-9] *) (\. [0-9] *)?) ? (?: ([+ -]) ([0 -9] {2} [:]?) ([0-9] {2}))? /;
Они действительно думали об этом; К сожалению, «они» были разработчиками языка Java, поскольку JS просто скопировал класс Date Java для своей первоначальной реализации.
@Xanthir Ооо, ты прав, и я забыл, насколько ужасным был исходный объект Java Date; но, по крайней мере, Java устарела и пошла дальше, чего Javascript, похоже, не может (это странный язык, Javascript: довольно симпатичный и далеко не такой ужасный, как кажется на первый взгляд).
var d = new Date(xiYear, xiMonth, xiDate);
d.setTime( d.getTime() + d.getTimezoneOffset()*60*1000 );
Этот ответ специально разработан для исходного вопроса и не даст ожидаемого ответа. В частности, некоторые люди захотят вычесть смещение часового пояса вместо того, чтобы добавлять его. Однако помните, что весь смысл этого решения состоит в том, чтобы взломать объект даты javascript для конкретной десериализации, а не во всех случаях.
можно было просто сделать *60000 вместо *60*1000 :)
@gthmb, конечно, но мне кажется, что *60*1000 в данном случае более понятен; Другими словами, совершенно очевидно, почему он здесь.
Это почти работает для меня, за исключением того, что я должен использовать - (минус) вместо + (плюс), чтобы получить правильное время для моего часового пояса.
это определенно был самый элегантный / самый сексуальный ответ на уродливую проблему. благодарю вас!
Да, как отмечали другие, я думаю, что в этом ответе есть ошибка. Должен быть минус, а не плюс.
Согласно developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… значение, возвращаемое getTimezoneOffset, подписано в соответствии с фактическим смещением в вашем языковом стандарте на момент вызова функции, включая учет летнего времени, поэтому я не понимаю, почему вам нужно вычесть его.
Если вы добавите timezoneOffset к объекту даты, его значение, отформатированное в локальном часовом поясе, будет выглядеть как правильное значение в UTC, но все равно будет иметь исходное смещение часового пояса (и некоторые представления, такие как «ISOString», фактически покажут это). Итак, в зависимости от того, как вы затем сериализуете объект даты, JS может применить смещение часового пояса очередной раз, что даст вам неправильный ответ. Я считаю, что это является причиной путаницы в этих комментариях между +/-. В любом случае, мой голос против этого факта, а также за то, что «в большинстве случаев вы получаете то, что ожидаете».
Пример того, о чем я говорю, с компьютера в Калифорнии 26 августа 2014 года в часовом поясе PST: d = new Date(2014, 07, 26, 11) дает мне Tue Aug 26 2014 11:00:00 GMT-0700 (PDT), d.getTimezoneOffset() возвращает 420, поэтому преобразование, предложенное в этом ответе, превращает локальное представление d в Tue Aug 26 2014 18:00:00 GMT-0700 (PDT) (7 часов спустя, что точно показывает, что 11:00 PDT - 18:00 GMT). За исключением этого надоедливого суффикса «-0700 (PDT)», показывающего, что смещение часового пояса на 420 секунд все еще существует, и: d.toISOString() возвращает 2014-08-27T01:00:00.000Z.
@metamatt Вы правы. Я удалил свое мнение из ответа и пояснил, что это не правильный ответ для всех, кто интересуется исходным вопросом.
d.setTime (d.getTime () + Math.abs (d.getTimezoneOffset ()) * 60 * 1000);
Чтобы получить значение, эквивалентное new Date(Date.UTC(y, m,d));, вам действительно нужно вычесть часовой пояс, а не добавлять его.
Это ошибочный ответ. Это не удается, если преобразование перемещает дату в часовой пояс, то есть дата находится прямо рядом с границей перехода на летнее время. Если inputDate имеет значение Sun 1 апреля 2007 г. 00:00:00 GMT + 1300 (новозеландское летнее время), преобразованное в новую дату (inputDate.getTime () + (inputDate.getTimezoneOffset () * 60000)), возвращает Sat 31 марта 2007 г., 11:00 : 00 GMT + 1300 (летнее время Новой Зеландии). Вместо этого используйте createDateAsUTC и convertDateToUTC @ monsterclub.
@RockResolve Я не очень склонен пытаться украсть ответы monsterclub оптом; Я поддержал это, хотя
Лучшее решение, которое я видел из этого, пришло из
http://www.codingforums.com/archive/index.php/t-19663.html
Функция времени печати
<script language = "javascript" type = "text/javascript">
//borrowed from echoecho
//http://www.echoecho.com/ubb/viewthread.php?tid=2362&pid=10482&#pid10482
workDate = new Date()
UTCDate = new Date()
UTCDate.setTime(workDate.getTime()+workDate.getTimezoneOffset()*60000)
function printTime(offset) {
offset++;
tempDate = new Date()
tempDate.setTime(UTCDate.getTime()+3600000*(offset))
timeValue = ((tempDate.getHours()<10) ? ("0"+tempDate.getHours()) : (""+tempDate.getHours()))
timeValue += ((tempDate.getMinutes()<10) ? ("0"+tempDate.getMinutes()) : tempDate.getMinutes())
timeValue += " hrs."
return timeValue
}
var now = new Date()
var seed = now.getTime() % 0xfffffff
var same = rand(12)
</script>
Banff, Canada:
<script language = "JavaScript">document.write(printTime("-7"))</script>
Пример полного кода
<html>
<head>
<script language = "javascript" type = "text/javascript">
//borrowed from echoecho
//http://www.echoecho.com/ubb/viewthread.php?tid=2362&pid=10482&#pid10482
workDate = new Date()
UTCDate = new Date()
UTCDate.setTime(workDate.getTime()+workDate.getTimezoneOffset()*60000)
function printTime(offset) {
offset++;
tempDate = new Date()
tempDate.setTime(UTCDate.getTime()+3600000*(offset))
timeValue = ((tempDate.getHours()<10) ? ("0"+tempDate.getHours()) : (""+tempDate.getHours()))
timeValue += ((tempDate.getMinutes()<10) ? ("0"+tempDate.getMinutes()) : tempDate.getMinutes())
timeValue += " hrs."
return timeValue
}
var now = new Date()
var seed = now.getTime() % 0xfffffff
var same = rand(12)
</script>
</head>
<body>
Banff, Canada:
<script language = "JavaScript">document.write(printTime("-7"))</script>
<br>
Michigan:
<script language = "JavaScript">document.write(printTime("-5"))</script>
<br>
Greenwich, England(UTC):
<script language = "JavaScript">document.write(printTime("-0"))</script>
<br>
Tokyo, Japan:
<script language = "JavaScript">document.write(printTime("+9"))</script>
<br>
Berlin, Germany:
<script language = "JavaScript">document.write(printTime("+1"))</script>
</body>
</html>
Ваш пример исключает переход на летнее время. CurrentTime: Пт, 4 октября 2013 г., 11:13:43 GMT-0700 (Тихоокеанское летнее время) UtcTime: Пт, 4 октября 2013 г., 18:13:43 GMT Банф, Канада: 12.13. Мичиган: 1413 часов. Гринвич, Англия (UTC): 19.13. Токио, Япония: 04:13. Берлин, Германия: 2013 час.
getTimeZoneOffset - минус для UTC + z.
var d = new Date(xiYear, xiMonth, xiDate);
if (d.getTimezoneOffset() > 0){
d.setTime( d.getTime() + d.getTimezoneOffset()*60*1000 );
}
Небольшая ошибка,! = 0 не> 0. В итоге я использовал это
Это может кому-то помочь, поместите UTC в конец того, что вы передаете новому конструктору
По крайней мере в хроме можно сказать var date = new Date("2014-01-01 11:00:00 UTC")
Возвращает "Недействительную дату" в Safari
Замените `UTC` на +0000 (заметили, что пробел между 00 и UTC необходимо удалить), и это будет работать как в Firefox, так и в Chrome. Не уверен, что для Safari. (Ссылка: stackoverflow.com/a/17545854/1273587)
Я знаю, что это устарело, но если это поможет, вы можете использовать момент и часовой пояс. Если вы их не видели, посмотрите.
две действительно удобные библиотеки для управления временем.
Однострочное решение
new Date(new Date(1422524805305).getTime() - 330*60*1000)
Вместо 1422524805305 используйте метку времени в миллисекундах. Вместо 330 используйте смещение часового пояса в минутах относительно. GMT (например, Индия +5: 30 составляет 5 * 60 + 30 = 330 минут)
Это будет код, запускаемый на клиенте, а это означает, что часовой пояс будет отличаться для ваших пользователей, расположенных по-разному. Это решение потребует, чтобы все, кому оно нужно, жили в одном часовом поясе (вашем).
@Kevin Beal в этом случае просто используйте getTimezoneOffset
d = new Date();
utc = d.getTime() + (d.getTimezoneOffset() * 60000);
nd = new Date(utc + (3600000*offset));
offset value base on which location time zone you would like to set
For India offset value +5.5,
New York offset value -4,
London offset value +1
для всего смещения местоположения Вики-список смещений времени по Гринвичу
Как это помогает Нью-Йорку при переходе на летнее время?
Для Нью-Йорка используйте значение смещения -4.
Смещение для Нью-Йорка варьируется в зависимости от летнего времени. Иногда -4, иногда -5 en.wikipedia.org/wiki/Eastern_Time_Zone
Самый простой способ получить правильную дату - использовать datejs.
Я получаю свои даты через Ajax в этом формате в виде строки: '2016-01-12T00: 00: 00'
var yourDateString = '2016-01-12T00:00:00';
var yourDate = new Date(yourDateString);
console.info(yourDate);
if (yourDate.getTimezoneOffset() > 0){
yourDate = new Date(yourDateString).addMinutes(yourDate.getTimezoneOffset());
}
console.info(yourDate);
Консоль будет читать:
Пн 11 января 2016 19:00:00 GMT-0500 (восточно-американское стандартное время)
Вт, 12 января 2016 г., 00:00:00 GMT-0500 (восточно-американское стандартное время)
https://jsfiddle.net/vp1ena7b/3/
'AddMinutes' происходит от datejs, вы, вероятно, могли бы сделать это в чистом js самостоятельно, но у меня уже был datejs в моем проекте, поэтому я нашел способ использовать его для получения правильных дат.
Я думал, что это может кому-то помочь ...
Пробовал все методы, и это был единственный способ получить полночь, чего я и добивался!
Это ЛУЧШЕЕ решение
С использованием:
// TO ALL dates
Date.timezoneOffset(-240) // +4 UTC
// Override offset only for THIS date
new Date().timezoneOffset(-180) // +3 UTC
Код:
Date.prototype.timezoneOffset = new Date().getTimezoneOffset();
Date.setTimezoneOffset = function(timezoneOffset) {
return this.prototype.timezoneOffset = timezoneOffset;
};
Date.getTimezoneOffset = function() {
return this.prototype.timezoneOffset;
};
Date.prototype.setTimezoneOffset = function(timezoneOffset) {
return this.timezoneOffset = timezoneOffset;
};
Date.prototype.getTimezoneOffset = function() {
return this.timezoneOffset;
};
Date.prototype.toString = function() {
var offsetDate, offsetTime;
offsetTime = this.timezoneOffset * 60 * 1000;
offsetDate = new Date(this.getTime() - offsetTime);
return offsetDate.toUTCString();
};
['Milliseconds', 'Seconds', 'Minutes', 'Hours', 'Date', 'Month', 'FullYear', 'Year', 'Day'].forEach((function(_this) {
return function(key) {
Date.prototype["get" + key] = function() {
var offsetDate, offsetTime;
offsetTime = this.timezoneOffset * 60 * 1000;
offsetDate = new Date(this.getTime() - offsetTime);
return offsetDate["getUTC" + key]();
};
return Date.prototype["set" + key] = function(value) {
var offsetDate, offsetTime, time;
offsetTime = this.timezoneOffset * 60 * 1000;
offsetDate = new Date(this.getTime() - offsetTime);
offsetDate["setUTC" + key](value);
time = offsetDate.getTime() + offsetTime;
this.setTime(time);
return time;
};
};
})(this));
Кофейная версия:
Date.prototype.timezoneOffset = new Date().getTimezoneOffset()
Date.setTimezoneOffset = (timezoneOffset)->
return @prototype.timezoneOffset = timezoneOffset
Date.getTimezoneOffset = ->
return @prototype.timezoneOffset
Date.prototype.setTimezoneOffset = (timezoneOffset)->
return @timezoneOffset = timezoneOffset
Date.prototype.getTimezoneOffset = ->
return @timezoneOffset
Date.prototype.toString = ->
offsetTime = @timezoneOffset * 60 * 1000
offsetDate = new Date(@getTime() - offsetTime)
return offsetDate.toUTCString()
[
'Milliseconds', 'Seconds', 'Minutes', 'Hours',
'Date', 'Month', 'FullYear', 'Year', 'Day'
]
.forEach (key)=>
Date.prototype["get#{key}"] = ->
offsetTime = @timezoneOffset * 60 * 1000
offsetDate = new Date(@getTime() - offsetTime)
return offsetDate["getUTC#{key}"]()
Date.prototype["set#{key}"] = (value)->
offsetTime = @timezoneOffset * 60 * 1000
offsetDate = new Date(@getTime() - offsetTime)
offsetDate["setUTC#{key}"](value)
time = offsetDate.getTime() + offsetTime
@setTime(time)
return time
Вау, мне это тоже не нравится, но я думаю, что люди В самом деле ненавидят, когда вы переопределяете прототип встроенных команд!
@JoshfromQaribou Нет ничего плохого в смене прототипа =) это миф и распространенное заблуждение. Эти люди просто мыслят шаблонно и не применяют критического мышления. Им сказали, что это плохо, слепо верят в это =) Матрица везде ахах.
@JoshfromQaribou Плохо менять прототип, ЕСЛИ вы пишете библиотеку. Если вы измените прототип как ЧАСТЬ своего проекта, то в этом нет ничего плохого. Например, если в будущем браузеры добавят метод с таким же именем, вы просто переопределите его =), и это также означает, что ТЕКУЩИЕ пакеты, которые вы используете, и ваш код НЕ используют недавно добавленное свойство. Это основы javascript, но не все их понимают =) дело в том, что я гениальный программист и между моим опытом и опытом обычных людей огромный разрыв =)
Этот код вернет ваш Дата объекта в формате часовой пояс браузера.
Date.prototype.timezone = function () {
this.setHours(this.getHours() + (new Date().getTimezoneOffset() / 60));
return this;
}
Редактировать:
Чтобы избежать загрязнения Date API, указанная выше функция может быть преобразована в служебную функцию. Функция принимает объект Date и возвращает измененный объект Date.
function setTimeZone(date) {
date.setHours(date.getHours() + (new Date().getTimezoneOffset() / 60));
return date;
}
Нет расширению собственных объектов
Я использовал пакет timezone-js.
var timezoneJS = require('timezone-js');
var tzdata = require('tzdata');
createDate(dateObj) {
if ( dateObj == null ) {
return null;
}
var nativeTimezoneOffset = new Date().getTimezoneOffset();
var offset = this.getTimeZoneOffset();
// use the native Date object if the timezone matches
if ( offset == -1 * nativeTimezoneOffset ) {
return dateObj;
}
this.loadTimeZones();
// FIXME: it would be better if timezoneJS.Date was an instanceof of Date
// tried jquery $.extend
// added hack to Fiterpickr to look for Dater.getTime instead of "d instanceof Date"
return new timezoneJS.Date(dateObj,this.getTimeZoneName());
},
Это сработало для меня. Не уверен, что это хорошая идея.
var myDate = new Date();
console.info('myDate:', myDate); // myDate: "2018-04-04T01:09:38.112Z"
var offset = '+5'; // e.g. if the timeZone is -5
var MyDateWithOffset = new Date( myDate.toGMTString() + offset );
console.info('MyDateWithOffset:', MyDateWithOffset); // myDateWithOffset: "2018-04-03T20:09:38.000Z"// My clock 2018-07-25, 00:26:00 (GMT+7)
let date = new Date(); // 2018-07-24:17:26:00 (Look like GMT+0)
const myTimeZone = 7; // my timeZone
// my timeZone = 7h = 7 * 60 * 60 * 1000 (millisecond);
// 2018-07-24:17:26:00 = x (milliseconds)
// finally, time in milliseconds (GMT+7) = x + myTimezone
date.setTime( date.getTime() + myTimeZone * 60 * 60 * 1000 );
// date.toISOString() = 2018-07-25, 00:26:00 (GMT+7)
Объяснение вашего кода и того, как он решает проблему, повысит качество вашего ответа и поможет обучению пользователей.
Просто установите часовой пояс и вернитесь в соответствии с
new Date().toLocaleString("en-US", {timeZone: "America/New_York"})
Other Time-zones are as Following
var world_timezones =
[
'Europe/Andorra',
'Asia/Dubai',
'Asia/Kabul',
'Europe/Tirane',
'Asia/Yerevan',
'Antarctica/Casey',
'Antarctica/Davis',
'Antarctica/DumontDUrville',
'Antarctica/Mawson',
'Antarctica/Palmer',
'Antarctica/Rothera',
'Antarctica/Syowa',
'Antarctica/Troll',
'Antarctica/Vostok',
'America/Argentina/Buenos_Aires',
'America/Argentina/Cordoba',
'America/Argentina/Salta',
'America/Argentina/Jujuy',
'America/Argentina/Tucuman',
'America/Argentina/Catamarca',
'America/Argentina/La_Rioja',
'America/Argentina/San_Juan',
'America/Argentina/Mendoza',
'America/Argentina/San_Luis',
'America/Argentina/Rio_Gallegos',
'America/Argentina/Ushuaia',
'Pacific/Pago_Pago',
'Europe/Vienna',
'Australia/Lord_Howe',
'Antarctica/Macquarie',
'Australia/Hobart',
'Australia/Currie',
'Australia/Melbourne',
'Australia/Sydney',
'Australia/Broken_Hill',
'Australia/Brisbane',
'Australia/Lindeman',
'Australia/Adelaide',
'Australia/Darwin',
'Australia/Perth',
'Australia/Eucla',
'Asia/Baku',
'America/Barbados',
'Asia/Dhaka',
'Europe/Brussels',
'Europe/Sofia',
'Atlantic/Bermuda',
'Asia/Brunei',
'America/La_Paz',
'America/Noronha',
'America/Belem',
'America/Fortaleza',
'America/Recife',
'America/Araguaina',
'America/Maceio',
'America/Bahia',
'America/Sao_Paulo',
'America/Campo_Grande',
'America/Cuiaba',
'America/Santarem',
'America/Porto_Velho',
'America/Boa_Vista',
'America/Manaus',
'America/Eirunepe',
'America/Rio_Branco',
'America/Nassau',
'Asia/Thimphu',
'Europe/Minsk',
'America/Belize',
'America/St_Johns',
'America/Halifax',
'America/Glace_Bay',
'America/Moncton',
'America/Goose_Bay',
'America/Blanc-Sablon',
'America/Toronto',
'America/Nipigon',
'America/Thunder_Bay',
'America/Iqaluit',
'America/Pangnirtung',
'America/Atikokan',
'America/Winnipeg',
'America/Rainy_River',
'America/Resolute',
'America/Rankin_Inlet',
'America/Regina',
'America/Swift_Current',
'America/Edmonton',
'America/Cambridge_Bay',
'America/Yellowknife',
'America/Inuvik',
'America/Creston',
'America/Dawson_Creek',
'America/Fort_Nelson',
'America/Vancouver',
'America/Whitehorse',
'America/Dawson',
'Indian/Cocos',
'Europe/Zurich',
'Africa/Abidjan',
'Pacific/Rarotonga',
'America/Santiago',
'America/Punta_Arenas',
'Pacific/Easter',
'Asia/Shanghai',
'Asia/Urumqi',
'America/Bogota',
'America/Costa_Rica',
'America/Havana',
'Atlantic/Cape_Verde',
'America/Curacao',
'Indian/Christmas',
'Asia/Nicosia',
'Asia/Famagusta',
'Europe/Prague',
'Europe/Berlin',
'Europe/Copenhagen',
'America/Santo_Domingo',
'Africa/Algiers',
'America/Guayaquil',
'Pacific/Galapagos',
'Europe/Tallinn',
'Africa/Cairo',
'Africa/El_Aaiun',
'Europe/Madrid',
'Africa/Ceuta',
'Atlantic/Canary',
'Europe/Helsinki',
'Pacific/Fiji',
'Atlantic/Stanley',
'Pacific/Chuuk',
'Pacific/Pohnpei',
'Pacific/Kosrae',
'Atlantic/Faroe',
'Europe/Paris',
'Europe/London',
'Asia/Tbilisi',
'America/Cayenne',
'Africa/Accra',
'Europe/Gibraltar',
'America/Godthab',
'America/Danmarkshavn',
'America/Scoresbysund',
'America/Thule',
'Europe/Athens',
'Atlantic/South_Georgia',
'America/Guatemala',
'Pacific/Guam',
'Africa/Bissau',
'America/Guyana',
'Asia/Hong_Kong',
'America/Tegucigalpa',
'America/Port-au-Prince',
'Europe/Budapest',
'Asia/Jakarta',
'Asia/Pontianak',
'Asia/Makassar',
'Asia/Jayapura',
'Europe/Dublin',
'Asia/Jerusalem',
'Asia/Kolkata',
'Indian/Chagos',
'Asia/Baghdad',
'Asia/Tehran',
'Atlantic/Reykjavik',
'Europe/Rome',
'America/Jamaica',
'Asia/Amman',
'Asia/Tokyo',
'Africa/Nairobi',
'Asia/Bishkek',
'Pacific/Tarawa',
'Pacific/Enderbury',
'Pacific/Kiritimati',
'Asia/Pyongyang',
'Asia/Seoul',
'Asia/Almaty',
'Asia/Qyzylorda',
'Asia/Qostanay',
'Asia/Aqtobe',
'Asia/Aqtau',
'Asia/Atyrau',
'Asia/Oral',
'Asia/Beirut',
'Asia/Colombo',
'Africa/Monrovia',
'Europe/Vilnius',
'Europe/Luxembourg',
'Europe/Riga',
'Africa/Tripoli',
'Africa/Casablanca',
'Europe/Monaco',
'Europe/Chisinau',
'Pacific/Majuro',
'Pacific/Kwajalein',
'Asia/Yangon',
'Asia/Ulaanbaatar',
'Asia/Hovd',
'Asia/Choibalsan',
'Asia/Macau',
'America/Martinique',
'Europe/Malta',
'Indian/Mauritius',
'Indian/Maldives',
'America/Mexico_City',
'America/Cancun',
'America/Merida',
'America/Monterrey',
'America/Matamoros',
'America/Mazatlan',
'America/Chihuahua',
'America/Ojinaga',
'America/Hermosillo',
'America/Tijuana',
'America/Bahia_Banderas',
'Asia/Kuala_Lumpur',
'Asia/Kuching',
'Africa/Maputo',
'Africa/Windhoek',
'Pacific/Noumea',
'Pacific/Norfolk',
'Africa/Lagos',
'America/Managua',
'Europe/Amsterdam',
'Europe/Oslo',
'Asia/Kathmandu',
'Pacific/Nauru',
'Pacific/Niue',
'Pacific/Auckland',
'Pacific/Chatham',
'America/Panama',
'America/Lima',
'Pacific/Tahiti',
'Pacific/Marquesas',
'Pacific/Gambier',
'Pacific/Port_Moresby',
'Pacific/Bougainville',
'Asia/Manila',
'Asia/Karachi',
'Europe/Warsaw',
'America/Miquelon',
'Pacific/Pitcairn',
'America/Puerto_Rico',
'Asia/Gaza',
'Asia/Hebron',
'Europe/Lisbon',
'Atlantic/Madeira',
'Atlantic/Azores',
'Pacific/Palau',
'America/Asuncion',
'Asia/Qatar',
'Indian/Reunion',
'Europe/Bucharest',
'Europe/Belgrade',
'Europe/Kaliningrad',
'Europe/Moscow',
'Europe/Simferopol',
'Europe/Kirov',
'Europe/Astrakhan',
'Europe/Volgograd',
'Europe/Saratov',
'Europe/Ulyanovsk',
'Europe/Samara',
'Asia/Yekaterinburg',
'Asia/Omsk',
'Asia/Novosibirsk',
'Asia/Barnaul',
'Asia/Tomsk',
'Asia/Novokuznetsk',
'Asia/Krasnoyarsk',
'Asia/Irkutsk',
'Asia/Chita',
'Asia/Yakutsk',
'Asia/Khandyga',
'Asia/Vladivostok',
'Asia/Ust-Nera',
'Asia/Magadan',
'Asia/Sakhalin',
'Asia/Srednekolymsk',
'Asia/Kamchatka',
'Asia/Anadyr',
'Asia/Riyadh',
'Pacific/Guadalcanal',
'Indian/Mahe',
'Africa/Khartoum',
'Europe/Stockholm',
'Asia/Singapore',
'America/Paramaribo',
'Africa/Juba',
'Africa/Sao_Tome',
'America/El_Salvador',
'Asia/Damascus',
'America/Grand_Turk',
'Africa/Ndjamena',
'Indian/Kerguelen',
'Asia/Bangkok',
'Asia/Dushanbe',
'Pacific/Fakaofo',
'Asia/Dili',
'Asia/Ashgabat',
'Africa/Tunis',
'Pacific/Tongatapu',
'Europe/Istanbul',
'America/Port_of_Spain',
'Pacific/Funafuti',
'Asia/Taipei',
'Europe/Kiev',
'Europe/Uzhgorod',
'Europe/Zaporozhye',
'Pacific/Wake',
'America/New_York',
'America/Detroit',
'America/Kentucky/Louisville',
'America/Kentucky/Monticello',
'America/Indiana/Indianapolis',
'America/Indiana/Vincennes',
'America/Indiana/Winamac',
'America/Indiana/Marengo',
'America/Indiana/Petersburg',
'America/Indiana/Vevay',
'America/Chicago',
'America/Indiana/Tell_City',
'America/Indiana/Knox',
'America/Menominee',
'America/North_Dakota/Center',
'America/North_Dakota/New_Salem',
'America/North_Dakota/Beulah',
'America/Denver',
'America/Boise',
'America/Phoenix',
'America/Los_Angeles',
'America/Anchorage',
'America/Juneau',
'America/Sitka',
'America/Metlakatla',
'America/Yakutat',
'America/Nome',
'America/Adak',
'Pacific/Honolulu',
'America/Montevideo',
'Asia/Samarkand',
'Asia/Tashkent',
'America/Caracas',
'Asia/Ho_Chi_Minh',
'Pacific/Efate',
'Pacific/Wallis',
'Pacific/Apia',
'Africa/Johannesburg'
];
Это должно быть вверху
Только имейте в виду, что это не работает в некоторых браузерах. Например. IE11.
Очень просто, очень элегантно. Вы можете найти здесь список всех часовых поясов stackoverflow.com/questions/38399465/…. Для UTC выберите часовой пояс Лондона.
Ни одно из этих значений не является "часовым поясом", они являются репрезентативными местоположениями База данных часовых поясов IANA для мест, которые имеют тот же исторический местный часовой пояс и переход на летнее время.
@ EPurpl3 - плохой совет. Во-первых, ответ stackoverflow не является авторитетным, расположение представителей IANA следует искать в базе данных часовых поясов IANA. Во-вторых, они не являются часовыми поясами, это репрезентативные местоположения для мест, которые имеют одинаковые исторические изменения смещения часовых поясов. Наконец, в Лондоне наблюдается переход на летнее время, поэтому «Европа / Лондон» будет отличаться от UTC с конца марта до конца октября каждый год, когда наблюдается переход на летнее время.
@RobG Да, ты прав. В список включены часы перехода на летнее время, которые могут быть полезны некоторым. Мне нужен был час с переходом на летнее время, так что это было идеально для меня. Вот полный список часов с летним временем и без него. en.wikipedia.org/wiki/List_of_tz_database_time_zones. Вскоре, если вы будете использовать Лондон в качестве UTC, летнего времени больше не будет, потому что 27 октября 2019 года Европа навсегда откажется от летнего времени, поэтому для Лондона будет всего 1 час. Мой ответ немного опередил свое время, но скоро он станет идеальным для всех, а не только для некоторых :). timeanddate.com/news/time/europe-may-scrap-dst.html
Если вы хотите проверить разницу во времени между двумя датами, вы можете просто проверить, меньше или больше второй часовой пояс от вашего первого желаемого часового пояса, и вычесть или добавить время.
const currTimezone = new Date().getTimezoneOffset(); // your timezone
const newDateTimezone = date.getTimezoneOffset(); // date with unknown timezone
if (currTimezone !== newDateTimezone) {
// and below you are checking if difference should be - or +. It depends on if unknown timezone is lesser or greater than yours
const newTimezone = (currTimezone - newDateTimezone) * (currTimezone > newDateTimezone ? 1 : -1);
date.setTime(date.getTime() + (newTimezone * 60 * 1000));
}
GMT -03: 00 Пример
new Date(new Date()-3600*1000*3).toISOString(); // 2020-02-27T15:03:26.261Z
Или даже
now = new Date().getTime()-3600*1000*3; // 1582818380528
data = new Date(now).toISOString(); // 2020-02-27T15:03:26.261Z
У меня была аналогичная проблема с выбором даты. Мои исследования привели к очень простому решению без каких-либо дополнительных библиотек или жестко запрограммированных множителей.
В моем средстве выбора даты дата отображается в локализованном формате: мм / дд / гггг
Однако он возвращает значение даты в формате ISO: гггг-мм-дд
//Select "08/12/2020" in Date Picker date_input
var input = $('#date_input').val(); //input: 2020-08-12
Если вы используете значение даты, возвращаемое по умолчанию, без изменения формата строки, Дата может не быть настроена на ваш часовой пояс. Это может привести к неожиданным результатам.
var input = $('#date_input').val(); //input: 2020-08-12
var date = new Date(input); //This get interpreted as an ISO date, already in UTC
//date: Tue Aug 11 2020 20:00:00 GMT-0400 (Eastern Daylight Time)
//date.toUTCString(): Wed, 12 Aug 2020 00:00:00 GMT
//date.toLocaleDateString('en-US'): 8/11/2020
При использовании формата строки даты, отличного от стандартного ISO yyyy-mm-dd, ваш часовой пояс применяется к Date.
var date = new Date("08/12/2020"); //This gets interpreted as local timezone
//date: Wed Aug 12 2020 00:00:00 GMT-0400 (Eastern Daylight Time)
//date.toUTCString(): Wed, 12 Aug 2020 04:00:00 GMT
//date.toLocaleDateString('en-US'): 8/12/2020
Чтобы применить часовой пояс к дате, не зависящей от формата, без манипуляций со строками, используйте Date.getTimezoneOffset() с минутами. Это работает либо с исходным форматом строки даты (то есть с датами в формате UTC или локализованными датами). Он обеспечивает согласованный результат, который затем можно точно преобразовать в UTC для хранения или взаимодействия с другим кодом.
var input = $('#date_input').val();
var date = new Date(input);
date.setMinutes(date.getMinutes() + date.getTimezoneOffset());
//date: Wed Aug 12 2020 00:00:00 GMT-0400 (Eastern Daylight Time)
//date.toUTCString(): Wed, 12 Aug 2020 04:00:00 GMT
//date.toLocaleDateString('en-US'): 8/12/2020
Когда я создаю объект даты:
new Date(year, month, day, hour, minute)
У меня нормально работает на localhost. Когда я развертываю на сервере, это перерывы, потому что сервер находится в другом часовом поясе.
Я не могу использовать getTimezoneOffset (). Мне нужен часовой пояс смещение моего дома - зависит от лето / зимнее время
// add diff minutes between myself (HOME) and server
timezoneHomeOffset (d, tz = 'Europe/Copenhagen') {
const utc = new Date(d.getTime())
const dHome = new Date(d.toLocaleString('en-US', { timeZone: tz }))
const diff = Math.round((utc - dHome) / 60000) // 60*1000 => minutes
d.setMinutes(d.getMinutes() + diff)
return d
}
const date = new Date("2020-12-16 17:45:00 UTC");
Работает отлично.
Вы можете использовать библиотеку, чтобы помочь изменить часовой пояс
moment-timezone
var moment = require("moment-timezone");
const today = new Date();
var timeGet = moment(today);
timeGet.tz("Asia/Karachi").format("ha z");
это может изменить ваш часовой пояс вашего региона, вставить регион и получить реальную проблему с gmt +
Для получения дополнительной информации посетите официальная документация по моменту часовой пояс
Не могли бы вы добавить краткое объяснение и ссылку для ответа на момент-часовой пояс?
Если принятый ответ указал вам правильное направление, но не ответил на ваш вопрос, я бы сказал, что это не должен быть принятый ответ. Ответ должен отвечать на заданный вопрос.