Skip to content

Commit

Permalink
Fix a bug when |time_ago didn’t consider timezones correctly
Browse files Browse the repository at this point in the history
  • Loading branch information
gchtr committed May 31, 2023
1 parent f248f3c commit c58f3ef
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 7 deletions.
23 changes: 17 additions & 6 deletions src/DateTimeHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,18 @@ public static function wp_date($format = null, $date = null, $timezone = null)
*
* Differentiates between past and future dates.
*
* @api
* @see \human_time_diff()
* @example
* ```twig
* {{ post.date('U')|time_ago }}
* {{ post.date('Y-m-d H:i:s')|time_ago }}
* {{ post.date(constant('DATE_ATOM'))|time_ago }}
* ```
*
* @param int|string $from Base date as a timestamp or a date string.
* @param int|string $to Optional. Date to calculate difference to as a timestamp or
* a date string. Default to current time.
* a date string. Default current time.
* @param string $format_past Optional. String to use for past dates. To be used with
* `sprintf()`. Default `%s ago`.
* @param string $format_future Optional. String to use for future dates. To be used with
Expand All @@ -78,14 +85,18 @@ public static function time_ago($from, $to = null, $format_past = null, $format_
$format_future = __('%s from now');
}

$to = $to === null ? time() : $to;
$to = is_int($to) ? $to : strtotime($to);
$from = is_int($from) ? $from : strtotime($from);
$to = $to ?? time();
$to = is_numeric($to)
? new \DateTimeImmutable('@' . $to, wp_timezone())
: new \DateTimeImmutable($to, wp_timezone());
$from = is_numeric($from)
? new \DateTimeImmutable('@' . $from, wp_timezone())
: new \DateTimeImmutable($from, wp_timezone());

if ($from < $to) {
return sprintf($format_past, human_time_diff($from, $to));
return sprintf($format_past, human_time_diff($from->getTimestamp(), $to->getTimestamp()));
} else {
return sprintf($format_future, human_time_diff($to, $from));
return sprintf($format_future, human_time_diff($to->getTimestamp(), $from->getTimestamp()));
}
}
}
9 changes: 9 additions & 0 deletions src/Post.php
Original file line number Diff line number Diff line change
Expand Up @@ -1307,19 +1307,28 @@ public function modified_timestamp()
* [`get_the_date`](https://developer.wordpress.org/reference/hooks/get_the_date/) filter to the
* output.
*
* If you use {{ post.date }} with the |time_ago filter, then make sure that you use a time
* format including the full time and not just the date.
*
* @api
* @example
* ```twig
* {# Uses date format set in Settings → General #}
* Published on {{ post.date }}
* OR
* Published on {{ post.date('F jS') }}
* which was
* {{ post.date('U')|time_ago }}
* {{ post.date('Y-m-d H:i:s')|time_ago }}
* {{ post.date(constant('DATE_ATOM'))|time_ago }}
* ```
*
* ```html
* Published on January 12, 2015
* OR
* Published on Jan 12th
* which was
* 8 years ago
* ```
*
* @param string|null $date_format Optional. PHP date format. Will use the `date_format` option
Expand Down
49 changes: 48 additions & 1 deletion tests/test-timber-dates.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<?php

use Timber\DateTimeHelper;
use Timber\Post;
use Timber\Timber;

/**
Expand Down Expand Up @@ -78,6 +77,54 @@ public function testTimeAgoWithPostDateTwigFilter()
$this->assertEquals($current_ago, $str);
}

/**
* @ticket https://github.com/timber/timber/issues/2737
* @return void
*/
public function testTimeAgoWithPostDateTwigFilterTimezoneAustralia()
{
$timezone_backup = get_option('timezone_string');

// Set timezone to Australia/Adelaide.
update_option('timezone_string', 'Australia/Adelaide');

$current_time = current_datetime();
// Subtract 3 hours to get a time in the past.
$post_date = $current_time->sub(new \DateInterval('PT3H'));

$post_id = $this->factory->post->create([
'post_date' => $post_date->format('Y-m-d H:i:s'),
]);
$post = Timber::get_post($post_id);

$diff1 = Timber::compile_string(
"{{ post.date('U')|time_ago }}",
[
'post' => $post,
]
);

$diff2 = Timber::compile_string(
"{{ post.date(constant('DATE_ATOM'))|time_ago }}",
[
'post' => $post,
]
);

$diff3 = Timber::compile_string(
"{{ post.date('Y-m-d H:i:s')|time_ago }}",
[
'post' => $post,
]
);

$this->assertEquals('3 hours ago', $diff1);
$this->assertEquals('3 hours ago', $diff2);
$this->assertEquals('3 hours ago', $diff3);

update_option('timezone_string', $timezone_backup);
}

public function testTimeAgoLabels()
{
$past = DateTimeHelper::time_ago('2016-11-29 02:00:00', '2016-11-30, 02:00:00', 'prePast %s afterPast');
Expand Down

0 comments on commit c58f3ef

Please sign in to comment.