Solved

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

Posted on 2016-08-03
7
55 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
How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

 
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

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

This is an updated version of a post made on my blog over 3 years ago. It is unfortunately, still very relevant as we continue to see both SQLi (SQL injection) and XSS (cross site scripting) attacks hitting some of the most recognizable website and …
CFGRID Custom Functionality Series -  Part 1 Hi Guys, I was once asked how it is possible to to add a hyperlink in the cfgrid and open the window to show the data. Now this is quite simple, I have to use the EXT JS library for this and I achiev…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …

762 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

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now