Because each JSQMessage object has a date property, you can simply compare the date of each message to the date of the previous message. 
[thisMessageDate timeIntervalSinceDate:(NSDate *)previousMessageDate] will give you the difference in seconds. If the difference is greater than, say, a minute (or whatever time interval you desire), then display a timestamp. 
This is how I'm doing it:
- (NSAttributedString *)collectionView:(JSQMessagesCollectionView *)collectionView attributedTextForCellTopLabelAtIndexPath:(NSIndexPath *)indexPath {
JSQMessage *message = [self.messages objectAtIndex:indexPath.item];
  if (indexPath.item == 0) {
      return [[JSQMessagesTimestampFormatter sharedFormatter] attributedTimestampForDate:message.date];
  }
  if (indexPath.item - 1 > 0) {
    JSQMessage *previousMessage = [self.messages objectAtIndex:indexPath.item - 1];
    if ([message.date timeIntervalSinceDate:previousMessage.date] / 60 > 1) {
        return [[JSQMessagesTimestampFormatter sharedFormatter] attributedTimestampForDate:message.date];
    }
  }
  return nil;
}
And then just repeat this logic to make sure the timestamps have the correct heights:
- (CGFloat)collectionView:(JSQMessagesCollectionView *)collectionView
               layout:(JSQMessagesCollectionViewFlowLayout *)collectionViewLayout heightForCellTopLabelAtIndexPath:(NSIndexPath *)indexPath {
  if (indexPath.item == 0) {
    return kJSQMessagesCollectionViewCellLabelHeightDefault;
  }
  if (indexPath.item - 1 > 0) {
    JSQMessage *previousMessage = [self.messages objectAtIndex:indexPath.item - 1];
    JSQMessage *message = [self.messages objectAtIndex:indexPath.item];
    if ([message.date timeIntervalSinceDate:previousMessage.date] / 60 > 1) {
        return kJSQMessagesCollectionViewCellLabelHeightDefault;
    }
  }
  return 0.0f;
}