Creating a JavaScript Clock

Use JavaScript's Date object and Window.setInterval method to make a simple real-time clock that you can place on any Web page. Along the way, you take a look at how to access text nodes in the DOM, and how to set an onLoad event handler.

One of the great things about JavaScript is that it lets you manipulate the contents of a Web page in real-time. This means that we can use JavaScript to create a digital clock, embedded in the Web page, that updates every second. This article shows you how to do just that.

Getting the current time

If we want to create a clock then obviously we need to retrieve the current time. We can do this via JavaScript's Date class. First, we create a new Date object with no parameters, which gives us a Date object containing the current date and time on the visitor's computer:


var currentTime = new Date ( );

Next, we extract the hours, minutes and seconds components of the current time from our Date object:


var currentHours = currentTime.getHours ( );
var currentMinutes = currentTime.getMinutes ( );
var currentSeconds = currentTime.getSeconds ( );

Formatting the time

Now that we have the three component values of our current time, let's format them into a nice string for displaying in the Web page. We want it to be in the format "HH:MM:SS XX", where XX is either "AM" or "PM" (assuming we're after a 12-hour clock format).

First we'll add a leading zero to the minutes and seconds values, if required:


currentMinutes = ( currentMinutes < 10 ? "0" : "" ) + currentMinutes;
currentSeconds = ( currentSeconds < 10 ? "0" : "" ) + currentSeconds;

The ? and : symbols used above comprise the ternary operator. This is a special operator that returns the value before the colon if the condition before the query (?) is true, or the value after the colon if the condition is false. It's a great way to write an if block in shorthand, provided you only need to return a single value.

Next we'll set a variable, timeOfDay, to "AM" or "PM" as appropriate, and subtract 12 from the hours component, if required, to convert it to 12-hour format. We'd also like the hours component to show 12 rather than 0, so we need to add a check for this too:


var timeOfDay = ( currentHours < 12 ) ? "AM" : "PM";
currentHours = ( currentHours > 12 ) ? currentHours - 12 : currentHours;
currentHours = ( currentHours == 0 ) ? 12 : currentHours;

Finally, we'll join all our formatted components together into a single string, in the format "HH:MM:SS XX":


var currentTimeString = currentHours + ":" + currentMinutes + ":" + currentSeconds + " " + timeOfDay;

Displaying the clock

Now that we have our time string ready for display, the next step is to display it in the Web page. To do this, we first create a span container in the markup to hold the time display:


<span id="clock">&nbsp;</span>

By placing the &nbsp; inside the span element, we're creating a child text node for the span in the DOM. We can then populate the container with our time string by retrieving this child text node then setting its nodeValue property, as follows:


document.getElementById("clock").firstChild.nodeValue = currentTimeString;

Putting it all together

Here's our finished JavaScript code, ready to be placed in the head element of the Web page. We've wrapped all the above code in a JavaScript function, updateClock():


<script type="text/javascript">
<!--

function updateClock ( )
{
  var currentTime = new Date ( );

  var currentHours = currentTime.getHours ( );
  var currentMinutes = currentTime.getMinutes ( );
  var currentSeconds = currentTime.getSeconds ( );

  // Pad the minutes and seconds with leading zeros, if required
  currentMinutes = ( currentMinutes < 10 ? "0" : "" ) + currentMinutes;
  currentSeconds = ( currentSeconds < 10 ? "0" : "" ) + currentSeconds;

  // Choose either "AM" or "PM" as appropriate
  var timeOfDay = ( currentHours < 12 ) ? "AM" : "PM";

  // Convert the hours component to 12-hour format if needed
  currentHours = ( currentHours > 12 ) ? currentHours - 12 : currentHours;

  // Convert an hours component of "0" to "12"
  currentHours = ( currentHours == 0 ) ? 12 : currentHours;

  // Compose the string for display
  var currentTimeString = currentHours + ":" + currentMinutes + ":" + currentSeconds + " " + timeOfDay;

  // Update the time display
  document.getElementById("clock").firstChild.nodeValue = currentTimeString;
}

// -->
</script>

To make the clock update every second, we need to use the Window.setInterval() method from within the page's body tag to call our updateClock() function once per second. (For more on setInterval, see our tutorial on setTimeout and setInterval.) We should also call updateClock() at the moment the page loads, so that the clock appears straightaway:


<body onload="updateClock(); setInterval('updateClock()', 1000 )">

That's it! You can see the clock in action on this demo page. We've also added some CSS to the clock container to make it prettier.

Feel free to use any of the above JavaScript code to make a clock for your own website. You might like to try putting the various time components in separate span containers, so that you can style them individually. You could also try converting the code to display a 24-hour clock instead. Have fun!

