I want to send notifications to users in different timezones on a date and time they provide.
I haven't implemented anything yet, but I plan to create a timestamp column and store everything in UTC. At the time of submission, the user will select a timezone and I will calculate the offset, add it to the timestamp column, and voila.
I wish it were that simple, but my plan lacks DST. I have no way of finding out if the user is in DST or not.
How do I get around this? Do I need extra columns? Is there a better approach than what I'm planning?
You can use the java TimeZone object.
<cfset tzObj = createObject("java","java.util.TimeZone") >
You can get a list of available IDs e.g. "US/Pacific" by doing this
<cfset tzList = arrayToList(tzObj.getAvailableIDs()) >
If you can match the ID to your users region/time zone you can do the following:
tzToTest = "US/Pacific"
dateTotest = now()
<!--- determines if dateTotest in tzToTest is in DST --->
<cfset tz = tzObj.getTimeZone(tzToTest) />
<cfset isDaylightSavings = tz.inDaylightTime(dateTotest) />
Related
I am using Taffy framework for creating api endpoints. In one of my endpoint I need to display time in particular format say hh:mm:ss, I used timeformat method in CFC file to get the desired result, but when I hit the endpoint I am getting January, 01 1970 17:00:00. Any suggestions?
Note:For field "clientHoursOfOperationOpenTime" Time value is returned from Mysql, I am querying the DB in CFC file and formatting the clientHoursOfOperationOpenTimevalue.
<cfset var getLocationHours = QueryNew('') >
<cfquery name="getLocationHours" datasource="#appSettings.DSN#">
Select some fields here
</cfquery>
<cfset getLocationHours.clientHoursOfOperationOpenTime= "#timeFormat(getLocationHours.clientHoursOfOperationOpenTime, 'hh:mm:ss')#">
<cfreturn getLocationHours >
When I dump this field getLocationHours.clientHoursOfOperationOpenTime I am getting the formatted value. But when I use taffy, I am getting the format issue.
ColdFusion 9 using Access Database stores the Dates such as 1/12/2015, 2/22/2015, 1/21/2015 etc...
I am looking to only get Month results such as January only, Feb only etc...
I can easily pull the year only If I need it using:
<cfquery name="f" datasource="ds">
select * from master
where eventdate like '%#yr#%'
</cfquery>
Where year is like 2015 - I can easily get year.
But when I switch to:
where eventdate like '%1/%'
I get a Syntax FROM error - I can't get only January. Likely simple solution - but I'm missing it.
Thx for any help.
Use real dates, in a sane format.
yyyy-mm-dd is pretty much the only sane date format, whereas mm/dd/yyyy is pretty much the most insane date representation out there. Don't use that representation for any purpose except end user output.
<cfset date = Now()> <!--- or some other actual date -->
<cfset dtfrom = DateFormat(date, "yyyy-mm-01")>
<cfset dtuntil = DateFormat(DateAdd("m", 1, dtfrom), "yyyy-mm-01")>
<cfquery name="f" datasource="ds">
select * from master
where eventdate >= '#dtfrom#' and eventdate < '#dtuntil#'
</cfquery>
The advantage of using this form >= ... and < ... is that if you have an index on eventdate, it can be used for that. Almost every other variant of expressing the same condition (for example Month(eventDate) = ...) can't use an index.
You escape special characters in access using brackets like so:
WHERE evendate LIKE '%1[/]%'
Also, if your field is an actual DATE (doesn't sound like it) you can tease it out with month() as in:
WHERE MONTH(eventDate) = 1
You might also be able to convert/cast your character field into a data using ASDATE like so:
WHERE MONTH(asDate(eventdate)) = 1
There's the limit of my ancient access experience. good luck. :)
You can use the Format method available in Access.
Try this: Format([eventdate],"yyyy/mm/dd") or if you just want the month and don't care about the year, your query could look like this:
select * from master
where Format([eventdate],"mm") = 1
I'm not sure my title explains this very well. Frankly, I'm not sure how to put it into words, but here goes:
I am capturing variables from dynamically created form fields on another page, that have been submitted to a page containing the code below. So far, everything works as I want it to. I'm getting the dynamically named form fields. Now I need to add the subtotal dollar amounts together to create a grand total. Unfortunately, I can't figure out how to get the individual totals out of the loop so I can do the math for the final number, due to their dynamic nature.
This part of the code below generates the subtotals, and I need to be able to add all of them together to get a grand total, but I can't figure out how:
#dollarformat(val(getticket[item].ticketprice * form[item]))#
Maybe I need to take a different approach...suggestions/help appreciated.
Here's the full code:
<CFLOOP LIST="#form.fieldnames#" INDEX="item">
<cfoutput>
<cfquery datasource="outertixdb" name="getticket[item]">
select * from tickets
where ticketid = '#item#'
</cfquery>
#getticket[item].ticketname#: #dollarformat(getticket[item].ticketprice)# x #form[item]# = #dollarformat(val(getticket[item].ticketprice * form[item]))#<br/>
</cfoutput>
You would need to set the name attribute of your cfquery using the following format:
<cfquery datasource="outertixdb" name="#getticket[item]#">
To handle the total, you would first need a variable before the cfloop
<cfset total = 0 />
Then, inside the loop, you simply add the price of the ticket to the total
<cfset total = total + getticket[item].ticketprice />
Also, you should be using cfqueryparam in your query. You can read more about it here
Lastly, if you do not need all the data in the tickets table, do not use 'select *..', only pull pack the data that you need.
Not sure I completely understand, but it sounds like you are simply trying to look up a bunch of ticket records, by "id". Then display the individual costs, plus a grand total. If that is all your doing, just give the fields the same name: ticketID. For example:
<input name="ticketID" value="1" ...>
<input name="ticketID" value="22" ...>
<input name="ticketID" value="45" ...>
<input name="ticketID" value="16" ...>
Then the values will be submitted as a list ie 1,22,45,16, which you can feed into your query using an IN clause. That lets you grab all of the data in a single query. (Generally you want to avoid running queries within a loop because performing a separate database query for each id generates a lot of unnecessary overhead and degrades performance).
* Change the cfsqltype as needed
SELECT TicketID, TicketPrice
FROM YourTable
WHERE TicketID IN ( <cfquerparam value="#FORM.ticketID#"
list="true"
cfsqltype="cf_sql_integer">
)
UPDATE:
form[item] is the value of the quantity select from the previous page.
That is a confusing naming convention. I would recommend using a slightly more intuitive name like "quantity". Something more descriptive of the contents. You can still use the ticket id to generate unique names, ie quantity_#ticketID#. For example, using the same ticket id's as above:
<input name="quantity_1" ...>
<input name="quantity_22" ...>
<input name="quantity_45" ...>
<input name="quantity_16" ...>
Once you have the results, there are several ways to generate a grand total. The simplest being to initialize a variable before your loop, then increment it as you iterate. Use the query ticket ID to grab the quantity value from the FORM scope:
<cfset grandTotal = 0>
<cfoutput query="yourQuery">
<!--- extract quantity value --->
<cfset currQuantity = FORM["quantity_"& yourQuery.ticketID ]>
... display price ...
<cfset grandTotal += val(yourQuery.ticketPrice * currQuantity )>
</cfoutput>
GrandTotal <cfoutput>#grandTotal#</cfoutput>
I would recommend throwing out the whole dynamically named query thing.
<cfset total = 0>
<CFLOOP LIST="#form.fieldnames#" INDEX="item">
<cfquery datasource="outertixdb" name="getticket">
select * from tickets
where ticketid = <cfqueryparam cfsqltype="cf_sql_varchar" value="#item#">
</cfquery>
<cfset total += getticket.ticketprice />
<cfoutput query="getTicket">
#ticketname#: #dollarformat(ticketprice)# × #form[item]#
= #dollarformat(val(ticketprice * form[item]))#<br/>
</cfoutput>
</cfloop>
Output your total as needed
I am trying to use memcached for the first time but I have a few questions when it comes to queries with dynamic variables.
This is a sample of my code so far. I got everything working but if you see any mistakes on my code please let me know.
<cfoutput>
<cfset variables.memcachedFactory = createObject("component","memcachedfactory").init("127.0.0.1:11211")>
<cfset variables.memcached = variables.memcachedFactory.getmemcached()>
<cfset email = "sbcglobal"> //Pretend that this is a list with multiple choices for the user to choose from.
//The query below would have multiple outputs based on the selection of the user above
<cfquery name="test" datasource="#ds#">
select top 10 * from contact where email like '%#email#%'
</cfquery>
//Setting the key
<cfset set100 = variables.memcached.set(key="queryTest2",value=test,expiry="5000")>
//Getting the key
<Cfset test6 = variables.memcached.get("queryTest2")>
<br><br>this is the query test - did we retrieve it correctly? - <br />
<Cfdump var="#Test6#"><br />
</cfoutput>
Now, do i have to set a key for every possible outcome of the query? (which in my case would be a few hundred keys to cover all possible outcomes)
My understanding is that memcached saves the value to a key after the first request and after that you get the output without db calls.
If I use memcached in my case would it just be a waste of code since each query would be different based on the user's choice?
Also, how do you update the values in cache in case the output changes? Is this something that I would have to do manually? My database get 100's of transactions daily, a select * from contacts at 10 am will not have the same output at 5pm
The idea behind caching (in this case) is that you first check memcached, and if the key exists, you get the data from the cache. If it doesn't exist, you go to the database, get the data, stick it in memcached, then return it to the user.
For your use case here, you want a unique key for each unique record set you're returning. Take your example. If email address is the unique key you are using to identify a record set, then use that as the key in memcached. Pseudo-code:
<cfset results = variables.memcached.set(key="foo_#email#",value=test,expiry="5000")>
foo_ lets you provide a "namespace" for the keys you are putting into memcached, which makes it easier to manage and avoid key collisions.
I am trying to retrieve and store ID's for each item retrieved from my table, so I can use these ID's later. I tried nesting the queries, but this didn't, work. Here is my first query:
<CFQUERY datasource="MyDSN" name="MAIN2"> SELECT * from order_items where orderID= #orderID#</CFQUERY>
Now, if I output this query it displays, 1 and 117 which are the two ID's I need.
My next query is:
<CFQUERY datasource="MyDSN" name="MAIN3">select c.catalogueID,
c.product_name,
c.product_price,
c.description,
p.productID
from products p
join product_catalogue c on c.catalogueid = p.catalogueid
where p.productid = "#productID#"</CFQUERY>
But it is telling me that productID is not defined, it is obviously empty. I am just getting started using ColdFusion, so I am not sure the best way to store the values I need so I use them again. I also need to loop the second query to run for each ID 1 and 117, so twice.
Any suggestions on how to accomplish this would be greatly appreciated.
Thanks
My basic rule is that if I find myself using queries to create other queries or looping over a query to execute other queries; it is time to consider combining the queries.
I'm not sure what field you are using in the MAIN2 query to feed the MAIN3 query. So, I put in "productID" in the query below. You may have to change it to fit your field name.
<CFQUERY datasource="MyDSN" name="MAIN3">select c.catalogueID,
c.product_name,
c.product_price,
c.description,
p.productID
from products p
join product_catalogue c on c.catalogueid = p.catalogueid
where p.productid IN (SELECT DISTINCT productID from order_items where orderID= <cfqueryparam value="#orderID#" cfsqltype="CF_SQL_INTEGER">)
</CFQUERY>
You could also change this query to utilize a "join" to connect [order_items] to the query.
Lastly, you should use the <cfqueryparam> tag for the where clauses; this helps protect your query from sql injection attacks.
Whenever I'm caching data for use later, I tend to ask myself how I'll be using that data, and whether it belongs in another data type rather than query.
For instance, if I'm wanting a bunch of data that I'm likely to access via ID, I can create a structure where the key is the ID, and the data is another structure of a dataset. Then I'll save this structure in application scope and only refresh it when it needs to be. This is zippy fast and so much easier to grab with
rather than querying for it every time. This is especially useful when the query that creates the original data set is kind of a resource hog with lots of joins, sub-queries, magical cross-db stored procedures, but the datasets returns are actually fairly small.
So creating your products structure would look something like this:
<CFQUERY datasource="MyDSN" name="MAIN3">
SELECT
c.catalogueID,
c.product_name,
c.product_price,
c.description,
p.productID
FROM products p
JOIN product_catalogue c
ON c.catalogueid = p.catalogueid
WHERE p.productid = <cfqueryparam value="#ProductID#" cfsqltype="cf_sql_integer">
</CFQUERY>
<cfset products = structNew() />
<cfset item = structNew() />
<cfloop query="MAIN3">
<cfif NOT structKeyExists(products, productID)>
<cfset item = structNew() />
<cfset item.catalogueID = catalogueID />
<cfset item.product_name = product_name />
<cfset item.product_price = product_price />
<cfset item.description = description />
<cfset products[productID] = structCopy(item) />
</cfif>
</cfloop>
<cfset application.products = structCopy(products) />