Converting DateTime throws SqlDateTime overflow - c#

Currently I've a string with a date and time. When I show the string it looks like:
2015-06-16 09:17:28 PM
But when I try to put it into the database it's telling me:
Additional information: SqlDateTime overflow. Must be between 1/1/1753
12:00:00 AM and 12/31/9999 11:59:59 PM.
I've to convert the string. So there is now other way!
What's the right way to do this? Obviously the value in database is datetime.
This is my code (I've put it together actually it's from multiple classes):
string time = date + " " + txtTime.Text;
DateTime temp = Convert.ToDateTime(time);
String query ="insert into reserveringen (reserveringId,klantId,medewerkerId,aantalPersonen,begintijd,eindtijd)values(#reserveringId,#klantId,#medewerkerId,#aantalPersonen,#begintijd,#eindtijd)";
SqlCommand comm = sqlCrud.returnSqlCommand(query);
comm.Parameters.AddWithValue("begintijd",temp);
I already googled a lot.... but nothing works.
Thanks

You should not use Convert.ToDateTime like that. You should use DateTime.Parse or DateTime.ParseExact.
DateTime temp = DateTime.ParseExact(time, "yyyy-MM-dd hh:mm:ss tt", CultureInfo.InvariantCulture);
Since DateTime.Parse(temp) worked for you, you can leave it as that.
Edit:
The difference between the two methods is very important in this situation.
Convert.ToDateTime(s)
This method will call DateTime.Parse internally with the following parameters:
DateTime.Parse(s, DateTimeFormatInfo.CurrentInfo, DateTimeStyles.None);
Now, DateTime.Parse(s) does something a little different:
DateTime.Parse(s, DateTimeFormatInfo.CurrentInfo, DateTimeStyles.AllowWhiteSpaces);
The difference is the DateTimeStyles flag. This flag completely changes the output. The Convert.ToDateTime(s) was likely returning a DateTime.MinValue object, which is what it does when it encounters a null string. (I can only guess without spending more time on research, but that result makes sense, as DateTime.MinValue is 1/1/0001 12:00:00 AM, which is outside the range SQL expects.)
References:
http://bytes.com/topic/c-sharp/answers/482419-convert-todatetime-vs-system-datetime-parse
https://msdn.microsoft.com/en-us/library/system.datetime.parse(v=vs.110).aspx
https://msdn.microsoft.com/en-us/library/system.datetime.minvalue(v=vs.110).aspx

Both
DateTime.Parse("2015-06-16 09:17:28 PM");
And
Convert.ToDateTime(date);
will return the same DateTime value.
I would try to focus on the query.
Note that you might be passing a value from C# that resolve in the minimum value for DateTime (1/1/0001 12:00:00 AM) which is out of range for DateTime value on SQL Server.

Related

Date was not recognized as a valid DateTime