Follow Elated

Related articles

Responses to this article

20 most recent responses (oldest first):

04-Apr-11 02:30
@SU45: yes the semicolon is essential.

I'm struggling to understand exactly what you want to do with the days/hours thing. An example might help. Can you post an example in a new topic please, and we can take it from there?

http://www.elated.com/forums/authoring-and-programming/topic/new/

@Diggadee: If I understand you correctly, then you'd want to multiply your yearly figure by the proportion of the year that has so far elapsed (based on the current date retrieved from the Date() object), then display the figure in the page. You'd wrap this in a function, then call it periodically using setInterval():

http://www.elated.com/articles/javascript-timers-with-settimeout-and-setinterval/

If you'd like further help on this, please start a new topic:

http://www.elated.com/forums/authoring-and-programming/topic/new/
22-Apr-11 16:37
Thank you for this article, it help me. The way that you explain each steps helps. Thanks again
25-Apr-11 04:43
@geneteninty: Thanks for your comment. I'm glad you found the article helpful!
02-May-11 18:57
Hi,

I realize this article is a bit old but, it's the best one I've found for what I was trying to do. In the article you mentioned

"You might like to try putting the various time components in separate span containers, so that you can style them individually."

I'm extremely new at this and have actually (surprisingly) gotten everything else to work except, I would love to be able to display the hours, minutes and seconds under separate div or span tags in order to modify them individually using css. Any help with this would be extremely helpful. Keep in mind I'm a complete noob and would love as step by step instructions as you possibly have patience for. I've pasted the code below.

I apologize in advance if it's very long and dirty...


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>


<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>

<style>

#Layer {
width: 322px;
height: 482px;
position: absolute;
top: -1px;
right: 0px;
down: 0px;
left: -1px;
}

.stretch {
width:100%;
height:100%;
}

#line {
-webkit-mask-box-image:-webkit-gradient(linear, left top, left bottom, from(rgba(0,0,0,0)), to(rgba(0,0,0,0)), color-stop(0.6773,white));
-webkit-box-shadow:0 0 5px #000;
background:rgba(255,255,255,1);
position:absolute;
left:72px;
height:425px;
width:1px;
top: 6px;
opacity: .7;

</style>

<div id="Layer"><img src="LockBackground.png" width="320" height="480"></div>

<div id="line"></div>

<style type="text/css">

@font-face {
font-family:HelveticaNeueUltraLight;
src:url(helveticaneue-ultralight-webfont.svg#webfontUsKRqVpD) format(svg);
font-weight:400;
font-style:normal;
}

#clock{
position:absolute;
width: 220px;
height: 60px;
text-align: right;
vertical-align:top;
z-index: +4;
top: 351px;
right: 327px;
font-family:HelveticaNeueUltraLight;
color:white;
font-size: 46px;
opacity: .5;
}

#hours {
position:absolute;
top:30px;
left:-34px;
height: 60px;
width:100px;
text-align:right;
font-family:HelveticaNeueUltraLight;
font-size: 46px;
color: white;
opacity: .5;

}

#minutes {
position:absolute;
left:80px;
top:30px;
height: 60px;
width:150px;
text-align:left;
font-family:HelveticaNeueUltraLight;
font-size: 46px;
color: white;
opacity: .5;
}

.weekday {
position: absolute;
top: 267px;
left: 80px;
width: 150px;
height: 60px;
text-align:left;
font-family:HelveticaNeueUltraLight;
font-size: 46px;
color: white;
opacity: .5;
}

.month{
position: absolute;
width: 150px;
height: 60px;
top: 309px;
left: 80px;
text-align:left;
font-family:HelveticaNeueUltraLight;
font-size: 46px;
color: white;
opacity: .5;
}

.date{
position: absolute;
top: 309px;
width: 100px;
height: 60px;
left: -34px;
text-align:right;
font-family:HelveticaNeueUltraLight;
font-size: 46px;
color: white;
opacity: .5;
}

.icon{
position: absolute;
z-index:10;
text-align: right;
left: 25px;
top: 228px;
opacity: .5;
}

#temp{
position:absolute;
z-index:7;
width: 150px;
height: 60px;
color:white;
top: 179px;
left: 80px;
font-size: 46px;
font-family:HelveticaNeueUltraLight;
text-align:left;
opacity: .5;
}

</style>

<script language="javascript" type="text/javascript">
var currentTime = new Date()
var hours = currentTime.getHours()
var minutes = currentTime.getMinutes()

