# Is it possible for Conky to display Time in words and not in numbers?

I want to have Conky display the time using words and not numbers.

What I want to do is more or less how the Pebble Watch looks (Red watch).

Like in the image, even if only the time and not the date can be shown.

Is this possible?

-
actually using images looks a lot harder to me... I never programmed in Lua or used Conky before, but I saw a nice Monday morning challenge, and it took me 2 hours from start to finish, including writing the answer down :P – Gerhard Burger Jan 14 '13 at 22:27
It's ok it was just some thought that I had. I still haven't tried which of answers work best. – Uri Herrera Jan 14 '13 at 22:30

## Lua scripting solution

This is indeed possible using Lua scripting. You can use the script below (the number conversion is taken from rosettacode.org).

The script can do a boring option, which will translate 12:45 to "twelve forty-five", and an awesome option which will translate it to "a quarter to one". It also does a Uri Herrera option which does the hour bold ;)

Also it automatically refreshes, when the time changes.

``````words = {"one ", "two ", "three ", "four ", "five ", "six ", "seven ", "eight ", "nine "}
levels = {"thousand ", "million ", "billion ", "trillion ", "quadrillion ", "quintillion ", "sextillion ", "septillion ", "octillion ", [0] = ""}
iwords = {"ten ", "twenty ", "thirty ", "forty ", "fifty ", "sixty ", "seventy ", "eighty ", "ninety "}
twords = {"eleven ", "twelve ", "thirteen ", "fourteen ", "fifteen ", "sixteen ", "seventeen ", "eighteen ", "nineteen "}

function digits(n)
local i, ret = -1
return function()
i, ret = i + 1, n % 10
if n > 0 then
n = math.floor(n / 10)
return i, ret
end
end
end

level = false
function getname(pos, dig)
level = level or pos % 3 == 0
if(dig == 0) then return "" end
local name = (pos % 3 == 1 and iwords[dig] or words[dig]) .. (pos % 3 == 2 and "hundred " or "")
if(level) then name, level = name .. levels[math.floor(pos / 3)], false end
return name
end

function numberToWord(number)
if(number == 0) then return "zero" end
vword = ""
for i, v in digits(number) do
vword = getname(i, v) .. vword
end

for i, v in ipairs(words) do
vword = vword:gsub("ty " .. v, "ty-" .. v)
vword = vword:gsub("ten " .. v, twords[i])
end
return vword
end

function conky_boringTime()
hour = os.date("%H") + 0
minute = os.date("%M") + 0
return numberToWord(hour) .. numberToWord(minute)
end

function conky_awesomeTime()
hour = os.date("%H") + 0
minute = os.date("%M") + 0
hour = hour % 12
if(hour == 0) then
hour, nextHourWord = 12, "one "
else
nextHourWord = numberToWord(hour+1)
end
hourWord = numberToWord(hour)
if(minute == 0 ) then
return hourWord .. "o'clock"
elseif(minute == 30) then
return "half past " .. hourWord
elseif(minute == 15) then
return "a quarter past " .. hourWord
elseif(minute == 45) then
return "a quarter to " .. nextHourWord
else
if(minute < 30) then
return numberToWord(minute) .. "past " .. hourWord
else
return numberToWord(60-minute) .. "to " .. nextHourWord
end
end
end

function conky_getHourWord()
return numberToWord(os.date("%H") + 0)
end

function conky_getMinuteWord()
return numberToWord(os.date("%M") + 0)
end
``````

Now save it somewhere, for the purpose of this question assume we save it as `~/.config/conky/scripts/pretty_time.lua`

Now edit your `.conkyrc`, before `TEXT` add a line

``````lua_load ~/.config/conky/scripts/pretty_time.lua
``````

this loads the script so we can access the functions.

Then, at the appropriate place below `TEXT`, you can call the functions in the following way (conky automatically adds the `conky_` prefix)

