2

I currently have a clock created from javascript, css, and html. I am trying to find away to edit the javascript so that if I add .5 or +30 to the html for timezone offset the minute hand will also adjust adding 30 minutes to the current position. I also would like for the hour hand to update when this +30 minute interval occurs so that when the minute hand reachs 60 the hour hand will adjust to the next hour as well. Thanks!

class Clock {
  constructor(id) {
    this.timezone = parseInt(document.getElementById(id).dataset.timezone);

    if (this.isDST(new Date())) {
      this.timezone += 1;
    }

    this.handSeconds = document.querySelector(`#${id} .hand.seconds`);
    this.handMinutes = document.querySelector(`#${id} .hand.minutes`);
    this.handHours = document.querySelector(`#${id} .hand.hours`);

    this.getTime();
    this.cycle();
  }

  isDST(now) {
    const jan = new Date(now.getFullYear(), 0, 1);
    const jul = new Date(now.getFullYear(), 6, 1);
    const dst = Math.max(jan.getTimezoneOffset(), jul.getTimezoneOffset());

    return now.getTimezoneOffset() < dst;
  }

  draw(hours, minutes, seconds) {
    const drawSeconds = (seconds / 60) * 360 + 90;
    const drawMinutes = (minutes / 60) * 360 + 90;
    const drawHours = (hours / 12) * 360 + 90;

    this.handSeconds.style.transform = `rotate(${drawSeconds}deg)`;
    this.handMinutes.style.transform = `rotate(${drawMinutes}deg)`;
    this.handHours.style.transform = `rotate(${drawHours}deg)`;

    // fix for animation bump on when clock hands hit zero
    if (drawSeconds === 444 || drawSeconds === 90) {
      this.handSeconds.style.transition = "all 0s ease 0s";
    } else {
      this.handSeconds.style.transition =
        "all 0.05s cubic-bezier(0, 0, 0.52, 2.51) 0s";
    }
  }

  getTime() {
    const now = new Date();

    const hours = now.getUTCHours() + this.timezone;
    const minutes = now.getUTCMinutes();
    const seconds = now.getUTCSeconds();

    this.draw(hours, minutes, seconds);
  }

  cycle() {
    setInterval(this.getTime.bind(this), 1000);
  }
}

new Clock("okinawa");
new Clock("seattle");
new Clock("amalfi");
html {
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #673AB7;
  overflow: hidden;
}

.content {
  display: flex;
  align-items: center;
}

.content .widget {
  padding: 24px;
  margin: 24px;
}

.content .widget.clock {
  position: relative;
  width: 456px;
  height: 456px;
  border-radius: 100%;
  box-sizing: border-box;
  background-color: #5A2EA5;
}

.content .widget.clock#okinawa,
.content .widget.clock#amalfi {
  width: 240px;
  height: 240px;
}

.content .widget.clock#okinawa:before,
.content .widget.clock#amalfi:before {
  border-width: 3px;
}

.content .widget.clock#okinawa .hand,
.content .widget.clock#amalfi .hand {
  height: 3px;
  top: 118.5px;
  transform-origin: right 1.5px;
}

.content .widget.clock#okinawa .hand.seconds,
.content .widget.clock#amalfi .hand.seconds {
  display: yes;
}

.content .widget.clock:before {
  content: "";
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
  border: 6px solid #FFF;
  border-radius: 100%;
  box-sizing: border-box;
}

.content .widget.clock .shadow {
  content: "";
  width: 100%;
  height: 500px;
  position: absolute;
  top: 50%;
  left: 0;
  background: linear-gradient(to bottom, rgba(0, 0, 0, 0.65) 0%, rgba(0, 0, 0, 0) 100%);
  transform: rotate(-45deg);
  transform-origin: 50% 0%;
  opacity: 0.3;
  z-index: -1;
}

.content .widget.clock .hand {
  height: 6px;
  position: absolute;
  top: 225px;
  background-color: #FFF;
  border-radius: 100% 0% 0% 100%;
  transform-origin: right 3px;
  transition: all 0.05s cubic-bezier(0, 0, 0.52, 2.51) 0s;
}

.content .widget.clock .hand.seconds {
  width: 45%;
  left: 5%;
  opacity: 0.25;
}

.content .widget.clock .hand.minutes {
  width: 35%;
  left: 15%;
  opacity: 0.5;
}

.content .widget.clock .hand.hours {
  width: 25%;
  left: 25%;
  opacity: 0.75;
}

.content .widget.clock .hand-cap {
  width: 5%;
  height: 5%;
  position: absolute;
  top: 47.5%;
  left: 47.5%;
  background-color: #FFF;
  border-radius: 100%;
}

