Ruby 1.8 strftime works differently on Linux and Windows
Running Ruby 1.8 on Linux, cygwin, Mac, any POSIX environment:
now = Time.now
=> Mon Dec 27 18:28:28 -0500 2010
now.strftime("%l") # that's a lowercase "L"
=> " 6"
Under Windows using the exact same Ruby version and patch level:
now = Time.now
=> Mon Dec 27 18:28:28 -0500 2010
now.strftime("%l") # that's a lowercase "L"
=> ""
What? It turns out in Ruby 1.8 they cheated by simply calling the standard C strftime() function to implement Ruby’s strftime method. Because different compilers implement strftime() differently, compiling it under Windows results in a different set of supported % directives. Specifically, it looks like under Windows only the basic ANSI C version is implemented, but under POSIX compilers you get a mix of directives defined by ANSI and other standards like Gnu and Single Unix Specification. The “%l” directive was not even listed in the Ruby 1.8 docs — it worked by accident.
The good news is in Rails 1.9 they appear to have implemented their own strftime for consistency, instead of handing it off to the C compiler. If you need to fix this in the meantime, I provide the following monkey patch (which I simply place in my Rails config/initializers folder on any Windows developer machine):
# monkey patch Ruby strftime methods to implement
# %l directive that is missing in Windows Ruby
#
# as a monkey patch, just use this on your Windows
# development boxes to bridge the gap, it's not
# recommended for production
#
# notes:
# - you may want to add support for other missing directives
# - check your RUBY_PLATFORM and make sure it is in the regexp below
#
if RUBY_PLATFORM =~ /mingw32|mingw64|mswin32|mswin64/
class Time
alias_method :original_strftime, :strftime
def strftime(fmt)
hour12 = "%2d" % ((hour + 11) % 12 + 1)
original_strftime(fmt.gsub(/%l/, hour12))
end
end
class Date
alias_method :original_strftime, :strftime
def strftime(fmt)
hour12 = "%2d" % ((hour + 11) % 12 + 1)
original_strftime(fmt.gsub(/%l/, hour12))
end
end
end
leave a comment