Reputation: 5213
Consider the following loop:
<cfloop from="#timeFormat(roomAvail.startTime,'short')#" to="#timeFormat(roomAvail.endTime,'short')#" step="#CreateTimeSpan(0,0,30,0)#" index="time">
<cfoutput>
#timeFormat(time,'short')#<br/>
</cfoutput>
</cfloop>
When my input is from:9:00 AM
to:8:00 PM
the code outputs every 30 min increment from 9:00 AM to 7:30 PM.
When my input is from:10:00 AM
to:1:00 PM
the code outputs every 30 min increment form 10:00 AM to 1:00 PM.
Can anyone explain what is happening and why there is one 30 min segment missing from the first loop and not the second? I was told this was a valid method of looping over times, but I'm starting to think that because the time is rendered as a float in the underlying Java method, some rounding is occurring and it's screwing up.
Edit: I really don't think it matters that I'm not passing in Date/Time objects. CF is casting that behind the scenes, otherwise the entire thing wouldn't work at all.
Upvotes: 3
Views: 120
Reputation: 31920
timeFormat returns a string. Could you use createTime instead to use a proper time object, as per their example in the docs?
https://wikidocs.adobe.com/wiki/display/coldfusionen/cfloop%3A+looping+over+a+date+or+time+range
<cfset startTime = CreateTime(9,0,0)>
<cfset endTime = CreateTime(20,0,0)>
<cfloop from="#startTime#" to="#endTime#" index="time" step="#CreateTimeSpan(0,0,30,0)#">
<cfoutput>#TimeFormat(time, "short")#<br /></cfoutput>
</cfloop>
<cfset startTime = CreateTime(10,0,0)>
<cfset endTime = CreateTime(13,0,0)>
<cfloop from="#startTime#" to="#endTime#" index="time" step="#CreateTimeSpan(0,0,30,0)#">
<cfoutput>#TimeFormat(time, "short")#<br /></cfoutput>
</cfloop>
Update: The above code didn't solve your problem. You could do this instead. Looping to the second previous means you always miss out on that end time. Then, assuming you want to display the end, add that in after the loop:
<cfset startTime = CreateTime(9,0,0)>
<cfset endTime = CreateTime(19,59,59)>
<cfloop from="#startTime#" to="#endTime#" index="time" step="#CreateTimeSpan(0,0,30,0)#">
<cfoutput>#TimeFormat(time, "short")#<br /></cfoutput>
</cfloop>
<cfoutput>#TimeFormat(dateAdd("s", 1, endTime), "short")#<br /></cfoutput>
<cfset startTime = CreateTime(10,0,0)>
<cfset endTime = CreateTime(12,59,59)>
<cfloop from="#startTime#" to="#endTime#" index="time" step="#CreateTimeSpan(0,0,30,0)#">
<cfoutput>#TimeFormat(time, "short")#<br /></cfoutput>
</cfloop>
<cfoutput>#TimeFormat(dateAdd("s", 1, endTime), "short")#<br /></cfoutput>
Upvotes: 0
Reputation: 29870
It'll be because under the hood, all CF is doing is converting the Dates to Doubles (or in your case: the Strings to Dates to Doubles), and 8pm (20/24ths of 1 day) will have a rounding error which leaves it within the intended upper boundary; whereas 1pm (13/24ths of 1 day) is slighty outside the intended upper boundary.
It probably doesn't help that you're passing a string when the loop is expecting dates.
Upvotes: 2