• This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.

XenForo's DateTime

James

Well-known member
#1
I'm creating an add-on that adds a date & time into the database from a date input.

The HTML:
HTML:
<input type="text" data-orig-type="date" name="new_post_date" value="{xen:datetime $serverTime, 'Y-m-d'" class="textCtrl date">
This gives me a date in the format YYYY-MM-DD and uses XenForo's datepicker.

The question: Is it possible to merge a specific date and time into one field in XenForo? Or am I going to have to create two separate fields and concatenate them in my controller?
At the minute, my add-on adds the correct date, but the time is always 12:00am.
 

digitalpoint

Well-known member
#2
Well, MySQL does have a DATETIME column type, but you probably would be better off converting it to a unix timestamp and storing it as an INT(10) column.

Unless there's a reason that's not an option for your addon?
 

James

Well-known member
#3
I'm fetching it as a XenForo_Input::DATE_TIME. I think XenForo automatically converts it to a unix timestamp, so it might just be a case of fetching a separate time input and concatenating them... I'll look into it. Here is (basically) my code:

PHP:
$input = $this->_input->filter(array(
                'thread_id'=> XenForo_Input::UINT,
                'changed_username'=> XenForo_Input::STRING,
                'new_post_date'=> XenForo_Input::DATE_TIME,
));

// some helper and model grabbing

$threadWriter = XenForo_DataWriter::create('XenForo_DataWriter_Discussion_Thread');
$threadWriter->setExistingData($thread['thread_id']);
$threadWriter->set('user_id', $newUser['user_id']);
$threadWriter->set('username', $input['changed_username']);
$threadWriter->set('post_date', $input['new_post_date']);
$threadWriter->save();
I guess I need to filter a new_post_time, add it to new_post_date and then set the new value.

Agree?
 

digitalpoint

Well-known member
#4
I took a peek at the XenForo_Input class, and from first glance it looks like DATE_TIME can work either way... if it's an int, it will treat it as a timestamp, if it's not an int, then it looks like it initiates the DateTime class and uses that to convert the input to a unix timestamp. So either way, you are going to end up with a time stamp regardless of how you pass the data to the Input class. So as long as your input is something that is a valid date/time format according to PHP, it should be fine...

http://www.php.net/manual/en/datetime.formats.time.php
http://www.php.net/manual/en/datetime.formats.date.php

Just note that you will end up with a unix timestamp regardless of how it's being input.
 

James

Well-known member
#5
How would I convert a date and time string (separate) into one unix timestamp? Example:
$date = '2011-10-23';
$time = '15:59';

$unixTimestamp = someFunctionToMergeAndCreateTimestamp($date, $time);

(P.S: this seems really, really obvious, so don't shoot me down for having a moment of madness! not that the PHP.net site helped...)
 

infis

Well-known member
#6
PHP:
$date_elements = explode('-', $date);
$time_elements = explode(':', $time);
$unixTimestamp = mktime($time_elements[0], $time_elements[1], 0, $date_elements[1], $date_elements[2], $date_elements[0]);
 

James

Well-known member
#7
OK so I've figured out they're both returned as timestamps when they're submitted (XenForo_Input::DATE_TIME must automatically convert them to timestamps), and I wasn't sure how to add a date timestamp and a time timestamp so I just converted them to XenForo_Input::STRING and then exploded and mktime()'d them.
 

digitalpoint

Well-known member
#8
I haven't tried it, but I would suspect you can just pass a compound format as a DAT_TIME input without needing to convert it to a timestamp first yourself...

http://www.php.net/manual/en/datetime.formats.compound.php

To answer your question on the easiest way to convert a separate time/date to a timestamp, probably just do this (object oriented style):

PHP:
$dateTime = new DateTime("$date $time");
$unixTimestamp = dateTime->format('U');
If you want to do it procedurally, something like this (no need to explode stuff):

PHP:
$unixTimestamp = strtotime("$date $time");
 

infis

Well-known member
#9
Yes. It is really possible to use a class for time obtaining in a format unixtimestamp. But it will be slightly more slowly, than at usage explode and mktime functions.
# cat test.php
PHP:
<?php
$count = 1000000;

$date = '2011-10-23';
$time = '15:59';

$startTime = microtime(true);
for ($i = 0; $i < $count; $i++)
{
    $date_elements = explode('-', $date);
    $time_elements = explode(':', $time);
    $unixTimestamp = mktime($time_elements[0], $time_elements[1], 0, $date_elements[1], $date_elements[2], $date_elements[0]);
}
$endTime = microtime(true);
printf("Explode and mktime function: %.4f seconds\n", $endTime - $startTime);

$startTime = microtime(true);
for ($i = 0; $i < $count; $i++)
{
    $dateTime = new DateTime("$date $time");
    $unixTimestamp = $dateTime->format('U');
}
$endTime = microtime(true);
printf("DateTime class: %.4f seconds\n", $endTime - $startTime);

$startTime = microtime(true);
for ($i = 0; $i < $count; $i++)
{
    $unixTimestamp = strtotime("$date $time");
}
$endTime = microtime(true);
printf("Strtotime: %.4f seconds\n", $endTime - $startTime);
?>
# php test.php
Code:
Explode and mktime function: 23.7755 seconds
DateTime class: 26.4913 seconds
Strtotime: 22.6474 seconds
And strtotime function faster both variants.