I need to convert a C# datetime object into the dreaded Excel date format:
https://datapub.cdlib.org/2014/04/10/abandon-all-hope-ye-who-enter-dates-in-excel/
i.e. number of days since 1 Jan 1900 expressed as a floating point number.
Is there any way to do it without resorting to DIY code?
I need it in order to create Excel-friendly CSV exports
Googling around I didn't find anything useful except that good blog post
Excel dates use the OLE Automation date format. You can retrieve it with DateTime.ToOADate
OA Dates are a double whose integer part is the date offset from 30 December 1899 (ie earlier dates are negative) and fractional part is the time divided by 24.
This type was used a lot in the COM/VB6 days. Nowadays it's needed for Excel and when you need to call COM APIs that expect dates or variants with a date content.
You can use following method to convert from Excel Date back to C# DateTime
return DateTime.FromOADate(SerialDate);
Related
Basically I have been tasked with editing the company database for dates field known as 'CreateDt'.
However the dates with in this field are stored in numerous amounts of formats which need to be converted into one, some examples are shown below;
29/01/2001 08:51:56
29/01/2001 12:09:07
05/06/2002
30/01/2001 11:48:53
31/01/2001 09:30:12
11/12/2014
12 December 2014
15/12/2014
15/12/2014
15 December 2014
15/12/2014
I have previously tried SQL server to convert however I have encountered problems when day and month values are less than 13 and dates are changing from
for example
11/12/2014
to
21/11/2014
Would anyone have C# code which would enable me to format all dates accordingly
There is no such code because simply put, a computer cannot do, what a human cannot define.
11/12/2014
Can you tell me whether that is "November 12th" or "11th of December"? Probably not and that's not surprising. But neither can a computer.
Your best bet is to gather all formats that you think are applicable. For example for the value above, you need to decide which format is correct and which value you want to get. Then convert all your data with those few formats.
In an Excel cell, I put 12, if I format it as Date, then it is 1/12/1900.
In C#, I use DateTime.FromOADate(12), it returns 1/11/1900.
but if I put 411 in Excel and format it as date, it will be 2/14/1901.
In C#, DateTime.FromOADate(411) returns 2/14/1901, too.
I am confused about the discrepancy. How can I get the right Date in C# then?
This is an Excel quirk where it emulates a Lotus 1-2-3 bug for compatibility.
The year 1900 was not a leap year, but Excel treats it as a leap year to be compatible with the Lotus 1-2-3 bug. The OLE date/time processing correctly does not.
There is this amusing anecdote about the issue: http://www.joelonsoftware.com/items/2006/06/16.html
If you need to work around this and emulate the Excel behaviour before 1 March 1900, you can set a double instead of a date, and do a DateTime to double conversion that respects the Excel bug too. Internally Excel always represents the dates as doubles anyway.
I've loaded data from a delimited .doc file into an Excel workbook application using a querytable.
Subsequently I'm trying to loop through the data on the worksheet and save the data into particular variable types e.g.:
string gender = range.Rows.Cells[index + 7].FormulaLocal;
DateTime birth_date =Convert.ToDateTime(range.Rows.Cells[index + 8].FormulaLocal);
int SSN = Convert.ToInt32(range.Rows.Cells[index + 9].FormulaLocal);
I get an exception, however with the above code saying
"String was not recognized as a valid DateTime."
Now on screen in the worksheet the data in that field reads "07/09/1972"
However in the debugger I'm instead getting a value of "26489" and this seems to be the source of the exception as c# cannot convert this into a DateTime Object.
Anyone know what's going on here and how best to fix it?
When converting from Office, you must use the DateTime.FromOADate method. This is because Office uses OLE Automation date, which is a format where a floating point value is calculated, counting the days from the last of December 1899. The hours and minutes are represented as fractional days, thus adding a few decimals to the value 26489 would result in a time stamp that also represents hours, minutes and seconds.
DateTime d = DateTime.FromOADate(26489);
Console.WriteLine(d);
will output
1972-07-09 00:00:00
Excel stores dates as numbers (representing number of days and fractional days since midnight, 30 December 1899) - use FromOADate to convert to a CLR DataTime
double dbl = range.Value;
DAteTime dt = DateTime.FromOADate(dbl);
DateTime.FromOADate(Convert.ToDouble(text)).ToString("MM/dd/yyyy")
I've got something like this DateTime.Now.ToString("dd.MM.yy"); In my code, And I need to add 1 week to it, like 5.4.2012 to become 12.4.2012 I tried to convert it to int and then add it up, but there is a problem when it's up to 30.
Can you tell me some clever way how to do it?
You want to leave it as a DateTime until you are ready to convert it to a string.
DateTime.Now.AddDays(7).ToString("dd.MM.yy");
First, always keep the data in it's native type until you are ready to either display it or serialize it (for example, to JSON or to save in a file). You wouldn't convert two int variables to strings before adding or multiplying them, so don't do it with dates either.
Staying in the native type has a few advantages, such as storing the DateTime internally as 8 bytes, which is smaller than most of the string formats. But the biggest advantage is that the .NET Framework gives you a bunch of built in methods for performing date and time calculations, as well as parsing datetime values from a source string. The full list can be found here.
So your answer becomes:
Get the current timestamp from DateTime.Now. Use DateTime.Now.Date if you'd rather use midnight than the current time.
Use AddDays(7) to calculate one week later. Note that this method automatically takes into account rolling over to the next month or year, if applicable. Leap days are also factored in for you.
Convert the result to a string using your desired format
// Current local server time + 7 days
DateTime.Now.AddDays(7).ToString("dd.MM.yy");
// Midnight + 7 days
DateTime.Now.Date.AddDays(7).ToString("dd.MM.yy");
And there are plenty of other methods in the framework to help with:
Internationalization
UTC and timezones (though you might want to check out NodaTime for more advanced applications)
Operator overloading for some basic math calcs
The TimeSpan class for working with time intervals
Any reason you can't use the AddDays method as in
DateTime.Now.AddDays(7)
I'm making a library that uses OpenXML in C# to read excel files. I can read a cell text and numbers just fine, but when it comes to dates there's a problem.
There's the type "date" for the cells, but apparently Excel 2007 doesn't save the dates in that type, so I can't tell if the value I'm reading is a date or not, instead it appears to use styles.
How could I detect if it is a date and return the string representation of it (ex: 29-12-2010)?
Excel stores dates as a float value... the integer part being the number of days since 1/1/1900 (or 1/1/1904 depending on which calendar is being used), the fractional part being the proportion of a day (ie the time part)... made slightly more awkward by the fact that 1900 is considered a leap year.
The only thing that differentiates a data from a number is the number format mask. If you can read the format mask, you can use that to identify the value as a date rather than a number... then calculate the date value/formatting from the base date.