Skip to content

Instantly share code, notes, and snippets.

@weilu
Last active October 9, 2020 15:55
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save weilu/7688343 to your computer and use it in GitHub Desktop.
Save weilu/7688343 to your computer and use it in GitHub Desktop.
World Clock widget for dashing

World Clock

screen shot 2013-11-28 at 12 29 37 pm

Description

A simple widget that's capable of displaying time for multiple locations around the world. In our company(neo), we use it to display time in different offices.

Installation

1. Download moment.js 2.5.1 from MomentJS,

2. Download moment-timezone.js 0.0.3 from Moment Timezone.

3. Build the timezone data for locations you are interested in: http://momentjs.com/timezone/data/ and save the data file as moment-timezone-data.js. Note that for the default timezone configuration(shown below in world_clock.cofee) to work, you will need to include timezone data of Asia, America and Europe when building moment-timezone-data.js.

4. Put all the downloaded files in your /assets/javascripts directory.

5. Include them in application.coffee in the following order:

#= require moment.min
#= require moment-timezone.min
#= require moment-timezone-data

6. The files world_clock.coffee, world_clock.html and world_clock.scss go in the /widget/world_clock directory.

7. Last but not least, add the widget html to your dashboard:

<li data-row="1" data-col="1" data-sizex="4" data-sizey="1">
  <div data-view="WorldClock" class="widget widget-world-clock"></div>
</li>
class Dashing.WorldClock extends Dashing.Widget
# configuration
locations: [
{ zone: "Asia/Singapore", display_location: "SG", primary: true },
{ zone: "Asia/Jakarta", display_location: "JK" },
{ zone: "America/Los_Angeles", display_location: "SF" },
{ zone: "America/New_York", display_location: "NYC" },
{ zone: "Europe/London", display_location: "EDH" }
]
startClock: ->
for location in @locations
date = moment().tz(location.zone)
location.time = [date.hours(), date.minutes(), date.seconds()].map (n)->
('0' + n).slice(-2)
.join(':')
minutes = 60 * date.hours() + date.minutes()
totalWidth = document.querySelector('.hours').clientWidth - 1
offset = (minutes / (24.0 * 60)) * totalWidth
clock = document.querySelector("." + location.display_location)
if(clock)
['-webkit-transform', '-moz-transform', '-o-transform', '-ms-transform', 'transform'].forEach (vendor) ->
clock.style[vendor] = "translateX(" + offset + "px)"
if(location.primary)
@set('time', location.time)
, @
setTimeout @startClock.bind(@), 1000
setupHours: ->
hours = []
for h in [0..23]
do (h) ->
hours[h] = {}
hours[h].dark = h< 7 || h>= 19
hours[h].name = if h == 12 then h else h%12
@set('hours', hours)
ready: ->
@setupHours()
@startClock()
<ul class="hours">
<li data-foreach-hour="hours" data-bind="hour.name" data-addclass-dark="hour.dark"></li>
</ul>
<ul class="locations">
<li data-foreach-location="locations" data-addclass-primary="location.primary" data-bind-class="location.display_location">
<div class="placeholder" data-hideif="location.primary"></div>
<div class="label" >
<div class="location" data-source="location.display_location" data-hideif="location.primary"></div>
<div class="location local" data-source="time" data-showif="location.primary"></div>
</div>
<div class="placeholder" data-showif="location.primary"></div>
</li>
</ul>
.widget.widget-world-clock {
$dark-text: #333;
$dark-background: grey;
font-size: 2em;
padding-top: 55px;
> ul li {
box-sizing: border-box;
display: inline-block;
color: $dark-text;
&.primary {
font-size: 2em;
margin-top: -185px;
.location {
margin-bottom: -10px;
}
.placeholder {
background: white;
}
}
}
.hours {
li {
background: white;
width: 4.16%;
&:not(:last-child) {
border-right: 1px solid;
}
}
.dark {
background: $dark-background;
color: white;
}
}
.locations {
text-align: left;
li {
position: absolute;
}
.placeholder {
height: 30px;
width: 2px;
background: $dark-background;
}
.label {
position: relative;
color: $dark-background;
.location {
margin-left: -50%;
&.local {
color: white;
}
}
.minute {
position: absolute;
top: 0;
}
}
}
}
@derrybarry
Copy link

could you post a copy of your 'moment-timezone-data.js' just so i can compare with my own as the guidelines stop my dashboard completey

@Doc-Savage
Copy link

I am having the same problem - the entire dashboard stalls. Did you ever figure it out?

@intaker
Copy link

intaker commented Feb 10, 2014

I got same issue and ended up placing the data.js file in widgets/world-clock. Also don't include it in application.coffee

  • Firebug gives this hint

@BeardyWalrus
Copy link

Even with the javascript files moved into the widgets folder, the formatting is all messed up. :(

@junkyard0
Copy link

I agree, even with the suggestion of moving the data.js file to the widgets folder, it is still not working. I did notice in the instructions the class was labeled as "widget widget-word-clock" I was assuming there was a typo and hoped changing it to "widget widget-world-clock" would solve the problem, but it did not. Any suggestions on getting this working?

@weilu
Copy link
Author

weilu commented Mar 18, 2014

@derrybarry https://gist.github.com/weilu/9613906

@Doc-Savage moment.js changed its interface. moment.tz(new Date(), location.zone) used to work but not anymore. I've updated it to moment().tz(location.zone)

@intaker by default application.coffee does #= require_directory . which does not guarantee the order things are required. By explicitly requiring the 3 different files the order is enforced.

@unkyard0 thanks for catching the typo. Fixed =)

