Solved

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

Posted on 2016-08-03
7
84 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
MIM Survival Guide for Service Desk Managers

Major incidents can send mastered service desk processes into disorder. Systems and tools produce the data needed to resolve these incidents, but your challenge is getting that information to the right people fast. Check out the Survival Guide and begin bringing order to chaos.

 
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

Hi, Even though I have created this Tutorial on My personal Blog, Some people might not able to find my website, So here i am posting it again Today, from the topic it is very clear that i will be showing you here the very basic usage of how we …
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 …
Email security requires an ever evolving service that stays up to date with counter-evolving threats. The Email Laundry perform Research and Development to ensure their email security service evolves faster than cyber criminals. We apply our Threat…

685 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