Local Time Format in Excel - c#

I'm using c# to import same data in Excel and on of the cell in each row has date time
var dataToImportToExcel= new object[1048576, 10] //Array of data
foreach(...)
{
...
dataToImportToExcel[row, columnIndex++] = UnixTime.LocalTimeToDateTime(time)
...
}
Here UnixTime is defined as Epoch.AddMilliseconds(unixTimeStamp)
After creating the above variable it's passed to current worksheet
var writeRange = currentWorkSheet.Range[i, j];
writeRange.Value2 = dataToImportToExcel;
Excel is showing date time format as 02/05/2021 06:04:37.000 pm instead of 5/2/2021 6:04:35 pm, here later on is the local date time format. Even if I change local date time format in machine it always uses first format only.
While debugging I can see in the IDE that date format is correctly showing in variable dataToImportToExcel

It looks your Excel understood that you wrote a DateTime value into the cell.
It's format is not defined by the value but by the formatting information set on Cell or Range. Looking into How to make correct date format when writing data to Excel topic you should set it like this:
Range rg = (Excel.Range)worksheetobject.Cells[1,1];
// Instead of "MM/DD/YYYY" you may use a format specifier appropriate for your needs.
rg.EntireColumn.NumberFormat = "MM/DD/YYYY";
This will format the entire column in the same way. Following the topic above you will find other examples like setting only one cell's format.

Related

Formatting '[$-F400]h:mm:ss\\ AM/PM' Excel 2007 date time in c#

I'm trying to read Excel 2007+ files in c# but all the libraries I have tried so far (OpenXML, ClosedXML and NPOI) seem unable to parse a cell with the time format correctly.
In Excel the data is formatted as Number > Time and uses '*hh:mm:ss' as it's type.
When I look at the raw value in the libraries it is appearing as 0.0416666666666667. I've followed advice from other posts which suggest using DateTime.FromOADate which (correctly) results in '30/12/1899 01:00:00'.
What I'm really stuck on is how to display the datetime object {30/12/1899 01:00:00} as it is displayed in Excel: '01:00:00'. I can see the Style.DateFormat is set to '[$-F400]h:mm:ss\ AM/PM' but how can I use this to format the DateTime object in C# as a string? The ToString() method doesn't recognise it as a valid format.
A DateTime by definition always has a date and a time. To only have the time you would have to use a TimeSpan. Here is a quick way you can get that.
DateTime originalDateTime = DateTime.Now;
TimeSpan hoursMinutesSeconds = originalDateTime.TimeOfDay;

C# to Excel set custom date display and value