@gregmac
Copy link

gregmac commented May 22, 2014

There's a bug in https://gist.github.com/weilu/7688343#file-world_clock-coffee-L38

hours[h].name = if h == 12 then h else h%12

should be:

hours[h].name = if h == 0 || h == 12 then 12 else h%12

It's showing midnight as "0" instead of "12". Credit goes to my wife looking over my shoulder, asking "why does that clock start with 0 but end with 11?"

@pytte
Copy link

pytte commented Sep 5, 2014

my default time is 1 hour off, does it not figure out DST?

@weilu
Copy link
Author

weilu commented Nov 4, 2014

@gregmac some people do use "zero o'clock" to differentiate midnight from noon, which is what I chose to do. So it's not a bug, it's a feature ;)

@pytte it depends on what moment timezone's behavior is. Try upgrading moment timezone and see if that fixes it. On a completely separate note, day light saving is BS that needs to be abolished.

@IMurdocI
Copy link

Awesome job on the Widget, love it.
Git one problem though, when cycling through Dashboards (sinatra cycle or switcher) sometimes the Clock doesn't load when it reach the first page again. (Numbers appear but the Timezones/Actual time doesn't show up).

Do you have an Idea why is this like this?

@asharpe-squiz
Copy link

Thanks heaps @weilu.

Seems I can't submit a PR with a gist so I'll leave that bit up to you (http://stackoverflow.com/a/8767309), however I've added the ability to invert the clock, and also specify configuration in the dashboard to allow multiple widgets with different timezones (https://gist.github.com/asharpe-squiz/03201139410da41835ab).

@uday3110
Copy link

Can someone please help me to get this widget working. I am using moment.js version : 2.10.6. and moment-timezone.js version : 0.4.0. I have these 2 lines in application.coffee for debugging

console.log(moment(1369266934311).zone('+0100').format('YYYY-MM-DD HH:mm'))
console.log(moment.tz("2013-11-18 11:55", "America/Toronto"))

the first line works correctly and displays a date in console.
The second console command does not work and displays the following message

TypeError: undefined is not a function (evaluating 'moment.tz("2013-11-18 11:55", "America/Toronto")') (anonymous function) global code

can please someone help me. I am going crazy over this.

@cob16
Copy link

cob16 commented Aug 31, 2015

Just a heads up if you are trying to get this to work when inserting:

#= require moment.min
#= require moment-timezone.min
#= require moment-timezone-data

make sure to place this BEFORE:

#= require_directory .

Else your .js files may not run in the correct order

@axlroden
Copy link

axlroden commented Aug 4, 2016

@BillLortz
Copy link

The pre-generated file that axlroden provided really helped me get this working. Unfortunately, moment.js's code has changed since the instructions were created for this tool. I played for a while and found the new moment.js and associated code works just fine and is maybe a bit simpler. These instructions tell you how to use the new code.

To start, make sure you don't have any of the moment.js, moment-timezone.js, or moment-timezone-data.js in the assets/javascripts directory. If one or more of those old files is present, they may load automatically and interfere with the new code. I tried renaming them instead of removing them and wound up with problems - so remove them.

If you go to the momentjs.com website, there are two major tabs - "Moment" and "Moment Timezone". You will need to load a file from each of those tabs.

  • From the "Moment" tab, download either "Moment.js" or "Moment.min.js". You don't need the locales version, but I suspect it would work.

  • From the "Moment Timezone" tab, download one of the two versions that includes years, the moment-timezone.js doesn't contain much of a timezone database. I downloaded "Moment-timezone-all-years.js" (you could probably load the min version to get better performance, or the 2010-2020 versions). The neat thing is that that file contains the code AND the database. So, you now only need two files.

  • Put those files in the assets/javascripts directory and edit application.coffee to include the two files you downloaded. The actual filename is different than the link name for the database. I added a "#= require moment" and "#= require moment-timezone-with-data". You don't need a third require for the database since the database is in the 2nd file.

Everything worked perfectly for me without changing the above coffee, html, or scss files. I now have a much more robust timezone database and I know it is current with regard to timezone rules.

Hopefully you'll find this helpful. I love this widget that weilu created and hope that others continue to use it.

@spynappels
Copy link

Thanks to BillLortz I've just got an instance set up and working, Awesome for distributed teams to keep an eye on the time in different offices.

@waa
Copy link

waa commented Sep 19, 2017

Thanks @weilu, this is really nice! A pretty unique display of time zones, I like it a lot!

Thanks @BillLortz for the post about the timezone files etc. This was what got everything finally working for me here.

@weilu, a suggestion perhaps: Can you consider having the Time zone tags be alternated high/low when they are very close? Currently they just overlap. For example, it would be cool when it can be detected that they overlap, to do something like this:

0  1  2  3  4  5  6
|  |              |
NY |             CEST
 Brazil

Nice work!

Bill

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment