3

ok lets say we have a website that need a realtime time;

example :

<div id="updatetime">21:12:52</div>

each seconds update hours:m:second.

what i have in minds using the interval function to do long pool and add the sec +1 if to 60 then add + 1 to m and same as hours. but is there a function already solving this problem?

how do you make this 21:12:52 a moving real clock with javascript that updates each seconds?

i have search google, stackoverflow, many of them tells us how to make the current real time datetime from javascript. but none from an existing time. if there is please do insert the link.

5
  • 1
    What do you mean a existing time? Commented Jun 7, 2012 at 11:51
  • 21:12:52(existing time) to 21:12:53 each seconds add the time to the div Commented Jun 7, 2012 at 11:54
  • Take a look to this TimeSpan class: codeproject.com/Articles/62852/… Commented Jun 7, 2012 at 11:57
  • existing time means whatever is set on the user's computer? Commented Jun 7, 2012 at 12:01
  • existing time means whatever is set on the div, sorry for the ambiguty, i want the div to be a live clock Commented Jun 7, 2012 at 12:08

5 Answers 5

8

It can be as easy as this:

setInterval(function(){
    document.getElementById("updatetime").innerHTML = (new Date()).toLocaleTimeString();
}, 1000);

Or use the other Date methods to fine-tune your output.

Update

I only now realized that OP was asking not about incrementing an element with the current time but with a predetermined time.

That's less trivial, but here is a solution that should fit the original question:

function increment_time_element(element, delay) {
    var interval, last,
        time_pattern = /(\d+):(\d+):(\d+)/,
        start = element.innerHTML.match(time_pattern),
        then = new Date;

    then.setHours  (parseInt(start[1], 10) || 0);
    then.setMinutes(parseInt(start[2], 10) || 0);
    then.setSeconds(parseInt(start[3], 10) || 0);

    function now() {
        return Date.now ? Date.now() : (new Date).getTime();
    }

    last = now();

    interval = setInterval(function () {
        var current = now();
        // correct for any interval drift by using actual difference
        then.setTime(then.getTime() + current - last)
        last = current;
        element.innerHTML = then.toString().match(time_pattern)[0];
    }, delay || 1000);

    return {cancel: function() { clearInterval(interval) }};
}

// Usage:
var incrementing_time =
    increment_time_element(document.getElementById("updatetime"));

// Then, if you want to cancel:
incrementing_time.cancel();
Sign up to request clarification or add additional context in comments.

3 Comments

new date(existing time) maybe?
With no arguments, the Date constructor returns the current date/time. toLocaleTimeString() gives something like "09:00:43" or "09:00:43 AM".
Be aware that toLocaleString behaves differently depends by OS and User's settings, so if it's mandatory display the time in the format 'hh:mm:ss', it can't be used because there is no guarantee.
2

If you don't need a very high fidelity, you can use this way:

​var container  = document.getElementById("updatetime").firstChild;
var values = container.nodeValue.split(":");

// Because there is only a datetime specified, I assume is the current date
var now = new Date();
var time = new Date(now.getFullYear(), now.getMonth(), now.getDate(),
                    values[0], values[1], values​[2]).getTime();

setInterval(function() {
    time += 1000;
    var date = new Date(time);
    var values = [date.getHours(), date.getMinutes(), date.getSeconds()];

    for (var i = 0; i < 3; i++)
        if (values[i] < 10)
            values[i] = "0" + values[i];

    container.nodeValue = values.join(":");
}, 1000);

If you want to be more in sync with the current computer clock, then I suggest to you to use setTimeout and adjust the delay argument with the proper elapsed time.

Update: due the comments, it seems the elements to update are not only one and multiple, and the code is using jQuery. Here an approach that works for multiple elements using class to identify them:

var containers  = $(".updatetime");
var times = [];
var now = new Date();

containers.each(function(index, node) {
    var values = $(node).text().split(":");

    times[index] = new Date(
        now.getFullYear(), now.getMonth(), now.getDate(),
        values[0], values[1], values[2]).getTime();
});

setInterval(function() {
    containers.each(function(index, node) {
        times[index] += 1000;

        var date = new Date(times[index]);
        var values = [date.getHours(), date.getMinutes(), date.getSeconds()];

        for (var i = 0; i < 3; i++)
            if (values[i] < 10)
                values[i] = "0" + values[i];

        $(node).text(values.join(":"));
    });

}, 1000);

4 Comments