var suffix = "AM";
if (hours >= 12) {
suffix = "PM";
hours = hours - 12;
}
if (hours == 0) {
hours = 12;
}
if (minutes < 10)
minutes = "0" + minutes

</script>

<script language="Javascript" type="text/javascript">
var today = new Date();
var monthnum = today.getMonth();
var monthname=new Array("JAN","FEB","MAR","APR","MAY",
"JUN","JUL","AUG","SEPT","OCT","NOV","DEC");
var day=today.getDate();
</script>



<script language="Javascript">

var this_weekday_name_array = new Array("SUN","MON","TUES","WED","THURS","FRI","SAT") //predefine weekday names

var this_date_timestamp=new Date() //get current day-time stamp

var this_weekday = this_date_timestamp.getDay() //extract weekday
var this_date = this_date_timestamp.getDate() //extract day of month


var this_weekday_string = this_weekday_name_array[this_weekday]
var this_day_string = this_date
//-->

</script>


<script type="text/javascript">

var iconExtWall = '.png'
var iconExtLock = '.png'
var locale = '33138'
var iconSetWall = 'stardock'
var iconSetLock = 'stardock'
var enableWallpaper = true
var isCelsius = false
var useRealFeel = false
var enableLockScreen = true
var source = 'appleAccuweatherStolen'
var stylesheetWall = 'mini'
var stylesheetLock = 'Under_StatusBar'
var updateInterval = 15

var postal;
var demoMode = false;
var enabled;

if (location.href.indexOf("Wallpaper") > 0){
stylesheet = stylesheetLock;
iconSet = iconSetLock;
iconExt = iconExtLock;
enabled = enableLockScreen;
}else{
stylesheet = stylesheetWall;
iconSet = iconSetWall;
iconExt = iconExtWall;
enabled = enableWallpaper;
}

if(enabled == true){
if(iconSet == null || iconSet == 'null' || iconSet == ""){
var iconSet = stylesheet;
}

var headID = document.getElementsByTagName("head")[0];
var styleNode = document.createElement('link');
styleNode.type = 'text/css';
styleNode.rel = 'stylesheet';
styleNode.href = 'Stylesheets/'+stylesheet+'.css';
headID.appendChild(styleNode);

var scriptNode = document.createElement('script');
scriptNode.type = 'text/javascript';
scriptNode.src = 'Sources/'+source+'.js';
headID.appendChild(scriptNode);
}

function onLoad(){
if (enabled == true){
if (demoMode == true){
document.getElementById("weatherIcon").src="IconSets/"+iconSet+"/"+"cloudy1"+iconExt;
document.getElementById("temp").innerText="100�";
document.getElementById("forecast").innerText="Sun";
}else{
document.getElementById("weatherIcon").src="IconSets/"+iconSet+"/"+"dunno"+iconExt;
validateWeatherLocation(escape(locale).replace(/^%u/g, "%"), setPostal)
}
}else{
document.getElementsByTagName("body")[0].innerText='';
}
}

function convertTemp(num)
{
if (isCelsius == true)
return Math.round ((num - 32) * 5 / 9);
else
return num;
}

function setPostal(obj){

if (obj.error == false){
if(obj.cities.length > 0){
postal = escape(obj.cities[0].zip).replace(/^%u/g, "%")
document.getElementById("WeatherContainer").className = "";
weatherRefresherTemp();
}else{
document.getElementById("WeatherContainer").className = "errorLocaleNotFound";
}
}else{
document.getElementById("WeatherContainer").className = "errorLocaleValidate";
setTimeout('validateWeatherLocation(escape(locale).replace(/^%u/g, "%"), setPostal)', Math.round(1000*60*5));
}
}

