field<t> invalid cast - c#

I'm having problems when using linq on a datatable.asenumerable().
This throws InvalidCastException.
DateTime date=r.Field<DateTime>("date");
This works fine.
DateTime date = DateTime.Parse(r.Field<string>("date"));
What am I missing?
Regards Sven

Why would you expect it to work? The following code doesn't compile:
DateTime dt1 = (DateTime)"2004-01-01";
Whereas this does:
DateTime dt1 = DateTime.Parse("2004-01-01");
As in, you can't just cast a string to a DateTime, so if your value is a string, you need to explicitly convert it.

Are you sure your "date" column is of type DateTime?
This test code works as expected:
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("date", typeof(DateTime)));
for (int i = 0; i < 10; i++)
{
DataRow row = dt.NewRow();
row["date"] = DateTime.Now.AddDays(i);
dt.Rows.Add(row);
}
foreach (var r in dt.AsEnumerable())
{
DateTime d = r.Field<DateTime>("date"); // no problems here!
Console.Write(d.ToLongDateString());
}

Cast works between related types. string and date don't belong to same hierarchy & hence no direct translation is possible.
You can use cast, when you are sure that the types are related and conversion is possible.
Parse is different than cast.
i.e you are telling the runtime to see if it can be parsed to make a date out of it (per your example).

Related

How can I store a formatted DateTime into column of type DateTime in Database?

I'm retrieving data from the database in a dataset and printing it in a pdfdocument. One table has got a DateTime column and the value comes as "12/27/2018 12:00:00 AM". I'm trying to format that as dd/MM/yyyy but with no success since it is expecting a DateTime and formatting return a string value. Should I change the column datatype or there is a way to maintain it and format the datetime?
I recommend changing the database from string to DateTime. But if you cannot you can use something like this
DataTable dt1 = new DataTable();
DataTable dt2 = dt1.Clone();
//change columns type
dt2.Columns["Col A"].DataType = typeof(DateTime);
int colNumber = dt2.Columns.IndexOf("Col A");
foreach (DataRow row in dt1.AsEnumerable())
{
object[] rowData = row.ItemArray;
rowData[colNumber] = DateTime.Parse(row.Field<string>("Col A"));
dt2.Rows.Add(rowData);
}

How to update first column of a datatable for all rows using LINQQ or any other method?

I have a data table with 4 columns datetime,id, message & status. I want to update the datetime column with a new datetime (updated datetime is in different time zone, from CST to UTC). First I was thinking to do it like I would take the datetime column and store it in a list and convert the list to utc time zone from cst.Then add the list to the same table and rearrange the columns. But this sounds stupid so is there any way to update the existing value with new values for one column of datatable.
I found the below code in one of the posts but not sure what exactly is happening.
var rowsToUpdate =
dt.AsEnumerable().Where(r => r.Field<string>("datetime") == datetime);
foreach(var row in rowsToUpdate)
{
row.SetField("datetime", utcDate);
}
The data in datatable is in CST timezone but I want that timezone to be converted to UTC timezone and update the table.
List<DateTime> lstCST = new List<DateTime>();
lstCST = datatable.AsEnumerable().Select(r=>r.Field<DateTime>("CSTDatetime")).ToList();
List<DateTime> lstUTC = new List<DateTime>();
DateTime dt = DateTime.Now;
foreach(var v in lstCST )
{
dt= TimeZoneInfo.ConvertTimeToUtc(v);
lstUTC.Add(dt);
}
Can anybody point me in the right direction on how to do this.
If you want to update all rows you don't need LINQ but TimeZoneInfo.ConvertTimeToUtc:
TimeZoneInfo cstZone = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
foreach (DataRow row in dataTable.Rows)
{
DateTime cstDateTime = row.Field<DateTime>("CSTDatetime");
DateTime utcDateTime = TimeZoneInfo.ConvertTimeToUtc(cstDateTime, cstZone);
row.SetField("CSTDatetime", utcDateTime);
}
Look at this example:
DataTable table = new DataTable();
table.Columns.AddRange(new DataColumn[]
{
new DataColumn(),
new DataColumn(),
new DataColumn()
});
table.Rows.Add(1, 2, 3);
foreach (DataRow dr in table.Rows)
{
dr[0] = 99;
}
it will update all rows of the first column and set it to 99
To explain what the snippet does:
This is a filter:
var rowsToUpdate =
dt.AsEnumerable().Where(r => r.Field<string>("datetime") == datetime);
It selects all rows where the "datetime" column has a specific value. In your case, I guess you can ignore this, you want to do this on all rows.
So instead of iterating on the filtered rows, iterate all rows.
foreach(var row in rowsToUpdate)
{
row.SetField("datetime", utcDate);
}
The latter snippet sets the "datetime" value in each row of the selection to the value of utcDate. In your case, just replace this by first getting the "old" value, convert it and then use the above line to set the converted value.
#TimSchmelter already gave a ready-to-go solution so I won't repeat it. I rather wanted to explain what was seemingly unclear to you.