kinda got an issue that I cant solve right now.
I've got a discord bot running on my raspberry pi, which has a system for automated messages that are sent after a certain amount of time, or an exact date, has passed.
My code works on Windows when debugging there, but the console throws a warning on Linux when running the published project.
The date is taken from a table in my MySQL database and put into a DataTable. The code that grabs the date from the DataRow is:
DateTime datetime = DateTime.ParseExact(row["datetime"].ToString(), "dd.MM.yyyy HH:mm:ss", CultureInfo.InvariantCulture);
Why is it happening? No matter how I format the string (dots, dashes or slashes), the warning persists. The messages are not sent.
I even tried removing invisible whitespaces with regex, doesnt work either.
(The regex in question, though I scrapped it since it yielded no fruit anyways)
Regex.Replace($"{row["datetime"].ToString()}", #"[^\d\s\.:]", string.Empty);
If RDBMS type is DateTime then why should we convert to string and then parse it back to DateTime? Let's do it direct:
DateTime datetime = Convert.ToDateTime(row["datetime"]);
and let .net convert boxed DateTime (row["datetime"] is of type object?) to DateTime
There are a couple issues--at the highest level, your ParseExact method is encountering a Date Time string that does not match the supplied format.
According to the code you posted, the expected format of is dd.MM.yyyy HH:mm:ss, and in your exception exception, shows a Date time string (8/2/2021 2:00:00 PM) that does not match:
contains / and your expected format has .
dd is a 2-digit day, but the input date time string only has single digit days
MM expects a two digit month and the input date time only has a single digit month
the string contains AM/PM, and your format neglects to account for that.
Finally it's not clear if your date format is Month Day Year, or Day Month year.
The second issue, is that ParseExact should be enclosed in a try/catch block, so that your code can handle the case when an unexpected formatted date time string is passed in, and not crash.
To solve this, wrap your call into a try/catch, and gracefully handle the FormatException
And then make sure the Format string matches the expected input string.
Here is the .NET reference for the various DateTime format tokens
The error message is letting you know the issue.
You have :
DateTime datetime = DateTime.ParseExact(row["datetime"].ToString(), "dd.MM.yyyy HH:mm:ss", CultureInfo.InvariantCulture);
Notable, you are saying that the date format is going to be "dd.MM.yyyy HH:mm:ss"
Then your error message is saying that you couldn't parse :
8/2/2021 2:00:00 PM
Which is essentially a format of "d/M/yyyy h:mm:ss tt" (Assuming that days come before months).
If you change your code to :
DateTime datetime = DateTime.ParseExact(row["datetime"].ToString(), "d/M/yyyy h:mm:ss tt", CultureInfo.InvariantCulture);
You should be good to go. DateTime.ParseExact does what it says on the tin, it parses the date format exactly how you say it should come. If you aren't sure you can use DateTime.Parse() (But you can occassionally run into issues where days/months are around the wrong way).
Tested using the following code :
var myDateString = "8/2/2021 2:00:00 PM";
DateTime datetime = DateTime.ParseExact(myDateString, "d/M/yyyy h:mm:ss tt", CultureInfo.InvariantCulture);
Console.WriteLine(datetime.ToString());

Inconsistency when parsing DateTime in the same format

I have the following strings:
10/10/2021 00:00:00 and 18/11/2021 23:59:59
I have this code:
bool first = DateTime.TryParse("10/10/2021 00:00:00",
CultureInfo.InvariantCulture,
DateTimeStyles.None,
out DateTime firstDate);
bool second = DateTime.TryParse("18/11/2021 23:59:59",
CultureInfo.InvariantCulture,
DateTimeStyles.None,
out DateTime secondDate);
Console.WriteLine(firstDate + " --- " + secondDate);
The output is:
10/10/2021 12:00:00 AM --- 1/1/0001 12:00:00 AM
As you can see the second date is not properly parsed, even though it's in the same format. What is the reason for that and how can I fix it?
As you can see the second date is not properly parsed, even though it's in the same format.
Here my two cents.
Programming languages and frameworks are not smart enough to know which kind of format data you applied, specially for dates, times, numbers etc.. If you provide these data, you kinda have to provide the proper format as well so they can do their job. You "said" the same format, but you didn't apply any format in your code. So, as we humans, we know (at least you told us) but the computer don't know.
Let's look what TryParse(String, IFormatProvider, DateTimeStyles, DateTime) documentation says;
Converts the specified string representation of a date and time to its
DateTime equivalent using the specified culture-specific format
information and formatting style, and returns a value that indicates
whether the conversion succeeded.
You didn't supply format information you supplied IFormatProvider as InvariantCulture. So, what are these "culture specific formats"?
Well, most of them are returns with GetAllDateTimePatterns method (but not all of them) but be aware because documentation says;
You can use the custom format strings in the array returned by the
GetAllDateTimePatterns method in formatting operations. However, if
you do, the string representation of a date and time value returned in that formatting operation cannot always be parsed successfully by the
Parse and TryParse methods. Therefore, you cannot assume that the
custom format strings returned by the GetAllDateTimePatterns method
can be used to round-trip date and time values.
So, if you run;
CultureInfo.InvariantCulture.DateTimeFormat.GetAllDateTimePatterns().Dump();
*Dump is just an extension method of LINQPad by the way, it just outputs to the console.
You will get a lot of datetime patterns, but for our case, the important one is we get MM/dd/yyyy HH:mm:ss format for InvariantCulture.
As you can see, your 18/11/2021 23:59:59 data doesn't match with MM/dd/yyyy HH:mm:ss format because there is no 18th month on Gregorian calendar which is a DateTime instance belongs internally.
Your second parsing fails by the way, that's quite different just saying "the second date is not properly parsed" and this is how DateTime.TryParse method works as explained in the documentation;
When this method returns, contains the DateTime value equivalent to
the date and time contained in s, if the conversion succeeded, or
MinValue (which is 1/1/0001 12:00:00 AM) if the conversion failed. The conversion fails if the s
parameter is null, is an empty string (""), or does not contain a
valid string representation of a date and time.
So, best way to handle this to supply a "specific" format using with DateTime.TryParseExact method or one of its overloads like;
bool first = DateTime.TryParseExact("10/10/2021 00:00:00",
"dd/MM/yyyy HH:mm:ss",
CultureInfo.InvariantCulture,
DateTimeStyles.None,
out DateTime firstDate);
bool second = DateTime.TryParseExact("18/11/2021 23:59:59",
"dd/MM/yyyy HH:mm:ss",
CultureInfo.InvariantCulture,
DateTimeStyles.None,
out DateTime secondDate);
The default DateTime format is 'MM/dd/yyyy' and since you have the date in 'dd/MM/yyyy' format it gives you the output.
Maybe try changing the date format input as 11/18/2021 23:59:59

SqlDateTime overflow error with parsing Date in SQL Server

I am trying to save date from C# to SQL Server. First want to display Date format as dd/MM/yyyy to the user. then after selecting the date on Winforms screen. I want to save it to database. If I remove datetimePicker1.CustomFormat line in the code it is saving fine to the database. But I want to display the date format as dd/MM//yyyy. How to solve this?
I'm getting this error:
SqlDateTime overflow.Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM.
Code:
//c#
DateTime fromDate;
public void SetMyCustomFormat()
{
// Set the Format type and the CustomFormat string.
//dateTimePicker1.Format = DateTimePickerFormat.Custom;
dateTimePicker1.CustomFormat = "dd/MM/yyyy";
DateTime.TryParse(dateTimePicker1.Text, out fromDate);
fromDate = fromDate.Date;
}
You didn't include any code of where you are using this value with respect to SQL Server, however the error is likely due to the D/M/Y format. This will cause a problem on, for example, Dec 31 because it will be passed as text 31/12/2014 which typically causes problems when converting to a date (depending on locale settings).
For your case just use the DateTimePicker.Value property to extract the date. This will return a DateTime type so you don't have to parse the value.
DateTime fromDate;
public void SetMyCustomFormat()
{
// Set the Format type and the CustomFormat string.
dateTimePicker1.CustomFormat = "dd/MM/yyyy";
fromDate = dateTimePicker1.Value.Date;
}
The Sql DateTime and the C# DateTime types have different valid date ranges (hence they aren't fully compatible).
Sql Datetime only support January 1, 1753, through December 31, 9999.
The issue is that your TryParse is failing causing fromDate to be 1/1/0001 which the Sql DateTime type doesn't support.
In SQL use DateTime2 and always validate the success of the parse.
http://msdn.microsoft.com/en-us/library/ms187819.aspx
http://msdn.microsoft.com/en-us/library/bb677335.aspx
UPDATED:
And the reason your TryParse is failing is because it is expecting the format mm/dd/yyyy. Instead of using TryParse use:
bool success = DateTime.TryParseExact(dateTimePicker1.Text,
"dd/MM/yyyy",
CultureInfo.InvariantCulture,
DateTimeStyles.None,
out fromDate);

sql datetime parameter problem

HI all,
I am passing the date parameter as like this:
DateTime date = DateTime.Now;
date.ToString("YYYY-MM-DD 00:00:00:000");
But getting this exceptions:
System.Data.SqlTypes.SqlTypeException: SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM. at System.Data.SqlTypes.SqlDateTime.FromTimeSpan(TimeSpan value) at System.Data.SqlTypes.SqlDateTime.FromDateTime(DateTime value)
There should be a decimal dot between the seconds and the milliseconds. The format string is case sensitive. Try:
date.ToString("yyyy-MM-dd")
or
date.ToString("yyyy-MM-dd HH:mm:ss.fff")
Also ask yourself whether you really need to convert arguments to strings. It smells odd and it may not be necessary. If you want to pass only the date and not the time, then pass the Date property of your DateTime object as your parameter value. Keep it strongly-typed to avoid SQL-injection, performance and type conversion issues.
No parameter is being passed in here, the code sample you have posted is incomplete by looking at the resulting SqlTypeException
Also the date format should be:
date.ToString("yyyy-MM-dd HH:mm:ss:fff")
If you are trying to ignore the time portion (hence your zeros) try
date.ToString("yyyy-MMM-dd");
If you want the time portion too ...
date.ToString("yyyy-MMM-dd hh:mm:ss.fff tt");
Note both have 3 Ms for the month which makes them unambiguous strings that SQL should be able to parse and cannot misinterpret.
But, why not just pass the value as a date object rather than convert to a string?

Convert.DateTime

What Convert.DateTime will convert the date 7/25/2010 12:00:00 it's current format is(MM/dd/yyyy HH:mm:ss)?
When I convert this string format to date time I am getting the error "string was not recognized as valid DateTime"
None. Dates are not stored internally as a certain format.
If you want to parse a string into a date, use DateTime.ParseExact or DateTime.TryParseExact (the former will throw an exception if the conversion fails, the second uses an out parameter):
DateTime myDate = DateTime.ParseExact("7/25/2010 12:00:00",
"MM/dd/yyyy HH:mm:ss",
CultureInfo.InvariantCulture);
If you want to display a certain format, use ToString with the format string.
So, if you have a date object that represents midday of the 25th of July 2010 (doesn't matter how it is represented internally) and you want to format it with the format string "MM/dd/yyyy HH:mm:ss" you do the following:
string formattedDate = myDate.ToString("MM/dd/yyyy HH:mm:ss");
If you need to use Convert.DateTime, I'll assume you're working with a string you want to convert to a date. So you might try this:
DateTime date = Convert.DateTime("7/25/2010 12:00:00 am");
string formattedDateString = date.ToString("MM/dd/yyyy HH:mm:ss")
I'm making no assumptions as to why you'd want to do this, except that, well, you have your reasons.
DateTime.TryParse() or DateTime.Parse() will do the trick.
Edit: This is assuming that you are going from a string to a DateTime object.
Edit2: I just tested this with your input string, and I receive no error with DateTime.Parse

Categories