Repository: sunpy/sunpy

Issue:
Use `'XPOSURE'` instead of `'EXPTIME'` key when creating `exposure_time` property
Currently, we pull the exposure time information from the `EXPTIME` key when creating the `exposure_time` property,

https://github.com/sunpy/sunpy/blob/f33efda2b758d3e9791ae4092bd639d260434223/sunpy/map/mapbase.py#L909-L917

However, the FITS-4 standard uses `XPOSURE` to denote this value. We should be using this by default to access the exposure time. We currently have two map sources (WISPR and EUI) that special case this because those FITS headers use `XPOSURE`

A few comments:

- Do we change the default key to `XPOSURE` and special case all of our other sources that use `EXPTIME` (most of them)?
- Alternatively, do we, in `GenericMap` look first for `XPOSURE` and then for `EXPTIME`? This is easiest but is inconsistent with our model of having a single default for such properties and then special casing individual sources. 
- We should also modify the header helper to set the exposure time using `XPOSURE`.


Discussion:

Resolving patch:
diff --git a/sunpy/map/mapbase.py b/sunpy/map/mapbase.py
--- a/sunpy/map/mapbase.py
+++ b/sunpy/map/mapbase.py
@@ -911,10 +911,12 @@ def exposure_time(self):
         """
         Exposure time of the image.
 
-        This is taken from the 'EXPTIME' FITS keyword.
+        This is taken from the 'XPOSURE' keyword or the 'EXPTIME' FITS keyword,
+        in that order.
         """
-        if 'exptime' in self.meta:
-            return self.meta['exptime'] * self.timeunit
+        exptime = self.meta.get('xposure') or self.meta.get('exptime')
+        if exptime:
+            return exptime * self.timeunit
 
     @property
     def instrument(self):
diff --git a/sunpy/map/sources/psp.py b/sunpy/map/sources/psp.py
--- a/sunpy/map/sources/psp.py
+++ b/sunpy/map/sources/psp.py
@@ -27,10 +27,6 @@ def processing_level(self):
             return
         return int(lvl[1])
 
-    @property
-    def exposure_time(self):
-        return self.meta.get('xposure', 0.0) * self.timeunit
-
     @property
     def name(self):
         return 'WISPR ' + super().name
diff --git a/sunpy/map/sources/solo.py b/sunpy/map/sources/solo.py
--- a/sunpy/map/sources/solo.py
+++ b/sunpy/map/sources/solo.py
@@ -47,10 +47,6 @@ def processing_level(self):
             # The level number is prepended by the letter L
             return int(self.meta.get('level')[1:])
 
-    @property
-    def exposure_time(self):
-        return self.meta.get('xposure', 0.0) * self.timeunit
-
     @property
     def date(self):
         t = self.meta.get('date-avg')


Test patch:
diff --git a/sunpy/map/tests/test_mapbase.py b/sunpy/map/tests/test_mapbase.py
--- a/sunpy/map/tests/test_mapbase.py
+++ b/sunpy/map/tests/test_mapbase.py
@@ -210,6 +210,19 @@ def test_timeunit(generic_map):
     assert generic_map.timeunit == u.Unit('h')
 
 
+def test_exposure_time(generic_map):
+    exptime = 2 * u.s
+    generic_map.meta['exptime'] = exptime.to_value('s')
+    assert generic_map.exposure_time == exptime
+    exptime = 3 * u.s
+    # XPOSURE should take priority over EXPTIME
+    generic_map.meta['xposure'] = exptime.to_value('s')
+    assert generic_map.exposure_time == exptime
+    del generic_map.meta['exptime']
+    del generic_map.meta['xposure']
+    assert generic_map.exposure_time is None
+
+
 def test_dsun(generic_map):
     assert_quantity_allclose(generic_map.dsun, sun.earth_distance(generic_map.date))