I have an logging content API which returns an list of json objects which will have transactions logged details. Say for example if i do GET request, it will log the details in log table and the log API also will return that content along with previously logged content. So if i do GET for 5 times, i would see 5 objects in the log API returned list. But only key for me to extract the latest logged data is 'timestamp' and all other keys in the object will be same. I am not sure how to extract the latest data correctly with 'timestamp'.
[
{
"type": "SERVICE_CALL",
"timestamp": "2022-12-14T10:03:01.343Z",
"method": "GET",
"uri": "<test>/v5/accounts/123",
"requestBody": "",
"requestTime": "",
"statusCode": 404
},
{
"type": "SERVICE_CALL",
"timestamp": "2022-12-14T10:03:30.343Z",
"method": "GET",
"uri": "<test>/v5/accounts/123",
"requestBody": "",
"requestTime": "",
"statusCode": 404
}
]
In the above example, both the log content is same except 'timestamp' with difference in seconds. I need to grab the latest data from this. How can i get it in JAVA?
CodePudding user response:
One way is to iterate the JSONArray
and compare the timestamp
fields using java.time.*
APIs. Since all other fields are same, you just need to store the index in the array where the max timestamp was seen. Then you can extract the corresponding JSONObject
at the end.
JSONArray jsonArr = ...; // get the JSONArray object from source
int index = -1;
Instant maxTimestamp = Instant.ofEpochMilli(0);
for (int i = 0; i < jsonArr.length(); i ) {
JSONObject jsonObj = jsonArr.getJSONObject(i);
Instant timestamp = Instant.parse(jsonObj.getString("timestamp"));
if (timestamp.isAfter(maxTimestamp)) {
maxTimestamp = timestamp;
index = i;
}
}
if (index == -1) {
return null;
}
return jsonArr.getJSONObject(index);
CodePudding user response:
java.time.Instant
Your timestamp strings are in standard ISO 8601 format. These standard formats are used by default when the java.time classes are parsing/generating text.
Parse as Instant
objects. Then sort.
List
.of(
Instant.parse( "2022-12-14T10:03:30.343Z" ) ,
Instant.parse( "2022-12-14T10:03:01.343Z" )
)
.stream()
.max( Instant :: compare )
.get()
Sort text
Or, if you just want the latest without really understanding the value as a date-time, just sort the text. ISO 8601 formats are cleverly designed to be in chronological order when sorted alphabetically.
Caveat: This approach assumes your inputs have the same number of digits in the fraction of a second. Seems like a risky assumption to me, so I would rather parse as an Instant
.
List
.of(
"2022-12-14T10:03:30.343Z" ,
"2022-12-14T10:03:01.343Z"
)
.stream()
.max( String :: compare )
.get()