Skip to content

Instantly share code, notes, and snippets.

@bbatsche
Created September 10, 2015 14:53
Show Gist options
  • Save bbatsche/2d2d53282bfd6dc8e992 to your computer and use it in GitHub Desktop.
Save bbatsche/2d2d53282bfd6dc8e992 to your computer and use it in GitHub Desktop.
How to use a custom Angular filter with Moment.js to parse and display dates from PHP

When a PHP DateTime (or Carbon date) object is converted to JSON it is sent in a format that native JavaScript cannot parse, like this:

{
  "date": "2015-09-10 14:09:46",
  "timezone_type": 3,
  "timezone": "UTC"
}

To solve this involves several steps that we will break down here. First, you will need to download both Moment.js and Moment's Timezone extension. When downloading the Timezone library, be sure to use one that also includes data about the current timezones like moment-timezone-2010-2020.min.js. Include both above your script tags for Angular:

<script src="/js/moment.min.js"></script>
<script src="/js/moment-timezone-2010-2020.min.js"></script>
<script src="/js/angular.min.js"></script>
<script src="/js/blog.js"></script>

Next, in your module you need to create a custom filter. It should be done after creating your app variable, but before declaring any controllers for it:

// Create a filter called "phpDate"
app.filter('phpDate', function() {
    // A filter declaration should return an anonymous function.
    // The first argument is the input passed to the filter
    // Any additional arguments are paramaters passed AFTER the filter name
    return function(input, format) {
        // Create an instance of Moment. Use both the
        // date value and timezone information PHP sent
        var date = moment.tz(input.date, input.timezone);
        
        if (format == "human") {
            // Special case for formatting. If user asks for "human" format
            // return a value like "13 minutes ago" or "2 weeks ago" etc.
            return date.fromNow();
        } else {
            // Covert the moment to a string using the passed format
            // If nothing is passed, uses default JavaScript date format
            return date.format(format);
        }
    };
});

To use this in our view, we simply pass a PHP DateTime JSON object through our phpDate filter like so:

<td>{{ post.created_at | phpDate }}</td>

This should display a date like 2015-08-25T16:52:56-05:00.

Note: If you're using Laravel Blade, don't forget your leading @ sign! ;-)

Some additional examples of using different formats:

{{ post.created_at | phpDate : "human" }} <!-- "24 days ago" -->
{{ post.created_at | phpDate : "MMMM Do, YYYY h:mm a" }} <!-- "August 25th, 2015 4:52 pm" -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment