MySQL script to convert DateTime.Ticks values to SQL Date - c#

I have an old MySQL database where I stored dates as C# DateTime.Ticks.
Now I want to convert that old database to a new structure for a PHP app that has needs a datefield. How do I convert DateTime.Ticks to MySQL dates?
I am looking for something in the following format YYYY-MM-DD HH:mm:ss:
SELECT someconversion(olddate) as newDate FROM table;
Thank you so much in advance

Dotnet Ticks are stored in 64-bit integers in units of 100ns (ten million per second) since an epoch of 0001-01-01 00:00:00 UTC.
MySQL Days (as used in FROM_DAYS()) count elapsed days from 0000-01-01.
For example 2016-01-09 00:00:00 in Ticks is 635879124000000000 or, for readability
635 879 124 000 000 000
So, presumably your oldate column datatype is BIGINT or DOUBLE in MySQL. Either that, or it's a text string.
The thing to know is that the UNIX Epoch, 1970-01-01 00:00:00 UTC, has this Ticks value: 621355968000000000. This is the ultimate magic number.
At any rate, here's how to convert Ticks within MySQL. We'll convert to UNIX timestamps, then to DATETIME columns.
SELECT FROM_UNIXTIME((yourcolumn/10000000.0) - (62135596800.0))
But, here's the thing. The output of this FROM_UNIXTIME() gets converted implicitly to your local time. You may want to preserve the UTC times when you store this data.
There are two ways to do that. One is to use the TIMESTAMP datatype to store these converted times. The other is to set your MySQL session timestamp to 'UTC' before you do this conversion operation, like this:
SET time_zone = 'UTC';
Here is another way to do the same thing, but one that doesn't depend on using Unix timestamps. (Those timestamps are only valid from 1970 to 2038.) It depends on converting ticks to days, then on converting the remainder to seconds. It converts ticks directly to a DATETIME data type.
select FROM_DAYS(365+(yourcolumn / 864000000000))
+ INTERVAL (yourcolumn % 864000000000) / 10000000 SECOND
The constant 864000000000 (864 000 000 000) is the number of ticks in a day.
Breaking this down:
yourcolumn / 864000000000 is the number of days since 0001-01-01
FROM_DAYS(365+(yourcolumn / 864000000000)) is the date.
(yourcolumn % 864000000000) / 10000000 is the remainder of the division in step 1, in seconds.
FROM_DAYS(date) + INTERVAL seconds SECOND gets the full timestamp.

is this what you want?
select DATE_FORMAT([yourcolumn],'%Y-%M-%D %H:%m:%s') from [yourtable];
Here's the link for variant date format Date format options

This was a pain for me, but what I did was to store datetime.ticks in DB as Bigint then...
Datetime MyDateTimeVar = new datetime(Convert.toint64(DB.ticks)); //This gets the datetime from ticks!

Related

Comparing the binary representation of DateTime in C#

I have a DateTime represented as long (8 bytes), that came from DateTime.ToBinary(), let's call it dateTimeBin. Is there an optimal way of dropping the Time information (I only care for the date) so I can compare it to a start of day? Lets say we have this sample value as a start of day.
DateTime startOfDay = new DateTime(2020,3,4,0,0,0);
long startOfDayBin = startOfDay.ToBinary();
I obviously know I can always convert to a DateTime object then get the date component. However, this operation is going to happen billions of times and every little performance tweak helps.
Is there an efficient way of extracting the Date info of dateTimeBin without converting it to DateTime? Or any arithmetic operation on the long that will return the date only?
Is there a way to match startOfDay (or startOfDayBin) and dateTimeBin if they have the same date components?
Is there a way to see if (dateTimeBin >= startOfDayBin), I don't think the long comparison is valid.
N.B. all the dates are UTC
Since you are working only with UTC dates - makes sense to use DateTime.Ticks instead of DateTime.ToBinary, because former has relatively clear meaning - number of ticks since epoch, just like the unix time, the only difference is unix time interval is second and not tick (where tick is 1/10.000.000 of a second), and epoch is midnight January 1st of 0001 year and not year 1970. While ToBinary only promises that you can restore original DateTime value back and that's it.
With ticks it's easy to extract time and date. To extract time, you need to remainder of division of ticks by number of ticks in a full day, so
long binTicks = myDateTime.Ticks;
long ticksInDay = 24L * 60 * 60 * 10_000_000;
long time = binTicks % ticksInDay;
You can then use convert that to TimeSpan:
var ts = TimeSpan.FromTicks(time);
for convenience, or use as is. The same with extracting only date: just substract time
long date = binTicks - (binTicks % ticksInDay);
Regular comparision (dateTimeBin >= startOfDayBin) in also valid for tick values.

timestamp like 6.3527482515083E+17

I'm getting via WSDL from C# application timestamp number like
6.3527482515083E+17
6.3527482515047E+17
6.352748251638E+17
6.3527482514463E+17
All are the times in the past (this year, probably)
I think that's is the datetime counted from YEAR ZERO. I try to count up seconds from ZERO and get someting about 63537810544. But this is not exact, because missing leap years.
exists in PHP any function how to get UNIX timestamp ??? or convert it to STRING datetime ???
I get values via WSDL so I can't reformat it on source...
They are in 100 nanosecond ticks (1/10,000,000 of a second) from 12:00:00 midnight, January 1, 0001. This information can be found in this MSDN article.
A single tick represents one hundred nanoseconds or one ten-millionth of a second. There are 10,000 ticks in a millisecond, or 10 million ticks in a second.
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.
The magic constant that represents the number of 100ns ticks between 12:00:00 midnight January 1 0001 and 12:00:00 midnight January 1 1970 (Unix epoch time) is 62135596800000000. So if you subtract that from your numbers you get 100ns ticks since beginning of Unix Epoch time. Divide that by 10,000,000 and you get seconds. And that is usable in PHP. Sample code below to demonstrate (unixepoch is in seconds):
<?php
$msdatetime = 6.3527482515083E+17;
$unixepoch = ($msdatetime - 621355968000000000)/10000000 ;
echo date("Y-m-d H:i:s", $unixepoch);
?>
Output:
2014-02-08 11:55:15
I found this constant listed on this helpful site dealing with the problem of getting unix epoch time from other formats.

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

SQLIte SUM datetimes

I have a database with rows, with time values. I want a SUM of that time values (generaly, the format are %H:%M).
I used SUM value like that:
SELECT SUM(n_hores) FROM table;
But only I get 0.0.
How I can do that ?
Thanks
Time values in hh:mm format are strings, and strings cannot be summed meaningfully.
You should convert these time values into a number (strftime(%s) returns the number of seconds since 1970-01-01, so you have to subtract the offset from the start of the day to get the number of seconds corresponding to your time value):
SELECT sum(strftime('%s', MyTime) - strftime('%s', '00:00')) FROM MyTable
You can also convert this number of seconds back into a time string (time() returns it in hh:mm:ss format):
SELECT time(sum(strftime('%s', MyTime) - strftime('%s', '00:00'))) FROM MyTable
You're probably better off subtracting the two dates by getting the "number of milliseconds since the last epoch aka (modern epoch)." There should be a function, in SQLite, that returns the number of milliseconds since the last epoch. Once you've found this, the solution should be a simple subtraction and conversion to seconds, minutes and/or hours.

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();

Categories