Filed under: Hacks, Widget Watch, Snow Leopard
Weather Widget with time, updated for Snow Leopard
Back in 2005, John Gruber wrote about Hacking Apple's Weather Widget to Show the Time of the Last Update.
I was disappointed to learn that my customized Weather widget no longer worked in Snow Leopard, and for some reason John's instructions no longer worked for the Snow Leopard version of the Weather Widget.
The culprit seemed to be the JavaScript that John had modified to calculate the time. Unfortunately I don't speak JavaScript, but with a little help from Google I was able to find a workaround which will enable this tip to work again.
With John's permission, I'm posting the updated instructions here, but please understand that he did 99% of the work, and I'm just polishing the fenders. If you'd like more of an understanding for why some of these suggestions are made, I would encourage you to read his article.
(Note: all of the line numbers below refer to the files as they exist in 10.6.1 and may change in later versions, which is why context for each line is given.)
Step 1: Make your own copy of the Widget. The official Weather.wdgt is found in /Library/Widgets/ but you do not want to modify that version. Instead, copy it to ~/Library/Widgets/ in your home directory. (If there is already an old copy in there, delete it or rename it.)
Step 2: Edit ~/Library/Widgets/Weather.wdgt/Weather.css in a text editor. To access the component files that make up the Weather widget, right-click your copy of the widget and choose "Show Package Contents."
a) Look for the entry for ".smallinfo" at line 75. Change this line:
color: rgba(255, 255, 255, .7);
to
color: rgba(255, 255, 255, .85);
b) Next, look around line 81 for these lines:
#high {
top: 10px;
}
and then change it to this:
#high-lo {
top: 10px;
}
c) Finally, look around line 85 for
#lo {
top: 37px;
}
and change it to
#updatetime {
top: 37px;
}
Save and close the file.
Step 3: Edit ~/Library/Widgets/Weather.wdgt/Weather.html in a text editor.
a) Around line number 69, replace this line:
<div class="text info smallinfo" id="high">
with this
<div class="text info smallinfo" id="high-lo">/
b) A few lines below that, change this:
<div class="text info smallinfo" id="lo">
to this:
<div class="text info smallinfo" id="updatetime">
Save and close the file.
Step 3: Edit ~/Library/Widgets/Weather.wdgt/Weather.js in a text editor.
This step will be the most intimidating, but you ought to be able to simply copy and paste. This is also the only step which has any significant difference (beyond line numbers) from John's original post.
Open the file and look around line 251 for this:
var lastIcon = null;
function handleDataFetched (object)
{
lastResults = new Array;
The important difference here is that unlike the other steps so far this time we are not going to replace any text. We are going to add text, but do not remove any of the existing text.
After the open bracket "{" simply paste these lines:
// Format the time of the last data refresh
var currentTime = new Date()
var h = currentTime.getHours()
var m = currentTime.getMinutes()
var ampm = 'am';
// default to am
if (h == 12)
{
// noon
ampm = 'pm';
}
else if (h == 0)
{
// midnight
h = 12;
}
else if (h > 12)
{
h -= 12;
ampm = 'pm';
}
if (m < 10) { m = '0' + m; }
document.getElementById('updatetime').innerText = h + ':' + m + ' ' + ampm;
The final result should look something like this (the bold text indicates what we have added):
var lastIcon = null;
function handleDataFetched (object)
{
// Format the time of the last data refresh
var currentTime = new Date()
var h = currentTime.getHours()
var m = currentTime.getMinutes()
var ampm = 'am';
// default to am
if (h == 12)
{
// noon
ampm = 'pm';
}
else if (h == 0)
{
// midnight
h = 12;
}
else if (h > 12)
{
h -= 12;
ampm = 'pm';
}
if (m < 10) { m = '0' + m; }
document.getElementById('updatetime').innerText = h + ':' + m + ' ' + ampm;
lastResults = new Array;
The "lastResults = new Array;" line was already in the file, and is shown simply to demonstrate how the new code should look when integrated with the existing code.
Save and close the file.
That's it! You now have a custom version of the Weather widget in ~/Library/Widgets/. Open that folder, double-click on the widget icon, and it will be added to your Dashboard. (You might want to make sure you don't already have the Weather widget showing, to avoid confusion.)
If anything goes wrong, simply delete the ~/Library/Widgets/Weather.wdgt then copy the original from /Library/Widgets/ and try again.
On the Mac, little things mean a lot. To me, this tip lets me know that I am looking at current information. It's a little thing, but it's a little thing I've used countless times for several years. Thanks again to John for the initial discovery.
UPDATE: TUAW reader Harvey posted a shell script which will automatically patch the necessary files and create a customized widget in your ~/Library/Widgets/ folder. I tested it and found that it worked perfectly for me, but standard disclaimers apply: use at your own risk. To use it, simply save it to your ~/Desktop (or wherever else you choose) and then do
chmod u+x ~/Desktop/CreateNewWeatherWdgt.sh
~/Desktop/CreateNewWeatherWdgt.sh
If you save it somewhere else, adjust the ~/Desktop/ as appropriate. Thanks Harvey!
If you preferred Accuweather, checkout they have a widget available also.

![TUAW [Cafepress]](http://www.blogsmithmedia.com/www.tuaw.com/media/tuaw-cafepress-promo.png)


Reader Comments (Page 1 of 2)
Ben said 8:23AM on 9-27-2009
Now that you've kindly posted all the editing instructions for Weather widget (and perhaps you've submitted them to Mac OS X Hints as well), have you considered posting a modified version of the widget for download?
Reply
BigB said 8:45AM on 9-27-2009
They can't redistribute the widget because it's Apples copyright. They'd get a slap on the hand.
Harvey said 7:18PM on 9-27-2009
But TUAW *could* post a patch file or even better, a script which does everything...
I've uploaded one here: http://sr105.org/CreateNewWeatherWdgt.sh
Just run that script from Terminal and it will do everything, but install the new widget. Double-click the new widget to install.
You may have to make the script executable:
chmod u+x CreateNewWeatherWdgt.sh
echo said 8:30AM on 9-27-2009
The weather widget updates itself as soon as you enter Dashboard, so what's the point of this mod, I wonder
Reply
TJ Luoma said 4:12PM on 9-29-2009
1. It does not necessarily reload every time you enter the Dashboard. It judges for itself (based on some internal logic I'd probably understand if I read JavaScript) how often to update.
2. On a high-latency connection (like mine), even an "instant" update can take more time than you'd expect, so it's a helpful signal that new data has been received.
I'd agree this might not be something that everyone would want to do, but for those who'd want to do it, it's a nice feature to have.
Bill Waggoner said 9:11AM on 9-27-2009
You missed a couple of the .js changes I think and the line
// default to am if (h == 12)
should be split to
// default to am
if (h == 12)
and these two lines (159 and 160):
document.getElementById('high').innerText = getLocalizedString('H: ') + convertToCelcius(object.hi) + 'º';
document.getElementById('lo').innerText = getLocalizedString('L: ') + convertToCelcius(object.lo) + 'º';
need to be changed to:
document.getElementById('high-lo').innerText = getLocalizedString('H: ') + convertToCelcius(object.hi) + 'º' +
'/' + getLocalizedString('L: ') + convertToCelcius(object.lo) + 'º';
The same thing for lines 274-275
The wrapping displayed above doesn't affect the program. It can look a mess and still work.
Hope that helps someone!
Bill W
Reply
Stuart said 12:40PM on 9-27-2009
Yep, that fixed it for me. Thanks!
TJ from TUAW said 1:07PM on 9-27-2009
Thanks for the correction. Looks like the CMS ate some line breaks. I fixed the "// default to am if (h == 12) " part.
I'm not sure what you're saying needs to be done with lines 159 and 160.
Bill Waggoner said 1:50PM on 9-27-2009
In your weather.js what does line 159 say? If it looks like mine (setting 'high-lo') then you have changed that also and the instructions need to be changed to match. The same pair of lines occur farther down in the script and need the same change.
TJ Luoma said 10:43AM on 9-28-2009
Bill
Thanks again for helping out. What I was asking was: what are these changes (lines 159 and 160 and 274-275) doing?
As I mentioned, I don't speak JavaScript, so I'm just trying to understand it a little better. The widget appears (key word "appears"!) to work OK without those changes which is why I ask. It's entirely possible that I'm missing something.
eolone said 9:13AM on 9-27-2009
I have a question related to the Weather Widget since long time, both
for Iphone and macbook.
As you can see from the image in the example
the temperature in Philadelphia is between H 65º and L 59º
so how come that the current temperature is 67º ?!?!?!
I try to find a logical answer but I didnt managed,
probably the answer is really stupid.. but please help me :)
Ciao ciao
Reply
solarpos said 9:22AM on 9-27-2009
The lower numbers are forecasts and the large upper number is reality.
Reply
Isaac said 9:27AM on 9-27-2009
I believe you made a mistake here:
var ampm = 'am';
// default to am if (h == 12)
{
// noon
ampm = 'pm';
}
The if statement should be on the next line, and not in the comment..
Reply
mark said 9:37AM on 9-27-2009
Is there any way to change the source of the weather data? Apple changed to using Yahoo, which doesn't recognise my home town, the capital city of Lapland, Rovaniemi. Whatever they used before always used to work.
Reply
Steven Ledbetter said 9:48AM on 9-27-2009
That kind of surprises me that you're having issues now, since Yahoo! gets their data from Weather.com. That was a welcome change on my end since AccuWeather would give me screwy readings at times.
Charlie said 11:15AM on 9-27-2009
Clearly, if you have time to hack the weather widget to show the time, you don't need to know the time.
Reply
Justin said 11:20AM on 9-27-2009
He speaks the truth.
Stuart said 12:33PM on 9-27-2009
Not working at all for me...
Reply
Kent said 1:02PM on 9-27-2009
Was not working for me either until I read through the comments and implemented the additional code changes suggested by Bill Waggoner above. Perhaps you should update the original post.
Reply
Kevin said 1:24PM on 9-27-2009
I would also like to see a data feed fix to go back to using accuweather.com. The URLs for the data such as this one for the 97232 zip code (Portland, OR)
http://apple.accuweather.com/adcbin/apple/Apple_Weather_Data.asp?zipcode=97232
should be what the earlier version of the widget (pre Snow Leopard) and the iPhone use. I haven't dug up the new Yahoo, Weather.com data feeds to compare needed parsing changes. I assume some clever JS coder can look at the old widget code and post an update to "fix" the Snow Leopard widget to go back to accuweather.
Reply