A lightweight Angular directive/filter/service to format a date so it displays a contextual relative time ("how long ago") in addition to the date. This is useful for things like feeds, emails, comments, etc. to show how recent the timestamp occurred in addition to simplifying the date display to a more relevant format.
At it's simplest, it can be used out of the box as a filter: <span>{{ someDate | contextualDate }}</span>
, but it's highly configurable via a service which is what the rest of this document describes.
The goals of this module are twofold:
-
We did not want to use
am-time-ago
in moment.js because while the library is great, we really didn't want to have to load all of moment.min.js (35.5K) as well as angular-moment.min.js (4.5K) purely for this functionality. So we built a 3.5K library that does mostly the same thing, we think a little bit better. -
We also didn't want to have to repeat the same format filter for every single date we were displaying across a site. We love DRY principles, so
angular-contextual-date
uses a service to allow configurations that will apply across the board for certain scenarios (e.g. one format for today, a different one for the last month), and then if you really need to change it you can always tweak the format on individual dates.
contextual-date
changes the display format depending on how far away the date is relative to now. The formats are configurable, but the defaults should be good for most use-cases.
- 11:15 am (7 minutes ago)
- 8:00 am (3 hours ago)
- Jul 25 at 2:38 pm (2 days ago)
- Jul 15 at 10:00 am (1 week ago)
- Mar 30 (4 months ago)
- Jun 14, 2014 (1 year ago)
- Jul 29 at 9:05 am (2 days from now)
- Jul 29, 2016 (1 year from now)
- Jul 29 at 9:05 am (just now)
See a working demo here: http://helioscene.github.io/angular-contextual-date/
Term | Meaning |
---|---|
contextual-date |
The full display of a resulting date. e.g. Jul 25 at 2:38 pm (2 days ago) |
fullDate |
The component of a contextual-date that displays the real date. e.g. Jul 25 at 2:38 pm |
relativeDate |
The component of a contextual-date that displays the relative time. e.g. 2 days ago |
contextual-date
can be used as a filter or an element. The service can also be directly called if you want to use the results yourself, though normally you probably won't need to.
<span>{{ myDate | contextualDate }}</span>
<contextual-date datetime="myDate"></contextual-date>
The element also takes in a full-date-override
property if you want to override the fullDate
component with your own string.
<contextual-date datetime="myDate" full-date-override="myFormattedDate"></contextual-date>
See the Service's fullDateOverride section
You can also call the service directly if you want to do something else with the results
angular.controller('appCtrl', function ($scope, contextualDateService)) {
// Get the contextual date
var contextualDate = contextualDateService.format($scope.myDate);
// Get the filtered full date
var fullDate = contextualDateService.formatFull($scope.myDate);
// Get the relative date
var relativeDate = contextualDateService.formatRelative($scope.myDate);
}
The service also allows you to pass in a fullDateOverride
if you've formatted the full date on your end and want to override all fullDate
formatting contextual-date
will do.
Instead of:
contextualDateService.format($scope.myDate);
// Jun 24 at 2:38 pm (7 minutes ago)
you can pass in your own override
contextualDateService.format($scope.myDate, "Mah date!!");
// Mah date!! (7 minutes ago)
To configure the service, access the .config
settings of the service in code:
angular.controller('appCtrl', function (contextualDateService) {
contextualDateService.config.<setting> = <value>;
});
The following settings can be configured:
Default: false
When this is true, it will remove the fullDate
portion of the contextual-date
and only show the relativeDate
. Instead of 11:15 am (7 minutes ago)
it will display as 7 minutes ago
.
fullDateFormats
contains several formats for the fullDate
component of a contextual-date
. They all use the Angular date
format to generate the result.
contextualDateService.config.fullDateFormats.<option> = <format>;
Option | Description |
---|---|
today |
Applied to dates with the same year, month, and date Default: "h:mm a" Example: 2:38 pm |
thisMonth |
Applied to dates from one day to ~one month prior Default: "MMM d 'at' h:mm a" Example: Jul 23 at 2:38 pm |
thisYear |
Applied to dates from ~one month to ~one year prior Default: "MMM d" Example: Jul 14 |
historical |
Applied to dates over one year prior Default: "MMM d, y" Example: Jul 14, 2014 |
nextMonth |
Applied to dates from one day to ~one month in the future Default: "MMM d 'at' h:mm a" Example: Jul 23 at 2:38 pm |
nextYear |
Applied to dates from ~one month to ~one year in the future Default: "MMM d, y" Example: Jul 23, 2016 |
future |
Applied to dates over one year in the future Default: "MMM d, y" Example: Jul 23, 2017 |
Default: 0
(milliseconds)
Threshold that "just now" will be displayed until before the other descriptions take over. For instance, if there is a date representing 600 milliseconds ago, the default configuration will display the relativeDate
as "600 milliseconds ago". However, if this is set to 60000
, it will display "just now" until one minute ago, and then display "1 minute ago".
Default: "%fullDate% (%relativeDate%)"
This describes the display format for the full contextual-date
. It will replace %fullDate%
and %relativeDate%
with the fullDate
and relativeDate
components respectively.
Default: en_US
This sets the language contextual-date
will use. See Language Support for the current languages supported.
Right now, contextual-date
only supports en_US
. It was built to easily support multiple languages, so pull requests or a discussion could add support for them very quickly -- see the contextual-date.service.js language support
section for what's required.
There are two ways it attempts to detect the language:
- Priority 1: service configuration
contextualDateService.config.language = 'en_US';
- Priority 2: html document property
<html lang='en_US'>
...
- Default:
en_US
You can override specific language settings at load/runtime by modifying the values. The most typical case for this will be if you want a different prefix/suffix on the relativeDate
. These values are configured by the prefix
, suffix
, futurePrefix
, and futureSuffix
properties of each language.
For example, the default future date format is: Jul 23 (5 days from now)
where futurePrefix == ""
and futureSuffix == "from now"
.
However, if you wanted this to display as Jul 23 (in 5 days)
, you could set:
contextualDateService.languages["en_US"].futurePrefix = "in";
contextualDateService.languages["en_US"].futureSuffix = "";
and this would have the desired effect.
Contact Jon Gregorowicz for any questions, or submit a pull request.
If you want to contribute, we welcome pull requests! Please follow our contributing guide.