Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

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

Posted on 2016-08-03
7
Medium Priority
?
104 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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 2000 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
Application Discovery Service in AWS

In the era of the cloud, customers migrating away from their existing on-premise infrastructure. This requires lots of planning, strategies, and effort to identify their existing resources and determine how best to migrate.  Datacenter migrations happen in four phases -

 
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

On Demand Webinar: Networking for the Cloud Era

Did you know SD-WANs can improve network connectivity? Check out this webinar to learn how an SD-WAN simplified, one-click tool can help you migrate and manage data in the cloud.

Question has a verified solution.

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

Today, I was working on some optimization and spam-stopping techniques when I encountered Ben Nadel's post to reduce spam feature using Math (http://www.bennadel.com/blog/197-How-I-Stop-Spammers-On-My-ColdFusion-Blog.htm). While this method is not o…
Hi. There are several upload tutorials using jquery and coldfusion. I found a very interesting one here Upload Your Files using Jquery & ColdFusion and Preview them (http://www.randhawaworld.com/) . I did keep the main js functions but made sever…
This course is ideal for IT System Administrators working with VMware vSphere and its associated products in their company infrastructure. This course teaches you how to install and maintain this virtualization technology to store data, prevent vuln…
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…

705 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