Given a certain date, I want to set the value of a cell with a DateTime object, but without the "Time" information. For example, for today the value would just be "29/06/2012" and not "29/06/2012 16:54:36".
Concerning the display, for today's date I want it to be written like this (it is in french, I don't know how it would be in english): "29 juin" and not "29/06/2012".
How can I achieve this?
EDIT : I just took a look at the display formatting I need in Excel, it is "jj mmmm" ("dd mmmm" in C#). But the cell, though taking the value, does not take the formatting. Here is a piece of code:
cell.Value = string.Format("{0:dd/MM/yyyy}", DateTime.Now);
cell.NumberFormat = "jj mmmm";
I also tried:
cell.Value = DateTime.Now;
cell.NumberFormat = "jj mmmm";
In that case, the display formatting is OK, but the cell value contains the Time information, which is not OK.
See this StackOverflow question, and my answer to it. It will allow you to set the custom format for the cell directly in the excel sheet, from there you just need to research what the different date format strings are.
That is only helpful if you are using excel automation though.
Otherwise, formatting the DateTime.ToString output will be better. Once again, researching the different DateStringFormatting options will be helpful to you.
Final option. Directly change the template, not using automation. Goto the cell and manually change the cell format until the display is what you want. This does not change the actual data, just its display.
UPDATE
There are two specific issues to deal with.
Issue one is making sure excel recognizes that this IS a date. To that end, make certain that the date data itself is formatted en-US. Why, because Microsoft is dumb, and doesn't recognize international date formats.
Issue two is the display format for the cell. For a 3 letter abbreviation of the month, use the string d mmm. If you want the full month name, use d-mmmm.
I was testing and noted that excel refused to treat 29/06/2012 16:54:36 as a date, but it accepted 06/29/2012 16:54:36 without an issue. As I said, microsoft is dumb.
just change DateTime.Now to DateTime.Date and the time will be zero'd out
DateTime has a method called ToShortDateString
// Displays Fri 29 Aug
Console.WriteLine(date1.ToString("ddd d MMM", CultureInfo.CreateSpecificCulture("fr-FR")));
This would be a good resource for you: msdn custom date and time format strings

changing date format before insertion to database

I'm uploading an excel file to a server and then inserting its rows and columns into a database. I'm doing it line by line but I have a problem with datetime. After inserting 146 rows of data I get an error which reads:
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
The statement has been terminated.
The problem is its the date. In the excel files the dates are formatted dd/mm/yyyy but the the database is taking them as being mm/dd/yyyy so when the date does past the 12th I get the out-of-range errror. I dont want to change my excel files so is there an option I can change on the database (MS SQL-server) or do I have to use c# code which can convert them before they get inserted... Thanks...
If you know the format coming from Excel, you are best parsing the string to a DateTime in C# with a specific IFormatterProvider.
The problem here is there is no culture information on the string coming from Excel, so the conversion to a DateTime can only take into account the culture of the database - in this case a format that reverses the month and day. This will mean that dates outside the range (as in your case) or ambiguous dates will never parse correctly.
In C# code you are able to specify a culture that implements IFormatterProvider, en-GB has the date format of the Excel dates you specify. The example in the MSDN documentation shows how to do this. My example briefing shows how to convert a string with an en-GB date format into a DateTime that is culture agnostic:
var culture = CultureInfo.CreateSpecificCulture("en-GB");
var date = DateTime.Parse("13/12/2011", culture);
SQL has the same problem with culture. A string representation of any culture-sensitive data will always lose the current culture. When converting that data you need to specify the culture if it differs from the server.
You can do this in SQL and hard-code the format of the string you are trying to convert (103 represents en-GB date formats dd/mm/yyyy):
declare #datestring varchar(10) = '13/12/2011' --13th December
-- 103 is the format code for UK dates with full yyyy century.
select convert(date, #datestring, 103) --gives 2011-12-13
declare #datestring2 varchar(10) = '05/04/2011' --5th April, ambiguous date.
select convert(date, #datestring2, 103) --gives 2011-04-05
Convert / cast format codes.
It is also worth noting that this will also correctly convert ambiguous dates such as 05/04/2011, which would reverse the month/day if the culture wasn't known.
For example, if you tried to convert the UK 5th April 2011 into a US date without telling the parser what the format is, you will get 4th May 2011 as output - reversing the month and day.
You can do this before inserting with T-SQL :
set dateformat dmy
See http://msdn.microsoft.com/fr-fr/library/ms189491.aspx
You can do in database as well probably try to write a stored procedure that inserts your data to database using your excelsheet.
User below mentioned TSQL code in your SP and that will work.
CREATE PROCEDURE ABC
AS
-- Do some operation
SET DATEFORMAT ydm;
insert into #dates
select '2008-09-01','2008-09-01'
END
I think you have to do it in c#.
Try something like this:
String excelDate = ...
String[] dateParts = excelDate.Split('/');
String sqlDate = dateParts[1] + "/" + dateParts[0] + "/" + dateParts[2];
...
First parse your excel datetime to C# datetime object and format the datetime object as let's say
DateTime dt = DateTime.Parse(drExcel["dateofExcel"]);
drDB["DateTime"] = dt.ToString("s");
hopefully it will solve your problem

Strange behavior when converting String to DateTime

Im experiencing strange behavior when converting String to DateTime and then again ToString().
Convert.ToDateTime("16-02-2012").ToString("MM/dd/yyyy") results in 02-16-2012
Convert.ToDateTime("16-02-2012").ToLongDateString() results in 16. februar 2012
As you can see the conversion is correct when using ToLongDateString() but somehow the / is converted to - when using ToString().
When I insert the first result into a Excel sheet the value is actually '02-16-2012 (notice the ' in the beginning)
When I use a date where the first segment is lower than 12 the result contains / as expected but is reverted to dd/MM/yyyy.
I've tried using new System.Globalization.CultureInfo("da-DK", false) when converting ToDateTime() but with no effect (Our system is already set to da-DK - but I got desperate).
Anyone seen this behavior before?
EDIT
To clarify my post a little, the date format in danish is dd-mm-yyyy (which I want to format to mm/dd/yyyy) - I know that the first segment is month in a english date.
Change
Convert.ToDateTime("16-02-2012").ToString("MM/dd/yyyy")
to
Convert.ToDateTime("16-02-2012").ToString("dd/MM/yyyy")
It's just a typo.
If that's not what you want, try this:
DateTime.Parse("16-02-2012", CultureInfo.CreateSpecificCulture("da-DK"));
Then you can add whatever .ToString(...) you want on the end.
Edit 2: Your computer is outputting the date in your own culture. If you want it parsed and displayed correctly, you need to provide culture info for each operation.
Console.WriteLine(DateTime.Parse("16-02-2012", CultureInfo.CreateSpecificCulture("da-DK")).ToString(CultureInfo.CreateSpecificCulture("da-DK")));
// 16-02-2012 00:00:00
To export the data in the format you want, you can insert the data as DateTime and use a cell format like in the following example (assuming your dates are in column A):
Application Excel = new Application();
Workbook workbook = Excel.Workbooks.Add(1);
Worksheet sheet = workbook.Sheets[1];
sheet.Cells[1, 1] = DateTime.Now;
sheet.Cells[2, 1] = DateTime.Now.AddDays(1);
sheet.Cells[3, 1] = DateTime.Now.AddDays(2);
sheet.UsedRange.Columns["A:A", Type.Missing].NumberFormat = "MM/dd/yyyy";
workbook.Sheets.Add(sheet);
// Save the workbook or make it visible

Formatting DateTime in Excel XML worksheet

When generating an Excel XML workbook with ASP.NET i'm appending 3 cells in a row like:
sb.Append(String.Format(
"<Cell><Data ss:Type=\"DateTime\">{1}</Data></Cell>{0}",
Environment.NewLine,
item.DateAvailable.ToString("yyyy-MM-ddTHH:mm:ss.fffffffK")
)); // newlines added for readability;
item.DateAvailable is a C# DateTime that has to end in Excel as An cell-DateTime.
so
value from debug in VS2010 in asssembly:
2011-08-15T01:16:06.8470000
value in excel:
40761,2299142361
after manual conversion of the cell formatting:
6-08-11 5:31
However, when converting it outputs in excel as a number, and the cell formatting is set to custom. When I manually change the cell formatting back to DateTime the correct??? date is shown in the correct format. But of course, the business would not accept such a raw data they have to convert themselves ;)
Perhaps I am using the wrong StringFormat?
What is the correct format to write a DateTime in this case and output it in Excel in the correct DateTime Format?
Yes, you are using a "wrong" string format, i.e. a format that Excel does not automatically recognize (or parse appropriately) as a date. Drop the T. Also, the date-time format in Excel rounds at least to milliseconds, if not to integer seconds, so you might as well drop some of those decimal places.
This should work:
item.DateAvailable.ToString("yyyy-MM-dd HH:mm:ss.ffff")

Categories