1

I have a function that takes a datetime.timedelta as an argument in a script that I want to use in ModelBuilder. I don't see an option for that as a parameter type, so for now I have a solution that involves setting the parameter as a String in ModelBuilder and the following code:

...
startOffset = eval('datetime.timedelta(' + arcpy.GetParameterAsText(0) + ')')
...

Which works, but relies on inputting a valid set of timedelta arguments for the parameter in ModelBuilder (e.g. days=0,hours=3) and just seems like a bad idea in general.

Is there a better way to get a timedelta into a script from a Model using only one parameter?

PolyGeo
65.5k29 gold badges115 silver badges350 bronze badges
asked Jan 7, 2014 at 17:50
7
  • 2
    Why not try it as two float parameters, one for days and one for seconds and then do datetime.timedelta(float(arcpy.GetParameterAsText(0)), float(arcpy.GetParameterAsText(1))) Commented Jan 7, 2014 at 19:14
  • My main reservation with that is that I'd either need to insist that users convert to the appropriate units or require 7 parameters to actually specify any possible initialization for it (i.e. timedelta([days[, seconds[, microseconds[, milliseconds[, minutes[, hours[, weeks]]]]]]]). As it is, there's 1 parameter to specify any combination of values. Commented Jan 7, 2014 at 22:00
  • 1
    What do your users actually need to be able to input? What does the value mean? Commented Jan 7, 2014 at 22:41
  • Making a tool to find flights in an area during a time period relative to another event. So they'd put in a timedelta relative to the start of the event and another one relative to the end of the event to specify the time period that they want to see flights for. Commented Jan 8, 2014 at 20:41
  • 1
    Why not just use two dates as a range and use the subtraction operator to get the delta when you need it? Commented Jan 9, 2014 at 15:49

1 Answer 1

1

This article discusses parsing human-readable timedeltas in Python. It can be extended to include seconds, milliseconds, and microseconds, depending on your specifications (and knowledge of regexps), but primarily just allows the input to be specified in a more human-readable string format:

e.g.:

>>> tdelta("1m")
datetime.timedelta(0, 60)
>>> tdelta("1h")
datetime.timedelta(0, 3600)
>>> tdelta("1d")
datetime.timedelta(1)
>>> tdelta("1w")
datetime.timedelta(7)
>>> tdelta("1w 1d 1h 1m")
datetime.timedelta(8, 3660)

As for whether this is actually any better than what you are doing now only you could answer.

Code for posterity:

import re
from datetime import timedelta
def tdelta(input):
 keys = ["weeks", "days", "hours", "minutes"]
 regex = "".join(["((?P<%s>\d+)%s ?)?" % (k, k[0]) for k in keys])
 kwargs = {}
 for k,v in re.match(regex, input).groupdict(default="0").items():
 kwargs[k] = int(v)
 return timedelta(**kwargs)
PolyGeo
65.5k29 gold badges115 silver badges350 bronze badges
answered Jan 13, 2014 at 19:55
1
  • 1
    That's interesting, but my original issue isn't really with the number of characters necessary to input the parameter, but with the fact that the parameter is having to be parsed into a timedelta instead of finding a way to actually pass it in as one. For my purposes I don't think the few characters saved in the input by doing this outweighs the fact that you're now relying on people knowing a non-standard set of arguments for the timedelta they're trying to create. Commented Jan 20, 2014 at 21:56

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.