Conversion failed when converting date and/or time from character string - c#

I am trying to query the database where date is between today and yesterday but am getting error saying Conversion failed when converting date and/or time from character string.
My query is below with my parameters today and yesterday
string today = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day).ToString("yyyy-MM-dd");
string yesterday= new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day-1).ToString("yyyy-MM-dd");
string errorsPerHourQuery = "WITH data_CTE(ErrorDay)" +
"AS(" +
"SELECT DATEPART(hh, Date) AS ErrorDay FROM cloud.ErrorLog " +
"WHERE Date BETWEEN '#yesterday' AND '#today' " +
"AND CAST(Message AS varchar(200)) ='#message'"+
")" +
"SELECT ErrorDay, COUNT(*) AS count FROM data_CTE GROUP BY ErrorDay ORDER BY ErrorDay";
conn.Open();
cmd.Parameters.AddWithValue("#message", message);
cmd.Parameters.AddWithValue("#yesterday", yesterday);
cmd.Parameters.AddWithValue("#today", today);
cmd.CommandType = CommandType.Text;

You must remove simple cote ' from parmeters in query :
..BETWEEN #yesterday AND #today
You don't need to create today and yesterday with specific format, you can simply get variable like :
var today = DateTime.Today;
var yesterday = DateTime.Today.AddDays(-1);
and use Parameter with SqlDbType.DateTime and then pass the DateTime directly to the parameter (do not need to convert).
cmd.Parameters.Add("#yesterday", SqlDbType.DateTime).Value = yesterday
cmd.Parameters.Add("#today", SqlDbType.DateTime).Value = today