function dealWithWeather(obj){
var translatedesc="description";
if (obj.error == false){

document.getElementById("desc").innerText=obj.description.toLowerCase();


if(useRealFeel == true){
tempValue = convertTemp(obj.realFeel);
}else{
tempValue = convertTemp(obj.temp)
}
document.getElementById("temp").innerText=tempValue+"º";
document.getElementById("weatherIcon").src="IconSets/"+iconSet+"/"+MiniIcons[obj.icon]+iconExt;

/*ProductRed*/
lastResults = new Array;
lastResults[0] = {daycode:obj.daycode, icon:obj.icon, hi:obj.hi, lo:obj.lo, now:obj.temp};
var c = obj.forecast.length;
var titi = new Array("Sun","Mon","Tue","Wed","Thu","Fri","Sat");
var toto =new Date();
var tutu = toto.getDay();
var tata;
if (c > 6) c = 6; // just to be safe
for (var i=0; i<c; ++i)
{
var forecast = obj.forecast[i];

tata = tutu + i;
if(tata > 6) {tata = tata - 7;}
document.getElementById('day'+i).innerText = titi[tata];
document.getElementById('hi'+i).innerHTML = convertTemp(forecast.hi)+'&#176 ';
document.getElementById('low'+i).innerHTML= convertTemp(forecast.lo)+'&#176 ';
document.getElementById('wIcon'+i).src="IconSets/"+iconSet+"/"+MiniIcons[forecast.icon]+iconExt;

lastResults[i+1] = {daycode:forecast.daycode, icon:forecast.icon, hi:forecast.hi, lo:forecast.lo};
}
/*ProductRed*/

document.getElementById("WeatherContainer").className = "";



}else{
//Could be down to any number of things, which is unhelpful...
document.getElementById("WeatherContainer").className = "errorWeatherDataFetch";
}

var this_date_timestamp = new Date()
var this_weekday = this_date_timestamp.getDay()
var this_date = this_date_timestamp.getDate()
var this_month = this_date_timestamp.getMonth()
var this_year = this_date_timestamp.getYear()

if (this_year < 1000)
this_year+= 1900;
if (this_year==101)
this_year=2001;

}

function weatherRefresherTemp(){ //I'm a bastard ugly hack. Hate me.
fetchWeatherData(dealWithWeather,postal);
setTimeout(weatherRefresherTemp, 60*1000*updateInterval);
}




// Modified from weatherParser.js from Leopard. Apologies to all offended.
// I'm hoping that no-one objects since it's Apple hardware and so forth.

/*
Copyright _ 2005, Apple Computer, Inc. All rights reserved.
NOTE: Use of this source code is subject to the terms of the Software
License Agreement for Mac OS X, which accompanies the code. Your use
of this source code signifies your agreement to such license terms and
conditions. Except as expressly granted in the Software License Agreement
for Mac OS X, no other copyright, patent, or other intellectual property
license or right is granted, either expressly or by implication, by Apple.
*/

var MiniIcons = //Fix Up for weatherParser.js but also enables standardisation of sorts
[
"sunny", // 1 Sunny
"cloudy1", // 2 Mostly Sunny
"cloudy2", // 3 Partly Sunny
"cloudy3", // 4 Intermittent Clouds
"cloudy4", // 5 Hazy Sunshione
"cloudy5", // 6 Mostly Cloudy
"cloudy5", // 7 Cloudy (am/pm)
"overcast", // 8 Dreary (am/pm)
"dunno", // 9 retired
"dunno", // 10 retired
"fog", // 11 fog (am/pm)
"shower1", // 12 showers (am/pm)
"shower3", // 13 Mostly Cloudy with Showers
"shower2", // 14 Partly Sunny with Showers
"tstorm3", // 15 Thunderstorms (am/pm)
"tstorm2", // 16 Mostly Cloudy with Thunder Showers
"tstorm1", // 17 Partly Sunnty with Thunder Showers
"light_rain", // 18 Rain (am/pm)
"cloudy5", // 19 Flurries (am/pm)
"cloudy4", // 20 Mostly Cloudy with Flurries
"cloudy2", // 21 Partly Sunny with Flurries
"snow5", // 22 Snow (am/pm)
"snow3", // 23 Mostly Cloudy with Snow
"hail", // 24 Ice (am/pm)
"sleet", // 25 Sleet (am/pm)
"hail", // 26 Freezing Rain (am/pm)
"dunno", // 27 retired
"dunno", // 28 retired
"sleet", // 29 Rain and Snow Mixed (am/pm)
"sunny", // 30 Hot (am/pm)
"sunny_night", // 31 Cold (am/pm)
"mist", // 32 Windy (am/pm)
// Night only Icons;
"sunny_night", // 33 Clear
"cloudy1_night", // 34 Mostly Clear
"cloudy2_night", // 35 Partly Cloudy
"cloudy3_night", // 36 Intermittent Clouds
"cloudy4_night", // 37 Hazy
"cloudy5", // 38 Mostly Cloudy
"shower2_night", // 39 Partly Cloudy with Showers
"shower3_night", // 40 Mostly Cloudy with Showers
"tstorm1_night", // 41 Partly Cloudy with Thunder Showers
"tstorm2_night", // 42 Mostly Cloudy with Thunder Showers
"cloudy4_night", // 43 Mostly Cloudy with Flurries
"cloudy4_night" // 44 Mostly Cloudy with Flurries
];

function getURLForSmallIcon (code)
{
var src = '';
if (code)
{
src = miniIconTable[code];

if (src === undefined)
src = '';
}

return src;
}

