Repository: Qiskit/qiskit-terra (python)

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.

Pull request:
Edit Result to always contain date, status, header
<!--
⚠️ 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.

- [X] I have added the tests to cover my changes.
- [X] I have updated the documentation accordingly.
- [X] I have read the CONTRIBUTING document.
-->

### Summary
Fixes #7781
Closes #7877


### Details and comments
Addresses final comments in #7781.



Patch:
diff --git a/qiskit/result/result.py b/qiskit/result/result.py
index c6c3d67ae..b9c820f58 100644
--- a/qiskit/result/result.py
+++ b/qiskit/result/result.py
@@ -62,12 +62,9 @@ class Result:
         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 @@ class Result:
                 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 @@ class Result:
         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 @@ class Result:
 
         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)
 
diff --git a/releasenotes/notes/result-fix-e4eaa021f49b5f99.yaml b/releasenotes/notes/result-fix-e4eaa021f49b5f99.yaml
new file mode 100644
index 000000000..123275116
--- /dev/null
+++ b/releasenotes/notes/result-fix-e4eaa021f49b5f99.yaml
@@ -0,0 +1,9 @@
+---
+upgrade:
+  - |
+    :class:`.Result` was modified so that it always contains ``date``, ``status``,
+    and ``header`` attributes (set to ``None`` if not specified). 
+fixes:
+  - |
+    Fixed a bug in :meth:`.Result.__repr__` that caused the attributes to be
+    specified incorrectly.


Test patch:
diff --git a/test/python/result/test_result.py b/test/python/result/test_result.py
index 9749ad252..17d2f8e3d 100644
--- a/test/python/result/test_result.py
+++ b/test/python/result/test_result.py
@@ -121,7 +121,8 @@ class TestResultOperations(QiskitTestCase):
             "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))