How to createDateTime from passed arguments date and time? - datetime

I have form where user can pick start/end date and time, after from is submitted I want to create createDateTime and use passed arguments. So I tried this way but I got only date stored in my DB. Here is my code:
<cfargument name="DateFrom" type="date" required="yes">
<cfargument name="DateTo" type="date" required="yes">
<cfargument name="TimeFrom" type="string" required="yes">
<cfargument name="TimeTo" type="string" required="yes">
<cfset StartDateTime = createDateTime(year(arguments.DateFrom), month(arguments.DateFrom), day(arguments.DateFrom), hour(arguments.TimeFrom), minute(arguments.TimeFrom), 0)>
<cfset EndDateTime = createDateTime(year(arguments.DateTo), month(arguments.DateTo), day(arguments.DateTo), hour(arguments.TimeTo), minute(arguments.TimeTo), 0)>
<cfquery name="addReservation" datasource="test">
Insert Into tableReserv(PickDateTime,DropDateTime)
Select <cfqueryparam cfsqltype="cf_sql_date" maxlength="12" value="#StartDateTime#">,
<cfqueryparam cfsqltype="cf_sql_date" maxlength="12" value="#EndDateTime#">
Where Not Exists(Select UserID
From aviRequests
Where PickDateTime < <cfqueryparam cfsqltype="cf_sql_timestamp" value="#StartDateTime#">
And DropDateTime > <cfqueryparam cfsqltype="cf_sql_timestamp" value="#EndDateTime#">
)
Select SCOPE_IDENTITY() As RecID;
</cfquery>
For some reason my StartDateTime and EndDateTime do not create date and time together. Here is how my value looks stored in DB:
Start:2016-01-20 00:00:00.000
End:2016-01-21 00:00:00.000
Is my createDateTime properly formatted or something else is wrong in my code?

This is from your question:
<cfset StartDateTime = createDateTime(year(arguments.DateFrom)
, month(arguments.DateFrom)
, day(arguments.DateFrom)
, hour(arguments.TimeFrom)
, minute(arguments.TimeFrom), 0)>
The date part is fine because your date arguments are dates. The time part is not because your time arguments are strings. You have to process that string to get the hours and minutes.
In the comments, you said your time strings resemble 7 AM. You have to process this to get the correct number of hours and minutes. Things you have to consider are:
Are the last two characters AM or PM?
Does the number of hours have 1 or 2 digits?
If it's not at the top of the hour, how are minutes represented?
Having said all that, you are probably not the first person to have this problem. Look at cflib.org to see if there a function you can use.

Related

ColdFusion - Date/Time - Insert Available Slots for Date Range