function findChild (element, nodeName)
{
var child;

for (child = element.firstChild; child != null; child = child.nextSibling)
{
if (child.nodeName == nodeName)
return child;
}

return null;
}


function trimWhiteSpace (string)
{
return string.replace(/^\s*/, '').replace(/\s*$/, '');
}

// returns an anonymous object like so
// object
// error: Boolean false for success
// errorString: failure string
// hi: Fahrenheit
// lo: Fahrenheit
// temp: Fahrenheit
// realFeel: Farenheit
// icon : accuweather icon code
// description: accuweather description
// city: City (first caps)
// time: time 24 hours(nn:nn)
// sunset: time 24 hours (nn:nn)
// sunrise: time 24 hours (nn:nn)

function fetchWeatherData (callback, zip)
{
//var url = 'http://apple.accuweather.com/adcbin/apple/Apple_Weather_Data.asp?zipcode=';
var url = 'http://wu.apple.com/adcbin/apple/Apple_Weather_Data.asp?zipcode=';

if (window.timerInterval != 300000)
window.timerInterval = 300000; // 5 minutes

var xml_request = new XMLHttpRequest();
xml_request.onload = function(e) {xml_loaded(e, xml_request, callback);}
xml_request.overrideMimeType("text/xml");
xml_request.open("GET", url+zip);
xml_request.setRequestHeader("Cache-Control", "no-cache");
xml_request.setRequestHeader("wx", "385");
xml_request.send(null);

return xml_request;
}

function constructError (string)
{
return {error:true, errorString:string};
}

// parses string of the form nn:nn
function parseTimeString(string)
{
var obj = null;
try {
var array = string.match (/\d{1,2}/g);

obj = {hour:parseInt(array[0], 10), minute:parseInt(array[1],10)};
}
catch (ex)
{
// ignore
}

return obj;
}

function parseDayCode (dayCode)
{
return trimWhiteSpace(dayCode).substr (0, 3).toUpperCase();
}

function xml_loaded (event, request, callback)
{
if (request.responseXML)
{
var obj = {error:false, errorString:null};
var adc_Database = findChild (request.responseXML, "adc_Database");
if (adc_Database == null) {callback(constructError("no <adc_Database>")); return;}

var CurrentConditions = findChild (adc_Database, "CurrentConditions");
if (CurrentConditions == null) {callback(constructError("no <CurrentConditions>")); return;}

var tag = findChild (CurrentConditions, "Time");
if (tag != null)
obj.time = parseTimeString (tag.firstChild.data);
else
obj.time = null;

tag = findChild (CurrentConditions, "City");
if (tag == null) {callback(constructError("no <City>")); return;}
obj.city = trimWhiteSpace(tag.firstChild.data.toString()).toLowerCase();

tag = findChild (CurrentConditions, "Temperature");
if (tag == null) {callback(constructError("no <Temperature>")); return;}
obj.temp = parseInt (tag.firstChild.data);

tag = findChild (CurrentConditions, "RealFeel");
if (tag == null) {callback(constructError("no <RealFeel>")); return;}
obj.realFeel = parseInt (tag.firstChild.data);

tag = findChild (CurrentConditions, "WeatherText");
if (tag == null)
obj.description = null;
else
obj.description = trimWhiteSpace(tag.firstChild.data);

tag = findChild (CurrentConditions, "WeatherIcon");
if (tag == null) {callback(constructError("no <WeatherIcon>")); return;}
obj.icon = parseInt (tag.firstChild.data, 10);
obj.icon -= 1; //Accuweather starts at 1

obj.sunset = null;
obj.sunrise = null;
var Planets = findChild (adc_Database, "Planets");
if (Planets != null)
{
tag = findChild (Planets, "Sun");
if (tag != null)
{
var rise = tag.getAttribute("rise");
var set = tag.getAttribute("set");

if (rise != null && set != null)
{
obj.sunset = parseTimeString (set);
obj.sunrise = parseTimeString(rise);
}
}
}

obj.forecast = new Array;
var Forecast = findChild (adc_Database, "Forecast");
if (Forecast == null) {callback(constructError("no <Forecast>")); return;}

// assume the days are in order, 1st entry is today
var child;
var j=0;
var firstTime = true;

for (child = Forecast.firstChild; child != null; child = child.nextSibling)
{
if (child.nodeName == 'day')
{
if (firstTime) // today
{
obj.hi = 0;
tag = findChild(child, 'High_Temperature');
if (tag != null)
obj.hi = parseInt (tag.firstChild.data);

obj.lo = 0;
tag = findChild(child, 'Low_Temperature');
if (tag != null)
obj.lo = parseInt (tag.firstChild.data);

firstTime = false;
}

var foreobj = {description:null, hi:0, lo:0, icon:-1};

tag = findChild(child, 'DayCode');
if (tag != null)
foreobj.daycode = trimWhiteSpace(tag.firstChild.data.toString()).substring(0,3);

tag = findChild(child, 'High_Temperature');
if (tag != null)
foreobj.hi = parseInt (tag.firstChild.data);

tag = findChild(child, 'Low_Temperature');
if (tag != null)
foreobj.lo = parseInt (tag.firstChild.data);

tag = findChild(child, 'WeatherIcon');
if (tag != null)
{
foreobj.icon = parseInt (tag.firstChild.data, 10);
foreobj.ouricon = MiniIcons[foreobj.icon-1];
}

obj.forecast[j++]=foreobj;
if (j == 7) break; // only look ahead 7 days
}
}

callback (obj);

}
else
{
callback ({error:true, errorString:"XML request failed. no responseXML"}); //Could be any number of things..
}
}