.content .widget label {
  display: block;
  width: 100%;
  position: absolute;
  top: -24px;
  left: 0;
  font-family: sans-serif;
  font-weight: 200;
  font-size: 12px;
  text-transform: uppercase;
  text-align: center;
  letter-spacing: 4px;
  color: #FFF;
  opacity: 0.5;
}
<div class="content">
  <div class="widget clock" id="okinawa" data-timezone="+9">
    <div class="shadow"></div>
    <div class="hand seconds"></div>
    <div class="hand minutes"></div>
    <div class="hand hours"></div>
    <div class="hand-cap"></div>
    <label>Okinawa</label>
  </div>
  <div class="widget clock" id="seattle" data-timezone="-8">
    <div class="shadow"></div>
    <div class="hand seconds"></div>
    <div class="hand minutes"></div>
    <div class="hand hours"></div>
    <div class="hand-cap"></div>
    <label>Seattle</label>
  </div>
  <div class="widget clock" id="amalfi" data-timezone="+1">
    <div class="shadow"></div>
    <div class="hand seconds"></div>
    <div class="hand minutes"></div>
    <div class="hand hours"></div>
    <div class="hand-cap"></div>
    <label>Amalfi</label>
  </div>
</div>
StackGuru
  • 133
  • 7
  • `Uncaught TypeError: Cannot read property 'style' of null`. Your selector is incorrect.Try `\`#${id} .seconds\`` – Jeremy Thille Mar 26 '20 at 14:48
  • I had to remove the +30 from `this.handSeconds = document.querySelector(\`#${id} .hand.seconds\` + 30);` - that is NOT where you want to do it - that is just wishful thinking – mplungjan Mar 26 '20 at 14:49
  • You want to change `const now = new Date();` – mplungjan Mar 26 '20 at 14:51
  • @mplungjan In what manner would I change it? Also is there away to just change the html next to the clock I want changed like how I did the offset for hours for this to be done? – StackGuru Mar 26 '20 at 14:55
  • https://stackoverflow.com/questions/1197928/how-to-add-30-minutes-to-a-javascript-date-object – epascarello Mar 26 '20 at 14:56

1 Answers1

2

