Python Timestamp Increment

I composed this concise solution to ncm‘s “coding challenge” in November 2004. I’m not entirely satisfied with its elegance, but I’m pleased with its brevity.

def dateinc(s) :
  def carry(list, modulus) :
    if len(list) == 1 : return [list[0] // modulus[0], list[0] % modulus[0]]
    else              : q = carry(list[1:], modulus[1:]); return [(list[0] + q[0]) // modulus[0], (list[0] + q[0]) % modulus[0]] + q[1:]
  s = reduce(lambda x,y:x+y, map(lambda x : (x >= '0' and x <= '9') * x, s))
  result = map(lambda x,y:x+y, map(int,(s[0:4],s[4:6],s[6:8],s[8:10],s[10:12],s[12:14])),(0,-1,-1,0,0,1))
  modulus = [10000,12,[31,28,31,30,31,30,31,31,30,31,30,31][result[1]],24,60,60]
  if result[0] % 4 == 0 and (result[0] % 100 != 0 or result[0] % 400 == 0) :
    modulus[2] += 1                               # Account for leap day.
  result = carry(result, modulus)[1:]             # Carry the extra second.
  result[1:3] = map(lambda x:x+1, result[1:3])    # Readjust to 1-base.
  return reduce(lambda x,y:x+y, map(lambda x : (x < 10) * '0' + str(x), result))

I further reduced this as follows, turning the carry function into a one-liner that computes the carry in-place (and also using builtins wherever possible). I’m much more satisfied with this solution.

def dateinc(s) :
  s = reduce(lambda x,y:x.isdigit()*x+y.isdigit()*y, s)
  ans = map(int.__add__, map(int,(s[0:4],s[4:6],s[6:8],s[8:10],s[10:12],s[12:14])),(0,-1,-1,0,0,1))
  mod = [10000,12,[31,28,31,30,31,30,31,31,30,31,30,31][ans[1]],24,60,60]
  if ans[0] % 4 == 0 and (ans[0] % 100 != 0 or ans[0] % 400 == 0) : mod[2] += 1
  ans = map(lambda x:(ans[x] + reduce(int.__mul__, map(lambda y:ans[y]>=mod[y]-1,range(x+1,len(ans))),x!=len(ans)-1)) % mod[x], range(len(ans)))
  ans[1:3] = map(int.__add__,ans[1:3],[1,1])      # Readjust to 1-base.
  return reduce(str.__add__, map(lambda x : (x < 10) * '0' + str(x), ans))

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s