PHP’s date() function in Python
In switching from PHP to Python I’m discovering an increasing number of PHP functions that I’ve learnt to rely on but have no direct equivalent in the Python standard library. Often Python simply provides a different way of approaching the problem, but old habits die hard and I’ve been replicating some of PHP’s functionality in Python for my own personal use.
Python 2.3 introduced the datetime module, which has comprehensive support for performing calculations on dates. Users of earlier Python versions can still benefit from the module thanks to a pure Python implementation available here. datetime objects can be formatted as strings using the strftime method, documented here; PHP offers a similar function. strftime() is a powerful function which takes full account of the current locale when formatting dates. PHP’s date() function ignores the locale but provides a far richer set of formatting options, including my favourite: the ability to display a date with an ordinal, for example “7th October”.
I’ve always preferred date(), so I’ve ported it to to Python. My version supports most of PHP’s date format options, raising a NotImplemented exception for any that are unsupported. Usage looks like this:
>>> import datetime >>> from DateFormat import DateFormat >>> d = datetime.datetime.now() >>> df = DateFormat(d) >>> print df.format('jS F Y H:i')
The class works using a neat piece of introspection. Each of the available formatting options is implemented as a method of the class which returns that part of the date formatted in the correct way. For example, the ’a’ command (for returning ’am’ or ’pm’ in lower case) looks like this:
def a(self): '"am" or "pm"' if self.date.hour > 12: return 'pm' else: return 'am'
The format method simply cycles through the characters in the format string, attempting to call the method of that name each time round using getattr(). If a method doesn’t exist (i.e the character isn’t one of the special formatting commands) a try/except block catches the thrown AttributeError. The whole method looks like this:
def format(self, formatstr): result = '' for char in formatstr: try: result += str(getattr(self, char)()) except AttributeError: result += char return result
I might alter the interface a bit in the future, maybe creating an extended version of the datetime class itself, but for the moment this serves my purposes just fine.