Repository: Qiskit/qiskit

Issue:
Add date attribute to BasicAer job result
### What is the expected enhancement?

This is a practical improvement because it aligns the API with AerJob. It is also required according to https://arxiv.org/abs/1809.03452. See https://github.com/Qiskit-Partners/mthree/issues/94 for context.
add date to all Result objects - QAMP
<!--
⚠️ If you do not respect this template, your pull request will be closed.
⚠️ Your pull request title should be short detailed and understandable for all.
⚠️ Also, please add a release note file using reno if the change needs to be
  documented in the release notes.
⚠️ If your pull request fixes an open issue, please link to the issue.

- [ ] I have added the tests to cover my changes.
- [ ] I have updated the documentation accordingly.
- [ ] I have read the CONTRIBUTING document.
-->

### Summary
Executing the following code gives an error because BasicAer backend job has no attribute date.
Fixes #7781 
``` python
import numpy as np
import mthree
from qiskit import BasicAer, QuantumCircuit, Aer

backend = BasicAer.get_backend("statevector_simulator")
mit = mthree.M3Mitigation(backend)
mit.cals_from_system(range(2))

circuit = QuantumCircuit(2)
circuit.rx(np.pi / 4, 0)
circuit.rx(np.pi / 2, 1)
circuit.measure_all()
```

### Details and comments
This error can be solved by putting the attribute`job.result().date = None` as a default parameter.

Part of https://github.com/qiskit-advocate/qamp-spring-22/issues/37


Discussion:

Resolving patch:
diff --git a/qiskit/result/result.py b/qiskit/result/result.py
--- a/qiskit/result/result.py
+++ b/qiskit/result/result.py
@@ -62,12 +62,9 @@ def __init__(
         self.job_id = job_id
         self.success = success
         self.results = results
-        if date is not None:
-            self.date = date
-        if status is not None:
-            self.status = status
-        if header is not None:
-            self.header = header
+        self.date = date
+        self.status = status
+        self.header = header
         self._metadata.update(kwargs)
 
     def __repr__(self):
@@ -83,12 +80,7 @@ def __repr__(self):
                 self.results,
             )
         )
-        if hasattr(self, "date"):
-            out += ", date=%s" % self.date
-        if hasattr(self, "status"):
-            out += ", status=%s" % self.status
-        if hasattr(self, "header"):
-            out += ", status=%s" % self.header
+        out += f", date={self.date}, status={self.status}, header={self.header}"
         for key in self._metadata:
             if isinstance(self._metadata[key], str):
                 value_str = "'%s'" % self._metadata[key]
@@ -107,17 +99,14 @@ def to_dict(self):
         out_dict = {
             "backend_name": self.backend_name,
             "backend_version": self.backend_version,
+            "date": self.date,
+            "header": None if self.header is None else self.header.to_dict(),
             "qobj_id": self.qobj_id,
             "job_id": self.job_id,
+            "status": self.status,
             "success": self.success,
             "results": [x.to_dict() for x in self.results],
         }
-        if hasattr(self, "date"):
-            out_dict["date"] = self.date
-        if hasattr(self, "status"):
-            out_dict["status"] = self.status
-        if hasattr(self, "header"):
-            out_dict["header"] = self.header.to_dict()
         out_dict.update(self._metadata)
         return out_dict
 
@@ -142,7 +131,7 @@ def from_dict(cls, data):
 
         in_data = copy.copy(data)
         in_data["results"] = [ExperimentResult.from_dict(x) for x in in_data.pop("results")]
-        if "header" in in_data:
+        if in_data.get("header") is not None:
             in_data["header"] = QobjHeader.from_dict(in_data.pop("header"))
         return cls(**in_data)
 


Test patch:
diff --git a/test/python/result/test_result.py b/test/python/result/test_result.py
--- a/test/python/result/test_result.py
+++ b/test/python/result/test_result.py
@@ -121,7 +121,8 @@ def test_result_repr(self):
             "results=[ExperimentResult(shots=14, success=True, "
             "meas_level=2, data=ExperimentResultData(counts={'0x0': 4,"
             " '0x2': 10}), header=QobjExperimentHeader(creg_sizes="
-            "[['c0', 2], ['c0', 1], ['c1', 1]], memory_slots=4))])"
+            "[['c0', 2], ['c0', 1], ['c1', 1]], memory_slots=4))], date=None, "
+            "status=None, header=None)"
         )
         self.assertEqual(expected, repr(result))