// returns an anonymous object like so
// object
// error: Boolean false for success
// errorString: failure string
// cities: array (alphabetical by name)
// object
// name: city name
// zip: postal code
// state: city state
// refine: boolean - true if the search is too generic
function validateWeatherLocation (location, callback)
{
//var url = 'http://apple.accuweather.com/adcbin/apple/Apple_find_city.asp?location=';
var url = 'http://wu.apple.com/adcbin/apple/Apple_find_city.asp?location=';

var xml_request = new XMLHttpRequest();
xml_request.onload = function(e) {xml_validateloaded(e, xml_request, callback);}
xml_request.overrideMimeType("text/xml");
xml_request.open("GET", url+location);
xml_request.setRequestHeader("Cache-Control", "no-cache");
xml_request.send(null);
}

function xml_validateloaded (event, request, callback)
{
if (request.responseXML)
{
var obj = {error:false, errorString:null, cities:new Array, refine:false};
var adc_Database = findChild (request.responseXML, "adc_Database");
if (adc_Database == null) {callback(constructError("no <adc_Database>")); return;}

var CityList = findChild (adc_Database, "CityList");
if (CityList == null) {callback(constructError("no <CityList>")); return;}

if (CityList.getAttribute('extra_cities') == '1')
obj.refine = true;

for (child = CityList.firstChild; child != null; child = child.nextSibling)
{
if (child.nodeName == "location")
{
var city = child.getAttribute("city");
var state = child.getAttribute("state");
var zip = child.getAttribute("postal");

if (city && state && zip)
{
obj.cities[obj.cities.length] = {name:city, state:state, zip:zip};
}
}
}

callback (obj);
}
else
{
callback ({error:true, errorString:"No Response"});
}
}

function createGoToURL (location)
{
return 'http://apple.accuweather.com/adcbin/apple/Apple_weather.asp?location=' + escape(location);
}

function updateClock ( )
{

var currentTime = new Date ( );

var currentHours = currentTime.getHours ( );

var currentMinutes = currentTime.getMinutes ( );

var currentSeconds = currentTime.getSeconds ( );


// Pad the minutes and seconds with leading zeros, if required

//currentHours = ( currentHours < 10 ? "0" : "" ) + currentHours;

currentMinutes = ( currentMinutes < 10 ? "0" : "" ) + currentMinutes;

currentSeconds = ( currentSeconds < 10 ? "0" : "" ) + currentSeconds;


// Convert an hours component of "0" to "12"

currentHours = ( currentHours == 0 ) ? currentHours + 24 : currentHours;


// Convert the hours component to 12-hour format if needed

currentHours = ( currentHours > 12 ) ? currentHours - 12 : currentHours;


// Convert an hours component of "0" to "12"

currentHours = ( currentHours == 0 ) ? 12 : currentHours;


// Compose the string for display

var currentTimeString = currentHours + " " + currentMinutes + " " + suffix;

// Update the time display


document.getElementById("clock").firstChild.nodeValue = currentTimeString;
}


</script>

</head>

<div id="WeatherContainer"> <div id="TextContainer"><p id="temp">&#176;</p> <p id="desc">...</p> </div>

<body onload="onLoad()" background-color="transparent"><base href="Private/"/>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>





<!-- Time -->
<div id="clock">
<span id="clock"><script language="JavaScript">updateClock(); setInterval('updateClock()', 1000 )</script></span></div>
<span id="hours"><script language="JavaScript">document.write(hours); updateClock(); setInterval('currentTime.getHours ( )', 1000 )</script>
</div>
<div id="minutes"><script language="JavaScript">document.write(minutes + " " + suffix); updateClock(); setInterval('updateClock ()', 1000 )</script>
</div>