You mean like this?

  1. get the time in hours and minutes if present

    this.timezone = document.getElementById(id).dataset.timezone;
    let [hh,mm] = this.timezone.slice(1).split("."); // remove the +/- before splitting
    this.timezoneMM = 60*hh +(mm ? parseInt(mm) : 0)
    
    this.timezoneMM *= this.timezone.indexOf("-")===0 ? -1:-1;
    
  2. Add the minutes to the now object

    now.setMinutes(now.getMinutes()+this.timezoneMM)
    

    class Clock {
      constructor(id) {
        this.timezone = document.getElementById(id).dataset.timezone;
        let [hh,mm] = this.timezone.slice(1).split("."); // remove the +/- before splitting
        this.timezoneMM = 60*hh +(mm ? parseInt(mm) : 0)
        
        this.timezoneMM *= this.timezone.indexOf("-")===0 ? -1:-1;
        
        if (this.isDST(new Date())) {
          this.timezone += 1;
        }
    
        this.handSeconds = document.querySelector(`#${id} .hand.seconds`);
        this.handMinutes = document.querySelector(`#${id} .hand.minutes`);
        this.handHours = document.querySelector(`#${id} .hand.hours`);
    
        this.getTime();
        this.cycle();
      }
    
      isDST(now) {
        const jan = new Date(now.getFullYear(), 0, 1);
        const jul = new Date(now.getFullYear(), 6, 1);
        const dst = Math.max(jan.getTimezoneOffset(), jul.getTimezoneOffset());
    
        return now.getTimezoneOffset() < dst;
      }
    
      draw(hours, minutes, seconds) {
        const drawSeconds = (seconds / 60) * 360 + 90;
        const drawMinutes = (minutes / 60) * 360 + 90;
        const drawHours = (hours / 12) * 360 + 90;
    
        this.handSeconds.style.transform = `rotate(${drawSeconds}deg)`;
        this.handMinutes.style.transform = `rotate(${drawMinutes}deg)`;
        this.handHours.style.transform = `rotate(${drawHours}deg)`;
    
        // fix for animation bump on when clock hands hit zero
        if (drawSeconds === 444 || drawSeconds === 90) {
          this.handSeconds.style.transition = "all 0s ease 0s";
        } else {
          this.handSeconds.style.transition =
            "all 0.05s cubic-bezier(0, 0, 0.52, 2.51) 0s";
        }
      }
    
      getTime() {
        const now = new Date();
    
        now.setMinutes(now.getMinutes()+this.timezoneMM)
    
        const hours = now.getUTCHours();
        const minutes = now.getUTCMinutes();
        const seconds = now.getUTCSeconds();
    
        this.draw(hours, minutes, seconds);
      }
    
      cycle() {
        setInterval(this.getTime.bind(this), 1000);
      }
    }
    
    new Clock("okinawa");
    new Clock("kolkata");
    new Clock("amalfi");
    html {
      height: 100%;
      display: flex;
      justify-content: center;
      align-items: center;
      background-color: #673AB7;
      overflow: hidden;
    }
    
    .content {
      display: flex;
      align-items: center;
    }
    
    .content .widget {
      padding: 24px;
      margin: 24px;
    }
    
    .content .widget.clock {
      position: relative;
      width: 456px;
      height: 456px;
      border-radius: 100%;
      box-sizing: border-box;
      background-color: #5A2EA5;
    }
    
    .content .widget.clock#okinawa,
    .content .widget.clock#amalfi {
      width: 240px;
      height: 240px;
    }
    
    .content .widget.clock#okinawa:before,
    .content .widget.clock#amalfi:before {
      border-width: 3px;
    }
    
    .content .widget.clock#okinawa .hand,
    .content .widget.clock#amalfi .hand {
      height: 3px;
      top: 118.5px;
      transform-origin: right 1.5px;
    }
    
    .content .widget.clock#okinawa .hand.seconds,
    .content .widget.clock#amalfi .hand.seconds {
      display: none;
    }
    
    .content .widget.clock:before {
      content: "";
      width: 100%;
      height: 100%;
      position: absolute;
      top: 0;
      left: 0;
      border: 6px solid #FFF;
      border-radius: 100%;
      box-sizing: border-box;
    }
    
    .content .widget.clock .shadow {
      content: "";
      width: 100%;
      height: 500px;
      position: absolute;
      top: 50%;
      left: 0;
      background: linear-gradient(to bottom, rgba(0, 0, 0, 0.65) 0%, rgba(0, 0, 0, 0) 100%);
      transform: rotate(-45deg);
      transform-origin: 50% 0%;
      opacity: 0.3;
      z-index: -1;
    }
    
    .content .widget.clock .hand {
      height: 6px;
      position: absolute;
      top: 225px;
      background-color: #FFF;
      border-radius: 100% 0% 0% 100%;
      transform-origin: right 3px;
      transition: all 0.05s cubic-bezier(0, 0, 0.52, 2.51) 0s;
    }
    
    .content .widget.clock .hand.seconds {
      width: 45%;
      left: 5%;
      opacity: 0.25;
    }
    
    .content .widget.clock .hand.minutes {
      width: 35%;
      left: 15%;
      opacity: 0.5;
    }
    
    .content .widget.clock .hand.hours {
      width: 25%;
      left: 25%;
      opacity: 0.75;
    }
    
    .content .widget.clock .hand-cap {
      width: 5%;
      height: 5%;
      position: absolute;
      top: 47.5%;
      left: 47.5%;
      background-color: #FFF;
      border-radius: 100%;
    }
    
    .content .widget label {
      display: block;
      width: 100%;
      position: absolute;
      top: -24px;
      left: 0;
      font-family: sans-serif;
      font-weight: 200;
      font-size: 12px;
      text-transform: uppercase;
      text-align: center;
      letter-spacing: 4px;
      color: #FFF;
      opacity: 0.5;
    }
    <div class="content">
      <div class="widget clock" id="okinawa" data-timezone="+9">
        <div class="shadow"></div>
        <div class="hand seconds"></div>
        <div class="hand minutes"></div>
        <div class="hand hours"></div>
        <div class="hand-cap"></div>
        <label>Okinawa</label>
      </div>
      <div class="widget clock" id="kolkata" data-timezone="+5.30">
        <div class="shadow"></div>
        <div class="hand seconds"></div>
        <div class="hand minutes"></div>
        <div class="hand hours"></div>
        <div class="hand-cap"></div>
        <label>Kolkata</label>
      </div>
      <div class="widget clock" id="amalfi" data-timezone="+1">
        <div class="shadow"></div>
        <div class="hand seconds"></div>
        <div class="hand minutes"></div>
        <div class="hand hours"></div>
        <div class="hand-cap"></div>
        <label>Amalfi</label>
      </div>
    </div>
mplungjan
  • 169,008
  • 28
  • 173
  • 236