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).

enter image description here

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

Is this possible?


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

enter image description here

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


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.


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.