PHP Code to show relative date/time for Threads

LPH

Well-known member
Code currently uses the WordPress method of date time format but the XenForo way of showing the relative date information is much nicer. How is this done in XenForo?

Current code:
PHP:
        $featured_forum_threads = $featured_threadModel->getThreadsInForum( $featured_forum, $conditions, $fetchOptions );

        foreach ( $featured_forum_threads as $featured_forum_thread) {
           
            $threadTitle        = $featured_forum_thread['title'];
            $threadDate         = date_i18n( get_option('date_format'), $featured_forum_thread['post_date'] );
            $lastThreadDate     = date_i18n( get_option('date_format'), $featured_forum_thread['last_post_date'] );
        }

Reading older threads suggests people were using 'l, F j - g:i a' but that isn't relative and would always show the name of the day of the week, etc.

XenForo_Input::DATE_TIME is simply returning a string.

Any suggestions?
 

Lukas W.

Well-known member
Have a look at XenForo_Template_Compiler_Function_DateTime and Lines 3120-3221 of js/XenForo/full/xenforo.js
 

LPH

Well-known member
Thank you. I was looking at XenForo_Locale::getRelativeDateTime() and trying to figure out how to call it.
 

Lukas W.

Well-known member
No problem. If you need any further help just ask. Was only short on time this morning, so I had only time to locate the files for you.
 

LPH

Well-known member
This is the current state of trying to get relative time outside of XenForo on a WordPress widget.

1. Created a file named class-xenword-relative.php which is based off the human_time_diff in WordPress.

PHP:
<?php

/**
 * Filename: class-xenword-relative-time.php
 *
 * Formats time in human readable format.
 *
 * Based on human_time_diff in /wp-includes/formatting.php
 */

class XenWord_Time {

    public static function xenword_time_diff( $from, $to = '' ) {
        if ( empty( $to ) ) {
            $to = time();
        }

        $diff = (int) abs( $to - $from );

        if ( $diff < HOUR_IN_SECONDS ) {
            $mins = round( $diff / MINUTE_IN_SECONDS );
            if ( $mins <= 1 )
                $mins = 1;
            /* translators: min=minute */
            $since = sprintf( _n( '%s min', '%s mins', $mins ), $mins );
        } elseif ( $diff < DAY_IN_SECONDS && $diff >= HOUR_IN_SECONDS ) {
            $hours = round( $diff / HOUR_IN_SECONDS );
            if ( $hours <= 1 )
                $hours = 1;
            $since = sprintf( _n( '%s hour', '%s hours', $hours ), $hours );
        } elseif ( $diff < WEEK_IN_SECONDS && $diff >= DAY_IN_SECONDS ) {
            $days = round( $diff / DAY_IN_SECONDS );
            if ( $days <= 1 )
                $days = 1;
            $since = sprintf( _n( '%s day', '%s days', $days ), $days );
        } elseif ( $diff < MONTH_IN_SECONDS && $diff >= WEEK_IN_SECONDS ) {
            $weeks = round( $diff / WEEK_IN_SECONDS );
            if ( $weeks <= 1 )
                $weeks = 1;
            $since = sprintf( _n( '%s week', '%s weeks', $weeks ), $weeks );
        } elseif ( $diff < YEAR_IN_SECONDS && $diff >= MONTH_IN_SECONDS ) {
            $months = round( $diff / MONTH_IN_SECONDS );
            if ( $months <= 1 )
                $months = 1;
            $since = sprintf( _n( '%s month', '%s months', $months ), $months );
        } elseif ( $diff >= YEAR_IN_SECONDS ) {
            $years = round( $diff / YEAR_IN_SECONDS );
            if ( $years <= 1 )
                $years = 1;
            $since = sprintf( _n( '%s year', '%s years', $years ), $years );
        }

        /**
        * Filter the human readable difference between two timestamps.
        *
        * @since 4.0.0
        *
        * @param string $since The difference in human readable text.
        * @param int    $diff  The difference in seconds.
        * @param int    $from  Unix timestamp from which the difference begins.
        * @param int    $to    Unix timestamp to end the time difference.
        */
        return apply_filters( 'xenword_time_diff', $since, $diff, $from, $to );
    }
}

new XenWord_Time();

// End class-xenword-relative-time.php

2. Call method in the featured forum widget

PHP:
$threadDate         = XenWord_Time::xenword_time_diff( $featured_forum_thread['post_date'], XenForo_Application::$time ) . ' ago';
$lastThreadDate     = XenWord_Time::xenword_time_diff( $featured_forum_thread['last_post_date'], XenForo_Application::$time ) . ' ago';

The XenWord_Time::xenword_time_diff isn't perfect. There is no "yesterday" and I need to change the cut off so that month, date, year are shown after certain time difference. The "Today at " isn't there either.

Please let me know if you have any suggestions. It would be nicer to simply have a XenForo human readable time method to call.
 

LPH

Well-known member
My times are off for some reason. It can be noon at the post will say "Today at 6pm." Guess I'll have to break this apart some more.
 

Jeremy P

XenForo developer
Staff member
For what it's worth, XenForo accomplishes this with JavaScript, which is a better solution for lots of reasons. It allows the relative information to be updated without page refreshes, and the correct timestamps can be picked up by things like search engines/caches/etc.
 

LPH

Well-known member
XenForo accomplishes this with JavaScript

It's worth tons, but I don't know how to call the XenForo script properly so that it formats it. Was looking through the code and couldn't find something that made sense to me. This is why I built my own, which is off on time.

Can you point in me in the right direction to call it externally (from a WP post, page, etc)?
 

Jeremy P

XenForo developer
Staff member
I believe it's a matter of including xenforo.js on your pages and formatting the elements in a way XF expects. The latter is the tricky part. A relevant element in XF looks like:
Code:
<span class="DateTime" title="Mar 25, 2016 at 4:29 PM">Mar 25, 2016</span></a>

Having the "DateTime" class on your element is key.
 
Top