Permalink
Browse files

NEW Date->Ago() with "less than a minute" support

  • Loading branch information...
1 parent c0a1226 commit 7e4629073a267d732591472ae7c0f91a44b43208 @chillu chillu committed Dec 13, 2012
Showing with 145 additions and 33 deletions.
  1. +43 −33 model/fieldtypes/Date.php
  2. +42 −0 tests/model/DateTest.php
  3. +60 −0 tests/model/DatetimeTest.php
View
@@ -197,58 +197,68 @@ public function Rfc3339() {
}
/**
- * Returns the number of seconds/minutes/hours/days or months since the timestamp
+ * Returns the number of seconds/minutes/hours/days or months since the timestamp.
+ *
+ * @param boolean $includeSeconds Show seconds, or just round to "less than a minute".
+ * @return String
*/
- public function Ago() {
+ public function Ago($includeSeconds = true) {
if($this->value) {
- if(strtotime($this->value) == time() || time() > strtotime($this->value)) {
+ $time = SS_Datetime::now()->Format('U');
+ if(strtotime($this->value) == $time || $time > strtotime($this->value)) {
return _t(
'Date.TIMEDIFFAGO',
"{difference} ago",
'Natural language time difference, e.g. 2 hours ago',
- array('difference' => $this->TimeDiff())
+ array('difference' => $this->TimeDiff($includeSeconds))
);
} else {
return _t(
'Date.TIMEDIFFIN',
"in {difference}",
'Natural language time difference, e.g. in 2 hours',
- array('difference' => $this->TimeDiff())
+ array('difference' => $this->TimeDiff($includeSeconds))
);
}
}
}
- public function TimeDiff() {
+ /**
+ * @param boolean $includeSeconds Show seconds, or just round to "less than a minute".
+ * @return String
+ */
+ public function TimeDiff($includeSeconds = true) {
+ if(!$this->value) return false;
- if($this->value) {
- $ago = abs(time() - strtotime($this->value));
-
- if($ago < 60) {
- $span = $ago;
- return ($span != 1) ? "{$span} "._t("Date.SECS", " secs") : "{$span} "._t("Date.SEC", " sec");
- }
- if($ago < 3600) {
- $span = round($ago/60);
- return ($span != 1) ? "{$span} "._t("Date.MINS", " mins") : "{$span} "._t("Date.MIN", " min");
- }
- if($ago < 86400) {
- $span = round($ago/3600);
- return ($span != 1) ? "{$span} "._t("Date.HOURS", " hours") : "{$span} "._t("Date.HOUR", " hour");
- }
- if($ago < 86400*30) {
- $span = round($ago/86400);
- return ($span != 1) ? "{$span} "._t("Date.DAYS", " days") : "{$span} "._t("Date.DAY", " day");
- }
- if($ago < 86400*365) {
- $span = round($ago/86400/30);
- return ($span != 1) ? "{$span} "._t("Date.MONTHS", " months") : "{$span} "._t("Date.MONTH", " month");
- }
- if($ago > 86400*365) {
- $span = round($ago/86400/365);
- return ($span != 1) ? "{$span} "._t("Date.YEARS", " years") : "{$span} "._t("Date.YEAR", " year");
- }
+ $time = SS_Datetime::now()->Format('U');
+ $ago = abs($time - strtotime($this->value));
+
+ if($ago < 60 && $includeSeconds) {
+ $span = $ago;
+ $result = ($span != 1) ? "{$span} "._t("Date.SECS", "secs") : "{$span} "._t("Date.SEC", "sec");
+ } elseif($ago < 60) {
+ $result = _t('Date.LessThanMinuteAgo', 'less than a minute');
+ } elseif($ago < 3600) {
+ $span = round($ago/60);
+ $result = ($span != 1) ? "{$span} "._t("Date.MINS", "mins") : "{$span} "._t("Date.MIN", "min");
+ } elseif($ago < 86400) {
+ $span = round($ago/3600);
+ $result = ($span != 1) ? "{$span} "._t("Date.HOURS", "hours") : "{$span} "._t("Date.HOUR", "hour");
+ } elseif($ago < 86400*30) {
+ $span = round($ago/86400);
+ $result = ($span != 1) ? "{$span} "._t("Date.DAYS", "days") : "{$span} "._t("Date.DAY", "day");
+ } elseif($ago < 86400*365) {
+ $span = round($ago/86400/30);
+ $result = ($span != 1) ? "{$span} "._t("Date.MONTHS", "months") : "{$span} "._t("Date.MONTH", "month");
+ } elseif($ago > 86400*365) {
+ $span = round($ago/86400/365);
+ $result = ($span != 1) ? "{$span} "._t("Date.YEARS", "years") : "{$span} "._t("Date.YEAR", "year");
}
+
+ // Replace duplicate spaces, backwards compat with existing translations
+ $result = preg_replace('/\s+/', ' ', $result);
+
+ return $result;
}
/**
View
@@ -160,4 +160,46 @@ public function testExtendedDates() {
$this->assertEquals('03 Apr 3000', $date->Format('d M Y'));
}
+ public function testAgoInPast() {
+ SS_Datetime::set_mock_now('2000-12-31 12:00:00');
+
+ $this->assertEquals(
+ '10 years ago',
+ DBField::create_field('Date', '1990-12-31')->Ago(),
+ 'Exact past match on years'
+ );
+
+ $this->assertEquals(
+ '10 years ago',
+ DBField::create_field('Date', '1990-12-30')->Ago(),
+ 'Approximate past match on years'
+ );
+
+ $this->assertEquals(
+ '1 year ago',
+ DBField::create_field('Date', '1999-12-30')->Ago(),
+ 'Approximate past match in singular'
+ );
+
+ SS_Datetime::clear_mock_now();
+ }
+
+ public function testAgoInFuture() {
+ SS_Datetime::set_mock_now('2000-12-31 00:00:00');
+
+ $this->assertEquals(
+ 'in 100 years',
+ DBField::create_field('Date', '2100-12-31')->Ago(),
+ 'Exact past match on years'
+ );
+
+ $this->assertEquals(
+ 'in 1 day',
+ DBField::create_field('Date', '2001-01-01')->Ago(),
+ 'Approximate past match on minutes'
+ );
+
+ SS_Datetime::clear_mock_now();
+ }
+
}
@@ -89,4 +89,64 @@ public function testURLDateTime(){
$this->assertEquals('2001-12-31%2022:10:59', $date->URLDateTime());
}
+ public function testAgoInPast() {
+ SS_Datetime::set_mock_now('2000-12-31 12:00:00');
+
+ $this->assertEquals(
+ '10 years ago',
+ DBField::create_field('SS_Datetime', '1990-12-31 12:00:00')->Ago(),
+ 'Exact past match on years'
+ );
+
+ $this->assertEquals(
+ '10 years ago',
+ DBField::create_field('SS_Datetime', '1990-12-30 12:00:00')->Ago(),
+ 'Approximate past match on years'
+ );
+
+ $this->assertEquals(
+ '1 year ago',
+ DBField::create_field('SS_Datetime', '1999-12-30 12:00:12')->Ago(),
+ 'Approximate past match in singular'
+ );
+
+ $this->assertEquals(
+ '50 mins ago',
+ DBField::create_field('SS_Datetime', '2000-12-31 11:10:11')->Ago(),
+ 'Approximate past match on minutes'
+ );
+
+ $this->assertEquals(
+ '59 secs ago',
+ DBField::create_field('SS_Datetime', '2000-12-31 11:59:01')->Ago(),
+ 'Approximate past match on seconds'
+ );
+
+ $this->assertEquals(
+ 'less than a minute ago',
+ DBField::create_field('SS_Datetime', '2000-12-31 11:59:01')->Ago(false),
+ 'Approximate past match on seconds with $includeSeconds=false'
+ );
+
+ SS_Datetime::clear_mock_now();
+ }
+
+ public function testAgoInFuture() {
+ SS_Datetime::set_mock_now('2000-12-31 00:00:00');
+
+ $this->assertEquals(
+ 'in 100 years',
+ DBField::create_field('SS_Datetime', '2100-12-31 12:00:00')->Ago(),
+ 'Exact past match on years'
+ );
+
+ $this->assertEquals(
+ 'in 1 hour',
+ DBField::create_field('SS_Datetime', '2000-12-31 1:01:05')->Ago(),
+ 'Approximate past match on minutes'
+ );
+
+ SS_Datetime::clear_mock_now();
+ }
+
}

0 comments on commit 7e46290

Please sign in to comment.