This post originated from an RSS feed registered with Ruby Buzz
by Patrick Lenz.
Original Post: Localization for Ruby's Time#strftime
Feed Title: poocs.net
Feed URL: http://feeds.feedburner.com/poocsnet
Feed Description: Personal weblog about free and open source software, personal development projects and random geek buzz.
While numerousarticles out there talk about the possibilities to use the Ruby Gettext package to translate your Rails application, I found that for my applications they were missing the point of translating the dates.
Although the aforementioned Rails Wiki entry does override the class constants MONTHNAMES, DAYNAMES and the like, this does not affect date strings composed via Time#strftime. Another thing I found was the Multi Language Library which sounded promising, was still in its very infants though (and had its last commits back in February!) and seemed to complicated for my little task to simply localize Time#strftime.
What I came up with was a quick hack to resort to a pure Ruby implementation for the strftime directives that actually need locales. Those are then simply swapped out of the strftime format string and the rest is being passed to the original (now aliased) function.
class Timealias:strftime_nolocale:strftimedef strftime(format)format.gsub!(/%a/,Date::ABBR_DAYNAMES[self.wday])format.gsub!(/%A/,Date::DAYNAMES[self.wday])format.gsub!(/%b/,Date::ABBR_MONTHNAMES[self.mon])format.gsub!(/%b/,Date::MONTHNAMES[self.mon])self.strftime_nolocale(format)endend
While I’m confident that you’ll be losing some precious microseconds with those regexes, I opted for something working now instead of waiting another couple of months for something natively (pun) written to show up.
Closing off, contrary to what is suggested in the Wiki page (which I referred to a couple of times now) I picked a different approach for the actual strings in the Date class constants.
Ruby tends to complain if you redefine constants at runtime which is why you shouldn’t simply reassign them a new slab of array values using the equal sign. Additionally, if you want to support multiple languages from a single instance of your Rails application, you want the reassignment to only happen after you properly bound your textdomain.
class Datedef self.translate_stringsDate::ABBR_DAYNAMES.replace[_("sun"),_("mon"),_("tue"),_("wed"),_("thu"),_("fri"),_("sat")]endend
By using replace you avoid the reassignment warnings. And by using a newly created class method of the Date class somewhere in a before_filter of your ApplicationController (which might be the same one you’re using to set the actual locale to be used (which you do, if you’ve been following the aforementioned Hieraki book)) you don’t actually use the gettextified strings until the actual locale has been bound. I only mentioned a single one of the Date class constants in the code snippet above, the other ones you should stick in there are Date::ABBR_MONTHNAMES, Date::DAYNAMES and Date::MONTHNAMES.