Ir al contenido principal

Ralsina.Me — El sitio web de Roberto Alsina

Javascript Makes Me Cry: Turning a Date into a String

Wo­rking la­te last ni­ght in Al­va I wanted to do so­me­thing that soun­ded tri­via­l:

When the pa­ge load­s, get the cu­rrent da­te and ti­me, and if a cer­tain in­put is emp­ty, put it the­re like this:

28/05/2013 23:45

So, how hard can that be, ri­gh­t? We­ll not har­d, bu­t...

Getting the current date-time is easy: now = new Da­te(); So, is there something like strftime in Javascript? Of course not. You can get code from the usual places and have a untested, perhaps broken, limited version of it. And I am not about to add a strftime implementation to use it once. Sure, there are a number of Date methods that convert to strings, but none of them lets you specify the output format. So, let's try to do this The Javascript Way, right?

To get the ele­men­ts I want to put in the va­lue, I us­ed ac­ce­s­sor me­tho­d­s. So, ob­vious­l­y, the­se should gi­ve me what I want for the strin­g, ri­gh­t?

no­w.­ge­tDa­y(), no­w.­ge­t­Mon­th(), no­w.­ge­tYea­r(), no­w.­ge­tHou­r() no­w.­ge­t­Mi­nu­te()

We­ll, they are, at the da­te men­tio­ned abo­ve, res­pec­ti­ve­l­y: 2, 4, 113, erro­r, error

Ok, the errors are easy to fix from the docs. It's actually getHours() and getMinutes(), so now we have 2, 4, 113, 23, 45 and of those five things, the last two are what one would expect, at least. Let's go over the other three and see why they are so weird:

Date.getDay() returned 2 instead of 28

Because getDay() gives you the week day and not the day of the month. Which is absolutely idiotic. So, you have to use getDate() instead. Which means the name is a lie, becasue the logical thing for getDate() to return is the whole date.

Date.getMonth() returned 4 instead of 5

Because getMonth() returns months in the [0,11] range. Which is beyond idiotic and bordering in evil. Come on, Javascript, people have been referring to may as "5" for nearly two thousand years now! What other language does this? Anyone knows one?

Date.getYear() returned 113 instead of 2013

Because it uses offset-from-1900. Which is amazing, and I had never heard of a language doing in a standard type. Because why? So, use getFullYear() instead.

No­w, ar­med wi­th the ri­ght 5 num­ber­s, le­t's for­mat it. Does Ja­vas­cript ha­ve the equi­va­lent of sprin­tf or for­mat ? Of cour­se not. In Ja­vaS­crip­t, wi­thout 3rd par­ty mo­du­le­s, you crea­te strings by addi­tio­n, like a ca­ve­man. Agai­n, I know I could add a for­mat me­thod to the String pro­to­ty­pe and make this wo­rk, but I am not adding an im­ple­men­ta­tion of for­mat or sprin­tf just to use it on­ce!

So, this pro­du­ces that I wan­t:

now.getDate()+'/'+(now.getMonth()+1)+'/'+now.getFullYear()+' '+now.getHours()+':'+now.getMinutes()

Un­le­ss... the day or mon­th are lo­wer than 10, in whi­ch ca­se it's mis­sing the le­ft-­pa­dding ze­ro. Lu­cki­l­y, for the pur­po­se I was using it, it wo­rked an­ywa­y. Be­cau­se OF COUR­SE the­re's no in­clu­ded func­tion to le­ft-­pad a strin­g. You ha­ve to do it by addi­tio­n. Or, of cour­se, add a 3rd par­ty func­tion tha­t's out the­re, in the in­ter­ne­t, so­mewhe­re.

Nothing Ever Really Goes Away On The Internet: ra-plugins

I us­ed to ma­na­ge a lar­ge num­ber of QMail ins­ta­lla­tion­s. And be­cau­se Qmail was ... weird­ly li­cen­s­e­d, I wro­te a set of plu­gins that ran on top of a pa­tch ca­lled Qmai­l-S­PP. I pre­tty mu­ch sto­pped doing that years ago be­cau­se li­fe took me in other di­rec­tion­s, and for­got all about it.

