Converting DateTime.Ticks to a Unix timestamp and back in PHP

By , March 16, 2011 7:45 am

I recently found out that the DateTime library in C# provides the ability for much higher resolution of time compared to the PHP date time function. While PHP can go down to an impressive microsecond, C# can go all the way down to nanoseconds. Though I am still skeptical that it can actually calculate that small of a division of a second, it does return an impressively large representative number. Since PHP does not go down to nanoseconds it requires a bit of extra effort to convert between nanoseconds and seconds, but it is definitely doable and even fairly trivial once you know the requirements.

Some background on the PHP side of things for those who may not know, when dealing with seconds in PHP it comes from the Unix epoch and is called a Unix timestamp. The Unix epoch date is 01-01-1970 (some have a slightly different figure, but you can find that debate yourself). So 00000000 is 01-01-1970 when converted from the Unix timestamp to something human readable. 05-15-1986 is 51552440.

Taking that knowledge we need to determine when the Unix epoch occurs in DateTime.Ticks. Though I was working with Ticks generated from C# I did not have access to C# while writing this, but luckily Kramer Campbell provided the answer for us in an article on his website. You can read his article for more information on finding this number.

Unix epoch date in C# DateTime.Ticks
621355968000000000

Converting DateTime.Ticks to a Unix timestamp in PHP

Now that we know the Unix epoch in Ticks we can use a simple equation to do the conversion for us. First we need to subtract the current Tick value from the Unix epoch Tick value (Remember, Unix timestamps start at the Unix epoch), then we need to convert the result from nanoseconds into seconds.

Equation
(TICKS – 621355968000000000) / 10000000

The PHP function to do this is as follows

  1. function ticks_to_time($ticks) {
  2. return ($ticks621355968000000000) / 10000000;
  3. }

Simple enough right? What if we are using a service where not only do we need to be able to read the DateTime.Ticks, but also we need to convert into Ticks as well.

Converting a Unix timestamp to DateTime.Ticks

We already have everything we need. Simple reverse the equation from above and you will get the nanoseconds from seconds.

Equation
(UNIX_TIMESTAMP * 10000000) + 621355968000000000

Not to hard right? The problem you will face lies with PHPs automatic conversion of this large number into scientific notation. An annoyance, but not really a big deal if you know how to deal with it. We run another mathematical equation on it, or even loop through and change each number in sequence manually but there is no need for that. PHP provides us with a very usable solution in the form of number_format().
Here is what you need to know for number_format() to work.

  1. umber_format(UNIX_TIMESTAMP, 0, ‘.’, ‘’);

Putting that all together in a simple function results in

  1. function time_to_ticks($time) {
  2. return number_format(($time * 10000000) + 621355968000000000 , 0, '.', '');
  3. }

Converting strings into DateTime.Ticks

Now that I had the ability to seamlessly convert between these two systems I also needed to find the Ticks N X ago, E.G. 10 Minutes ago. PHP provides the strtotime() function which let’s us find the Unix timestamp in plain English. For example, to find the Unix timestamp from 10 minutes ago you would use

  1. strtotime(-10 minutes”);

Pretty simple; instead of running the necessary functions manually in PHP I created another function to handle it for me. This function reuses the other functions we defined above and will take in and valid string PHP can convert into a Unix timestamp and convert it into DateTime.Ticks.

Here is the code:

  1. function str_to_ticks($str) {
  2. return time_to_ticks(strtotime($str));
  3. }

Wrap it up!

There you go, now you have the knowledge to convert between C# DateTime.Ticks and Unix timestamps in PHP. Take the provided code and toss it into a file somewhere which you can easily reference, or expand and build it into your own library. Happy timing!

Download PHP code to convert DateTime.Ticks to a Unix timestamp and back from github

 

Leave a Reply

2 Responses to“ Converting DateTime.Ticks to a Unix timestamp and back in PHP”

  1. Antonie says:

    Thank you very much!

    I’ve been struggling for a while to generate UTC time in ticks since a specific date and just couldn’t get it working as intended.

    This was the only article which showed me how to do this properly!

Theme by Blam Designs
Based on Themocracy

  Globals Profiler (1,750.00 ms) SQL (84 queries in 1,099.24 ms) Errors (1) Toggle Close
$_GET = array (
);

$_POST = array (
);

$_COOKIE = array (
);

$_SESSION = array (
);

