Minimum date for WDDX - coldfusion

I recently had a User enter a data of 6/13/204. SQL Server 2008 happily stored the date. The date was later retrieved and serialized to WDDX. It was encoded as
<field name='BASECYCLEDATE'><dateTime>204-6-13T0:0:0-8:0</dateTime></field>
Later when I deserialized it, I get
WDDX packet parse error at line 1, column 8772..
Invalid date string 204-6-13T0:0:0-8:0.
...
614 : </cfscript>
615 :
616 : <cfwddx action = "wddx2cfml" input = "#qryLabel.Config#" output = "stDat">
My question is, what is the minimum date to deserialize dates in WDDX?

Edit:
To answer your original question, that encoded string is wrong. The serialized dates should be in ISO8601 format, meaning they should have four digit years. A cursory test suggests cfwddx rejects any non-four digit years ie years < 1000 or > 9999.
SQL Server stores the date as 0204.
No, sql server does not store dates as formatted strings. Internally, they are stored as numbers. Ignoring validation for a moment, the cause is strictly on the CF side. When serializing that date into a wddx string, CF fails to generate the leading zero required by ISO8601. So the resulting string 204-6-13T0:0:0-8:0 is malformed and that is why the deserialization fails. That said, since that date range is not valid for your application, you should probably add some validation to reject invalid values like that one.

SQL Server stores the date as 0204. Apparently ColdFusion converts 0204 into 204. If users start doing this often, I will add an additional check to the data coming in. If necessary, I will
<cfif year(basecyledate) LT 1000>
...
</cfif>

Related

Sitecore date comparison doesn't return expected results

I'm trying to return a list of courses using an iqueryable query but am having issues with some date comparisons.
I'm currently using the code
query = query.Where(r => r.EndDate >= DateTime.UtcNow);
which returns courses with dates in the future, however it will not return courses that end on the same day with a time ending later than the time returned by DateTime.UtcNow.
Any ideas what I am doing wrong?
I've just used Luke to check the index and if I use
end_date:[20170531t092205609z TO *]
I get back the exact results I need, however in the logs the actual query uses
+end_date:[20170531t092205609z TO *] +_template:a84b75fccac64eafa746f4b71e628adc - Filter :
I then get more results back including the course I was missing.
a) Why do I get more results back using the second query?
b) Why is it that in my C# code the results returned do not match the search results?
Had a similar issue and described our solution here: https://ggullentops.blogspot.be/2015/12/sitecore-lucene-index-and-datetime.html.
Our problems had 2 reasons:
The first reason is that Sitecore stores its DateTimes in UTC (which was an hour difference with our local time)
Second reason was that Sitecore uses "t" in the dates as lowercase in the query. In my index however they are all uppercase. If I try the query with Luke it does give me the wrong results indeed.. When I alter the query in Luke to use uppercase T it works correctly..
The easiest solution we found was a format attribute in the index config:
<field fieldName="datefrom" storageType="YES" indexType="UNTOKENIZED" vectorType="NO" boost="1f"
format="yyyyMMdd" type="System.DateTime"
settingType="Sitecore.ContentSearch.LuceneProvider.LuceneSearchFieldConfiguration, Sitecore.ContentSearch.LuceneProvider"/>
(note the format="...")

CFSpreadSheet - format column not formatting the entire column

