Можно ли переопределить функцию часов, чтобы я мог изменить их часы? - PullRequest
0 голосов
/ 25 марта 2020

Я разрабатываю небольшой браузерный проект, в котором вы выбираете город из списка, и он представляет вам текущее время в выбранном вами городе. Хотя я столкнулся с проблемой. Код показывает только правильное время в течение короткого момента, а затем возвращается к исходному UT C Стандартное время. Проблема возникает в бите "setTimeout". Есть ли возможность переопределить это? Возможно, добавив clearTimeout?

function utcStandard(offset) {
  var date = new Date();
  var hh = date.getUTCHours();
  var mm = date.getUTCMinutes();
  var ss = date.getUTCSeconds();
  if (offset != undefined) {
    hh += offset
  };
  hh = checkTime(hh);
  mm = checkTime(mm);
  ss = checkTime(ss);
  document.getElementById("time").innerHTML =
    hh + ":" + mm + ":" + ss;
  var t = setTimeout(utcStandard, 500);

  function checkTime(i) {
    if (i < 10) {
      i = "0" + i
    };
    return i;
  }
}

Я решил добавить функцию к каждому элементу в списке HTML. Например.

<ul>
  <li><a href="#" onclick="utcStandard(1)">Amsterdam</a></li>
</ul>

Ответы [ 2 ]

0 голосов
/ 25 марта 2020

Следующая реализация имеет два элемента состояния:

  1. dateString - строковое представление времени
  2. offset - текущее выбранное смещение времени

tick многократно обновляет dateString, чтобы зафиксировать ход времени.

render отображает dateString в DOM, используя requestAnimationFrame.

const freeze = Object.freeze
const DTF = new Intl.DateTimeFormat('en', { hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false })
let state = freeze({ 
  dateString: '00:00:00',
  offset: 0
})

function setOffset(o) {
  clearTimeout(tickId)
  state = freeze({ ...state, offset: o })
  tick()
}

function toDateString(date = new Date) {
  const d = DTF.formatToParts(date)
  return `${d[0].value}:${d[2].value}:${d[4].value}`
}

let tickId = null
function tick() {
  const date = new Date
  date.setHours(date.getHours() + state.offset)
  const dateString = toDateString(date)
  tickId = setTimeout(tick, 16)
  if(dateString !== state.dateString)
    state = freeze({ ...state, dateString })
}

function render(state) {
  document.getElementById('time').innerText = state.dateString
}

let previousState = null
function loop() {
  if(state !== previousState)  {
    previousState = state
    render(state)
  }
  requestAnimationFrame(loop)
}

tick()
requestAnimationFrame(loop)
input[type="radio"] {
  display: none;
}

label {
  font-family: sans-serif;
  padding: 10px;
  margin: 10px;
  display: block;
  cursor: pointer;
  border-radius: 5px;
  -webkit-tap-highlight-color: rgba(0,0,0,0);
}

input[type="radio"]+label {
  background-color: rgba(0,220,220,0);
  transition: background-color .5s ease-out 0s;
}

input[type="radio"]:checked+label {
  background-color: rgba(0,220,220,1);
}

#time {
  width: 100%;
  font-family: sans-serif;
  font-size: 2em;
  text-align: center;
}
<input type="radio" name="group1" id="london" checked>
<label for="london" onclick="setOffset(0)">London</label>
<input type="radio" name="group1" id="amsterdam">
<label for="amsterdam" onclick="setOffset(1)">Amsterdam</label>
<input type="radio" name="group1" id="new-york">
<label for="new-york" onclick="setOffset(-4)">New York</label>
<div id="time"></div>
0 голосов
/ 25 марта 2020

Вот так - он короче и использует UT C там, где это необходимо

Я изменил на минуты, чтобы вы могли иметь 5:30 для Индии, например

Я не учел Летнее время

const pad = (num) => ("0"+num).slice(-2);
let t;
let curOffset = 0;

const reset = (offset) => { 
  clearInterval(t);
  curOffset = offset ? offset : curOffset;  
  t = setInterval(utcStandard,500);
  return false;
};

const utcStandard = () => {
  var date = new Date(new Date().toUTCString().substr(0, 25))
  date.setMinutes(date.getMinutes()+curOffset);
  const hh = pad(date.getHours());
  const mm = pad(date.getMinutes());
  const ss = pad(date.getSeconds());
  document.getElementById("time").innerHTML = "" + hh + ":" + mm + ":" + ss;
};
reset(0);
<span id="time"></span>

<ul>
  <li><a href="#" onclick="return reset(60)">Amsterdam</a></li>
  <li><a href="#" onclick="return reset(0)">London</a></li>
  <li><a href="#" onclick="return reset((5*60)+30)">Kolkata</a></li>
</ul>
...