reST (reStructuredText) Question

Parsing a JSON date time with AngularJS

I have a simple Spring MVC app which is accepting POST, GET and DELETE requests.
At the front end I have a simple JSP page which is importing AngularJS libaries and trying to parse the incoming JSON. I serialized the JSON with Jackson.
Below is the JSON response coming from my Spring MVC app and I want to get it with

ng-bind
like this:

<td><span ng-bind="u.creationDate"></span></td>


This is how my JSON date time looks like:



{
"dayOfMonth": 12,
"year": 2000,
"dayOfWeek": 2,
"era": 1,
"dayOfYear": 347,
"chronology": {
"zone": {
"fixed": true,
"id": "UTC"
}
},
"yearOfEra": 2000,
"centuryOfEra": 20,
"yearOfCentury": 0,
"monthOfYear": 12,
"weekyear": 2000,
"weekOfWeekyear": 50,
"fields": [
{
"lenient": false,
"minimumValue": -292275054,
"maximumValue": 292278993,
"rangeDurationField": null,
"leapDurationField": {
"unitMillis": 86400000,
"precise": true,
"name": "days",
"type": {
"name": "days"
},
"supported": true
},
"durationField": {
"unitMillis": 31556952000,
"precise": false,
"name": "years",
"type": {
"name": "years"
},
"supported": true
},
"name": "year",
"type": {
"durationType": {
"name": "years"
},
"rangeDurationType": null,
"name": "year"
},
"supported": true
},
{
"lenient": false,
"minimumValue": 1,
"maximumValue": 12,
"rangeDurationField": {
"unitMillis": 31556952000,
"precise": false,
"name": "years",
"type": {
"name": "years"
},
"supported": true
},
"leapDurationField": {
"unitMillis": 86400000,
"precise": true,
"name": "days",
"type": {
"name": "days"
},
"supported": true
},
"durationField": {
"unitMillis": 2629746000,
"precise": false,
"name": "months",
"type": {
"name": "months"
},
"supported": true
},
"name": "monthOfYear",
"type": {
"durationType": {
"name": "months"
},
"rangeDurationType": {
"name": "years"
},
"name": "monthOfYear"
},
"supported": true
},
{
"minimumValue": 1,
"maximumValue": 31,
"rangeDurationField": {
"unitMillis": 2629746000,
"precise": false,
"name": "months",
"type": {
"name": "months"
},
"supported": true
},
"lenient": false,
"durationField": {
"unitMillis": 86400000,
"precise": true,
"name": "days",
"type": {
"name": "days"
},
"supported": true
},
"unitMillis": 86400000,
"name": "dayOfMonth",
"type": {
"durationType": {
"name": "days"
},
"rangeDurationType": {
"name": "months"
},
"name": "dayOfMonth"
},
"supported": true,
"leapDurationField": null
}
],
"fieldTypes": [
{
"durationType": {
"name": "years"
},
"rangeDurationType": null,
"name": "year"
},
{
"durationType": {
"name": "months"
},
"rangeDurationType": {
"name": "years"
},
"name": "monthOfYear"
},
{
"durationType": {
"name": "days"
},
"rangeDurationType": {
"name": "months"
},
"name": "dayOfMonth"
}
],
"values": [
2000,
12,
12
]
}


How can I properly display this date using AngularJS?

Answer

From your JSON response, it appears that you're using DateTime from the Joda-Time library, but you're missing Jackson support for Joda. You should add the following Maven dependency:

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-joda</artifactId>
</dependency>

If you're not using Joda, but you're using the Java 8 time API, you can add support by adding the following dependency:

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
</dependency>

If you're using Spring boot, this module will automatically be recognized and loaded by Jackson. When you run your application now, your JSON should be a simple UNIX timestamp:

{"timestamp":1476709730090}

If you prefer a proper looking ISO datetime string, you can use the following properties in Spring boot:

spring.jackson.serialization.write-date-timestamps-as-nanoseconds=false
spring.jackson.serialization.write-dates-as-timestamps=false

This will output something like:

{"timestamp":"2016-10-17T13:13:41.386Z"}

Now you should be able to easily convert this with AngularJS/JavaScript by using:

obj.timestamp = new Date(obj.timestamp);

You can wrap this in a service/put it in transformResponse and afterwards you can use the AngularJS date filter to properly format your date, for example:

<td><span>{{obj.timestamp | date:'short'}}</span></td>