First off, you're calculating your today and yesterday wrong. Here's the correct way:
var today = DateTime.Today;
var yesterday = today.AddDays(-1);
And regaring query: remove ticks (') from around your named parameters so that your query reads ...BETWEEN #yesterday and #today... and you'll be all set.

Problem is that you are quoting your command parameters which is getting considered as string literal instead of parameter as seen below.
WHERE Date BETWEEN '#yesterday' AND '#today'
You should change it to
WHERE [Date] BETWEEN #yesterday AND #today

There are lots of good points in the other answers especially. #Abdellah does a good job of teaching the datetime datatype and the appropriate value, but your SQL query itself needs work and may be why you are not getting what you want. Because just like the #yesterday and #today you need to remove the ''(ticks) from #message. Then you can do your query in 1 step you don't need the cte. Plus if you aren't going to pass any dates other than yesterday or today there is no need for parameters use SQL's built in functions.
So remove all of the ticks around all of your parameters (#yest...)
Here is a SQL query that should work for you:
SELECT
ErrorHour = DATEPART(HH,[Date])
,[Count] = COUNT(*)
FROM
cloud.ErrorLog
WHERE
--use this line from midnight yesterday to midnight today
CAST([Date] AS DATE) BETWEEN CAST(GETDATE() - 1) AND CAST(GETDATE())
--what is the datatype for message does it really need to be cast?
AND CAST([Message] AS VARCHAR(200)) = #Message
GROUP BY
DATEPART(HH,[Date])
ORDER BY
ErrorHour
Note I put ErrorHour you are welcome to change to ErrorDay, but you are counting errors per hours not days, to change what you are counting simply change your DATEPART() to be the time component you want, e.g. minutes, etc..
Next Do you really need to cast Message field?
On the dates. Are you wanting everything today and yesterday or really just yesterday? If just yesterday swap this line into the query for the other date line:
--if you really just want yesterday midnight to 11:59:59 PM the it should be
CAST([Date] AS DATE) = CAST(GETDATE()-1 AS DATE)
Next if you really really want to pass yesterday and today as parameters and you want all of yesterday and all of today do the following and update your parameter definitions in your code as the other posts suggest.
--use this line from midnight yesterday to midnight today
CAST([Date] AS DATE) BETWEEN CAST(#yesterday AS DATE) AND CAST(#Today AS DATE)

Related

Finding Records Between 2 Times

I'm trying to get the records between two dates. Specifically between the start of the day and the time now. This is my query but it doesn't work for me. I have a MYSQL database
var query = (SELECT * FROM `jobs` WHERE `EventTime` < NOW() AND `EventTime` >= '" + dtstartofday + "' AND `PersonSel` = '" + personassigned + "' AND `PersonID` = '" + id + "'");
dtstartofday is of DateTime type.
You're using string concatenation to put query values directly into your SQL string. Don't do this, for a variety of reasons, one of which is the problem you're seeing here - how c# chooses to format the date as string, according to your regional preferences, and how MySQL chooses to parse the string as a date will have direct consequences for how the query runs. As a coarse example, if your date goes in as '2/3/2000' meaning third of feb, you could be using a mysql that interprets it as second of March. Alternatively you might find that c# is representing the date as something mysql doesn't recognise as a date so it is instead converting the EventTime date to a string and then comparing the strings, which is very unlikely to work out (and slow, because of all the conversions)
Either adjust your query so the start of day calculation is done by the db, and parameterize the other elements of your query:
var query = "SELECT * FROM `jobs` WHERE `EventTime` < NOW() AND `EventTime` >= CURDATE() AND `PersonSel` = #personSel AND `PersonID` = #personID"
Or parameterize the start date properly rather than passing its value as a string:
var query = "SELECT * FROM `jobs` WHERE `EventTime` < NOW() AND `EventTime` >= #eventTimeFrom AND `PersonSel` = #personSel AND `PersonID` = #personID"
To add values for the parameters you declare its name, type and value:
var cmd = new MySqlCommand(query, connection);
cmd.Parameters.Add("#eventTime", MySqlDbType.DateTime).Value = dtstartofday; //dtstartofday is a c# datetime representing midnight today e.g DateTime.Date
cmd.Parameters.Add("#personSel", MySqlDbType.Int).Value = personassigned;
cmd.Parameters.Add("#personID", MySqlDbType.DateTime).Value = id;
var x = cmd.ExecuteReader();
It is important to appreciate the difference between having the server do the time and your local machine do the time, especially if they are in different zones, but even if their clocks drift just a little. At some moment what each machine thinks of as "today" will differ. Consider it carefully
Later, when you're bored of writing this kind of code endlessly, you can install Dapper, an extension that does it for you. Take a look at http://dapper-tutorial.net for examples of how it will reduce code like this to just two lines; query and variables in, usable objects out.

Convert DateTime format to Another DateTime Format In C#

In my C# project I need system date time to another specific date time format.
My system datetime format is like "15/03/2017 9:25 AM" --->that can be changed according to computer wich my program run.
But I need to parse that datetime format to another date time format something like "2017-03-15 9:25 AM"----> save date in SQL datebase accept this format only.
I need Assign this to variable to Datetime Variable not need save in String variable.
I tried this code but not working
string datetimesss = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss")
It returns
// value of datetimesss="2017-03-15 09:33:25"
Then i parse again to date time format
DateTime dates = DateTime.Parse(datetimesss);
It returns
// value of dates ="15/03/2017 9:42:43 AM"
Convert back to my computer datetime format .How can I convert any datetime format to DateTime "yyyy-MM-dd hh:mm:ss"
Thank You!
You should avoid strings and just keep your data in DateTime variables. ADO.Net already knows how to translate between .NETs DateTime and SQL Server's datetime - and neither of these has a format (both of them, internally, are just numbers. .NETs DateTime is a count of 100ns intervals since 01/01/0001. SQL Server's datetime is a count of whole and fractional days since 01/01/1900).
Something like:
var updateCommand = new SqlCommand(
"UPDATE [User] SET Last_loign_date =#LastLoginDate"
,conn); //Assume conn is an SqlConnection object
updateCommand.Parameters.Add("#LastLoginDate",SqlDbType.DateTime).Value = DateTime.Now
or, in the alternative, why not use the database server time rather than passing it:
string sqlupdatepassword = "UPDATE [User] SET Last_loign_date =current_timestamp";
If sql server language is set as us-english then your date - > '15/03/2017 9:25 AM' will be considered as text and converting into date will not give correct results. You need create date based on day,month and year from your given date by using string functions. Use the below code to get required output :
declare #date varchar(30) = '15/03/2017 9:25 AM'
select cast(left(parsename(replace(#date,'/','.'),1),4) +
parsename(replace(#date,'/','.'),2) +
parsename(replace(#date,'/','.'),3) as datetime) +
ltrim(stuff(parsename(replace(#date,'/','.'),1),1,4,''))
Finaly I got the point,
I parse DateTime to String
string sqlupdatepassword = "UPDATE [User] SET Last_loign_date ='" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss tt") + "'";
In SQl database "Last_loign_date" is datetime format.
this may not correct, but this worked for me.
thanks!

Oracle - not a valid month

I get a timestamp from Facebook in the below code
cust_updated_time = obj["updated_time"].ToString();//2013-08-01T02:55:31+0000
abccusttime = cust_updated_time.Substring(0, cust_updated_time.ToString().Length - 3);//2013-08-01T02:55:31+0
Here I'm trying to insert into Oracle table
to_date('" + abccusttime + "', 'mm-dd-yyyy hh24:mi:ss')
but I get an error "not a valid month"
Any ideas? Thanks in advance.
if this is your date:
2013-08-01T02:55:31+0
It should look like this:
2013-08-01 02:55:31
Than you can use TO_DATE function (with correct mask format):
to_date('" + abccusttime + "', 'yyyy-mm-dd hh24:mi:ss')
When you try to map:
2013-08-01T02:55:31+0
with the format:
mm-dd-yyyy hh24:mi:ss
it's not going to work simply because your date components are in the wrong place. It's expecting a two-digit month at the start but you're giving it the century of 20, which is most definitely not a valid month.
You need to either change your data or your mapping so that they match.
It's probably easier to parameterize your query, but in this case you've got your time format wrong. To match;
2013-08-01T02:55:31+0000
you need a format like;
yyyy-MM-dd"T"hh24:mi:ss"+0000"
or, if you want the preprocessed format with a single zero;
yyyy-MM-dd"T"hh24:mi:ss"+0"
Sample;
SELECT TO_DATE('2013-08-01T02:55:31+0000', 'yyyy-MM-dd"T"hh24:mi:ss"+0000"') FROM DUAL;
> August, 01 2013 02:55:31+0000
Oracle date format reference.
You could also match/process the time zone information, but since it's not clear what result you'd like if it were set, I left it out (TZH and TZM will help there)
A rather trivial SQLfiddle.
The Oracle date format you want is mm-dd-yyyy, but the facebook timestamp is yyyy-mm-dd.
You should do something like this instead;
to_date(:abccusttime, 'mm-dd-yyyy hh24:mi:ss')
Then set a parameter for abbcusttime, also don't use apostrophes (') when adding parameters, it doesn't like that :)
OracleCommand.Parameters.Add(":abccusttime", OracleDbType.Varchar2).Value = abccusttime;
You better use parameters
DateTime updatedtime = obj["updated_time"] as DateTime;
var statement = "..... where Updated_time > :updatedtime";
using (OracleConnection connection = new OracleConnection(connectionString))
using (OracleCommand command = new OracleCommand(statement, connection))
{
command.Parameters.AddWithValue(":updatedtime", updatedtime );
command.Connection.Open();
command.ExecuteNonQuery();
}

Conversion failed when converting date and/or time from character string in gridview

In my GridView I can see my date column as mm/dd/yy normally but when I select a record and assign a string like so
GridViewRow row = GridView1.SelectedRow;
string sdate= row.Cells[2].Text; //Date is in Column 2
When I output this sdate string it returns: 1368309600000
And If I try to convert it, it doesn't work and I'm trying to select something from a SQL database and I get this error
Conversion failed when converting date and/or time from character string
EDIT: The part in the SQL statement for conversion is:
convert(datetime, '" + sdate +"', 101"+")
I suspect the problem is in the sdate itself but I'm not sure
Your date string appears to be expressed as the number of milliseconds since January 1, 1970, 00:00:00 GMT. The T-SQL CONVERT() function doesn't support this format. So, you could do a conversion to a C# DateTime like this...
DateTime date = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)
.AddMilliseconds(Convert.ToDouble(sdate));
1368309600000 converts to 11/05/2013 22:00:00Z (this is UTC)
Then adjust for local time and reformat the date for your SQL string like this...
"convert(datetime, '" + date.ToLocalTime().ToString("MM/dd/yyyy") + "', 101)"
UpdateCommand="UPDATE [dbo].[ENTRY] set [_DATE] = CONVERT( date , #_DATE ,103) where [NO] = #NO "
important part here is 103 it is for format dd-mm-yyyy
check out your local format.
this problem only rises for people outside America.

Compare dates as strings

I can't find a way to find all the dates(strings) less then at least one year from now.
i keep in database Date Field strings like "DateTime.toShortDateString()" and i need to compare now.
it looks like month/day/year = 9/6/2011
its need to be lower at least one year from DateTime.now.
i did this and it doesnt return all dates needed just few.
DateTime Date = DateTime.Now;
int Year = Date.Year;
Year -= 1;
int Month = Date.Month;
string MonthYear = Month.ToString() + "%" + Year.ToString();
string Query = "SELECT * FROM Orders WHERE DateOrder < #STU ";
SqlCommand cmd = new SqlCommand(Query, con);
cmd.Parameters.AddWithValue("#STU", MonthYear);
This is my problem
Modify your database schema and store dates as char(10) in ISO 8601 format (yyyy-mm-dd) or the ISO 8601 compact form (yyyymmdd).
http://www.cl.cam.ac.uk/~mgk25/iso-time.html
http://en.wikipedia.org/wiki/ISO_8601
That gives you proper collation and proper comparison. Further...DateTime.Parse() and TryParse() will both accept that format regardless of culture (well..one exception: Saudi Arabia, ar-SA. Go figure). DateTime.ToString("Y") orstring.Format( "{0:Y}" , someDateTimeInstance )` will give you the ISO 8601 format.
Should be a simple update to your database.
Even better, if you're using SQL Server 2008: store dates using the new datatype Date.
Maybe deserialize these DateTime strings and then compare as DateTime objects?
var date=DateTime.Parse(stringFromDb, new CultureInfo("en-US"));
Then you can do:
if (dateToCompare1 < dateToCompare2)
Or whatever comparison operator you want.
Edit: from your comment, I think you would like use only dates that are later (or equal to?) one year from now. And so you would do:
var date=DateTime.Parse(stringFromDb, new CultureInfo("en-US"));
if (date >= DateTime.Now.AddYears(1) {
// Do whatever you want with the "kept" dates
}
Assuming you have a string:
string strDate1 = "09/06/2011";
string strDate2 = "09/06/2011";
DateTime date1 = DateTime.Parse(strDate1);
DateTime date2 = DateTime.Parse(strDate2);
Then compare them.

Categories