1

I would like to create a string representation of a datetime object that could contain a None value. So far, I came up with a solution, but I was looking at a better/cleaner way of doing it.

Let's say I have the following two variables:

import datetime as dt

a = None
b = dt.datetime(2017, 11, 30)


def str_format(str):
    return '{:%Y-%m-%d}'.format(str)

The following would return a formatted string:

str_format(b)
'2017-11-30'

But the following would return an error:

str_format(a)
TypeError: unsupported format string passed to NoneType.__format__

So far I can up with the following solution:

def str_format(str):
    if isinstance(str, type(None)) is False:
        return '{:%Y-%m-%d}'.format(str)
    else:
        return '{}'.format(str)

str_format(a)
'None'

str_format(b)
'2017-11-30'

However, I was looking at a more efficient/cleaner way of writing the function.

Eric B
  • 1,635
  • 4
  • 13
  • 27
  • 2
    I think that it is better to test if your parameter is type of datetime. `isinstance(b, dt.datetime)`, you're sure that you format the right type – mdlx Dec 04 '17 at 21:15

2 Answers2

2

Often times these types of things are wrapped in a try/except

def str_format(str):
  try:
    return '{:%Y-%m-%d}'.format(str)
  except TypeError:
    # unrecognized type, return blank or whatever you want to return
    return ''

The answer on this question explains why you typically use try/except instead of a conditional check fairly well.

MCBama
  • 1,432
  • 10
  • 18
1

your function is overcomplex. None is a singleton, so the pythonic way of testing against it is just is None.

Just do it in one line with a ternary expression:

def str_format(s):
   return str(s) if s is None else '{:%Y-%m-%d}'.format(s)

or to return a default date (ex: 1/1/2010) if None is passed:

def str_format(s):
   return '{:%Y-%m-%d}'.format(s or dt.datetime(2010, 1, 1))

as a side note don't use str as a variable name as it is the python string type.

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219