Using CF10 Standard to create a spreadsheet from a query. No matter what I've tried so far, the formatting for a specific column stops at row 32 (1 header row, 31 data), even though the entire sheet is populated to 186 rows.
<cfscript>
dfStyle=StructNew();
dfStyle.fgcolor="pale_blue";
dfStyle.dataformat="mm/dd/yyyy";
theSheet = SpreadSheetNew('mysheet');
SpreadSheetAddRow(theSheet,'SID,FIRST,LAST,ADDRESS1,ADDRESS2,CITY,STATE,ZIP,EMAIL,ADDED,PID');
SpreadSheetAddRows(theSheet,qry);
SpreadSheetFormatColumn(theSheet,dfStyle,10);
</cfscript>
I'm trying to get a consistent mm/dd/yyyy format on the 'ADDED' column. Instead, I'm getting that through row 31, and then getting dates like 41937.56594 on the of the rows.
In the formula bar I show "10/20/2014 12:25:23 PM" as the first value and "41932.552037037" as the 2nd value.
If I format the date in the query (i.e. date_format(sp_add,'%c/%e/%Y') AS spadd) I do get a nice date format all the way down the column, but the blue still stops at row 32.
Here is the cfoutput of the anonymized query - top row is formatted, bottom row loses formatting (background color - formatting dates in query). I also dropped the ADDRESS2 column from the query for now.
I'm not sure what the problem is, but try using the XML format option (the option to produce an xlsx file instead of the older style xls file). In your code add the "true" as a second argument to your spreadsheetnew() function call.
<cfscript>
dfStyle=StructNew();
dfStyle.fgcolor="pale_blue";
dfStyle.dataformat="mm/dd/yyyy";
theSheet = SpreadSheetNew('mysheet',TRUE);
SpreadSheetAddRow(theSheet,'SID,FIRST,LAST,ADDRESS1,ADDRESS2,CITY,STATE,ZIP,EMAIL,ADDED,PID');
SpreadSheetAddRows(theSheet,qry);
SpreadSheetFormatColumn(theSheet,dfStyle,10);
</cfscript>
This will solve the problem - though we don't know why :)

coldfusion - parsing a string date into datetime format

We receive an XML file with a date node as follows:
<createdDate>1/11/2008 7:04:28 a.m.</createdDate>
Dates are UK format dd/mm/yyy, so 1/11/2008 is 1st November 2008.
We run a coldfusion function to parse the xml and insert into the database. The relevant database field is of datetime datatype and needs to remain that way. How would I format this string representation of the date into a format the database will accept?
Not an ideal situation, but the format you are getting data especially dots in am/pm strings make it hard to read and on top of that it comes in UK Date format. This can help:
<cfset x="21/11/2008 7:04:28 p.m.">
<cfset x=Replace(x,".","","All")>
<cfset y=LSDateFormat(x,"mm/dd/yyyy","English (UK)")>
<cfoutput>
x====#x#
<br/>y===#y#
<cfset z=CreateDateTime(Year(y),month(y),day(y),hour(x),minute(x),second(x))>
z====#z#
<cfset someDatevare=LSParseDateTime(x,"English (UK)")>
</cfoutput>
EDIT As Leigh mentioned, removing periods or any other non-standard characters from the string and then LSParseDateTime will return a date time object.

Coldfusion 10 DateFormat Issue

I am using the DateFormat function to convert dates to this format: yyyy-mm-dd. This is the original format of the date: dd-mm-yyyy. Below is a snippet of the code:
<cfset newdate = #DateFormat(Trim(mydate), "yyyy-mm-dd")# />
The problem is that I get different results for different dates. For example:
If my original date is: 15-05-2013 (dd-mm-yyyy)
The result is: 2013-05-15 (yyyy-mm-dd)
However, if I change the input and:
The original date is: 01-05-2013 (dd-mm-yyyy)
The result is: 2013-01-05 (yyyy-dd-mm)
Any help or guidance as to what is wrong would be highly appreciated.
I disagree with the other answer. The real cause of the problem is that DateFormat is not designed to handle non-US date strings.
The standard CF date functions always use U.S. date parsing rules. That means when you pass in an ambiguous date string, like 01-05-2013, it is parsed according to U.S. English date conventions. In this case, month first ie "mm-dd-yyyy". So the result will always be January 5th, not May 1st.
In some cases you get lucky. With the string 15-05-2013, there is obviously no 15th month, so CF/java must swap the month and day automatically, rather than throwing an error. That is why it seems to handle some dd-mm-yyyy date strings correctly, but not others.
If you want to parse non-US date strings, you should use the LS (Locale Sensitive) date functions instead. However, according to the docs dashes ie "-" are not a standard date separator in most non-US locales: only Dutch and Portuguese (Standard). So you would either need to change the separator OR use one of those two locales when parsing the date:
lsDateFormat( myDate, "yyyy-mm-dd", "pt_PT")
Side note:
As an aside, DateFormat does expect a date object. However, like most functions in CF it is flexible enough to accept a date string as well. That allows you to use it as a lazy shortcut to convert from date string => date object => then back to (formatted) date string again. Using date objects is preferable (and you really should validate date strings as well) but that is another conversation altogether ...
The problem is that DateFormat expects a date object, and returns a string.
You're passing it a string, not a date. What you want to do is firstly turn your string (of 01-05-2013 etc) into a date object.
To do this I'd recommend using either ParseDateTime or LSParseDateTime, and/or LSDateFormat.
e.g.
<cfset originalDateString = "01-05-2013">
<!--- turn that into a Date --->
<cfset dateObject = ParseDateTime(originalDateString)>
<cfset newdateString = DateFormat(dateObject, "yyyy-mm-dd")>
Alternatively, if you know your string is always in a dd-mm-yyyy format, you could parse the string yourself, e.g. treat it as a list delimited by hyphens.
<cfset dd = listFirst(originalDateString, "-")>
<cfset mm = listGetAt(originalDateString, 2, "-")>
<cfset yy = listLast(originalDateString, "-")>

