Как проверить, если DST (летнее время) в силе, и если это то, что смещение?
Это немного моего JS-кода, для которого это необходимо:
var secDiff=Math.abs(Math.round((utc_date-this.premiere_date)/1000));
this.years=this.calculateUnit(secDiff,(86400*365));
this.days=this.calculateUnit(secDiff-(this.years*(86400*365)),86400);
this.hours=this.calculateUnit((secDiff-(this.years*(86400*365))-(this.days*86400)),3600);
this.minutes=this.calculateUnit((secDiff-(this.years*(86400*365))-(this.days*86400)-(this.hours*3600)),60);
this.seconds=this.calculateUnit((secDiff-(this.years*(86400*365))-(this.days*86400)-(this.hours*3600)-(this.minutes*60)),1);
Я хочу получить дату и время назад, но если DST используется, то даты отключены на 1 час. Я не знаю, как проверить, используется ли DST или нет.
Как я могу узнать, когда начинается и заканчивается переход на летнее время?
10 ответов:
этот код использует тот факт, что
getTimezoneOffsetвозвращает a больше значение во время стандартного времени против летнего времени (DST). Таким образом, он определяет ожидаемый выход в течение стандартного времени и сравнивает, является ли выход данной даты одинаковым (стандартным) или меньше (DST).отметим, что
getTimezoneOffsetвозвращает положительное количество минут для зоны Запад UTC, которые обычно указываются как отрицательный часы (так как они "за" UTC). Например, Лос-Анджелес-это UTC-8h стандарт UTC-7h переход на летнее время.getTimezoneOffsetвозвращает480(положительные 480 минут) в декабре (зима, стандартное время), а не-480. Он возвращает отрицательный числа для Восточного полушария (такие-600для Сиднея зимой, несмотря на то, что это "впереди" (UTC+10h).Date.prototype.stdTimezoneOffset = function () { var jan = new Date(this.getFullYear(), 0, 1); var jul = new Date(this.getFullYear(), 6, 1); return Math.max(jan.getTimezoneOffset(), jul.getTimezoneOffset()); } Date.prototype.isDstObserved = function () { return this.getTimezoneOffset() < this.stdTimezoneOffset(); } var today = new Date(); if (today.isDstObserved()) { alert ("Daylight saving time!"); }
создать две даты: одна в июне, одна в январе. Сравните их значения getTimezoneOffset ().
- Если январское смещение > июньское смещение, клиент находится в северном полушарии
- Если январское смещение
- если нет разницы, часовой пояс клиента не соблюдает DST
теперь проверьте getTimezoneOffset () текущей даты.
- Если равно июню, северное полушарие, то ток часовой пояс - DST (+1 час)
- Если равно январь, южное полушарие, то текущий часовой пояс DST (+1 час)
я столкнулся с этой же проблемой сегодня, но так как наше летнее время начинается и останавливается в разное время от США (по крайней мере, из моего понимания), я использовал немного другой маршрут..
var arr = []; for (var i = 0; i < 365; i++) { var d = new Date(); d.setDate(i); newoffset = d.getTimezoneOffset(); arr.push(newoffset); } DST = Math.min.apply(null, arr); nonDST = Math.max.apply(null, arr);затем вы просто сравниваете текущее смещение часового пояса с DST и nonDST, чтобы увидеть, какой из них соответствует.
основываясь на комментарии Мэтта Йохансона к решению, предоставленному Шелдоном Гриффином, я создал следующий код:
Date.prototype.stdTimezoneOffset = function() { var fy=this.getFullYear(); if (!Date.prototype.stdTimezoneOffset.cache.hasOwnProperty(fy)) { var maxOffset = new Date(fy, 0, 1).getTimezoneOffset(); var monthsTestOrder=[6,7,5,8,4,9,3,10,2,11,1]; for(var mi=0;mi<12;mi++) { var offset=new Date(fy, monthsTestOrder[mi], 1).getTimezoneOffset(); if (offset!=maxOffset) { maxOffset=Math.max(maxOffset,offset); break; } } Date.prototype.stdTimezoneOffset.cache[fy]=maxOffset; } return Date.prototype.stdTimezoneOffset.cache[fy]; }; Date.prototype.stdTimezoneOffset.cache={}; Date.prototype.isDST = function() { return this.getTimezoneOffset() < this.stdTimezoneOffset(); };он пытается получить лучшее из всех миров с учетом всех комментариев и ранее предложенных ответов, а именно:
1) кэширует результат за год stdTimezoneOffset, так что вам не нужно пересчитывать его при тестировании нескольких дат в том же году.
2) он не предполагает, что DST (если он существует в все) обязательно в июле, и будет работать, даже если это будет в какой-то момент и в каком-то месте быть в любой месяц. Однако с точки зрения производительности он будет работать быстрее, если действительно июль (или рядом с месяцами) действительно DST.
3) в худшем случае он будет сравнивать getTimezoneOffset первого числа каждого месяца. [и делайте это один раз в год тестирования].
предположение, которое он все еще делает, заключается в том, что если есть период DST больше, чем один месяц.
Если кто-то хочет удалите это предположение, что он может изменить цикл на что - то более похожее на то, что в solutin предоставлено Аароном Коулом-но я все равно прыгну на полгода вперед и вырвусь из цикла, когда будут найдены два разных смещения]
этот ответ очень похож на принятый ответ, но не переопределить
Dateпрототип, и использует только один вызов функции, чтобы проверить, если летнее время действует, а не два.
идея заключается в том, что, поскольку ни одна страна не соблюдает DST, который длится в течение 7 месяцев[1], в области, которая наблюдает DST смещение от времени UTC в январе будет отличаться от того, в июле.
в то время как летнее время движется часы вперед, JavaScript всегда возвращает больше значение в течение стандартного времени. Таким образом, получение минимального смещения между январем и июлем приведет к смещению часового пояса во время DST.
затем мы проверяем, если дата часовой пояс равен этому минимальному значению. Если это так, то мы находимся в ДСТ; в противном случае нас нет.
следующая функция использует этот алгоритм. Он принимает объект даты,
d, и возвращаетtrueЕсли летнее время действует на эту дату, иfalseесли это не так:function isDST(d) { let jan = new Date(d.getFullYear(),0,1).getTimezoneOffset(); let jul = new Date(d.getFullYear(),6,1).getTimezoneOffset(); return Math.min(jan,jul) == d.getTimezoneOffset(); }
вы близки, но немного выключены. Вы никогда не должны рассчитывать свое время, так как это результат ваших собственных часов. Он может определить, используете ли вы летнее время в своем местоположении, но не для удаленного местоположения, созданного смещением:
newDateWithOffset = new Date(utc + (3600000*(offset)));Это все равно будет неправильно и час, если они находятся в летнее время. Вам нужно для удаленной учетной записи времени, если они в настоящее время находятся внутри своего DST или нет, и соответствующим образом настроить. попробуйте вычислить это и изменить часы на-скажем 2/1/2015 и сбросить часы назад на час, как будто за пределами DST. Затем вычислите смещение для места, которое все еще должно быть на 2 часа позади. Он покажет на час раньше двухчасового окна. Вам все равно нужно будет учитывать час и корректировать. Я сделал это для Нью-Йорка и Денвера и всегда иду неправильно (на час вперед) в Денвере.
недавно мне нужно было создать строку даты с UTC и DST, и на основе ответа Шелдона я собрал это вместе:
Date.prototype.getTimezone = function(showDST) { var jan = new Date(this.getFullYear(), 0, 1); var jul = new Date(this.getFullYear(), 6, 1); var utcOffset = new Date().getTimezoneOffset() / 60 * -1; var dstOffset = (jan.getTimezoneOffset() - jul.getTimezoneOffset()) / 60; var utc = "UTC" + utcOffset.getSign() + (utcOffset * 100).preFixed(1000); var dst = "DST" + dstOffset.getSign() + (dstOffset * 100).preFixed(1000); if (showDST) { return utc + " (" + dst + ")"; } return utc; } Number.prototype.preFixed = function (preCeiling) { var num = parseInt(this, 10); if (preCeiling && num < preCeiling) { num = Math.abs(num); var numLength = num.toString().length; var preCeilingLength = preCeiling.toString().length; var preOffset = preCeilingLength - numLength; for (var i = 0; i < preOffset; i++) { num = "0" + num; } } return num; } Number.prototype.getSign = function () { var num = parseInt(this, 10); var sign = "+"; if (num < 0) { sign = "-"; } return sign; } document.body.innerHTML += new Date().getTimezone() + "<br>"; document.body.innerHTML += new Date().getTimezone(true);<p>Output for Turkey (UTC+0200) and currently in DST: UTC+0300 (DST+0100)</p> <hr>
Я обнаружил, что с помощью момент.js библиотека с некоторыми из описанных здесь понятий (сравнивая Ян с июнем) работает очень хорошо.
эта простая функция вернет ли часовой пояс, что пользователь находится в наблюдает летнее время:
function HasDST() { return moment([2017, 1, 1]).isDST() != moment([2017, 6, 1]).isDST(); }простой способ проверить, что это работает (в Windows), - это изменить часовой пояс на зону без DST, например Arizona вернет false, тогда как EST или PST вернутся истинный.
The
getTimezoneOffset()метод в JavaScript, в браузере, возвращает количество минут смещения от часового пояса 00:00. Например, часовой пояс America/New_York в Daylight Savings (DST) возвращает число 300. 300 минут это 5 часов разницы с нуля. 300 минут разделить на 60 минут-5 часов. Каждый часовой пояс сравнивается с нулевым часовым поясом, +00: 00 / Etc/GMT / Гринвичское время.следующее, что вы должны знать, это что смещение имеет противоположный знак фактического часового пояса.
информация о часовых поясах поддерживается органом по присвоению номеров в Интернете (iana)
хорошо отформатированная таблица часовых поясов поставляется joda.org
+00: 00 или Etc / GMT-это Гринвичское время
все часовые пояса смещены от +00: 00 / "Etc / GMT" / Гринвич время
летнее время всегда является более ранним временем, чем" обычное " время летом. Вы устанавливаете свои часы обратно в осенний сезон. ("Отступить" лозунг, чтобы помнить, что делать)
таким образом, Америка/New_York время в летнее время (зима) на один час раньше обычного времени. Так, например, то, что обычно было 5 часов вечера в Нью-Йорке летом, теперь составляет 4 часа дня по времени Америки/Нью-Йорка в летнее время. Имя "Америка / New_York" время является "Длинный формат" название часового пояса. Восточное побережье США обычно называет свой часовой пояс восточным стандартным временем (EST)
если вы хотите сравнить сегодняшнее смещение часового пояса со смещением часового пояса какой - либо другой даты, вам нужно знать, что математический знак (+/- "положительный / отрицательный") смещения часового пояса противоположен часовому поясу.
посмотрите на таблицу часовых поясов на joda.org и найти часовой пояс для "America / New_York" он будет иметь отрицательный знак перед стандартное смещение.
Земля вращается против часовой стрелки на оси. Человек, наблюдающий восход Солнца в Гринвиче, видит восход солнца за 5 часов до того, как кто-то в Нью-Йорке увидит восход солнца. И кто-то на западном побережье США увидит восход солнца после того, как кто-то на восточном побережье США увидит восход солнца.
есть причина, почему вы должны знать все это. Так что вы сможете логически определить, получает ли какой-либо код JavaScript DST статус правильно или нет, без необходимости проверять каждый часовой пояс в разное время года.
представьте себе, что это ноябрь в Нью-Йорке, и часы были установлены на час назад. Летом в Нью-Йорке, смещение составляет 240 минут или 4 часа.
вы можете проверить это путем создания даты, в июле, а затем получить смещение.
var July_Date = new Date(2017, 6, 1); var july_Timezone_OffSet = July_Date.getTimezoneOffset(); console.log('july_Timezone_OffSet: ' + july_Timezone_OffSet)что будет печатать в журнале консоли инструментов разработчика браузера?
ответ: 240
Итак, теперь вы можете создать дату в январе и увидеть, что ваш браузер возвращает смещение часового пояса для зимнего сезона.
var Jan_Date = new Date(2017, 0, 1);//Month is zero indexed - Jan is zero var jan_Timezone_OffSet = Jan_Date.getTimezoneOffset(); console.log('jan_Timezone_OffSet: ' + jan_Timezone_OffSet)ответ: 300
очевидно, что 300 больше, чем 240. Так что же это значит? Если вы пишете код, который проверяет зимнее смещение больше, чем летнее смещение? Или летнее смещение меньше зимнего смещения? Если есть разница между смещениями летнего и зимнего часовых поясов, то вы можете предположим, что DST используется для этого часового пояса. Но это не говорит вам, если сегодня использование летнего времени для часового пояса браузерах. Итак, вам нужно будет получить смещение часового пояса на сегодня.
var today = new Date(); var todaysTimeZone = today.getTimezoneOffset(); console.log('todaysTimeZone : ' + todaysTimeZone)ответ: ? - Зависит от времени года
если сегодняшнее смещение часового пояса и летнее смещение часового пояса одинаковы,и смещения летнего и зимнего часовых поясов различны, то по логическому умозаключению, сегодня должны быть Не быть в DST.
можете ли вы опустить сравнение смещений летнего и зимнего часовых поясов (чтобы узнать, используется ли DST для этого часового пояса) и просто сравнить сегодняшнее смещение часового пояса с летним смещением TZ и всегда получать правильный ответ?
today's TZ Offset !== Summer TZ OffsetНу а сегодня зимой или летом? Если бы вы знали, что тогда вы могли бы применить следующую логику:
if ( it_is_winter && ( todays_TZ_Offset !== summer_TZ_Offset) { var are_We_In_DST = true; }но проблема в том, что вы не знаете, является ли сегодняшняя дата зимой или летом. Каждый часовой пояс есть свои правила для того, когда DST начинается и останавливается. Вам нужно будет отслеживать правила каждого часового пояса для каждого часового пояса в мире. Так что, если есть лучший и более простой способ, то вы могли бы также сделать это лучше и проще.
то, что у нас осталось, заключается в том, что вам нужно знать, использует ли этот часовой пояс DST, а затем сравнить сегодняшнее смещение часового пояса с смещением летнего часового пояса. Это всегда даст вам надежный ответ.
окончательная логика это:
if ( DST_Is_Used_In_This_Time_Zone && ( todays_TZ_Offset !== summer_TZ_Offset) { var are_We_In_DST = true; }функция для определения, если часовой пояс в браузере использует DST:
function is_DST_Used_In_This_TimeZone() { var Jan_Date, jan_Timezone_OffSet, July_Date, july_Timezone_OffSet offsetsNotEqual, thisYear, today; today = new Date();//Create a date object that is now thisYear = today.getFullYear();//Get the year as a number Jan_Date = new Date(thisYear, 0, 1);//Month is zero indexed - Jan is zero jan_Timezone_OffSet = Jan_Date.getTimezoneOffset(); console.log('jan_Timezone_OffSet: ' + jan_Timezone_OffSet) July_Date = new Date(thisYear, 6, 1); july_Timezone_OffSet = July_Date.getTimezoneOffset(); console.log('july_Timezone_OffSet: ' + july_Timezone_OffSet) offsetsNotEqual = july_Timezone_OffSet !== jan_Timezone_OffSet;//True if not equal console.log('offsetsNotEqual: ' + offsetsNotEqual); return offsetsNotEqual;//If the offsets are not equal for summer and //winter then the only possible reason is that DST is used for //this time zone }

Comments