$_SERVER = array (
  'SERVER_SOFTWARE' => 'Apache/2.2.22',
  'REQUEST_URI' => '/blog/749/converting-datetime-ticks-to-a-unix-timestamp-and-back-in-php',
  'PATH' => '/usr/local/bin:/usr/bin:/bin',
  'REDIRECT_HANDLER' => 'php-stable',
  'REDIRECT_STATUS' => '200',
  'UNIQUE_ID' => 'VHmQ4EAN6BoAABVDNbcAAAAL',
  'SCRIPT_URL' => '/blog/749/converting-datetime-ticks-to-a-unix-timestamp-and-back-in-php',
  'SCRIPT_URI' => 'http://ben.lobaugh.net/blog/749/converting-datetime-ticks-to-a-unix-timestamp-and-back-in-php',
  'WM_UCONTROL_XMLRPC_SERVER' => 'http://10.0.0.13',
  'ACCESS_DOMAIN' => 's21288.gridserver.com',
  'DATABASE_SERVER' => 'internal-db.s21288.gridserver.com',
  'SITE_ROOT' => '/home/21288',
  'SITE_CGIROOT' => '/home/21288/cgi-bin',
  'SITE_HTMLROOT' => '/home/21288/domains/ben.lobaugh.net/html',
  'PHPRC' => '/home/21288/etc/',
  'HTTP_PHPCONF' => '1127907457',
  'HTTP_HOST' => 'ben.lobaugh.net',
  'HTTP_ACCEPT_ENCODING' => 'x-gzip, gzip, deflate',
  'HTTP_USER_AGENT' => 'CCBot/2.0 (http://commoncrawl.org/faq/)',
  'HTTP_ACCEPT_LANGUAGE' => 'en-us,en-gb,en;q=0.7,*;q=0.3',
  'HTTP_ACCEPT' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
  'SERVER_SIGNATURE' => '<address>Apache/2.2.22 Server at ben.lobaugh.net Port 80</address>
',
  'SERVER_NAME' => 'ben.lobaugh.net',
  'SERVER_ADDR' => '64.13.232.84',
  'SERVER_PORT' => '80',
  'REMOTE_ADDR' => '54.197.183.230',
  'DOCUMENT_ROOT' => '/home/21288/domains/ben.lobaugh.net/html',
  'SERVER_ADMIN' => 'webmaster@ben.lobaugh.net',
  'SCRIPT_FILENAME' => '/home/21288/domains/ben.lobaugh.net/html/index.php',
  'REMOTE_PORT' => '48875',
  'REDIRECT_URL' => '/index.php',
  'GATEWAY_INTERFACE' => 'CGI/1.1',
  'SERVER_PROTOCOL' => 'HTTP/1.0',
  'REQUEST_METHOD' => 'GET',
  'QUERY_STRING' => '',
  'SCRIPT_NAME' => '/index.php',
  'ORIG_SCRIPT_FILENAME' => '/etc/apache2/gs-bin/php-stable',
  'ORIG_PATH_INFO' => '/index.php',
  'ORIG_PATH_TRANSLATED' => '/home/21288/domains/ben.lobaugh.net/html/index.php',
  'ORIG_SCRIPT_NAME' => '/gs-bin/php-stable',
  'PHP_SELF' => '/index.php',
  'REQUEST_TIME' => 1417253088,
  'argv' => 
  array (
  ),
  'argc' => 0,
);