Having headache day again. Need to make some changes to some things and populate available stuff first. Basically from when something is open till it closes. And add available spots every 15 minutes.
I can get the start date and end date populating - but can't get the inside loop populating the increment times that need to be inserted... Little lost here... Any help is appreciated...
Start Date and End Date come from a cfform - works fine...
Start Date:<br>
<cfinput type="datefield" name="startDate" required="true" message="Start Date Required">
<br><br>
End Date:<br>
<cfinput type="datefield" name="EndDate" required="true" message="End Date Required">
<cfloop index="dtToday" from="#StartDate#" to="#EndDate#">
<cfoutput>
<br>#DateFormat(dttoday)#<br>
<cfloop index="incr" from="#TimeFormat(sadd.topen)#" to="#TimeFormat(sadd.tclose)#" step="#CreateTimeSpan( 0, 0, sadd.increment, 0 )#">
[#TimeFormat(incr)#]
Do Database Insert of Date/Time at increments
</cfloop>
<cfset schdate = #DateAdd('d', 1, '#schdate#')#>
</cfoutput>
</cfloop>
I modified your code so that I could test it quickly. CF Live shows this to work in Railo and CF.
It isn't clear where your trouble is coming from because I didn't make any drastic changes to your code.
<!--- You can get rid of these two form declarations, and the sadd declaration. This was just mimicking your data. --->
<cfset form.startdate = "11/17/95">
<cfset form.enddate = "12/20/95">
<cfset sadd = {topen= "13:00", tclose= "17:00", increment = 15}>
<cfif isDate(form.startdate) and isDate(form.enddate)>
<cfloop index="dtToday" from="#form.StartDate#" to="#form.EndDate#">
<cfoutput>
<br>#DateFormat(dttoday)#<br>
<cfloop index="incr" from="#TimeFormat(sadd.topen)#" to="#TimeFormat(sadd.tclose)#" step="#CreateTimeSpan( 0, 0, sadd.increment, 0 )#">
[#TimeFormat(incr)#] - Do Database Insert of Date/Time at increments<br>
</cfloop>
<!---<cfset schdate = #DateAdd('d', 1, '#schdate#')#>--->
</cfoutput>
</cfloop>
<cfelse>
One or both of the dates entered is invalid.
</cfif>
I changed:
I form scoped startdate and enddate, it shouldn't have any negative impact on your code, it just seemed logical that startdate. While this is proper practice, the only way it could be causing you issues is if you had variables in multiple scopes with the name of startdate and/or enddate. (Safety against that, and security against exploitation of that is exactly why scoping your variables is best practice).
For my sample data, I set start time to 13:00 (1:00 PM) and end time to 17:00 (5:00). You can also use normal format of "1:00 PM" and "5:00 PM".
I commented out schDate because its use wasn't apparent here.
I added a sadd scope to mimic what it seems like your data probably is. In the future, give samples of what your data actually looks like :)

filter datetime based on date in different format

I want to filter the gridview by comparing a datetime column of type datetime in sql server with a date textbox.
The datetime column in sql server is being stored/displayed (as default) in the yyyy-mm-dd hh:mm:ss.sss format.
However the date textbox is in the format dd/mm/yyyy.
<asp:TextBox ID="date_tb" runat="server" TextMode="Date"></asp:TextBox>
I tried using
FilterExpression="CONVERT(VARCHAR, [ScheduledDateTime], 105) LIKE '%{0}%'">
but it didn't work.
FilterExpression="CONVERT([ScheduledDateTime], 'System.String', 105) LIKE '%{0}%'">
also did not work.
I then tried using
SelectCommand="SELECT [ScheduledDateTime], CONVERT(VARCHAR, [ScheduledDateTime], 105) as d ... FROM table1
FilterExpression="d LIKE '%{0}%'">
but it didn't work as well.
edit:
I have changed the ControlParameter into <asp:ControlParameter Name="ScheduledDateTime" ControlID="date_tb" PropertyName="Text" type="DateTime"/> so I no longer have to be concerned about the date format.
Although now there is a problem to comparing date with datetime.
This is what you can do
select * from MyTable where convert(varchar, a, 103) = '03/24/2013'
You probably don't want to compare date to the seconds. The right side of equasion comes from the textbox
If you want it really good, then do this
Dim sql as String = "select * from MyTable where convert(varchar, a, 103) = #1"
#1 is a parameter that you want to add to Command Object and it will have value of your textbox.
http://msdn.microsoft.com/en-us/library/ms187928.aspx
Use format 103 to convert a 'dd/mm/yyyy' string to a date. You are using 105, which is 'dd-mm-yyyy'
You should not need to do any string conversion to compare DateTimes in SQL. When you use LIKE, SQL will convert the DateTime into a string value and you need to make sure that you're using the same format on both ends. If your source data does not include any time component, then you should just be able to do:
FilterExpression="ScheduledDateTime = {0}"
If it does include time components and you want to truncate the time, you can try:
FilterExpression="dateadd(dd, datediff(dd,0, ScheduledDateTime ), 0) = {0}"
or
FilterExpression="ScheduledDateTime BETWEEN {0} AND dateadd(dd, 1, {0})"

ColdFusion: How to parse dd/mm/yyyy formated date?

I found the ParseDateTime function but it only parses a date/time string according to the English (U.S.) locale conventions.
How to parse the date which is in dd/mm/yyyy format?
Try out this:
<cfset TestdateFrom = ParseDateTime("10/9/2010") />
<cfloop index="i" from="1" to="30" step="1">
<cfset TestdateFrom = DateAdd( "d", 1, TestdateFrom ) />
#TestdateFrom#<br/>
</cfloop>
In CF9 there is a LSParseDateTime function.
I don't know whether this will help me or not.
At last should I use java library for this issue?
Looks like this is working:
<cfset formatter = createObject("java","java.text.SimpleDateFormat")>
<cfset formatter.init("dd/MM/yyyy")>
<cfset newDate = formatter.parse("10/09/2010")>
#newDate#
Any other suggestions?
If your format is consistent, you can also do something like this:
<cfset dy=listGetAt(dateString,1,"/")>
<cfset mo=listGetAt(dateString,2,"/")>
<cfset yr=listGetAt(dateString,3,"/")>
<cfset myDate=createDate(yr,mo,dy)>
But, really, Tim's answer is the best.
I've had success with this technique for dealing with (UK formatted) dates entered as free text:
<cfset SetLocale("English (UK)")>
<cfset valid = true>
<!--- Convert DD-MM-YYYY or DD.MM.YYYY to DD/MM/YYYY --->
<cfset dt = replacelist(dt, ".,-", "/,/")>
<!--- count date elememnts (must be 3 - LSParseDateTime will make potentially incorrect assumptions otherwise) --->
<cfif listlen(dt, "/") neq 3>
<!--- wrong number of elements --->
<cfset valid = false>
<cfelse>
<!--- Correct number of elements so try to interpret as date/time object --->
<cftry>
<cfset dt = LSParseDateTime(dt)>
<cfcatch type="Expression">
<cfset valid = false>
</cfcatch>
</cftry>
</cfif>
If valid is true at the end of this, the string date representation in dt has been converted to a date/time object. The replacelist step allows for the date to be entered as DD.MM.YYYY or DD-MM-YYYY as well as DD/MM/YYYY.
You need to use lsParseDateTime(). This is the locale specific date parser.
You can either pass a locale straight into the second parameter of the function or use setlocale() to set it for the request.
You'll probably find it useful to look at the other LS prefixed functions too.

displaying date field in the value of a datefield form

I am using CF8 and MySQL 5.
I have a form with several date fields (one for each day and the form may have 10+ days of data on it) that the user can select different dates for and they all have different var names within a loop.
The default values for these date fields is null in the DB. I can insert a date into a DATE column in MySQL with no issues and have verified that the data is inserted correctly (using cfqueryparam DATE also).
I have the 'value' of the form datefield set to the variable name and can not get the value to show up.
The date updates to the DB fine every time it is entered, but when the form posts back to itself the date fields are blank (other non-date fields work fine and changes show up).
Then when I submit it with the blank date fields the value is set back to null in the DB (empty string in the form) since the form field does not pull the value from the DB.
The field name (ses#i#Date) shows up correctly (ses1Date, ses2Date, etc...) in the form with the right value when I dump it.
<cfloop from="1" to="#form.days#" index="i"> <cfinput type="datefield" name="ses#i#Date" value="#DateFormat(qGetUWHeader["ses#i#Date"],"yyyy-mm-dd")#" /> ....
Thanks for your time and help.
To reference dynamic column names, you can use array notation. But as I mentioned, you must supply a row number.
#queryName["columnName"][rowNumber]#
If you know the query contains one (1) record, only, you could use the query object's "recordCount" property as the row number. Alternatively, you could hard code the row number "1". (Personally, I dislike hard-coding). But any one of these should work.
<!--- pick ONE option --->
<cfloop from="1" to="#form.days#" index="i">
<!--- syntax option 1 --->
<cfinput type="datefield" name="ses#i#Date" value="#DateFormat(qGetUWHeader['ses#i#Date'][qGetUWHeader.recordCount], 'yyyy-mm-dd')#" />
<!--- syntax option 2 --->
<cfinput type="datefield" name="ses#i#Date" value="#DateFormat(qGetUWHeader['ses'& i &'Date'][qGetUWHeader.recordCount],'yyyy-mm-dd')#" />
<!--- syntax option 3 --->
<cfinput type="datefield" name="ses#i#Date" value="#DateFormat(qGetUWHeader['ses#i#Date'][1], 'yyyy-mm-dd')#" />
</cfloop>
If however, you are looping through multiple records in the qGetUWHeader query, you can use the query object's "currentRow" property as the row number. But based on the field naming convention, I am guessing the query only contains one (1) record.
EDIT:
I forgot about the initial nulls. You could apply a simple if condition, and only call DateFormat() if the query value is a valid date.
<cfloop from="1" to="#form.days#" index="i">
<cfset dateValue = qGetUWHeader["ses#i#Date"][qGetUWHeader.recordCount]>
<!--- if this is a valid date, format the value --->
<cfif IsDate(dateValue)>
<cfset dateValue = dateFormat(dateValue, "yyyy-mm-dd")>
</cfif>
<cfinput type="datefield" name="ses#i#Date" value="#dateValue#" /><hr>
</cfloop>
Another option is to format the dates in your SQL. Then you would not need to use CF's DateFormat() function. Just be aware that the new result would be a string, not a datetime object.
SELECT DATE_FORMAT(ses1Date, '%Y-%m-%d') AS ses1Date, ....
Where is "qGetUWHeader" defined?
When a form is posted, all values will be posted to the form scope. Therefore in order to display a value from a postback, you should reference the form scope unless you're copying the value into 'qGetUWHeader'. Even though the correct date from the form is being stored in the form scope, you're displaying the default value from qGetUWHeader on post back, unless you're doing something there I'm not aware of. Then the next time you post your form, the default value overrides the prior entered value.
<!--- In order to reference FORM values, you must CFPARAM them first to define the default value. --->
<cfparam name="form.days" default="10">
<cfloop from="1" to="#form.days#" index="i">
<cfparam name="form['ses#i#Date']" default="">
</cfloop>
<!--- Display the Form --->
<cfform action="#cgi.SCRIPT_NAME#" method="post">
<cfloop from="1" to="#form.days#" index="i">
<cfset thisFieldName = "ses" & i & "Date">
<cfset thisFieldValue = form["ses#i#Date"]>
<cfoutput>#thisFieldName#</cfoutput> <!--- For Debugging --->
<cfinput type="datefield" name="#thisFieldName#" value="#thisFieldValue#" /><br /><br />
</cfloop>
<input type="submit" name="submit" value="submit" />
</cfform>
<!--- Debug --->
<cfdump var="#form#">

ISNULL Date month

I have two dropdownlists, one with months and the other one with year. The user selects the submit month and year for the items they want to retrieve. In database the date is entered in full eg. 01/12/2009. There is an option for "All years" and "All months" in the dropdown lists but when users choose either they get null results. Many thanks. This is my query:
SELECT ItemID, YEAR(Submit) AS SubmitYear, MONTH(Submit) AS SubmitMonth
FROM Items
WHERE (YEAR(Submit) LIKE ISNULL(#YearPay, ''))
AND (MONTH(Submit) LIKE ISNULL(#MonthPay, ''))
My parameter are:
<asp:ControlParameter ControlID="DropDownList1" DefaultValue="" Name="YearPay" PropertyName="SelectedValue" />
<asp:ControlParameter ControlID="DropDownList2" DefaultValue="" Name="MonthPay" PropertyName="SelectedValue" />
Here's one way to solve the problem:
SELECT ItemID, YEAR(Submit) AS SubmitYear, MONTH(Submit) AS SubmitMonth
FROM Items
WHERE (YEAR(Submit) = #YearPay OR #YearPay IS NULL)
AND (MONTH(Submit) = #MonthPay OR #MonthPay IS NULL)
That way, if you pass in NULL for either variable, that part of the WHERE clause will return true.
One fairly quick way is to make sure #YearPay and #MonthPay are INTEGER datatypes, then pass in (e.g.) -1 to indicate "ALL", so your query would become:
SELECT ItemID, YEAR(Submit) AS SubmitYear, MONTH(Submit) AS SubmitMonth
FROM Items
WHERE (YEAR(Submit) = #YearPay OR #YearPay = -1)
AND (MONTH(Submit) = #MonthPay OR #MonthPay = -1)
However, for overall performance, I'd personally steer away from doing it in this way, using YEAR() and MONTH() as you won't get good index usage. Instead, I'd be tempted to change the query to just accept a date range, whereby the to and from dates are generated by your .NET code based on the selected dropdown items.
e.g.
SELECT ItemID, YEAR(Submit) AS SubmitYear, MONTH(Submit) AS SubmitMonth
FROM Items
WHERE (Submit >= #FromDate OR #FromDate IS NULL)
AND (Submit < #ToDate OR #ToDate IS NULL)
So, using the following examples for month/year selections:
Jan 2009 would result in #FromDate = '2009-01-01', #ToDate - '2009-02-01'
Any month, 2009 would result in #FromDate = '2009-01-01', #ToDate = '2010-01-01'
Any month, any year would result = #FromDate = NULL, #ToDate = NULL
Try this
select * from sys.tables where name like ''
and this
select * from sys.tables where name like '%%'
That being said, I totally agree with Nebakanezer's comment (and solution).

Resources