Converting Timespan to DateTime in C# - c#

I am reading Excel worksheet data using C# and Microsoft.Office.Interop. The sheet contains some date values. When I am trying to read that value it is just giving the number (probably TimeSpan). I am having problem converting this number into DateTime.
Below is the code:
TimeSpan ts = TimeSpan.Parse(((Range)ws.Cells[4, 1]).Value2.ToString());
Where ws is Excel.WorkSheet.
Can anybody explain how should I convert this number (TimeSpan) into DateTime?
Thanks for sharing your valuable time.

You could do the following
double d = double.Parse(((Range)ws.Cells[4, 1]).Value2.ToString());
DateTime conv = DateTime.FromOADate(d);

Use the following:
DateTime dt = new DateTime().Add( TimeSpan.FromMilliseconds( 1304686771794 ) )

It all depends on what the number looks like ;p That is typically the offset in some interval, into some epoch - for example seconds since 1 Jan 1970. So try, for example:
var when = new DateTime(1970,1,1).AddSeconds(number);
and then try AddMilliseconds(number), AddTicks(number) etc until the date matches.

This is just icing: Excel represents dates as OLE automation dates. These values are floating point numbers, the integer part of which is the number of days after midnight, 30 Dec 1899. Or before, if it's negative. Greco's answer gives you the best way to convert :)

Related

C# Convert Date To Double

I have written a function in VBA which creates a code from the properties of a file.
I need a developer to do the same in C# on their end.
The developer says it is not possible to do the same in c#.
So in VBA, part of my process is to convert a date to a double. The way VBA does this is to basically count the number of days between the given date and 1 Jan 1900. So 19 Mar 2014 would be a double value of 41,717.
How would I say write a function in C# (not a language I am familiar with) that would convert a date data type to the number of days that have passed since 1 January 1900?
Any help would be appreciated.
Subtracting two DateTimes gives you a TimeSpan. You can just use TimeSpan.TotalDays to get the number of days between two dates:
double days = (DateTime.Today - new DateTime(1900,1,1)).TotalDays;
If the DateTime has a time component it will be represented as fractions of a day, so for example:
// current date and time (16:24:15)
(new DateTime(2014, 3, 18, 16, 24, 15) - new DateTime(1900,1,1)).TotalDays
would give you 41714.6835069444
Note that the result is 2 days different that using CDbl() in VBA since a date in VBA is represented by the number of days since 12/30/1899 rather than 1/1/1900.
Use .net DateTime method ToOADate() wich returns a double representing the OLE Automation date
VBA uses this same format to representa a date as a double.
I got exactly 3 days difference. Which might be because I'm in NZ at GMT + 12.
Or it might be because I was multiplying a double by "TicksPerDay" and .Net doesn't allow for some strange numbers.
DateTime.FromOADate(vbaTime) was the perfect solution for me moving dates between MS Access and C#.
Incidentally, I suspect that this is a result of the "date calculation issue" that Joel Spolsky refered to:
http://www.joelonsoftware.com/items/2006/06/16.html
when discussing Lotus notes compatibility in Excel as the program manager at Microsoft.
How about this, without using OLE Automation:
'get time elapsed since some earlier point in time, such as midnight today
Dim tim As TimeSpan = Now.Subtract(Today)
'calc the time elapsed in fractional seconds
'note that tim.Seconds only provides whole seconds, so add tim.Milliseconds
Dim tsec As Double = tim.Hours * 3600 + tim.Minutes * 60 + tim.Seconds + tim.Milliseconds / 1000

Data which shows up as a date in 'mm/dd/YYYY' format on spreadsheet appears as number in C#

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")

Convert Date to Milliseconds

I am working with Visual Studio 2010, MVC 3 and C#. I am creating some highcharts and need to have the x-axis be a date. I am pulling the dates from a database and adding them to and array that will then be passed to highcharts. I think highcharts requires the dates to be in millisecond format. Ho do I go about converting a DateTime of '12/20/2011 5:10:13 PM" for example to milliseconds?
Once you figure out what you want to calculate milliseconds from, you can just take one DateTime object from another to get a TimeSpan object. From TimeSpan you can get TotalMilliseconds.
In other words, if start and end are DateTime objects, you can do this:
double milliseconds = (end - start).TotalMilliseconds;
You can use the DateTime.Ticks property and convert the value to milliseconds.
The value of this property represents the number of 100-nanosecond intervals that have elapsed since 12:00:00 midnight, January 1, 0001, which represents DateTime.MinValue. It does not include the number of ticks that are attributable to leap seconds.
A single tick represents one hundred nanoseconds or one ten-millionth of a second. There are 10,000 ticks in a millisecond.
The .Ticks in C# DateTime gives you the value of any time in ticks. You can thereafter convert to milliseconds as shown below:
long dateticks = DateTime.Now.Ticks;
long datemilliseconds = dateticks / TimeSpan.TicksPerMillisecond;
DateTime[] dates = ;
var minDate = dates.Min();
var msDates = dates.Select(date => (date - minDate).TotalMilliseconds).ToArray();

Passing a datetime double that is larger than limited amount

DateTime dt=DateTime.FromOADate(duble); //e.g 3364072679.0
My double is unfortunately larger than the allowed range for OleAut Date. What should I do then ?
If the fractional (time) part isn't important you could add the remainder to the max OLE date:
double maxOLEDate = 2958466.0
int days = duble - maxOLEDate;
DateTime dt=DateTime.FromOADate(maxOLEDate).AddDays(days);
Or just add the value to the "Min" OLE Date:
DateTime dt = DateTime.FromOADate(0).AddDays((int)duble);
Edit
I stand corrected - The DateTime structure cannot support OLE date values past 2,958,466.0 (12/31/9999). Unless H. G. Wells is your user this is not valid input.
According to the online help for ToAuthDate, the maximum OLE date is the same as DateTime.MaxValue (i.e. the end of the year 9999).
Do you really need to work with dates in the year 10,000 and beyond?

how to add current date time in bigint field

I need to add the current date time in a bigint field in a database... and then display from that only the date in format: october 1, 2009.
I am currently thinking of storing the value in string variable and then converting it to int...
String s = DateTime.Now.ToString();
i dont know what to do next..
please help
You could just store the number of ticks as your bigint value. Ticks represent the number of elapsed 1/10,000 of milliseconds since January 1, 0001.
DateTime.Now.Ticks;
This can always be converted back to a DateTime by using the constructor that accepts a long:
DateTime storedTime = new DateTime(ticksFromDatabase);
To format your date, just use any of the standard date format strings. A custom format string might work better actually, I just perused them and it doesn't look like there's a built in one for the format you want. This should work:
date1.ToString("MMMM d, yyyy", CultureInfo.CreateSpecificCulture("en-US"))
I'd use a smart date key, since it's easier to find that using SQL:
20090927235000
yyyyMMddhhmmss
This way, if you want to find anything that happened on a given day, you could do:
select * from tbl where datecol between 20090927000000 and 20090927240000
Thereby making data validation a lot easier, even if you are using an ORM.

Categories