DB2 The syntax of the string representation of a datetime value is incorrect

We have a staging table that's used to load raw data from our suppliers.
One column is used to capture a time-stamp but its data-type is varchar(265). Data's dirty: about 40% of the time, there is garbage data, otherwise time-stamp data like this
2011/11/15 20:58:48.041
I have to create a report that filters some dates/timestamps out that column but where I try to cast it, I get an error:
db2 => select cast(loadedon as timestamp) from automation
1
--------------------------
SQL0180N The syntax of the string representation of a datetime value is incorrect. SQLSTATE=22007
What do I need to do in order to parse/cast the timestamp string?
The string format for a DB2 timestamp is either:
'2002-10-20-12.00.00.000000'
or
'2002-10-20 12:00:00'
You have to get your date string in either of these formats.
Also DB2 runs on a 24 hour clock even though the output sometimes uses a 12 hour clock (AM / PM)
So '2002-10-20 14:49:50' For 2:49:50 PM
Or '2002-10-20 00:00:00' For midnight. Output would be 12:00:00 AM
It seems you have a lot of garbage data, so firt of all you should check if the data is a valid timestamp in the format you expect ('2011/11/15 20:58:48.041'). We could use a simple solution - just replace all digits with '0' and check the result format:
TRANSLATE(timestamp_column,'0','0123456789','0') = '0000/00/00 00:00:00.000'
If the format is the expected one, you should convert to DB2 timestamp. In DB2 for iSeries there is a build-in function since V6R1 TIMESTAMP_FORMAT. In your case it will look like that:
TIMESTAMP_FORMAT('2011/11/15 20:58:48.041','YYYY/MM/DD HH24:MI:SS.NNNNNN')
So the solution query combined should look something like that:
SELECT
CASE
WHEN TRANSLATE(timestamp_column,'0','0123456789','0') = '0000/00/00 00:00:00.000'
THEN TIMESTAMP_FORMAT(timestamp_column,'YYYY/MM/DD HH24:MI:SS.NNNNNN')
ELSE NULL
END
FROM
your_table_with_bad_data
EDIT
I just saw your comment that provider agreed to clean the data. You could use the solution provided to speed up the process and clean the data by yourself:
ALTER your_table_with_bad_data ADD COLUMN clean_timestamp TIMESTAMP DEFAULT NULL;
UPDATE your_table_with_bad_data
SET clean_timestamp =
CASE
WHEN TRANSLATE(timestamp_column,'0','0123456789','0') = '0000/00/00 00:00:00.000'
THEN TIMESTAMP_FORMAT(timestamp_column,'YYYY/MM/DD HH24:MI:SS.NNNNNN')
ELSE NULL
END;