In my script component, I am trying to assign a value to a Date column (the datatype is DT_DATE). These are DateTime objects in C#, so I thought the following would work:
FooBuffer.Datevar = DateTime.Now;
It compiles, but the line gives an error at runtime:
Error: 0xC020901C at FoobarFlow, OLE DB Destination [77]: There was an error with OLE DB Destination.Inputs[OLE DB Destination Input].Columns[Datevar] on OLE DB Destination.Inputs[OLE DB Destination Input]. The column status returned was: "The value could not be converted because of a potential loss of data.".
My guess is that, since the DateTime class in C# is designed to have precision up to seconds (or even milliseconds -- not sure), and DT_DATE's precision only goes up to days, there would be a possible loss of information.
So the question is, how do I assign such a column's value correctly? Is there any way to convert DateTime object to a Date before assigning it?
Assuming you have a DateTime value in an arbitrarily named variable newDate, try the following:
FooBuffer.DateVar = new DateTime(newDate.Year,
newDate.Month,
newDate.Day,
newDate.Hour,
newDate.Minute,
newDate.Second);
DateTime.Now contains more precision than DT_DATE is capable of storing. Try this instead.
DateTime.Now.Date
Related
I have a Postgres db with a "time" field. Data is stored like "16:00:00".
C# does not have a Time type so I use DateTime.
However, I am getting an error when the time field has a value:
Error parsing column 71 (my_time_field=16:00:00 - Object) ---> System.InvalidCastException: Specified cast is not valid.
So Dapper is not able to automatically map a nullable Time field to a nullable C# DateTime property.
Is there a way to tell Dapper how to handle this one particular field? Currently I handle this when using a DataReader by just prepending a date like this:
string time = reader["my_time_field"].ToString();
var dateTime = DateTime.Parse($"01/01/0001 {time}");
I have some C# code that copies rows from one database and inserts them into another. It does this using a DataTable and SqlBulkCopy.
When imported into my C# application, the timestamp columns have the data type System.DateTime inside the DataTable that is inserted into SQL Server. Once SqlBulkCopy.WriteToServer() has executed, timestamp values inside the destination tables have the type datetimeoffset(6) and have a timezone offset added to them (... +01:00).
How do I stop this happening? It hasn't always happened, only started happening recently.
UPDATE:
The timezone expected is UTC, always, for my purposes. However, I am forced to store this in a datetimeoffset column for business reasons. So I'm expecting +00:00
DataTable data = importer.GetDataTable();
using (SqlBulkCopy copy = new SqlBulkCopy(conn)){
copy.WriteToServer(data);
}
If you have a DateTime and try to write it to a DateTimeOffset C# has to figure out what timezone to use. There are explicit conversion functions that allow you to specify but if you don't it will assume the DateTime is in the local timezone (as the majority of the time they are).
https://learn.microsoft.com/en-us/dotnet/standard/datetime/converting-between-datetime-and-offset provides several examples on how to convert between the two. Note that SpecifyKind doesn't require having a DateTimeOffset type.
Using DateTime.SpecifyKind() on timestamp columns before inserting them into Sql Server didn't work for me.
I solved this by converting (casting) the System.DateTime columns to DateTimeOffset with an explicit offset of new TimeSpan(0, 0, 0). This removed the need for C# to implicitly handle the conversion from DateTime to DbType.DateTimeOffset which was adding an undesired offset.
EDIT
Reading the comments, #JohnSkeet essentially recommended this but I hadn't read everyone's comments.
Another solution could be to use your DateTime.ToUniversalTime() method, and you will remove the time offset.
I want to convert date time value from datatable to only show time value.
I have below code to make this convert process;
DateTime ST = DateTime.ParseExact(dtPivot.Rows[e.DataRow][0].ToString(), "HH:mm:ss",CultureInfo.InvariantCulture);
ulbTime.Text = ST.ToString("HH:mm:ss");
However this throws an error
String was not recognized as a valid DateTime
I searched however couldn't find a solution for me.
How can I solve this ?
Your question asks how to show it so use String.Format to show the time portion
DateTime ST = Convert.ToDateTime(dtPivot.Rows[e.DataRow][0]);
var t = string.Format("{0:hh:mm}",ST);
You shouldn't need to parse, since the entry being pulled from the database should already be a DateTime field. So in theory, you should be able to pull the data in the following.
var model = IDbConnection.Query(query);
var time = model.First().Date.ToString("hh:mm:ss");
So if you're using a object relational mapper, such as Dapper your model has a DateTime for the object, then you use the string formatter to do the time.
You could also do:
var time = model.First().TimeOfDay();
Built directly into the DateTime is a time of day, works similar to a date short hand method. You could obviously use a DateReader or DataTable accessing the column information index, with a ToString("hh:mm:ss") to return the time specifically. But, you can't do ToString in some instances, because a DBNull.Value or invalid value will cause a reference exception. So you'll need to sanitize and ensure those odd values can't be passed.
I prefer the above, because the mapper should associate the value based on your defined type. So you don't need any extra casting or converting.
consider me a beginner in c#
I am doing some changes in a pre developed software (C#.Net) , we are saving data by datewise , Currently in insert query (build in c#) we are passing GETDATE() to save today date , but now we have to save data on the basis of a different date.
When I am building query in c# , I m passing that a datetime variable into query
after conversion , conversion as follow
Date_Stamp = DateTime.ParseExact(dt.Rows[0][0].ToString(), "MM/dd/yyyy HH:mm:ss tt", new CultureInfo("en-IN"));
but it is showing error "String was not recognized as a valid DateTime.".
The reason to convert is coz these date field are getting displayed in format ToString("yyyy-MM-dd"));
Which will give 2017-07-13 14:56:30.233 as 13-jul-2017 on front end (as per requirement). We cant change this part of code as it is being used in lot of places , hard to change .
Problem is
variable storing value as
2017-12-07 00:00:00.000
which give after conversion 07-Dec-2017 [wrong - it is needed as 12-jul-2017]
GETDATE storing value as
2017-07-12 14:56:30.233
which is after conversion coming right as 12-jul-2017
I know there is no datetime format in sql server when it come to storing data
But can we store value from variable [2017-12-07 ] as [2017-07-12 ] ?
How GETDATE() give us date in year-month-date format
?
Neither .NET's nor SQL Server's date related type have any format. All of them are binary values, just like integers and decimals. Formats apply only when they are explicitly or implicitly converted to strings, or parsed from strings.
Assuming your query looked something like SELECT GETDATE(), ... and you loaded the results to an DataTable, the values will be returned as DateTime values. If you used a strongly-typed DataTable you could just use the value. With a generic DataTable the value will be boxed and return as an object.
All you have to do is just cast the field value to DateTime :
Date_Stamp = (DateTime)dt.Rows[0][0];
This will also work for date and datetime2 types. datetimeoffset is returned as DateTimeOffset. time is returned as TimeSpan.
The problem in the original is caused because the field value is formatted into a string using the current culture dt.Rows[0][0].ToString() first. Then ParseExact is called trying to parse it using a different format. A simple DateTime.Parse(dt.Rows[0][0].ToString()) would have worked (even though it would be wasteful), since both DateTime.Parse and DateTime.ToString() use the same culture.
UPDATE
Reading date fields from a table has no issues - the values are returned using the appropriate date type. For example, running SELECT StartDate from ThatTable will return DateTime if the table's schema is :
CREATE TABLE ThatTable
(
ID int,
StartDate datetime
)
Problems are caused if, instead of using the correct type, dates are stored as strings in VARCHAR columns. That's a serious bug that needs to be fixed. There is NO assurance that the strings can be parsed to dates at all, or that they follow the same format. It's all too easy for some faulty application code to use eg DateTime.Now.ToString() and store a localized string in there.
Even if the format is the same, it's just wasteful and unreliable. The string takes more storage than the equivalent type, introduces conversion issues, prevents the use of date functions, and the server can't apply date optimizations to queries and indexing.
I need to have C# via Entity Framework save current datetime to sql server into table column of datatype datetime
Was reading that DateTime.Now in C# is not going to be correct ...
so I stumbled across where a guy posted that he was doing this as it saves down to the proper millisecond
System.Data.SqlTypes.SqlDateTime entry2
= new System.Data.SqlTypes.SqlDateTime(new DateTime(dto.LookUpDateTime));
DateTime entry = entry2.Value;
Now I assumed with the Overloads that I should be able to just do this:
System.Data.SqlTypes.SqlDateTime dt
= new System.Data.SqlTypes.SqlDateTime(new DateTime());
However, I get an error in catch block saying 'sqldatatime overflow...`
DateTime dateTime = dt.Value;
rpmuser.lst_pwd_chg_dtm = dateTime;
rpmuser.cre_dtm = dateTime;
Can I use DateTime.Now or what do I need to do to get this SqlDateTime to work?
This is almost certainly because you are trying to store a date that is outside the supported range. On MS SQL Server the datetime field type can hold datetime values in the range 1-Jan-1753 00:00:00 to 31-Dec-9999 23:59:59.997 inclusive. This is narrower than the range explicitly supported by the .NET DateTime type (1-Jan-0001 00:00:00 to 31-Dec-9999 23:59:59 plus a fraction). So any date prior to 1-Jan-1753 will cause that error.
A common problem is when you use either DateTime.MinValue to indicate a specific state of your data but don't filter that to something the SQL field can contain before sending the data to the database. The solution in this case would be to define a suitable lower boundary of the data and define a static value that is lower but still within the SQL range.
If your data needs to include dates and times outside of the valid range for the SQL datetime field type then you might want to use the datetime2 field type which has the same effective range as the .NET DateTime type. Which is unsurprising since it appears to be the same data structure - count of 100ns ticks since 1-1-1.