<!-- Date -->
<div class="date">
<script language="JavaScript">document.write(this_day_string)</script>
</div>

<!-- Month -->
<div class="month">
<script language="Javascript" type="text/javascript">
document.write(monthname[monthnum])
</script>
</div>

<!-- Weekday -->
<div class="weekday">
<script language="JavaScript">document.write(this_weekday_string)</script>
</div>

<div id="icon" class="icon">
<img id="weatherIcon" width="40" height="40"/>
</div>

<div id="WeatherContainer">
<div id="TextContainer">

<p style="font-family:HelveticaNeueUltraLight; " id="temp"></p>
</div>

</div>


</body>
</html>


[Edited by minegro on 02-May-11 18:59]
05-May-11 05:54
@minegro: I think all you'd need to do is create 3 spans:

<span id="hours">&nbsp;</span>
<span id="minutes">&nbsp;</span>
<span id="seconds">&nbsp;</span>

Then replace:


document.getElementById("clock").firstChild.nodeValue = currentTimeString;


with:


document.getElementById("hours").firstChild.nodeValue = currentHours;
document.getElementById("minutes").firstChild.nodeValue = currentMinutes;
document.getElementById("seconds").firstChild.nodeValue = currentSeconds;


Cheers,
Matt
05-May-11 23:31
matt,

Thanks so much for the help. I actually figured it out. Without having to re-write all the code and clean everything up to make up for my novice discrepancies, The quickest and easiest thing was to create a separate update function for each component in the clock and displaying them that way. I think the problem is that I have all the date and weather functions combined on one thing and they're not the most efficiently written as I was figuring it out as I went along. When I've learned a bit more I'll be able to go back in and re-write all the code much cleaner.

Thanks again though, I really appreciate the response.

Warmest,
09-May-11 00:58
@minegro: Great, glad you got it working
09-May-11 13:20
Good stuff!
I used it to create an analogic clock:

http://apps.mathieu-rodic.com/Beautiful/Clock
10-May-11 02:28
@creaweb: Cool, I like it
21-Jun-11 08:48
Great job on clock and documentation! Thanks so much for the information.
I have one question, when I attempt to seed the time to start the clock, I am getting error on console .

currentTime.getHours is not a function

When I return the code to new date(), my clock appears, this tells me somehow the formatting of my variable time isn't correct? Can you help me understand what format the data should be in? I am pulling time from our iseries.

thanks so much in advance, sorry for the noob question.

Dissi
23-Jun-11 03:43
@Dissi: This article lists the various date formats that you can pass to 'new Date()':

http://www.elated.com/articles/working-with-dates/

Hope that helps!
Matt
23-Jun-11 09:27
hm, I saw the article and I think I have followed the guidelines but I'm still getting errors. Although the error message is different now. I put an alert after I load currentTime and it tells me invalid date. The date I'm loading into the variable is formatted as follows: '2011,06,23,09,18,23'. I have tested by hardcoding in those values and still get invalid date.

I must need more coffee....

What I am trying to accomplish is to load a date with date and time values to start my clock. It sounded sooo easy.

thanks for all your help, sorry im still stuck.

Dis
23-Jun-11 22:46
@Dissi: Your date format works fine for me:


<script>
x = new Date ( 2011,06,23,09,18,23 );
alert(x);
</script>


This displays the following alert:

Sat Jul 23 2011 09:18:23 GMT+1000 (EST)

Matt
24-Jun-11 08:54
ah well, once I realized i was not updating my current copy of the html. All was fine.

thanks for all your help!

Dis
27-Jun-11 22:26
@Dissi: Great, glad you got it working!
13-Jan-12 04:20
Great post.. Thanks for sharing this.. i was searching for something just like this one..
25-Feb-12 04:50
Here is the code I finally settled on, which I think is correct, it works for me:


<style type="text/css">
#countbox { font-family: Arial, Helvetica, sans-serif; font-weight:bold; text-align:left; font-size: 85px; color: #5A0A4F; background-color: #CFCCCC; border: 12px solid #CFCCCC; padding-top: 32px; padding-bottom: 8px; padding-left: 141px; padding-right: 47px;}
</style>