Profiler Initiaded 0.0000 ms 13908 kB
Profiler Noise 0.0319 ms 13908 kB
Profiler Stopped 1,750.0000 ms 34205 kB
12.7850 [ms]
SELECT option_value FROM wp_options WHERE option_name = 'bwp_minify_advanced' LIMIT 1;
13.5529 [ms]
SELECT option_value FROM wp_options WHERE option_name = 'prlipro_options' LIMIT 1;
13.2511 [ms]
SELECT option_value FROM wp_options WHERE option_name = 'jetpack_id' LIMIT 1;
13.0520 [ms]
SELECT option_value FROM wp_options WHERE option_name = 'gplus_authors' LIMIT 1;
13.2010 [ms]
SELECT option_value FROM wp_options WHERE option_name = 'wp_mobile_app_promos' LIMIT 1;
13.2411 [ms]
SELECT option_value FROM wp_options WHERE option_name = 'wp_mobile_disable' LIMIT 1;
13.2790 [ms]
SELECT option_value FROM wp_options WHERE option_name = 'ap_stylesheet' LIMIT 1;
13.2699 [ms]
SELECT option_value FROM wp_options WHERE option_name = 'ap_dateTimeFormat' LIMIT 1;
13.1550 [ms]
SELECT option_value FROM wp_options WHERE option_name = 'widget_wysija' LIMIT 1;
13.1428 [ms]
SELECT option_value FROM wp_options WHERE option_name = 'widget_akismet_widget' LIMIT 1;
13.1938 [ms]
SELECT option_value FROM wp_options WHERE option_name = 'widget_toc-widget' LIMIT 1;
13.1671 [ms]
SELECT option_value FROM wp_options WHERE option_name = 'widget_facebook-likebox' LIMIT 1;
13.1509 [ms]
SELECT option_value FROM wp_options WHERE option_name = 'widget_gallery' LIMIT 1;
13.1750 [ms]
SELECT option_value FROM wp_options WHERE option_name = 'widget_grofile' LIMIT 1;
13.2210 [ms]
SELECT option_value FROM wp_options WHERE option_name = 'widget_image' LIMIT 1;
13.0961 [ms]
SELECT option_value FROM wp_options WHERE option_name = 'widget_jetpack_readmill_widget' LIMIT 1;
13.1080 [ms]
SELECT option_value FROM wp_options WHERE option_name = 'widget_rss_links' LIMIT 1;
13.1021 [ms]
SELECT option_value FROM wp_options WHERE option_name = 'widget_upcoming_events_widget' LIMIT 1;
13.2589 [ms]
SELECT option_value FROM wp_options WHERE option_name = 'widget_jetpack_display_posts_widget' LIMIT 1;
13.2761 [ms]
SELECT option_value FROM wp_options WHERE option_name = 'akismet_comment_nonce' LIMIT 1;
13.2711 [ms]
SELECT * FROM wp_prli_links WHERE slug='749/converting-datetime-ticks-to-a-unix-timestamp-and-back-in-php';
12.8429 [ms]
SELECT * FROM wp_prli_links WHERE slug='749/converting-datetime-ticks-to-a-unix-timestamp-and-back-in-php';
13.1569 [ms]
SELECT * FROM wp_prli_links WHERE slug='749/converting-datetime-ticks-to-a-unix-timestamp-and-back-in-php';
13.2389 [ms]
SELECT * FROM wp_prli_links WHERE slug='749/converting-datetime-ticks-to-a-unix-timestamp-and-back-in-php';
12.9571 [ms]
SELECT * FROM wp_prli_links WHERE slug='749/converting-datetime-ticks-to-a-unix-timestamp-and-back-in-php';
13.0520 [ms]
SELECT * FROM wp_prli_links WHERE slug='749/converting-datetime-ticks-to-a-unix-timestamp-and-back-in-php';
12.8498 [ms]
SELECT * FROM wp_prli_links WHERE slug='749/converting-datetime-ticks-to-a-unix-timestamp-and-back-in-php';
12.7392 [ms]
SELECT * FROM wp_prli_links WHERE slug='749/converting-datetime-ticks-to-a-unix-timestamp-and-back-in-php';
12.7480 [ms]
SELECT * FROM wp_prli_links WHERE slug='749/converting-datetime-ticks-to-a-unix-timestamp-and-back-in-php';
12.9480 [ms]
SELECT * FROM wp_prli_links WHERE slug='749/converting-datetime-ticks-to-a-unix-timestamp-and-back-in-php';
13.0160 [ms]
SELECT * FROM wp_prli_links WHERE slug='749/converting-datetime-ticks-to-a-unix-timestamp-and-back-in-php';
13.2201 [ms]
SELECT * FROM wp_prli_links WHERE slug='749/converting-datetime-ticks-to-a-unix-timestamp-and-back-in-php';
12.9261 [ms]
SELECT * FROM wp_prli_links WHERE slug='749/converting-datetime-ticks-to-a-unix-timestamp-and-back-in-php';
12.8262 [ms]
SELECT * FROM wp_prli_links WHERE slug='749/converting-datetime-ticks-to-a-unix-timestamp-and-back-in-php';
12.9168 [ms]
SELECT * FROM wp_prli_links WHERE slug='749/converting-datetime-ticks-to-a-unix-timestamp-and-back-in-php';
12.9709 [ms]
SELECT * FROM wp_prli_links WHERE slug='749/converting-datetime-ticks-to-a-unix-timestamp-and-back-in-php';
12.8191 [ms]
SELECT * FROM wp_prli_links WHERE slug='749/converting-datetime-ticks-to-a-unix-timestamp-and-back-in-php';
12.7120 [ms]
SELECT * FROM wp_prli_links WHERE slug='749/converting-datetime-ticks-to-a-unix-timestamp-and-back-in-php';
12.8040 [ms]
SELECT * FROM wp_prli_links WHERE slug='749/converting-datetime-ticks-to-a-unix-timestamp-and-back-in-php';
12.8841 [ms]
SELECT * FROM wp_prli_links WHERE slug='749/converting-datetime-ticks-to-a-unix-timestamp-and-back-in-php';
12.8989 [ms]
SELECT * FROM wp_prli_links WHERE slug='749/converting-datetime-ticks-to-a-unix-timestamp-and-back-in-php';
12.9089 [ms]
SELECT * FROM wp_prli_links WHERE slug='749/converting-datetime-ticks-to-a-unix-timestamp-and-back-in-php';
12.7888 [ms]
SELECT * FROM wp_prli_links WHERE slug='749/converting-datetime-ticks-to-a-unix-timestamp-and-back-in-php';
12.7511 [ms]
SELECT * FROM wp_prli_links WHERE slug='749/converting-datetime-ticks-to-a-unix-timestamp-and-back-in-php';
12.8608 [ms]
SELECT * FROM wp_prli_links WHERE slug='749/converting-datetime-ticks-to-a-unix-timestamp-and-back-in-php';
12.7032 [ms]
SELECT * FROM wp_prli_links WHERE slug='749/converting-datetime-ticks-to-a-unix-timestamp-and-back-in-php';
13.4361 [ms]
SELECT   wp_posts.* FROM wp_posts  WHERE 1=1  AND wp_posts.post_name = 'converting-datetime-ticks-to-a-unix-timestamp-and-back-in-php' AND wp_posts.ID
= 749 AND wp_posts.post_type = 'post'  ORDER BY wp_posts.post_date DESC ;
12.7978 [ms]
SELECT t.*, tt.*, tr.object_id FROM wp_terms AS t INNER JOIN wp_term_taxonomy AS tt ON tt.term_id = t.term_id INNER JOIN wp_term_relationships AS tr
ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ('category', 'post_tag', 'post_format') AND tr.object_id IN (749) ORDER BY t.name
ASC;
13.3631 [ms]
SELECT post_id, meta_key, meta_value FROM wp_postmeta WHERE post_id IN (749) ORDER BY meta_id ASC;
12.9941 [ms]
SELECT option_value FROM wp_options WHERE option_name = 'ap_rssUrl' LIMIT 1;
12.9991 [ms]
SELECT option_value FROM wp_options WHERE option_name = 'ap_layout' LIMIT 1;
13.1168 [ms]
SELECT option_value FROM wp_options WHERE option_name = 'ap_headerRotate' LIMIT 1;
13.0241 [ms]
SELECT option_value FROM wp_options WHERE option_name = 'ap_linkColour' LIMIT 1;
13.1078 [ms]
SELECT option_value FROM wp_options WHERE option_name = 'ap_hoverColour' LIMIT 1;
13.0458 [ms]
SELECT option_value FROM wp_options WHERE option_name = 'disabled_likes' LIMIT 1;
13.2990 [ms]
SELECT p.ID FROM wp_posts AS p  WHERE p.post_date < '2011-03-16 07:45:56' AND p.post_type = 'post' AND p.post_status = 'publish'  ORDER BY p.post_date
DESC LIMIT 1;
13.2511 [ms]
SELECT * FROM wp_posts WHERE ID = 745 LIMIT 1;
13.2580 [ms]
SELECT p.ID FROM wp_posts AS p  WHERE p.post_date > '2011-03-16 07:45:56' AND p.post_type = 'post' AND p.post_status = 'publish'  ORDER BY p.post_date
ASC LIMIT 1;
13.1650 [ms]
SELECT * FROM wp_posts WHERE ID = 755 LIMIT 1;
13.0498 [ms]
SELECT option_value FROM wp_options WHERE option_name = 's4nometa' LIMIT 1;
13.2699 [ms]
SELECT option_value FROM wp_options WHERE option_name = 's4nofbjava' LIMIT 1;
12.9931 [ms]
SELECT option_value FROM wp_options WHERE option_name = 's4cjscript' LIMIT 1;
13.0930 [ms]
SELECT option_value FROM wp_options WHERE option_name = 'ap_logoUrl' LIMIT 1;
13.0370 [ms]
SELECT option_value FROM wp_options WHERE option_name = 'ap_includeHome' LIMIT 1;
12.8040 [ms]
SELECT option_value FROM wp_options WHERE option_name = 'ap_pageMenuOrder' LIMIT 1;
12.8109 [ms]
SELECT option_value FROM wp_options WHERE option_name = 'ap_pagesOmit' LIMIT 1;
13.2980 [ms]
SELECT * FROM wp_posts  WHERE (post_type = 'page' AND post_status = 'publish')     ORDER BY menu_order ASC;
12.8078 [ms]
SELECT * FROM wp_users WHERE ID = '2';
13.5438 [ms]
SELECT user_id, meta_key, meta_value FROM wp_usermeta WHERE user_id IN (2) ORDER BY umeta_id ASC;
13.0239 [ms]
SELECT option_value FROM wp_options WHERE option_name = 's4dispvb' LIMIT 1;
12.9740 [ms]
SELECT t.*, tt.* FROM wp_terms AS t INNER JOIN wp_term_taxonomy AS tt ON t.term_id = tt.term_id WHERE tt.taxonomy = 'category' AND t.term_id = 17
LIMIT 1;
12.8539 [ms]
SELECT t.*, tt.* FROM wp_terms AS t INNER JOIN wp_term_taxonomy AS tt ON t.term_id = tt.term_id WHERE tt.taxonomy = 'category' AND t.term_id = 5 LIMIT
1;
12.9268 [ms]
SELECT t.*, tt.* FROM wp_terms AS t INNER JOIN wp_term_taxonomy AS tt ON t.term_id = tt.term_id WHERE tt.taxonomy = 'category' AND t.term_id = 19
LIMIT 1;
12.7649 [ms]
SELECT t.*, tt.* FROM wp_terms AS t INNER JOIN wp_term_taxonomy AS tt ON t.term_id = tt.term_id WHERE tt.taxonomy = 'category' AND t.term_id = 20
LIMIT 1;
13.6900 [ms]
SELECT t.*, tt.* FROM wp_terms AS t INNER JOIN wp_term_taxonomy AS tt ON t.term_id = tt.term_id WHERE tt.taxonomy = 'category' AND t.term_id = 36
LIMIT 1;
12.9960 [ms]
SELECT * FROM wp_comments  WHERE ( comment_approved = '1' ) AND comment_post_ID = 749  ORDER BY comment_date_gmt ASC ;
13.1240 [ms]
SELECT option_value FROM wp_options WHERE option_name = 'highlander_comment_form_prompt' LIMIT 1;
12.9731 [ms]
SELECT option_value FROM wp_options WHERE option_name = 'jetpack_comment_form_color_scheme' LIMIT 1;
13.1650 [ms]
SELECT option_value FROM wp_options WHERE option_name = '_transient_timeout_wpcom_subscribers_total' LIMIT 1;
13.0780 [ms]
SELECT option_value FROM wp_options WHERE option_name = '_transient_wpcom_subscribers_total' LIMIT 1;
14.2159 [ms]
SELECT   wp_posts.ID FROM wp_posts  WHERE 1=1  AND wp_posts.post_type = 'post' AND ((wp_posts.post_status = 'publish'))  ORDER BY wp_posts.post_date
DESC LIMIT 0, 5;
13.1431 [ms]
SELECT wp_posts.* FROM wp_posts WHERE ID IN (183391,178652,176003,175127,175406);
14.2488 [ms]
SELECT t.*, tt.*, tr.object_id FROM wp_terms AS t INNER JOIN wp_term_taxonomy AS tt ON tt.term_id = t.term_id INNER JOIN wp_term_relationships AS tr
ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ('category', 'post_tag', 'post_format') AND tr.object_id IN (175127, 175406, 176003,
178652, 183391) ORDER BY t.name ASC;
13.0100 [ms]
SELECT post_id, meta_key, meta_value FROM wp_postmeta WHERE post_id IN (175127,175406,176003,178652,183391) ORDER BY meta_id ASC;
Deprecated Assigning the return value of new by reference is deprecated on line 48 in file /nfs/c02/h13/mnt/21288/domains/ben.lobaugh.net/html/blog/wp-content/plugins/code-highlighter/codehighlighter.php
Add this ribbon to your WordPress website re-abolish slavery
%d bloggers like this: