I'm having some trouble with the CreateDate() function, it's just erroring and I have no idea why!
I am running this query to get all of the dates from news stories so that I can create a news archive monthly.
<cfquery name="selectNews" datasource="#Request.dsn#">
SELECT Month(NewsDate) AS theCount
FROM news
GROUP BY Month(NewsDate)
</cfquery>
Then when I output it, I'm trying to output it in the following format
Aug 2012
Sept 2012
Oct 2012
So I'm using the following code to try to output this list
<ul>
<cfloop query="selectNews">
<cfoutput>
<cfset theDay = DateFormat(Now(), 'dd')>
<cfset theMon = theCount>
<cfset theYear = DateFormat(Now(), 'yyyy')>
<li>#CreateDate(theYear, theMon, theDay)#</li>
</cfoutput>
</cfloop>
</ul>
It works fine for the first item, it will output Aug 2012, however it will then error, saying this
Error Occurred While Processing Request
MONTH
Which to me, at least, is useless!
My guess is that the SQL Month() function is returning a 0 for January and CreateDate expects a 1 for January.
Edit
<ul>
<cfloop query="selectNews">
<cfset theDay = Day(Now())>
<cfset theMon = #theCount#>
<cfset theYear = Year(Now())>
<cfoutput><li>#DateFormat(CreateDate(theYear, theMon, theDay), "mmm yyyy")#</li></cfoutput>
</cfloop>
</ul>
Edit
This seems to be working but only with odd numbered months
<cfset months = [1,3,5] />
<ul>
<cfloop array="#months#" index="currentmonth">
<cfoutput><li>#DateFormat(CreateDate(Year(Now()), currentmonth, Day(Now())), "mmm yyyy")#</li></cfoutput>
</cfloop>
</ul>
This was me being an idiot. I was using DateFormat(Now(), 'dd'), which is a huge stupid mistake, seeing as there is only 30 days in September. It was running CreateDate(2012, 09, 31), which obviously won't work!
Related
I am using ColdFusion 2016. What code is needed to get the previous Monday in the previous week and the previous Friday in the previous week?
This code below gets the previous Monday, but I want the previous Monday in the previous week. Same thing for Friday.
<cfset currentDate = Now() />
<cfset mostRecentMonday = dayOfWeek(currentDate) gt 1 ? dateAdd("d", 2-
dayOfWeek(currentDate), currentDate) : dateAdd("d", -6, currentDate) />
You just need to simplify your solution.
<cfset currentDate = Now() />
<cfset obj = {}>
<cfset todaydayOfWeek = dayOfWeek(currentDate)>
<cfset mondayOffset = (2-todaydayOfWeek)-7>
<cfset fridayOffset = (6-todaydayOfWeek)-7>
<cfset obj.mostRecentMonday = dateAdd("d", mondayOffset, currentDate)>
<cfset obj.mostRecentFriday = dateAdd("d", fridayOffset, currentDate)>
<cfdump var="#obj#">
DEMO
You can get last Friday like,
<cfset today=dayofweek(now())>
<span>Last Friday is:</span>
<cfif today eq 7>
<span>#dateformat(dateAdd("d",-1,now()))#</span>
<cfelse>
<span>#dateformat(dateAdd ("d",-(1+today),now()))#</span>
</cfif>
Last Monday :
<cfif today eq 7>
<span>#dateformat(dateAdd("d",-5,now()))#</span>
<cfelse>
<span>#dateformat(dateAdd ("d",-(5+today),now()))#</span><br>
</cfif>
#user1669296, make sure, your last Monday also return wrong value.For ex. Today ( 06-sep-2018) is Monday if you run that code it's will return today date only not last Monday. So please correct it too.
Is there a way to display all the days of the week using coldfusion from Sunday through saturday. Any pointers will be appreciated thanks
<cfoutput>
<cfloop from="1" to"7" index="dow">
#dayOfWeekAsString(dow)#
</cfloop>
</cfoutput>
We religiously use cfqueryparam in our SQL queries.
Some of my predecessors seem to have been a little overzealous when using it with direct values rather than variables.
Isn't
record_is_deleted_bt = <cfqueryparam cfsqltype="cf_sql_bit" value="0">
overkill? I mean, there's no chance for SQL injection and I don't think that using a bind variable here does anything helpful vis-à-vis improving performance in the database. Wouldn't it be just as reasonable to do
record_is_deleted_bt = 0
?
Is there any advantage to using cfqueryparam in such an instance, besides ingraining the habit of using it? Is there a disadvantage?
No, this is not overkill. cfqueryparam's first job is data binding. It helps in sql injection prevention is just the add-on bonus. The prepared statements through data binding execute faster. You are wrong to assume that it is there to help on sql attack prevention only.
Important Note:
I am adding Test case provided by #Dan Bracuk on an oracle db.
<cfquery name="without" datasource="burns">
select count(*)
from burns_patient
where patientid = 1
</cfquery>
<cfquery name="with" datasource="burns">
select count(*)
from burns_patient
where patientid = <cfqueryparam cfsqltype="cf_sql_integer" value="1">
</cfquery>
<cfscript>
TotalWithout = 0;
TotalWith = 0;
</cfscript>
<cfloop from="1" to="1000" index="i" step="1">
<cfquery name="without" datasource="burns" result="resultwithout">
select count(*)
from burns_patient
where patientid = 1
</cfquery>
<cfquery name="with" datasource="burns" result="resultwith">
select count(*)
from burns_patient
where patientid = <cfqueryparam cfsqltype="cf_sql_integer" value="1">
</cfquery>
<cfscript>
TotalWithout += resultwithout.executiontime;
TotalWith += resultwith.executiontime;
</cfscript>
</cfloop>
<cfdump var="With total is #TotalWith# and without total is #TotalWithout#.">
The with total ranges from 700 to 900 total milliseconds. The without total ranges from 1800 to 4500 milliseconds. The without total is always at least double the with total.
I am working on a tax project. Taxes are broken down into quarters. the months the taxes are run are March, June, Sept, and December. once run my website displays when the taxes will run again. my problem is that in my results page when the next run date is December instead of displaying 12-2012 i get something that looks like 0-2012.
Here is my code:
<td style="white-space: nowrap;"> #stec_mysql_search_results.cover_date# </td>
<td style="white-space: nowrap;"> <cfif "" neq stec_mysql_search_results.next_run>0<cfset temp_next_run = stec_mysql_search_results.next_run MOD 4><cfswitch expression="#temp_next_run#">
<cfcase value="1">3</cfcase>
<cfcase value="2">6</cfcase>
<cfcase value="3">9</cfcase>
<cfcase value="4">12</cfcase>
</cfswitch>-<cfif 4 lt stec_mysql_search_results.next_run>#year(now())+1#<cfelse>#year(now())#</cfif></cfif> </td>
Here is the output when you view source:
<td style="white-space: nowrap;"> 07-16-2012 </td>
<td style="white-space: nowrap;"> 0-2012 </td>
The key to the problem is your code is expecting 12 mod 4 to give 4, when it gives 0.
The code you've provided has been formatted with hardly any line-breaks in, which is a stupid way of writing code because it makes it very difficult to maintain (in terms of readability, modification, and even simple revision comparisons), especially when later developers have to come along and understand what's going on.
Make sure you use newlines - particularly if that means fixing code written by others. If the output of whitespace is an issue then the ideal solution is generally to put the logic in a function (and use output=false), though you can also use <cfsilent>..</cfsilent> blocks, appropriately placed comments <!--- --->, and other means.
Here is the relevant part of your code translated to something actually readable:
<cfif "" neq stec_mysql_search_results.next_run>
0
<cfset temp_next_run = stec_mysql_search_results.next_run MOD 4>
<cfswitch expression="#temp_next_run#">
<cfcase value="1">3</cfcase>
<cfcase value="2">6</cfcase>
<cfcase value="3">9</cfcase>
<cfcase value="4">12</cfcase>
</cfswitch>
-
<cfif 4 lt stec_mysql_search_results.next_run>
#year(now())+1#
<cfelse>
#year(now())#
</cfif>
</cfif>
The 0 you are seeing in your results is the hard-coded one just inside the cfif.
Because the switch doesn't have a case for 0 it is not outputting anything.
To make the existing code work, just change the cfcase for 4 to 0.
However, since this is dealing with quarters, I don't think you're calculating what you mean to be.
Here is what simply changing the cfcase from 4 to 0 would result in...
January = January
February = February
March = March
April = December
May = January
June = February
July = March
August = December
September = January
October = February
November = March
December = December
When what you probably want is this:
January = March
February = March
March = March
April = June
May = June
June = June
July = September
August = September
September = September
October = December
November = December
December = December
Which can be done really simply with 3*ceiling(next_run/3).
If this assumption is correct, there's a significantly better way to write your code:
<td>#calculateNextRunQuarter(stec_mysql_search_results.next_run)#</td>
<cffunction name="calculateNextRunQuarter()" returntype="String" output=false>
<cfargument name="NextRunMonth" type="Numeric" required />
<cfset var Quarter = 3*ceiling(Arguments.NextRunMonth/3) />
<cfset var TheYear = Year(Now()) />
<cfif Arguments.NextRunMonth GTE 4 >
<cfset TheYear = TheYear + 1 />
</cfif>
<cfreturn Right('0'&Quarter,2) & '-' & TheYear />
</cffunction>
And because the logic is all inside a function with output=false there's no stray whitespace and the code is still perfectly readable
cfcase will accept a list, maybe you're over complicating it, why not do this:
<cfswitch expression="#stec_mysql_search_results.next_run#">
<cfcase value="1,2,3">3</cfcase>
<cfcase value="4,5,6">6</cfcase>
<cfcase value="7,8,9">9</cfcase>
<cfcase value="10,11,12">12</cfcase>
</cfswitch>
What is the quickest way in ColdFusion to get first and last day of quarter?
There doesn't seem to be a built in function for this.
First day of quarter:
FirstDayOfQuarter = CreateDate(year, (quarter-1)*3 + 1, 1)
Last day of quarter:
LastDayOfQuarter = DateAdd("d", -1, DateAdd("m", 3, FirstDayOfQuarter))
I have a feeling that your question might be more complex that it appears... for most purposes these values are a known set - no need to calculate:
Quarters:
January 1 - March 31
April 1 - June 30
July 1 - September 30
October 1 - December 31
Since the set is known in advance there's no real need for a function for this - determine in which date a quarter falls is a simple series of "if" statements (psuedocode):
if date > Oct 1 then Q4 else
if date > Jul 1 then Q3 else
if date > Apr 1 then Q2 else
if date > Jan 1 then Q1
(You do the check backwards in this case to check for the most restrictive match first. Although, as Kimvais points out, there is a function to do exactly that already in CFML.)
It should be essentilly the same for other "quarter" systems unless those dates are calculated in some way.
If I've missed the mark feel free to add comment to clarify.
The problem is that "quarter" is a relative term, while many organizations follow the default quarter breakdown of a year starting Jan 1 through Dec 31, many other organizations follow other quarters.
For example most retail organizations. Particularly those that depend on Christmas, don't want to be spending time doing end of quarter/year financials in december. They also want the entire holiday season (including the 2 weeks afterwards) on the same books as the rest of the season. So for them the "year" begins Feb 1.
The U.S. federal government and most of the states begin their financial year Oct 1 because of the way the legislature, elections and budgets work.
So a single function that always worked off of just one quarter layout would never work. Any of the functions listed in the other answers are fine I'm sure as long as your program is only dealing with one set. But if your coding a general use application then you may want to make it configurable.
Looks like there is a function for finding out the Quarter, based on this you could hardcode these?
I don't think there are built in functions for this - it's not clear whether you're looking for the numeric day of month or the string day of month (e.g. Monday). Anyway, this may be a little over-the-top - two functions which require an integer quarter value, and return the first and last dates of the quarter for further manipulation:
<cffunction name="QuarterFirstDate" returnType="date">
<cfargument name="quarternumber" required="yes" type="numeric">
<cfargument name="yr" type="numeric" default="2009">
<cfargument name="startmonth" type="numeric" default="1">
<cfset firstDate = DateAdd("m",startmonth-1,CreateDate(yr, ((quarternumber-1)*3)+1, "1"))>
<cfreturn firstDate>
</cffunction>
<cffunction name="QuarterLastDate" returnType="date">
<cfargument name="quarternumber" required="yes" type="numeric">
<cfargument name="yr" type="numeric" default="2009">
<cfargument name="startmonth" type="numeric" default="1">
<cfset lastDate = DateAdd("m",startmonth-1,CreateDate(yr, quarternumber*3, DaysInMonth(CreateDate(yr, quarternumber*3, "1"))))>
<cfreturn lastDate>
</cffunction>
<cfset year = "2009">
<cfset startmonth = "1">
<cfloop index="quarter" from="1" to="4">
<cfoutput>
<h2>Quarter #quarter#</h2>
#DateFormat(QuarterFirstDate(quarter, year, startmonth))#, day #DayOfYear(QuarterFirstDate(quarter, year, startmonth))#, #DayOfWeekAsString(DayOfWeek(QuarterFirstDate(quarter, year, startmonth)))#<br />
#DateFormat(QuarterLastDate(quarter, year, startmonth))#, day #DayOfYear(QuarterLastDate(quarter, year, startmonth))#, #DayOfWeekAsString(DayOfWeek(QuarterLastDate(quarter, year, startmonth)))#<br />
</cfoutput>
</cfloop>
edit: updated to allow a quarter start month to be specified
How about?
<cfset dt = now()>
<cfset DateLastQuarter = DateAdd("m",-3,dt)> <!--- Any date three months ago falls in previous quarter --->
<cfset quarterNumber = (month(DateLastQuarter)-1)\3+1> <!--- range from quarter 1-4 --->
<cfset StartQuarterMonth = (quarterNumber-1)*3+1> <!--- start of quarter month-number where Jan=1 (Mathematical magic) --->
<cfset LastQuarterFrom = CreateDate(year(DateLastQuarter),StartQuarterMonth,1)>
<cfset LastQuarterTo = DateAdd("d",-1,DateAdd("m",3,LastQuarterFrom))> <!--- the day before three months later --->
this above returns the first date in the previous quarter in LastQuarterFrom
and the last date in the previous quarter in LastQuarterTo