While converting .NET DateTime (when is default(DateTime)) to SqlDateTime should I always check if the .NET date is between SqlDateTime.MinValue and SqlDateTime.MaxValue [or] Is there a good way to do this.
Is it possible that the date could actually be outside that range? Does it come from user input? If the answer to either of these questions is yes, then you should always check - otherwise you're leaving your application prone to error.
You can format your date for inclusion in an SQL statement rather easily:
var sqlFormattedDate = myDateTime.Date.ToString("yyyy-MM-dd HH:mm:ss");
If you are checking for DBNULL, converting a SQL Datetime to a .NET DateTime should not be a problem. However, you can run into problems converting a .NET DateTime to a valid SQL DateTime.
SQL Server does not recognize dates prior to 1/1/1753. Thats the year England adopted the Gregorian Calendar. Usually checking for DateTime.MinValue is sufficient, but if you suspect that the data could have years before the 18th century, you need to make another check or use a different data type. (I often wonder what Museums use in their databases)
Checking for max date is not really necessary, SQL Server and .NET DateTime both have a max date of 12/31/9999 It may be a valid business rule but it won't cause a problem.
Also please remember resolutions [quantum of time] are different.
http://msdn.microsoft.com/en-us/library/system.data.sqltypes.sqldatetime.aspx
SQL one is 3.33 ms and .net one is 100 ns.
on my quest to do this with entitie, i stumbled over here, just hitting back to post what i've found out...
when using EF4, "a sql's" datetime column can be filled from .NET's DateTime using BitConverter.
EntitieObj.thetime = BitConverter.GetBytes(DateTime.Now.ToBinary());
also Fakrudeen's link brought me further... thank you.
-To compare only the date part, you can do:
var result = db.query($"SELECT * FROM table WHERE date >= '{fromDate.ToString("yyyy-MM-dd")}' and date <= '{toDate.ToString("yyyy-MM-dd"}'");
var sqlCommand = new SqlCommand("SELECT * FROM mytable WHERE start_time >= #StartTime");
sqlCommand.Parameters.Add("#StartTime", SqlDbType.DateTime);
sqlCommand.Parameters("#StartTime").Value = MyDateObj;
Related
i'm trying to parse a user input of a date to a MySQL Timestamp format (YYYY-MM-DD).
User input could be something like:
input - wanted conversion
1) January - ThisYear-01-01, ThisYear-01-31
2) February 2017 - 2017-02-01, 2017-02-28
3) 01. April 2016 - 2016-04-01
4) 5.4.15 - 2015-04-05
P.S.:
The examples above are the suggested formats that we want to support (supporting only some of them would be also fine).
The users are not random or international, they will always write and understand dates in this format (Day Month Year).
Handling the missing year entry or the zero (like 5/4 in #4) isn't a problem but finding a proper way to handle the mentioned possible date input formats (DD MM YY, DD MM, DD Month, Month, Month YY, DD Month YY....etc.) with something that doesn't look very ugly and long in code is a little bit hard for me to imagine.
P.S.:
D,DD,MM,YY,YYYY are short for the numerical input.
Month is for the word input variant.
Could you please tell me if there is anything that could help me to make this process easier/more readable or at least point me to the right direction?
Thanks
Update #1:
By looking again to my question above i see that it's missing some background information, but i didn't want to write a long description to it, just only to the wanted function. Sorry.
So here are some general infos about the Program:
The Program is a Chatbot written in C# (UWP) which accepts a user request in natural language and give back the requested info (if recognized) from a mySQL DB (DB is based on a OSTicket support system).
Internally we send the user input to LUIS.ai to get it recognized and we get back the intents and entities from the service, which we then parse to a SQL Query and send it to the DB.
The results from the DB are then sent back to the user.
Many parsed queries work perfectly, that's why i want now to extend it by letting the user give a certain date in the request (e.g. give me all the support tickets from April).
What i only want is to take this new input "April" and convert it to a MySQL TimeStamp format, so that it would be also recognized from MySQL.
My current approach is to build a string like this:
string convertedTS = year + "-" + month + "-" + day;
And using 3 functions try to detect all three variables. But that's it for now.
E.g. "give me all the tickets from April":
April (recognized from LUIS AI as given date) will be converted to (04)
Year will be taken from
DateTime.Today.Year
and inserted too (2018-04)
The first day is always 01 and the last day of the month will be:
DateTime.Today.Year
Final Query from the example:
select ..........between '2018-04-01' AND '2017-04-30'
If you're worried about formatting the years, months, days, etc, you're doing it wrong. You have C#, and you have a date string from the user. Your concern is getting that string into a C# DateTime value. MySql has no part of this.
Once you have the DateTime value, let your connection provider worry about formatting via parameterized queries:
DateTime d = GetMyDateTimeValueFromUser();
string sql = "pretend SQL comnand with a datetime #variable";
using (var cn = new MySqlConnection("connection string here"))
using (var cmd = new MySqlCommand(sql, cn))
{
cmd.Parameters.Add("#variable", MySqlDbType.Timestamp).Value = d;
cn.Open();
//pick one.
cmd.ExecuteReader();
cmd.ExecuteNonQuery();
}
No special SQL format needed. If you're not using parameterized queries, you're not doing it right! This applies to much more than just DateTime values. All data used in an SQL statement should be handled this way. This has security and performance implications that go way beyond simple date values. Go parameters, or go home (I mean that: go home. Don't write bad code. We don't need any more.)
As it applies to the question, it means the problem is entirely about parsing a string to a C# DateTime value. The next step of moving this data to SQL is just not relevant. Thankfully, .Net has some options for you here. Specifically, take a look at the Parse family of functions, including:
DateTime.Parse()
DateTime.TryParse()
DateTime.ParseExact()
DateTime.TryParseExact()
The latter two allow you specify a set of allowed formats that can match the formats actually seen by your system. NuGet can be a further resource in this area.
What's that, you say? You want to allow the user to input anything? That just won't work. Period. Real humans can and will come up with far more ways to enter a date than you could possibly ever handle. Not to mention you need to know what to do when a British citizen inputs the value 1/2/2018 into your system, because that person almost certainly believes it means February 1, 2018, and not January 2. Cultural differences like this mean it is impossible to accept date inputs without some kind of contextual input filter on the front end. You must look to your user interface to help your users create values your code will understand... but we don't have enough info in the question to provide any guidance yet in that area.
I fixed that for the purpose of using it in my program.
Now i can detect and understand such inputs:
"09 11 2008"
"2017"
"today"
"yesterday"
"09/11/2002"
"march 2017"
"01.01.2010"
"01-01-2010"
"01 may 2019"
"31.October 2020"
"01 april"
"december"
If anyone is also interested in writing a similar function leave a comment, because the code is almost 300 lines.
I am working in creating to get the data from the PostgreSQL and insert in to MS SQL Database. So the field in the PostgreSQL is of datatype Timestamp without time zone and this needs to be going in to the field of DataTime type in MS SQL DB. I am using the scripting functoid in the map to convert them and insert.Below is the scripting I am using
public string ConvertSampDateRec(string dateReceived)
{
DateTime recDate;
DateTime.TryParseExact("yyyy-MM-dd HH:mm:ssZ", dateReceived, System.Globalization.CultureInfo.CurrentCulture, System.Globalization.DateTimeStyles.None, out recDate);
string returnRec = recDate.ToString("yyyy-MM-ddTHH:mm:ss");
return returnRec;
}
I am not sure if the format is yyyy-MM-dd HH:mm:ssZ for the TimeStamp without time zone. With this I am getting error like below
Details:"System.Data.SqlTypes.SqlTypeException: SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM.
It is making the returnRec as 0001-01-01T00:00:00 for all the dateReceivedeven if it is not null.I tried even using DateTimeOffset but still no help
You can't put 0001-01-01T00:00:00 into a SQL database, as the error message shows, the smallest date that can be handled is 1753-01-01T00:00:00
Also, why aren't you handling the return value from DateTime.TryParseExact? You have no way of knowing when it's failing to parse the string, so you are getting the default for a DateTime object (equal to DateTime.MinValue)
Make sure you're handling the return similar to this:
private static DateTime _sqlDefaultDateTime = new DateTime(1753, 01, 01);
private void foo()
{
string parsedDate;
if (!DateTime.TryParseExact())
{
parsedDate = _sqlDefaultDateTime;
}
}
HOLD ON everyone. Sorry, but this keep going around and around, there's two other questions for the exact same thing.
OP needs to use the 'o' format to emit a xs:datetime compatible string so that it can be properly converted to a SQL date time.
This is a BizTalk specific circumstance and this explanation has been offered several times.
There's also some additional handling required which has already been described in another post.
I use this C# code to convert a datetime to a string:
MyDatetime.ToString("dd/MM/yyyy HH:mm")
it works, but not every time. What do I mean?
If the input datetime is, for example, 2016-10-19 17:27:41.727, I get the string as expected, 19/10/2016 17:27. If the day in datetime (and/or the month) has only one digit, I get something weird.
If the input is 2016-01-07 14:58:13.560, I get 1/7/2016 and if it is 2016-10-26 17:14:16.000 I get 10/6/2016.
Do you know why? How can I always set a leading zero for days and months with only one digit? And, further, why I don't see the time part in the date I wrote as examples?
UPDATE
.
Some datetime fields from a SQL Server database (this is SQL Server Management Studio).
Most probably your DateTime already has invalid value (day and month are mixed)
new DateTime(2016, 01, 07,14,58,13,56).ToString("dd/MM/yyyy HH:mm")
returns 07-01-2016 14:58.
Take a look how do you read this DateTime value from the database. I believe the problem is there. (for example SqlDataReader.GetDateTime)
When you input a date as "XXXX-XX-XX" it assumes you're using the format "YYYY-MM-DD".
Just look at your input-output and you can see the pattern.
A lot of people in programming (that I work with) use this format because it is auto-filtering without any punctuation (20170102 will always go after 20161231, etc).
The DateTime method works in conjunction with the computer language. If your computer (or server) is in English (or vice versa) and you pass an American non-standard date format, you will have problems like this.
If you are using a web application, configure the correct language in web.config
I am having trouble while storing date in sql server DB through C# asp.net, online
I have used asp Text box and asp calender extender in ASP file to get date from user,
<asp:TextBox runat="server" ID="txt_date"></asp:TextBox>
<asp:CalendarExtender runat="server" ID="cal_date" TargetControlID="txt_date"></asp:CalendarExtender>
code behind file is, assume connection and command are declared and initialized ,
mycom = new SqlCommand("insert into mytable(dtCol1) values('"+Convert.ToDateTime(txt_dob.Text).ToString("dd-MMM-yyyy") + "')", mycon);mycom.ExecuteNonQuery();
Problem is, when I select date less than 12 of any month it works perfect,
but when date/day is greater than 12 of any month it gives error,
Exception Details: System.FormatException: String was not recognized as a valid DateTime.
I have tried all combinations of .ToString("dd-MMM-yyyy")
Please Help
thanks in advance
try this
mycom = new SqlCommand("insert into mytable(dtCol1) values(#value1)");
mycom.Parameters.AddWithValue("#value1",Convert.ToDateTime(txt_dob.Text));
mycom.ExecuteNonQuery();
Try this
CultureInfo provider = CultureInfo.InvariantCulture;
System.Globalization.DateTimeStyles style = DateTimeStyles.None;
DateTime dt;
DateTime.TryParseExact(txt_dob.Text, "m-d-yyyy", provider, style, out dt);
mycom = new SqlCommand("insert into mytable(dtCol1) values(#datevalue)", mycon);
cmd.Parameters.Add("#datevalue",SqlDbType.DateTime).Value =dt;
mycom.ExecuteNonQuery();
The problem seems to come from here: Convert.ToDateTime(txt_dob.Text). This type of conversion is not good because:
It disregards the format that the control uses. Convert.ToDateTime(...) expects the string to be in a certain format(s) in order to parse it correctly. This cannot handle any custom formats that the txt_dob could use.
It is ignorant of culture-specific formatting. Internally, Convert.ToDateTime(...) will probably stick to CultureInfo.CurrentCulture, which is not said to be capable of parsing the date. Also, some front-end controls in .NET recognize and use the client culture passed by the browser (for web apps), and it is likely for that culture to be different than the server culture. CultureInfo.CurrentCulture will represent the server-side culture and formatting discrepancies are possible to occur
If you know the format of the txt_dob.Text you have to explicitly parse it. In the example below I have assumed the format is "MM/dd/yyyy":
String dateFormat = "MM/dd/yyyy";//The format that the txt_dob control uses
DateTime parsedDate = DateTime.ParseExact(
txt_dob.Text, dateFormat, CultureInfo.InvariantCulture);
You can also check this related topic with some additional information on a similar case like yours
TLDR; You're using the wrong DateTime format.
There's plenty of issues here that will blow up Death Stars, left right and center.
Firstly, you're creating the sql query on the fly - that's probably the biggest no-no in the last 10 years and everyone has stopped doing that. In other words, please please please don't start doing (the very out of date) ADO.NET programming to pass data from the website to the database. Modern replacements like Entity Framework, NHibernate or even Linq2Sql if you're desperate.
Ok - that said, lets try and answer your question none-the-less.
The reason is because u're passing in the values in the wrong format. You're doing dates first. Your sql server is probably wanting it to be MONTHS first. Because it's probably been setup to be style 121 (<-- that's a real technical sql server setting thing for Compatibility crap..)
But don't try and fight and guess.
Lets use a more universal and start string format: yyyy-mm-dd hh:mm:ss.ms
eg.
SELECT CAST('2013-02-08 09:53:56.223' as DateTime)
And you can see this in action over at SQLFIDDLE.
This is a really good StackOverflow question that explains what the default DateTime format is, etc.
Use this:
mycom = new SqlCommand("insert into mytable (dtCol1) values ('" + Convert.ToDateTime(txt).ToString("MMM-dd-yyyy") + "')", mycon);
Thanks
User DateTime.ParseExact() in place of Convert.ToDateTime() method.
dateString = "12-31-2012";
format = "MM-dd-yyyy";
try
{
DateTime result = DateTime.ParseExact(dateString, format, CultureInfo.CurrentCulture);
}
catch (FormatException)
{
}
[Date_Of_Birth]='" + Convert.ToDateTime(TxtDate_Of_Birth.Text).ToString("MM-dd-yyyy") + "'
Will help the cause of error that sqlserver accepts datetime in format MM/dd/yyyy, but not in dd/MM/yyyy.
I had an issue like this. In my development environment, when I read the record from SQL Database: 12:00:00.000, the convertion always return 12PM in my application. But in the customer environment, it always return 12AM....and of course it's wrong
Have you ever faced this issue?
Thank & best regards,
Assuming "12:00:00.000" is a string, consider converting it to a DateTime using the following method call:
string myValue = "12:00:00.000";
DateTime myDate = DateTime.ParseExact(myValue, "HH:mm:ss:fff");
Using HH as the hour, a 24h date format is used.
Remember: this only works in the exact format specified in the input.
return DateTime.ParseExact("12:00:00.000", "HH:mm:ss:fff");