Solved

I am trying to set a time variable based on the current time with ColdFusion

Posted on 2016-08-03
7
81 Views
Last Modified: 2016-08-05
I am trying to use the below code to change a variable based on the current time. The left column would be a current time range, the right column is what I want to set the variable to. I'm not sure how to handle the overlapping of days.  Could someone assist?

23:01 to 07:00  same day(or next day if past 12) 15:30
07:01 to 15:30  same day 23:00
15:31 to 23:00      next day 15:30

<cfset currentDateTime=Now()> 
<cfset theDateTimeand1 = #DateAdd("h",1,currentDateTime)# />
<cfif hour(theDateTimeand1) gte 23 and hour(theDateTimeand1) lte 7 >
      <cfset variables.CompleteBy = dateFormat(dateAdd("d", 1, theDateTimeand1), "yyyy/mm/dd")&" 15:30:00">
<cfelseif hour(theDateTimeand1) gte 7 and hour(theDateTimeand1) lte 15:30 >
      <cfset variables.CompleteBy = dateFormat(theDateTimeand1, "yyyy/mm/dd")&" 23:00:00">
<cfelseif hour(theDateTimeand1) gt 15:30 and hour(theDateTimeand1) lte  23>
      <cfset variables.CompleteBy = dateFormat(dateAdd("d", 1, theDateTimeand1), "yyyy/mm/dd")&" 15:30:00>
</cfif>

Open in new window

0
Comment
Question by:earwig75
  • 3
  • 3
7 Comments
 
LVL 4

Expert Comment

by:Justin Smith
ID: 41741419
Does this help or is it irrelevant?

http://c2.com/cgi/wiki?TestIfDateRangesOverlap

and try reading this page and the first comment is the answer:

http://stackoverflow.com/questions/2231406/using-coldfusion-how-do-i-determine-if-a-given-time-span-occurs-during-business

basically you just have to set a range using a formula...kinda like this, but read those pages it will make sense.

(StartA <= EndB) and (EndA >= StartB)

Proof:
Let ConditionA Mean that DateRange A Completely After DateRange B
_                        |---- DateRange A ------|
|---Date Range B -----|                           _
(True if StartA > EndB)

Let ConditionB Mean that DateRange A is Completely Before DateRange B
|---- DateRange A -----|                       _
 _                          |---Date Range B ----|
(True if EndA < StartB)

Then Overlap exists if Neither A Nor B is true -
(If one range is neither completely after the other,
nor completely before the other, then they must overlap.)

Now one of De Morgan's laws says that:

Not (A Or B) <=>  Not A And Not B

Which translates to: (StartA <= EndB)  and  (EndA >= StartB)

NOTE: This includes conditions where the edges overlap exactly. If you wish to exclude that,
change the >= operators to >, and <= to <

NOTE2. Thanks to @Baodad, see this blog, the actual overlap is least of:
{ endA-startA, endA - startB, endB-startA, endB - startB }
0
 
LVL 52

Accepted Solution

by:
_agx_ earned 500 total points
ID: 41743522
EDIT: Fix code typo

Justin's logic is a solid way to check a date and/or time against a range. Though in this scenario, most of it could be handled by a single >= or <= comparison. Ultimately you can reduce it to 3 checks:

- If current time is between midnight and 7 AM -> use current day 15:30
- If current time is between 7:01 and 15:30 -> use same day 23:00
- Otherwise, the time must be between 15:31 and 23:59 -> use next day 15:30