``````TEXT
...
\${color grey}Boring time:\$color \${lua boringTime}
\${color grey}Awesome time:\$color \${lua awesomeTime}
\${color grey}Special Uri Herrera:\$color \${font Aria:bold} \${lua getHourWord}\$font \${lua getMinuteWord}
...
``````

This will result in

If you want the seconds, this shouldn't be too hard to add yourself.

-
Great! works good, now to find how to change the size of the text. – Uri Herrera Jan 17 '13 at 21:19

you can write a python script for this using `pynum2word` library available at this sourceforge page

Basically what it does is:

``````>>> import num2word
>>> num2word.to_card(10)
'ten'
>>> num2word.to_card(100)
'one hundred'
>>> num2word.to_card(1025)
'one thousand and twenty-five'
``````

a trivial example is what I did here:

``````>>> import datetime
>>> import num2word
>>> now = datetime.datetime.now()
>>> t = datetime.time(now.hour, now.minute, now.second).strftime('%H:%M:%S').split(':')
>>> print "%s hours %s minutes and %s seconds" %(num2word.to_card(t[0]), num2word.to_card(t[1]), num2word.to_card(t[2]))
>>> two hours thirty one minutes and fifteen seconds
``````

Now to make this rendered by conky, create a directory inside your conky config directory e.g. `~/.conky/pyscripts/` and put `pynum2word` library inside it, now create another file say `timeToWord` and put this script into this file:

``````#!/bin/python
import datetime
import num2word
now = datetime.datetime.now()
t = datetime.time(now.hour, now.minute, now.second).strftime('%H:%M:%S').split(':')
print "%s hours %s minutes and %s seconds" %(num2word.to_card(t[0]), num2word.to_card(t[1]), num2word.to_card(t[2]))
``````

You can change the formatting of time and include the date too, if you want. For formatting options have a look at this page.

then open the conky config file `/etc/conky/conky.conf` and put this line somewhere:

``````{execpi 30 ~/.conky/pyscripts/timeToWord}
``````

What this line does is, it execute the script file every 30 seconds and update the output on conky window.

Of course you can freely place the script files in any directory but make sure the `pynum2word` library is in same directory.

-
Interesting, but Say that I don't know how to add this to Conky. How do I add or What do to the Conky file so it imports the library? so it displays the time like that. – Uri Herrera Jan 13 '13 at 21:22
I just updated the answer, please review. – Gufran Jan 14 '13 at 14:23

Couldn't you create a symbol-font which consists of images of the written word for every numeral? Than you should just have to choose this font (if possible) for the display of time.

-
That's the thing, amazingly Conky doesn't load all fonts. I have fonts that Conky just won't load, and they default to Arial or Times New Roman. Not to mention that all the work making a Font means. Also the image I used is an example, I'd like to have Hours in a bold font and Minutes in a Thin/Light font. – Uri Herrera Jan 13 '13 at 20:22
This wouldn't even work anyway for numbers greater than nine. – Alistair Buxton Jan 14 '13 at 23:36

Yes, it's possible, but only through Lua scripting. You'll need a script that takes in numbers and outputs words. A lot of frameworks like Django have this feature, but you might be on your own unless there's an equivalent Lua library for it:

``````function conky_translate_number(number) {
if (number == 1) {
return "one";
} else {
return "not a clue";
}
}
``````

You may just simply want to write a Python script which leverages Django for the translation using its templating language.

-
Ok thanks, can you add an example? – Uri Herrera Jan 11 '13 at 5:58
Done, rudimentary, but yeah. I can elaborate if you'd like, but it seems outside of the scope of the question to teach you Python in its entirety :) – Naftuli Tzvi Kay Jan 11 '13 at 6:05
It's a bit complicated than I thought, I was thinking more along the lines of possibly even using images that contained full words (one, two, three, etc) and that each of these images would change according to the time, so if it's 12:22 it would display twelve twentytwo. – Uri Herrera Jan 11 '13 at 6:22
@UriHerrera actually it's quite doable, see my answer – Gerhard Burger Jan 14 '13 at 11:22