how can I format this string to MM/dd/yyyy

I have tried a lot of syntax but I can't get it work,
from my DataTable i have this values , please see below
the above values are from the jQuery datepicker, I just make them values in my query.
C#:
I catch the values from the datepicker using this parameter`
List<DateTime> WeekDates
how can i make it to display as 1/6/2016 . thank you for any help!
foreach (DataRow row in dt.Rows)
{
Sale sales = new Sales();
sale.WeekStart = row["WeekStart"].ToString("MM/dd/yyyy");
}
UPDATE
is my date values are string or a DateTime already? I catch the values in my webmethod using this
List<DateTime> WeekDates, but when it comes to my dataTable it has a single quotes , notice it.
Try
foreach (DataRow row in dt.Rows)
{
Sale sales = new Sales();
var date = Convert.ToDateTime(row["WeekStart"]);
sale.WeekStart = date.ToString("MM/dd/yyyy"); // If sale.WeekStart field is string
}
Complete description: http://www.csharp-examples.net/string-format-datetime/
[YourDateTimeVarialble].ToString("MM/dd/yyyy");
[date].ToString("MM/dd/yyyy");
you can use this one
Have you tried
sale.WeekStart =DateTime.Parse(row["WeekStart"].ToString()).ToString("MM/dd/yyyy");
I think this is work for you
Try
(DateTime.ParseExact(row["WeekStart"]), "M/d/YYYY hh:mm:SS tt", System.Globalization.CultureInfo.InvariantCulture)).ToString("MM/dd/yyyy");
If those values came from a database, you may want to format them first before populating to your DataTable. For your desired format, you may refer to this post.
Update 1
Try formatting your jQuery DatePicker to something like:
$(".selector").datepicker({ dateFormat: "MM/dd/yyyy" });
Update 2
foreach (DataRow row in dt.Rows)
{
Sale sales = new Sales();
sale.WeekStart = Convert.ToDateTime(row["WeekStart"]).ToString("MM/dd/yyyy");
}
Try something like this
string date = "1/6/2016 12:00:00 AM";
string d = Convert.ToDateTime(date).ToShortDateString();
O/P : 1/6/2016
In your case perhaps following code will be useful
DataTable dt = new DataTable();
dt.Columns.Add("Date");
DataRow row1 = dt.NewRow();
row1["Date"] = "1/6/2016 12:00:00 AM";
dt.Rows.Add(row1);
DataRow row2 = dt.NewRow();
row2["Date"] = "2/6/2016 12:00:00 AM";
dt.Rows.Add(row2);
List<string> WeekStart = new List<string>();
foreach (DataRow row in dt.Rows)
{
WeekStart.Add(Convert.ToDateTime(row["Date"]).ToShortDateString());
}
try this
string text = row["Weekstart"].ToString();
DateTime date = DateTime.ParseExact(text, "dd/MM/yyyy", null);
Thank you for all who answered my question. As for now the quick solution for me is to remove unnecessary string to display the format MM/dd/yyyy
using this syntax
row["WeekStart"].ToString().Remove(9);
Most of you answered the correct syntax to convert it to the MM/dd/yyyy but I figured out that the values of dates from my jQuery datepicker has a single quote value, what I did is removed it before feeding to my SQL parameters and everything works fine. I already used that syntax before I post here , I just need to remove the single quote in my datetime values.

Filtering DateTime Column of DataTable Causes FormatException

I have a DataTable dt bound to a DataGridView. I have been filtering the data in this grid at run-time using the standard query syntax. However, for a known DateTime column in this DataTable the query
DataRow[] rowArray = dt.Select("DOB >= #01/01/97# AND DOB <= #31/01/97#");
But this is throwing a FormatException with the message:
String was not recognized as a valid DateTime.
I have tried changing the above to
DataRow[] rowArray = dt.Select("DOB >= #01/01/1997# AND DOB <= #31/01/1997#");
But this gave the same error. From MSDN it seems I am filtering correctly. I can confirm that the DataTable column 'DOB' is indeed a DateTime type.
What is wrong with the filter statement?
Thanks for your time.
The only thing I can think about is the Locale. This seems you use GB Locale. Try this.
CultureInfo myCultureInfo = new CultureInfo("en-gb");
dt.Locale = myCultureInfo;
DataRow[] rowArray = dt.Select("DOB >= #01/01/1997# AND DOB <= #31/01/1997#");
Just pass two DateTime variables into your Select statement like this: (based on your comment regarding inputting the date in text boxes, I also added some data validation)
DateTime startDate;
DateTime endDate;
var isValidStartDate = DateTime.TryParse(txtStartDate.Text, out startDate);
var isValidEndDate = DateTime.TryParse(txtEndDate.Text, out endDate);
if (isValidStartDate && isValidEndDate)
{
var rowArray = dt.Select(
string.Format("DOB >= #{0}# AND DOB <= #{1}#", startDate, endDate));
// do something with rowArray
}
else
{
// uh-oh...
}

Specified cast is not valid when getting Datatable Column Value

The above error message appears when I am trying to get Column Value from Datatable.
This is what I find in the stacktrace:
System.Linq.Enumerable.WhereSelectEnumerableIterator2.MoveNext()
at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable1
source)
and this in the TargetSite when debugging:
{ Boolean b__0(System.Data.DataRow)}
Here is my code:
DataTable hr = new DataTable();
hr.Columns.Add("BookingDate");
hr.Columns.Add("BookingId");
hr.Columns.Add("BookingSource");
hr.Columns.Add("CheckInDate");
hr.Columns.Add("CheckOutDate");
for (int i = 0; i < gmisc.GetModifiedBookings(gmoreq).Bookings.Length; i++)
{
hr.Rows.Add();
hr.Rows[i]["BookingDate"] = Convert.ToDateTime(gmisc.GetModifiedBookings(gmoreq).Bookings[i].BookingDate.ToString());
hr.Rows[i]["BookingId"] = Convert.ToInt64(gmisc.GetModifiedBookings(gmoreq).Bookings[i].BookingId.ToString());
hr.Rows[i]["BookingSource"] = gmisc.GetModifiedBookings(gmoreq).Bookings[i].BookingSource.ToString();
hr.Rows[i]["CheckInDate"] = Convert.ToDateTime(gmisc.GetModifiedBookings(gmoreq).Bookings[i].CheckInDate.ToString());
hr.Rows[i]["CheckOutDate"] = Convert.ToDateTime(gmisc.GetModifiedBookings(gmoreq).Bookings[i].CheckOutDate.ToString());
}
Int64 BookingId = (from DataRow dr in hr.Rows
where (Int64)dr["BookingId"] == BookId
select (Int64)dr["BookingId"]).FirstOrDefault();
TextBox1.Text = Convert.ToString(BookingId);
Where did I go wrong, if somebody can please tell me.
Check your code, the very first two lines:
hr.Rows[i]["BookingDate"] = Convert.ToDateTime(gmisc.GetModifiedBookings(gmoreq).Bookings[i].BookingDate.ToString());
hr.Rows[i]["BookingId"] = Convert.ToInt64(gmisc.GetModifiedBookings(gmoreq).Bookings[i].BookingId.ToString());
if gmisc.GetModifiedBookings(gmoreq).Bookings[i].BookingDate is null then ???
you are trying to convert it into string and then to datetime
if null then .ToString will give error "Specified cost......."
and same will happen at the time of converting to datetime.
If dr["BookingId"] is never null (otherwise add null check)
Use
Int64 BookingId = (from DataRow dr in hr.Rows
where Int64.Parse(dr["BookingId"].ToString()) ==BookId
select Int64.Parse(dr["BookingId"].ToString())).FirstOrDefault();
Instead of
Int64 BookingId = (from DataRow dr in hr.Rows
where (Int64)dr["BookingId"] == BookId
select (Int64)dr["BookingId"]).FirstOrDefault();
When you create a data column using the Add(string) overload, the type of the column is string (see http://msdn.microsoft.com/en-us/library/52xzw8tf.aspx). You cannot cast a string directly to Int64 or DateTime.
Use the Add(string, Type) overload or the Add(string, Type, string) overload to specify the type of the column's data.

Categories