Function:
<cfscript>
	// ** Requires CF10+ **
	public date function calculateCompleteByDate( date currentDateTime ) {

		Local.currentTime 	 = createTime( hour(arguments.currentDateTime), minute(arguments.currentDateTime), 0 );
		Local.todaysDate  	 = dateFormat( arguments.currentDateTime, "yyyy-mm-dd");
		Local.tomorrowsDate  = dateFormat( dateAdd("d", 1, arguments.currentDateTime), "yyyy-mm-dd");
		
		// Between midnight and 7:00 AM -> due same day at 15:30
		if (local.currentTime <= createTime(7,0,0)) {
			Local.completeBy = Local.todaysDate &" 15:30:00" ;
		}
		// Between 7:01 and 15:30 -> due same day at 23:00
		else if (local.currentTime >= createTime(7,1,0) && local.currentTime <= createTime(15,30,0)) {
			Local.completeBy = Local.todaysDate &" 23:00:00" ;
		}
		// Otherwise it is between 15:31 and 23:59:59 -> due tomorrow at 15:30 
		else {
			Local.completeBy = Local.tomorrowsDate &" 15:30:00";
		}

		// *** DEMO ONLY ****
		writeOutput("<br>[#dateTimeFormat(arguments.currentDateTime, 'yyyy-MM-dd HH:nn:ss tt')#] 
					 --> #dateTimeFormat(Local.completeBy, 'yyyy-MM-dd HH:nn:ss tt')# "
				);
		
		return parseDateTime(Local.completeBy, "yyyy-MM-dd HH:mm:ss");
	}
</cfscript>

Open in new window


Usage:
<cfscript>
	dates = [ 
				createDateTime( 2016,8,4, 0, 0, 0)
				, createDateTime( 2016,8,4, 7, 0, 0)
				, createDateTime( 2016,8,4, 7, 1, 0)
				, createDateTime( 2016,8,4, 15, 30, 0)
				, createDateTime( 2016,8,4, 15, 31, 0)
				, createDateTime( 2016,8,4, 23, 0, 0)
				, createDateTime( 2016,8,4, 23, 1, 0)
				, createDateTime( 2016,8,4, 23, 59, 0)
			];
	for (value in dates) {
		calculateCompleteByDate( value );
	}
</cfscript>

Open in new window

0
 

Author Comment

by:earwig75
ID: 41744162
@AGX, thank you. I now understand the function/script, but how can I use it? I am just trying to have the completeByDate output to a page, depending on the current time. I think I'm going to be using it as the default value in a text box/date picker. Would you be able to help with that?
0
Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

 
LVL 52

Expert Comment

by:_agx_
ID: 41744188
@earwig75 - There are different options. Simplest is to include the function definition somewhere in your .cfm page.  

<cfscript>
	public date function calculateCompleteByDate( date currentDateTime ) {
              // .... function content here 
	     return parseDateTime(Local.completeBy, "yyyy-MM-dd HH:mm:ss");
	}
</cfscript>

Open in new window


Then invoke it where ever you need it and output the value as usual:

         
<cfoutput>Complete By Date: #calculateCompleteByDate( now() )#</cfoutput>

Open in new window


IMO wrapping the logic in a function is cleaner, but it is not required. You could just as easily do it all inline if you prefer:

<cfscript>
	variables.currentDateTime = now();
	variables.currentTime 	 = createTime( hour(variables.currentDateTime), minute(variables.currentDateTime), 0 );
		
	// Between midnight and 7:00 AM -> due same day at 15:30
	if (variables.currentTime <= createTime(7,0,0)) {
		variables.completeBy = dateFormat( variables.currentDateTime, "yyyy-mm-dd") &" 15:30:00" ;
	}
	// Between 7:01 and 15:30 -> due same day at 23:00
	else if (variables.currentTime >= createTime(7,1,0) && variables.currentTime <= createTime(15,30,0)) {
		variables.completeBy = dateFormat( variables.currentDateTime, "yyyy-mm-dd") &" 23:00:00" ;
	}
	// Otherwise it is between 15:31 and 23:59:59 -> due tomorrow at 15:30 
	else {
		variables.completeBy = dateFormat( dateAdd("d", 1, variables.currentDateTime), "yyyy-mm-dd") &" 15:30:00";
	}

        // Display complete by date
	writeOutput("Complete by: "& parseDateTime(variables.completeBy, "yyyy-MM-dd HH:mm:ss"));
	