works great!, the only problem that it doesnt update all the ids. updatetime.
the id has to be unique, that's why is called "id": to identify one specific element. There is an attribute called name, where the same value can be associate to multiple elements, but it doesn't apply to div. My suggestion is using the class attribute, so you will have <div class='updatetime'>. Then you can use querySelectorAll where supported, or using library like Sizzle or jQuery where is not, and handle an array of "container" objects instead of only one.
im using jquery, heres what ive done pastebin.com/NCehgm7P somehow it work with all the class, but they are all the same value.
That's because you have to take in account multiple containers, therefore multiples different values, and time. You can still have one setInterval, but you have to add a loop to handle all containers. In my code above, it means at least that container and time variables have to be arrays (you can still use one values in a loop to convert the string in datetime).
2

If your after a realtime clock that ticks along, take a look at the code I used when I created a "flip clock". I split each digit into a seperate individual digit to use for graphic placement within the clock, but if you strip it down you will have just text that updates.

Javascript Flip Clock

1 Comment

link doesn't work. I did find another Flip Clock: flipclockjs.com
2

using HTML canvas

code:

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var radius = canvas.height / 2;
ctx.translate(radius, radius);
radius = radius * 0.90
setInterval(drawClock, 1000);

function drawClock() {
  drawFace(ctx, radius);
  drawNumbers(ctx, radius);
  drawTime(ctx, radius);
}

function drawFace(ctx, radius) {
  var grad;
  ctx.beginPath();
  ctx.arc(0, 0, radius, 0, 2 * Math.PI);
  ctx.fillStyle = 'white';
  ctx.fill();
  grad = ctx.createRadialGradient(0, 0, radius * 0.95, 0, 0, radius * 1.05);
  grad.addColorStop(0, '#333');
  grad.addColorStop(0.5, 'white');
  grad.addColorStop(1, '#333');
  ctx.strokeStyle = grad;
  ctx.lineWidth = radius * 0.1;
  ctx.stroke();
  ctx.beginPath();
  ctx.arc(0, 0, radius * 0.1, 0, 2 * Math.PI);
  ctx.fillStyle = '#333';
  ctx.fill();
}

function drawNumbers(ctx, radius) {
  var ang;
  var num;
  ctx.font = radius * 0.15 + "px arial";
  ctx.textBaseline = "middle";
  ctx.textAlign = "center";
  for (num = 1; num < 13; num++) {
    ang = num * Math.PI / 6;
    ctx.rotate(ang);
    ctx.translate(0, -radius * 0.85);
    ctx.rotate(-ang);
    ctx.fillText(num.toString(), 0, 0);
    ctx.rotate(ang);
    ctx.translate(0, radius * 0.85);
    ctx.rotate(-ang);
  }
}

function drawTime(ctx, radius) {
  var now = new Date();
  var hour = now.getHours();
  var minute = now.getMinutes();
  var second = now.getSeconds();
  //hour
  hour = hour % 12;
  hour = (hour * Math.PI / 6) +
    (minute * Math.PI / (6 * 60)) +
    (second * Math.PI / (360 * 60));
  drawHand(ctx, hour, radius * 0.5, radius * 0.07);
  //minute
  minute = (minute * Math.PI / 30) + (second * Math.PI / (30 * 60));
  drawHand(ctx, minute, radius * 0.8, radius * 0.07);
  // second
  second = (second * Math.PI / 30);
  drawHand(ctx, second, radius * 0.9, radius * 0.02);
}

function drawHand(ctx, pos, length, width) {
  ctx.beginPath();
  ctx.lineWidth = width;
  ctx.lineCap = "round";
  ctx.moveTo(0, 0);
  ctx.rotate(pos);
  ctx.lineTo(0, -length);
  ctx.stroke();
  ctx.rotate(-pos);
}
<canvas id="canvas" width="400" height="400" style="background-color:#333">
</canvas>

Comments

0

you can do it with below code

<!DOCTYPE html>
<html>
<head>
<script>
function startTime() {
    var today = new Date();
    var h = today.getHours();
    var m = today.getMinutes();
    var s = today.getSeconds();
    m = checkTime(m);
    s = checkTime(s);
    document.getElementById('txt').innerHTML =
    h + ":" + m + ":" + s;
    var t = setTimeout(startTime, 500);
}
function checkTime(i) {
    if (i < 10) {i = "0" + i};  // add zero in front of numbers < 10
    return i;
}
</script>
</head>

<body onload="startTime()">

<div id="txt"></div>

</body>
</html>

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.