<script type="text/javascript">
dateFuture = new Date(2045,0,1,0,0,0);
function GetCount(){
dateNow = new Date();
//grab current date

amount = dateFuture.getTime() - dateNow.getTime();

//calc milliseconds between dates

delete dateNow;

// time is already past if(amount < 0)

{document.getElementById('countbox').innerHTML="LIVE UTOPIA!<br>Singularity is<br>here...<br><i>NOW!</i> &nbsp; &#9829; &#9829; &#9829;";}

// date is still good
else{days=0;hours=0;mins=0;secs=0;out="";

amount = Math.floor(amount/1000);//kill the "milliseconds" so just secs

days=Math.floor(amount/86400);//days

amount=amount%86400;

hours=Math.floor(amount/3600);//hours

amount=amount%3600;

mins=Math.floor(amount/60);//minutes
amount=amount%60;

secs=Math.floor(amount);//seconds

if(days != 0){out += days +"&nbsp; day"+((days!=1)?"s":"")+",<br>";}

if(days != 0 || hours != 0){out += hours +"&nbsp; hour"+((hours!=1)?"s":"")+",<br>";}

if(days != 0 || hours != 0 || mins != 0){out += mins +"&nbsp; minute"+((mins!=1)?"s":"")+",<br>";}

out += secs +""+((secs==1)?"&nbsp; second":"&nbsp; seconds")+".";

document.getElementById('countbox').innerHTML=out;

setTimeout("GetCount()", 1000);

}
}

window.onload=GetCount;//call when everything has loaded

</script><div id="countbox" div style="margin-top: 26px; margin-left: 90px; margin-right: 90px;">

</div>
</body>
</html>


[Edited by SU45 on 25-Feb-12 05:04]
27-Feb-12 22:20
@SU45: Glad you got it working how you wanted in the end
23-Aug-12 07:35
Hi good morning,
I like the script, but I was wondering how I can add a leading 0 (zero) for hours from 0:00 to 9:00 i.e. 07:35 a.m.

Thanks!

- Robert.

Edit: Never mind my question, I already figured it out when I came back with my coffee.. it's a little early in the morning

currentHours = ( currentHours == 0 ) ? 10 : "0" + currentHours;

^^ Is what I added.
Edit 2: Ok that didn't work

But I bet this does..
// Pad the hours, minutes and seconds with leading zeros, if required
currentMinutes = ( currentMinutes < 10 ? "0" : "" ) + currentMinutes;
currentSeconds = ( currentSeconds < 10 ? "0" : "" ) + currentSeconds;
currentHours = ( currentHours < 10 ? "0" : "" ) + currentHours;

Seems I wasn't awake after all

[Edited by Robert30 on 23-Aug-12 11:38]
24-Aug-13 09:23
The way the javascript is written causes resources of the clock not to be free and stay alive in memory. After testing this code I noticed the memory of the browser session was being eaten up because the updateClock function you've assigned via setInterval calling the javascript function, keeps a live reference to everything that was in-scope of the function call during that function call (whether it uses it or not). This keeps all variables in the updateClock function alive in memory until it's eaten all memory possible and not releasing the reference. You can release this by setting the setInterval and embedding the funtion in the same statement. It's not a memory leak in the function, but the way it's implemented that causes this problem.

The way around this is to do the following;

<script type="text/javascript">

setInterval(function updateClock() {
var monthNames = ["January", "February", "March", "April", "May", "Jume", "July", "August", "Spetember", "October", "November", "December"];
var currentTime = new Date();
var currentDay = currentTime.getDate();
var currentMonth = monthNames[currentTime.getMonth()];
var currentYear = currentTime.getYear();
var currentHours = currentTime.getHours();
var currentMinutes = currentTime.getMinutes();
var currentSeconds = currentTime.getSeconds();
currentMinutes = (currentMinutes < 10 ? "0" : "") + currentMinutes;
currentSeconds = (currentSeconds < 10 ? "0" : "") + currentSeconds;
var timeOfDay = (currentHours < 12) ? "AM" : "PM";
currentHours = (currentHours > 12) ? currentHours - 12 : currentHours;
currentHours = (currentHours == 0) ? 12 : currentHours;
var currentTimeString = currentMonth + " " + currentDay + ", " + currentYear + " " + currentHours + ":" + currentMinutes + ":" + currentSeconds + " " + timeOfDay;
document.getElementById("clock").firstChild.nodeValue = currentTimeString;
delete currentTime;
}, 1000);

</script>

You could make this a anonymous function if you like.

Hope this helps somebody trying to achieve a active clock on your web page without killing memory on the client.

[Edited by bobbyhabib on 24-Aug-13 09:31]

View all 36 responses »

Post a response

Want to add a comment, or ask a question about this article? Post a response.

To post responses you need to be a member. Not a member yet? Signing up is free, easy and only takes a minute. Sign up now.

Top of Page