That co­llec­tion is ca­lled ra-­plu­gins and I had not tou­ched it sin­ce la­te 2008.

And to­da­y... I got a pa­tch wi­th two who­le plu­gins to add to it so that it makes Qmail hand­le email addres­ses mo­re like Gmail does (a­lia­ses using use­r+­foo and making use­r.­foo the sa­me as user­foo).

So, I got the­m, added the­m, fixed a few sim­ple buil­ding is­sues, up­dated the libs­m­tp it uses in­ter­na­lly for one of the plu­gins to a la­ter ver­sio­n, and the­re it sta­ys, perhaps not to be tou­ched un­til 2018.

(Re)Introducing Alva, a Nikola Server

Over a year ago (ti­me flie­s!) I pos­ted so­me­thing about a pro­ject ca­lled Al­va. Let me quo­te mysel­f:

Al­va is al­most the oppo­si­te of Niko­la. If Niko­la is about making sta­tic si­tes, Al­va is a dy­na­mic si­te. Ho­we­ve­r, as He­gel su­gges­ts, from the the­sis and the an­ti­the­sis co­mes the syn­the­sis.

So, Al­va is about dy­na­mi­ca­lly crea­ting sta­tic si­tes. If you want to ha­ve Niko­la in your ser­ver ins­tead of in your own com­pu­te­r, and ha­ve the con­ve­nien­ce of an on­li­ne tool, tha­t's the ni­che Al­va tries to fi­ll.

So, you would ins­ta­ll Al­va, and use it like any other we­b-­ba­sed blo­gging tool. Ye­t, be­hind the sce­nes, you would ha­ve Niko­la, and all the per­for­man­ce and se­cu­ri­ty be­ne­fi­ts of sta­tic si­tes.

And ma­y­be so­me­da­y, I (or so­meo­ne) wi­ll put up a mul­ti-u­ser ver­sion of Al­va, and you wi­ll be able to get hos­ted blogs, kno­wing all the da­ta is yours and you can lea­ve an­y­ti­me and do your own thin­g.

The appro­ach I was taking at the ti­me pro­ved to be un­suc­ce­ss­fu­l, and the­re we­re a few other fai­lu­res along the wa­y. Of cour­se, the pro­blem was in how I was appro­aching the ta­sk. So I did the ri­ght thin­g, and lear­ned how to do it "ri­gh­t".

Sti­ll not usa­ble, sti­ll not hos­ted an­ywhe­re, but al­ready se­mi-­func­tio­na­l: Al­va li­ves now

The­re's a lot of wo­rk sti­ll to be do­ne. But I now know how to do it. To pre­vent the usual ar­gu­men­ts, he­re is a li­ttle ex­pla­na­tion of mo­ti­va­tio­n, toolin­g, etc.


I want a way to host blogs ve­ry chea­pl­y. How chea­pl­y? I want at least 1000 rea­so­na­bly ac­ti­ve users in a $5 VP­S. That would make Al­va a rea­so­na­ble al­ter­na­ti­ve to hos­ted mul­ti-u­ser wor­dpress, whi­ch means it would be a rea­so­na­ble so­lu­tion (if se­tup is ea­sy enou­gh) for sma­ll-­to­-­me­dium or­ga­ni­za­tions whi­ch do­n't want to se­tup ex­pen­si­ve in­fras­truc­tu­re yet want to own their da­ta (thi­nk school­s, sma­ll bu­si­nesses, FLO­SS pro­jec­ts, etc.) I al­so want to pro­vi­de that ser­vi­ce, for free. Whi­ch is why ano­ther rea­son I want it to be su­per chea­p.

How does Al­va help pro­vi­de this su­pe­r-­cheap blog hos­tin­g?

  1. It nee­­ds to sca­­le fo­­­llo­­wing the nu­m­­ber of edi­­ts not views.

  2. If it ge­­ts too busy wi­­th edi­­ts, chan­­ges take lo­n­­ger to appea­­r, but the si­­te itself does­n't get any slo­­we­­r.

  3. Edi­­ting and se­r­­ving can be pro­­­vi­­ded by se­­pa­­ra­­te se­r­­vi­­ce­s, so I can use so­­­me su­­pe­­r-­­fast sta­­tic fi­­le se­r­­ver and a su­­pe­­r-­­co­n­­fi­­gu­­ra­­ble WS­­GI de­­plo­­­y­­men­­t.

  4. In­­di­­vi­­dual pa­­ges can be hea­­vi­­ly op­­ti­­mi­­zed so that they do­­wn­­load fast


