Poking around in others' software is sometimes useful (and thanks to Zorn)
I need an NSNumberFormatter subclass for a PyObjC project I'm working on that reformats an NSNumber to hours:minutes:seconds. Thinking I've seen this before (and kind of hoping that there was some voodoo I was missing somewhere to make this simple), I decided to poke around in applications that deal with time. After a little head-scratching, I was reminded of that most useful time-tracking and invoicing application I've grown to love called Billable (Zorn!). On this screenshot (from the Clickable Bliss site) we see a field labeled "Time Spent:" with a "Start" button next to it. Thinking to myself, "I want that formatter!" I fired up F-Script Anywhere, injected it into Billable and dug down until I was the class name for the formatter.
Time to pray to google. Ah! Zorn! You beautiful helpful coding-type person. You've pasted it for us. Thank you!
Now all that is left is to pythonify it. (I made a few modifications to the behavior, but it's the same general idea)
Time to pray to google. Ah! Zorn! You beautiful helpful coding-type person. You've pasted it for us. Thank you!
Now all that is left is to pythonify it. (I made a few modifications to the behavior, but it's the same general idea)
#
# CBTimeLengthFormatter.py
# PuppyTracker
#
# Created by Jonathan Saggau on 12/3/07.
# Copyright (c) 2007 __MyCompanyName__. All rights reserved.
from Foundation import *
from math import floor
#modified from http://paste.lisp.org/display/21854
class CBTimeLengthFormatter(NSNumberFormatter):
def stringForObjectValue_(self, anObject):
if (not (anObject.isKindOfClass_(NSNumber))):
return(None)
if (anObject.intValue() <= 0):
return("00:00:00")
intval = int(floor(anObject))
hours = intval / (60*60)
minutes = (intval - (hours * 60 * 60)) / 60
seconds = intval - (minutes * 60) - (hours * 60 * 60)
string = "%02i:%02i:%02i" %((hours), (minutes), (seconds))
return(string)
def getObjectValue_forString_errorDescription_(self, objVal, inString, err):
"""Take a string like "00:00:00" and turns it into a NSNumber and returns YES
Also able to handle 10:10 (as 10 minutes, 10 seconds) and 10 (as 10 seconds)"""
string = NSString.stringWithString_(inString)
#catch for nil or empty string
if (string == None or string.isEqualToString_("")):
return True, 0, None
stringList = string.split(":")
#make seconds first, instead of hours
stringList.reverse()
#turn each into an integer, filtering out empty strings
try:
stringList = [int(each) for each in stringList if each is not u'']
#if we can't make any part of this into an int, bail
except ValueError, e:
return False, 0, None
#make sure we have Seconds, Hours, Minutes by padding the list with zeros
#in case we have (say) Seconds, Hours only
while ( len(stringList) < 3):
stringList.append(0)
#sec #min #hour
timeInSeconds = stringList[0] + stringList[1]*60 + stringList[2]*60*60
return True, timeInSeconds, None