How to replace the time in a datetime object in python

I'm trying to set the time in a datetime object in a python script. I've tried using the datetime.replace and also the datetime.combine and neither one will work.

checkDate = datetime.date(2024,3,1)
startTime = checkDate.replace(hour=6)
endTime = checkDate.replace(hour=18)

in the script console I get the error:

TypeError: replace() got an unexpected keyword argument 'hour'

Don't use datetime, use java's built-in objects java.util.Date, it's what ignition's system.date.* functions use.
So then, you can use system.date.setTime | Ignition User Manual

checkDate = system.date.parse('2024/03/01', 'yyyy/MM/dd')
startTime = system.date.setTime(checkDate, 6, 0, 0)
endTime = system.date.setTime(checkDate, 18, 0, 0)
1 Like

I'm trying to do a manipulation with the dates and I found a way to do that with the python datetime.

I have a start date and end date that may be a month or several months. I need to loop through each day from 6am to 6pm and run another script on each day.

Again: Don't do this with python's datetime, use Java's dates instead.

If you can describe what you're trying to do, we can help you.
But as it is, it's confusing to say the least.
Do you need to run the script once per day ? Then what are the times for ?
Do you have a start and end DATES (not TIMES) ?
Do you have a number of days instead ?

In the end, what is the whole thing supposed to do ?

While the advice to use Ignition's date/time functions stands, your issue here is that:

checkDate = datetime.date(2024,3,1)

Gives you a datetime.date, not a datetime.datetime, and a date has no hour on it.

The start date and end date are picked from a calendar component in vision for a report viewer. The example I gave was just my trying things out in the script console.

If the start date is 1/1/2024 and the end date is 3/31/2024, I need to go through these dates in a script for each day isolating each shift (6am-6pm and 6pm-6am) to get data from several different data sources.

Try this

date = system.date.parse('2024/01/01', 'yyyy/MM/dd')
end_date = system.date.parse('2024/01/11', 'yyyy/MM/dd')

def do_your_thing(date):
	print "doing stuff for {}".format(date, 'yyyy/MM/dd HH:mm:ss')

while system.date.isBefore(date, end_date):
	do_your_thing(date)
	date = system.date.addDays(date, 1)

I'm not sure what you mean by "isolating each shift", but you can easily use setTime on the date object to get whatever time of day you want

edit:
damn it's been a while since i've used a while loop

3 Likes

That worked. I hesitate to use a while loop, but I put in a counter to break if it gets too large.

You can make it iteratable:

startDate = system.date.parse('2024-01-01 00:00:00')
endDate = system.date.parse('2024-01-10 00:00:00')

dates = iter([system.date.addDays(startDate, n) for n in xrange(system.date.daysBetween(startDate, endDate)+1)])

for date in dates:
	do_your_thing(date)

It will work without the iter() function, but if there are a lot of dates, then making an iterator instead of an iterable list will help save memory.

Do you still get the memory benefits if you use a list comprehension? I would have expected the dates = ... expression without the square brackets.

dates = iter(system.date.addDays(startDate, n) for n in xrange(system.date.daysBetween(startDate, endDate)+1))
1 Like

You don't even need iter(), the (x for x in something) syntax is a generator expression and can be used as is for iteration.

4 Likes

Generator, iterator, list comprehension - it's all still a while loop under the hood. Be careful with the dates you pass into this function.

1 Like