I have an excel file in the first column which contains dates in the format dd.MM.yyyy hh:mm:ss. I'm trying to display data from an excel table in datagridview, but the date is displayed as a float number.
I tried to convert the date to the desired format in this way, but it does not work:
worksheet.Cells[2, 1, endCell.Row, 1].Style.Numberformat.Format = "dd.MM.yyyy hh:mm:ss";
The full code of my method:
public static DataTable readTableFromExcel(FileInfo file)
{
DataTable table = new DataTable();
Console.WriteLine(file.Exists);
using (ExcelPackage package= new ExcelPackage(file))
{
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
ExcelWorksheet worksheet = package.Workbook.Worksheets[0];
ExcelCellAddress startCell = worksheet.Dimension.Start;
ExcelCellAddress endCell = worksheet.Dimension.End;
ExcelRange range = worksheet.Cells[startCell.Row, startCell.Column, endCell.Row, endCell.Column];
ExcelTable excelTable = worksheet.Tables.Add(range, "table");
Console.WriteLine(worksheet.Cells[2, 1].Value.ToString());
table = excelTable.ToDataTable();
}
return table;
}
String with Console.Writeline outputs 44912,0912268519 instead of 17.12.2022 2:11:22.
Then I output the data to datagridview: tableView.DataSource = table;
And it looks like: https://i.stack.imgur.com/aXx6V.png
File used: https://drive.google.com/drive/folders/1hXKmKs_F7EyO5GdVU3HVATxDLlFWO4jk?usp=share_link
How can I display the datetime correctly?
In Excel, dates and times are stored as a floating point number representing the number of days since the epoch date of January 1, 1970. This means that when you read a date or time value from an Excel file into a C# DateTime object, you will need to convert the floating point value to a DateTime object.
// Assume that the Excel date value is stored in a variable called "excelDate"
// Convert the Excel date value to a DateTime object
DateTime dateTime = DateTime.FromOADate(excelDate);
system.datetime.fromoadate
Related
I have a excel file with a column with format like this
when i tried to get cell value by
var v = cell.Value;
it return Double, so how can i get value as text ?
Cast the cell value back to a DateTime object. Then you can format it any way you want.
DateTime date = DateTime.FromOADate((double)cell.Value);
string dateFormatted = date.ToLongDateString();
I am trying to read an Excel file in my ASP.NET application using the following piece of code (ADO.NET):
// Create OleDbCommand object and select data from worksheet Sheet1
String query = String.Format("Select * From [{0}$]", sheetName);
OleDbCommand cmd = new OleDbCommand(query, oledbConn);
// Create new OleDbDataAdapter
OleDbDataAdapter oleda = new OleDbDataAdapter();
oleda.SelectCommand = cmd;
//Fills Data to DataTable
oleda.Fill(dt);
The problem is that values in the data table are represented
1) For decimals either with a comma (3,14) or with a dot (3.14)
2) For dates with either the format 'DD/MM/YYYY' or'MM/DD/YYYY'
For the same Excel file depending on the locale settings server has.
Is there any way to read the data in a specific locale in order to get the correct values from the Excel file?
In the case of the column with decimals, use the following to parse them: (Decimal.Parse)
string decimal1 = "3,14";
string decimal2 = "3.14";
decimal d1 = decimal.Parse(decimal1, new NumberFormatInfo { NumberDecimalSeparator = "," });
decimal d2 = decimal.Parse(decimal2);
Note that with a , you need to use a custom NumberFormatInfo for it to parse right.
Then for your DateTime column:
string date1 = "14/03/2018";
string date2 = "03/14/2018";
DateTime dt1 = DateTime.ParseExact(date1, "dd/MM/yyyy", CultureInfo.InvariantCulture);
DateTime dt2 = DateTime.ParseExact(date2, "MM/dd/yyyy", CultureInfo.InvariantCulture);
Here you will want to specify the differnt formats for your dates.
EDIT:
To be more general about parsing an unknown DateTime format, you could try iterating through all the formats for your CultureInfo or multiple CultureInfo if you know there might be more than one. An example is below of how you could do this:
string dateTimeString = #"03/14/2018";
string[] possibleStandardFormats = new CultureInfo("en-US")
.DateTimeFormat.GetAllDateTimePatterns();
DateTime? result = null;
foreach (string format in possibleStandardFormats) {
if (DateTime.TryParse(dateTimeString, out DateTime dateTime)) {
// this format could work
result = dateTime;
break;
}
}
if (result == null) {
// no luck with any format
// try one last parse
if (DateTime.TryParse(dateTimeString, out DateTime dateTime)) {
// finally worked
result = dateTime;
}
else {
// no luck
}
}
Here it may be more effective to try the general DateTime.TryParse first (shown at the end of this example), as it could save you the iterations through the other formats. Up to you how you want to handle this, but this example should handle the majority of the cases.
EDIT 2:
In order to get the standard DateTime formats, you can use the CurrentCulture which will help with your dates. In my previous edit, I hard coded new CultureInfo("en-US"), but the below is a bit more general.
string[] possibleStandardFormats = new CultureInfo(CultureInfo.CurrentCulture.Name)
.DateTimeFormat.GetAllDateTimePatterns();
EDIT 3:
To expound a bit more on the previous parsing of decimals, first check if the string has a comma and then parse it according to the method I have listed above.
string decimal1 = "3,14";
if (decimal1.Contains(",")) {
decimal d1 = decimal.Parse(decimal1, new NumberFormatInfo { NumberDecimalSeparator = "," });
}
else {
decimal d1 = decimal.Parse(decimal1);
}
EDIT 4:
To incorporate culture into parsing decimals, you can try the Convert.ToDecimal method. One of its parameters takes a CultureInfo where you can pass in your current culture as CultureInfo.CurrentCulture. For example below, I am using de-de (German) since that is a valid culture for 1.234,14
string decimal1 = "1.234,14";
string decimal2 = "1,234.14";
decimal d1 = Convert.ToDecimal(decimal1, new CultureInfo("de-de"));
decimal d2 = Convert.ToDecimal(decimal2, CultureInfo.CurrentCulture);
I'm hoping that there is something I am not seeing clearly, but to simplify, I have the below code
foreach (DataRow row in dt.Rows)
{
row["StartOn"] = Convert.ToDateTime(row["StartOn"].ToString()).ToString("MMM dd").ToString();
}
If I run the below code I get “Aug 09”
Convert.ToDateTime(row["StartOn"].ToString()).ToString("MMM dd").ToString();
If I look to see what is in row[“StartOn”] after this change it contains “8/9/2016 12:00:00 AM”
I'm unable to format my DataRow to an "MMM dd" format
StartOn is apparently a DateTime type. DateTime types do NOT have a format. They are an object that specifies year, month, date, and time (among other things). All you are doing in your conversions is stripping out the time so that the new datetime has a time of 12:00 am.
What is dt.Columns["StartOn"]. I suspect this is DateTime. Let me break down your single line of code into 2 lines.
string s = Convert.ToDateTime(row["StartOn"].ToString()).ToString("MMM dd").ToString();
row["StartOn"] = s;
In line 1, you are converting a DateTime object to a string object. But on line 2, you are implicitly converting your string to a DateTime
var dt = new DataTable();
dt.Columns.Add("StartOn", typeof(DateTime));
dt.Rows.Add(DateTime.Today);
foreach (DataRow row in dt.Rows) {
var data = Convert.ToDateTime(row["StartOn"].ToString()).ToString("MMM dd").ToString();
Console.WriteLine($"Type of stored data is: {data.GetType()}");
row["StartOn"] = data;
}
// fetch the data
var fetchedData = dt.Rows[0][0];
Console.WriteLine($"Type of Fetched Data is: {fetchedData.GetType()}");
BTW, you can use the below line to do the conversion
((DateTime)row["StartOn"]).ToString("MMM dd");
I am new to excel and C#. I am fetching data from database and showing in excel. In a array when ever there is a null record I am replacing it with '0'. My issue is after I format the column to a date format '0' is replaced by default value '1/0/1900'. I need a custom format which will format only date records and but not zeros.
Note:In below Code Data= contains array of records. CreateDataArray will check for null records and will replace by 0.
object[,] updateValues = CreateDataArray(data, 1, direction);
IRange dataRange = _rangeHelper.GetRangeBeside(startCell, data.Length - 1, direction);
dataRange.Value2 = updateValues;
// Apply format
dataRange.NumberFormat = "m/d/yyyy";
dataRange.NumberFormatLocal = "m/d/yyyy";
Try this:
dataRange.NumberFormat = "m/d/yyyy;;#0";
when am trying to read datetime type value from excel sheet it is returning a double value.for example if want to read value '2007-02-19 14:11:45.730' like this, i am getting a double type value .further i am converting this double value using timespan,but not complete successfully because i am getting only this value '2007-02-19 12:00:00 AM'
now i want exact same datetime value as first one. My code is like :-
TimeSpan datefromexcel = new TimeSpan(Convert.ToInt32((range.Cells[rCnt, cCnt] as Excel.Range).Value2), 0, 0, 0);
DateTime inputdate = new DateTime(1900, 1, 1).Add(datefromexcel);
arrrow2[cCnt - 1] = inputdate.ToString();
Please help!!!
Thanks.
You need to convert the date format from OLE Automation to the .net format by using DateTime.FromOADate.
double d = double.Parse(b);
DateTime conv = DateTime.FromOADate(d);
Perhaps you could try using the DateTime.FromOADate method to convert between Excel and .net.
Reading Datetime value From Excel sheet : Try this will be work.
string sDate = (xlRange.Cells[4, 3] as Excel.Range).Value2.ToString();
double date = double.Parse(sDate);
var dateTime = DateTime.FromOADate(date).ToString("MMMM dd, yyyy");
Alternatively, if your cell is already a real date, just use .Value instead of .Value2:
excelApp.Range[namedRange].Value
{21/02/2013 00:00:00}
Date: {21/02/2013 00:00:00}
Day: 21
DayOfWeek: Thursday
DayOfYear: 52
Hour: 0
Kind: Unspecified
Millisecond: 0
Minute: 0
Month: 2
Second: 0
Ticks: 634970016000000000
TimeOfDay: {00:00:00}
Year: 2013
excelApp.Range[namedRange].Value2
41326.0
Or you can simply use OleDbDataAdapter to get data from Excel
i had a similar situation and i used the below code for getting this worked..
Aspose.Cells.LoadOptions loadOptions = new Aspose.Cells.LoadOptions(Aspose.Cells.LoadFormat.CSV);
Workbook workbook = new Workbook(fstream, loadOptions);
Worksheet worksheet = workbook.Worksheets[0];
dt = worksheet.Cells.ExportDataTable(0, 0, worksheet.Cells.MaxDisplayRange.RowCount, worksheet.Cells.MaxDisplayRange.ColumnCount, true);
DataTable dtCloned = dt.Clone();
ArrayList myAL = new ArrayList();
foreach (DataColumn column in dtCloned.Columns)
{
if (column.DataType == Type.GetType("System.DateTime"))
{
column.DataType = typeof(String);
myAL.Add(column.ColumnName);
}
}
foreach (DataRow row in dt.Rows)
{
dtCloned.ImportRow(row);
}
foreach (string colName in myAL)
{
dtCloned.Columns[colName].Convert(val => DateTime.Parse(Convert.ToString(val)).ToString("MMMM dd, yyyy"));
}
/*******************************/
public static class MyExtension
{
public static void Convert<T>(this DataColumn column, Func<object, T> conversion)
{
foreach (DataRow row in column.Table.Rows)
{
row[column] = conversion(row[column]);
}
}
}
Hope this helps some1
thx_joxin
You may want to try out simple function I posted on another thread related to reading date value from excel sheet.
It simply takes text from the cell as input and gives DateTime as output.
I would be happy to see improvement in my sample code provided for benefit of the .Net development community.
Here is the link for the thread C# not reading excel date from spreadsheet
Another option: when cell type is unknown at compile time and cell is formatted as Date Range.Value returns a desired DateTime object.
public static DateTime? GetAsDateTimeOrDefault(Range cell)
{
object cellValue = cell.Value;
if (cellValue is DateTime result)
{
return result;
}
return null;
}