</cfscript>

Open in new window

0
 

Author Comment

by:earwig75
ID: 41744216
As you have probably guessed, I am not that great with CFSCRIPT, that's why I was using cfif statements in my example.  I have one last question if you don't mind. In your function, there are 2 variables (I underlined them below). Can you explain why there is a "date" and a "currentDateTime"?  I am only passing one variable to the function. Sorry for being so confused!

public date function calculateCompleteByDate( date currentDateTime ) {
0
 
LVL 52

Expert Comment

by:_agx_
ID: 41744277
public date function calculateCompleteByDate( date currentDateTime ) {

No problem.  It's actually one variable "name" and the variable's data type. If you break it down, it's just like cffunction:

public                                     --->      CFFunction "access" level:     "public", "private", etc....
date                                        --->      CFFunction "returntype":     "date", "string", etc....
function                                 --->      Keyword identifying code block as UDF, ie "cffunction"
calculateCompleteByDate  --->   CFFunction "name"
(
          date                              --->  CFArgument "type", ie "date", "string", etc....
          currentDateTime        --->  CFArgument "name"
)

Here's the same signature in cfml:


<cffunction name="calculateCompleteByDate" returntype="date" access="public">
	        <cfargument name="currentDateTime" type="date">
                ....

Open in new window




CFML Version:

<cffunction name="calculateCompleteByDate" returntype="date" access="public">
	<cfargument name="currentDateTime" type="date">
	
	<cfset Local.currentTime 	 = createTime( hour(arguments.currentDateTime), minute(arguments.currentDateTime), 0 )>
	<cfset Local.todaysDate  	 = dateFormat( arguments.currentDateTime, "yyyy-mm-dd")>
	<cfset Local.tomorrowsDate  = dateFormat( dateAdd("d", 1, arguments.currentDateTime), "yyyy-mm-dd")>
		
	<!--- Between midnight and 7:00 AM -> due same day at 15:30 --->
	<cfif (local.currentTime lte createTime(7,0,0))>
		<cfset Local.completeBy = Local.todaysDate &" 15:30:00" >
	<!--- Between 7:01 and 15:30 -> due same day at 23:00 --->
	<cfelseif (local.currentTime gte createTime(7,1,0) && local.currentTime lte createTime(15,30,0))>
		<cfset Local.completeBy = Local.todaysDate &" 23:00:00" >
	<!--- Otherwise it is between 15:31 and 23:59:59 -> due tomorrow at 15:30 --->
	<cfelse>
		<cfset Local.completeBy = Local.tomorrowsDate &" 15:30:00">
	</cfif>
	
	<!--- DEBUG / DEMO ONLY ---->
	<cfoutput>
		<br>[#dateTimeFormat(arguments.currentDateTime, 'yyyy-MM-dd HH:nn:ss tt')#] 
		--> #dateTimeFormat(Local.completeBy, 'yyyy-MM-dd HH:nn:ss tt')# 
	</cfoutput>
	
	<cfreturn parseDateTime(Local.completeBy, "yyyy-MM-dd HH:mm:ss")>
</cffunction>

Open in new window

0
 

Author Closing Comment

by:earwig75
ID: 41744323
You're the best, thank you!
0

Featured Post

How our DevOps Teams Maximize Uptime

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us. Read the use case whitepaper.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

I spent nearly three days trying to figure out how incorporate OAuth in Coldfusion for the Eventful API. Hopefully, this article will allow Coldfusion Programmers to buzz through the API when they need to. Basically, what this script does is authori…
Sometimes databases have MILLIONS of records and we need a way to quickly query that table to return the results me need. Sure you could use CFQUERY but it takes too long when there are millions of records. That is why SOLR was invented. Please …
Two types of users will appreciate AOMEI Backupper Pro: 1 - Those with PCIe drives (and haven't found cloning software that works on them). 2 - Those who want a fast clone of their boot drive (no re-boots needed) and it can clone your drive wh…

791 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question