Strange behavior when converting String to DateTime - c#

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

Related

Culture dependent NumberFormat for dates in C# VSTO Excel

I'm relatively new to C# and I'm still learning a lot. I also searched stackoverflow for similar problems but got to a point where I'm stuck.
In my VSTO Excel project I'd like to output dynamic data coming from a database with a predefined number format per column also coming from the database. The user can define his own layout of the report. Everything is working just fine, I have just problems formatting the date value.
When it's about to output a date column, the format should be automatically be determined by the program instead of predefining it in the database as well. The date value gets already inserted in the Excel sheet as the decimal number it should be. Everything okay here. When I manually format it in Excel itself, it is displayed correctly.
But I want to format the date with C# like it would be formatted when I do it manually by clicking on the short date format in Excel. And it should work in every country, regardless in which language the office package was installed.
I'm working with a German installation and I expect the format to be "TT.MM.JJJJ". When formatting the column with this fixed string, it works perfectly (at least in Germany I guess).
It makes no difference if formatting it with
CurrentWorksheet.Columns[queryColumn.Position].NumberFormat = "TT.MM.JJJJ";
or
CurrentWorksheet.Columns[queryColumn.Position].NumberFormatLocal = "TT.MM.JJJJ";
Both end up in the same (correct) result. That the first line is working as well is the first thing which was unexpected for me, but that's not the main point. I tried to format it dynamically by replacing "TT.MM.JJJJ" with the following lines:
// Leads to dd.MM.yyyy
System.Globalization.DateTimeFormatInfo.CurrentInfo.ShortDatePattern;
// Fixed German culture still leads to dd.MM.yyyy
CultureInfo.CreateSpecificCulture("de-DE").DateTimeFormat.ShortDatePattern;
// MM/dd/yyyy - also not helpful
CultureInfo.InvariantCulture.DateTimeFormat.ShortDatePattern;
When using the first or second ShortDatePattern the date 27.08.2014 is shown as "dd.08.yyyy". Excel simply doesn't unterstand "dd" or "yyyy". I thought at least when using NumberFormat instead of NumberFormatLocal it would work, because it's the global format, but it doesn't. It feels like Microsoft has implemented the date formatting more complicated that it could be.
How would I determine the correct date pattern here?
The answer (it still is a kind of workaround) is pretty much found in another question:
How to set localized short-date format for a cell in Excel with C#?
There's just a very small difference I had to make in the method for constructing the ShortDatePattern (the Application parameter for DateFormatComponentCodes).
public static string ConstructExcelShortDatePattern()
{
var systemDateComponentCodes = new DateFormatComponentCodes();
var excelDateComponentCodes = new DateFormatComponentCodes(Globals.ThisAddIn.Application);
string systemShortDatePattern = CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern;
string excelShortDatePattern = systemShortDatePattern.Replace(systemDateComponentCodes.Year, excelDateComponentCodes.Year).Replace(systemDateComponentCodes.Month, excelDateComponentCodes.Month).Replace(systemDateComponentCodes.Day, excelDateComponentCodes.Day);
return excelShortDatePattern;
}
Thanks to Heinzi for finding a great answer and Jordan for providing such a useful class!

Local Time Format in Excel

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.

C# setting format of text correctly in Excel

I have a console app that creates several excel documents and everything works fine expect when I place a string called period which is Jan 19 into the cell A2.
Excel changes it to Jan-19 and when I try to change the format of the field using the code below nothing happens.
period = periodDescription.Substring(0, 3) + " 20" + year;
string numberFormat = "General";
xlWorksheet.Cells[2, 1].NumberFormat = numberFormat;
xlWorksheet.Cells[2, 1] = period;
What am i doing wrong?
Update:
Should add I have tried
string numberFormat = "";
string numberFormat = "MMM yyyy";
The General format will autodetect for dates and format them accordingly. I believe what you want to do is explicitly mark it a string by adding a single quote mark to the beginning of it.
Edit: It might be, depending on your final usage, more appropriate to change the formatting of the output to the "MMM dd". This would leave a date in the cell and format it for display the way you want.
The post here:
Changing excel format
Answer the question with:
string numberFormat = "#";
You can certainly do what you are seeking by using a raw text format (using #), but there may be advantages to treating the field as a date, in which case the format is definitely possible. For example, if you sort on this field as text, "Feb 19" will come before "Jan 19," which is probably not what you want.
The raw text solution is simply:
ws.Cells[1, 1].NumberFormat = "#";
ws.Cells[1, 1].Value = "Jan 19";
Presumably, you mean January 2019, in which case any reasonable date format (based on your locale) would result in a date within January, and then a format of mmm yy would render that as "Jan 19:"
ws.Cells[2, 1].Value = "1-Jan-2019";
ws.Cells[2, 1].NumberFormat = "mmm yy";
And just to prove this works, the notion of an Excel date (the number of days after 1/1/1900 or something similar) should even work directly:
ws.Cells[3, 1].Value = "43466";
ws.Cells[3, 1].NumberFormat = "mmm yy";
These last two methods will retain the format you desire and still treat the cells as values that enable sorting and math.
Here are the results of the above three statements:
Interestingly I am guessing the "Jan-19" was probably translated to 1/19/2018, which I am guessing is not what you intended.

EPPlus load custom value

I have cell which contains value
7.11.2014
in custom format
dd/mm/yyyy
so in excel it looks like
07/11/2014
when i load it via EPPLus
cellValue = sheet.Cells[row, column].Value.ToString();
it loads the General format value, which is
41950
How can i load the Value 07/11/2014 or other date format with i can work ?
Thank you
Looking over some similar code that I've done before, all you'll need to do is to use DateTime.Parse() and it should come out exactly how you want it.
As I mentioned in the comments Excel saves the actual dates as being a number of days from its epoch date of 1/1/1900 (hence why you keep seeing 41950). .NET code will accept that, and will convert it to the correct date.
OK i got it, this code works
long serialDate = long.Parse(sheet.Cells[r, c].Value.ToString());
cellValue = DateTime.FromOADate(serialDate).ToString("dd-MM-yyyy");
Thank you for help :)

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

Categories