One of the gui­ding prin­ci­ples he­re is that to de­li­ver this sort of thin­g, in my spa­re ti­me, the de­ve­lo­p­ment pro­ce­ss nee­ds to be stin­gy wi­th the most li­mited re­sour­ce: me. I can't spend a lot of me he­re. I need to be ca­re­ful and not ove­r-­pro­mi­se.

So, whe­ne­ver the­re was a 3r­d-­par­ty tool that saves a sig­ni­fi­cant amount of ti­me, tha­t's what I am usin­g.


Be­cau­se it has a mu­ch stron­ger 3r­d-­par­ty tool­set than Fla­sk or any mi­cro­-­fra­mewo­rk. For exam­ple, the Fla­sk equi­va­lent of djan­go­-a­llau­th bro­ke my wi­ll to li­ve. Be­cau­se the ad­min in­ter­fa­ce means I can start adding da­ta to see if it makes sen­se be­fo­re I wri­te all the re­qui­red views.


Be­cau­se I do­n't want you to ha­ve to crea­te ac­coun­ts he­re un­le­ss you want to, this pro­vi­des (op­tio­nal) so­cial lo­gin and re­gis­tra­tio­n. This was ea­sy to se­tup and wo­rks al­m­sost ou­t-o­f-­the-­box

Bootstrap and Django-bootstrap-toolkit

Niko­la is al­ready hea­vi­ly in­ves­ted in boots­tra­p, so it just ma­de sen­se to go fur­ther do­wn that road. I un­ders­tand boots­tra­p, and djan­go­-­boos­tra­p-­toolkit is ea­sy enou­gh (al­thou­gh I can't make their date­pi­cker wo­rk)


Be­cau­se fi­gh­ting is bo­rin­g.


Be­cau­se Djan­go­'s me­cha­nis­ms to find tem­pla­tes and sta­tic fi­les are many and con­fu­se me.

Redis + RQ + django-rq

It's crucial for the whole approach to use job queues in order to detach the rendering from the actual Django app. This combination makes job dispatching ridiculously easy, setup is trivial (install everything, start redis, a few lines of config, ./ rqworker and off you go) and they provide a django admin page where I can see the failed jobs, which is awesome.


Be­cau­se it's ea­sy enou­gh, and allo­ws me so­me free­dom ex­plo­ring da­ta or­ga­ni­za­tion in my mo­dels wi­thout co­m­mi­tting to it fo­re­ver or re­crea­ting da­ta­ba­ses wi­th test da­ta all the ti­me.


I wi­ll pro­ba­bly ser­ve the ge­ne­ra­ted si­tes via ga­tling just like my cu­rrent si­tes be­cau­se it has the sim­plest na­med do­main con­fi­gu­ra­tion po­s­si­ble, it's fast and ve­ry li­ght in re­sour­ce usage.


A cool, sim­ple edi­tor wi­th li­ve pre­views that su­ppor­ts al­most eve­ry ma­rku­p. Not WY­SIW­YG or even WY­SIW­YM so po­s­si­bly I wi­ll ha­ve to add an al­ter­na­ti­ve. I started using djan­go­-­ma­rki­tup but it's not a good idea (it uses a old ver­sion of ma­rki­tup whi­ch re­qui­res JQue­ry < 1.9) and am in the pro­ce­ss of just using Ma­rki­tup ma­nua­ll­y.

So, feel free to gi­ve Al­va a try an­d/or gi­ve me a han­d, co­m­men­ts wel­co­me.


Es­to es pa­ra ayu­dar­me en una char­la que voy a dar en el Py­Day Ro­sa­rio por fa­vor res­pon­dan ho­nes­ta­men­te!


Contents © 2000-2024 Roberto Alsina