task: metadata: install: pip install -e .[dev]
patch: diff --git a/docs/history.md b/docs/history.md
index 4d2de54..cce02e2 100644
--- a/docs/history.md
+++ b/docs/history.md
@@ -6,6 +6,8 @@
 * ADD: Add Alfonso to citation doc ({pull}`169`) by [@mgrover1](https://github.com/mgrover1).
 * ENH: Adding global variables and attributes to iris datatree ({pull}`166`) by [@aladinor](https://github.com/aladinor).
 * FIX: Set fillvalue before applying scale/offset when exporting to odim ({issue}`122`) by [@pavlikp](https://github.com/pavlikp), ({pull}`173`) by [@kmuehlbauer](https://github.com/kmuehlbauer).
+* FIX: Nexrad level2 time offset of 1 day, skip reading missing elevations, introduce new radial_status of 5
+ ({issue}`180`) by [@ghiggi](https://github.com/ghiggi), ({pull}`180`) by [@kmuehlbauer](https://github.com/kmuehlbauer).
 * ADD: Reader for Halo Photonics Doppler lidar data by [@rcjackson](https://github.com/rcjackson)
 
 ## 0.5.0 (2024-03-28)
diff --git a/xradar/io/backends/nexrad_level2.py b/xradar/io/backends/nexrad_level2.py
index 74bb8a0..5a951eb 100644
--- a/xradar/io/backends/nexrad_level2.py
+++ b/xradar/io/backends/nexrad_level2.py
@@ -644,18 +644,26 @@ class NEXRADLevel2File(NEXRADRecordFile):
                 msg_31_header["filepos"] = self.filepos
                 # retrieve data/const headers from msg 31
                 # check if this is a new sweep
-                if msg_31_header["radial_status"] in [0, 3]:
-                    # do not run for the first time
-                    if current_sweep > -1:
-                        sweep["record_end"] = self.rh.recnum - 1
-                        sweep["intermediate_records"] = sweep_intermediate_records
-                        self._data[current_sweep] = sweep
-                        # create new sweep object
-                        sweep = OrderedDict()
-                        _msg_31_header.append(sweep_msg_31_header)
-                        sweep_msg_31_header = []
-                        sweep_intermediate_records = []
+                status = msg_31_header["radial_status"]
+                if status == 1:
+                    # 1 - intermediate radial
+                    pass
+                if status in [2, 4]:
+                    # 2 - end of elevation
+                    # 4 - end of volume
+                    sweep["record_end"] = self.rh.recnum
+                    sweep["intermediate_records"] = sweep_intermediate_records
+                    self._data[current_sweep] = sweep
+                    _msg_31_header.append(sweep_msg_31_header)
+                if status in [0, 3, 5]:
+                    # 0 - start of new elevation
+                    # 3 - start of new volume
+                    # 5 - start of new elevation, last elevation in VCP
                     current_sweep += 1
+                    # create new sweep object
+                    sweep = OrderedDict()
+                    sweep_msg_31_header = []
+                    sweep_intermediate_records = []
                     sweep["record_number"] = self.rh.recnum
                     sweep["filepos"] = self.filepos
                     sweep["msg_31_header"] = msg_31_header
@@ -699,11 +707,6 @@ class NEXRADLevel2File(NEXRADRecordFile):
             else:
                 sweep_intermediate_records.append(msg_header)
 
-        # finalize last sweep
-        sweep["record_end"] = self.rh.recnum
-        sweep["intermediate_records"] = sweep_intermediate_records
-        self._data[current_sweep] = sweep
-        _msg_31_header.append(sweep_msg_31_header)
         return data_header, _msg_31_header, _msg_31_data_header
 
     def _check_record(self):
@@ -1333,7 +1336,8 @@ class NexradLevel2Store(AbstractDataStore):
         elevation = np.array([ms["elevation_angle"] for ms in msg_31_header])
 
         # time
-        date = np.array([ms["collect_date"] for ms in msg_31_header]) * 86400e3
+        # date is 1-based (1 -> 1970-01-01T00:00:00), so we need to subtract 1
+        date = (np.array([ms["collect_date"] for ms in msg_31_header]) - 1) * 86400e3
         milliseconds = np.array([ms["collect_ms"] for ms in msg_31_header])
         rtime = date + milliseconds
         time_prefix = "milli"
@@ -1533,10 +1537,15 @@ def open_nexradlevel2_datatree(filename_or_obj, **kwargs):
 
     engine = NexradLevel2BackendEntrypoint
 
-    ds = [
-        xr.open_dataset(filename_or_obj, group=swp, engine=engine, **kwargs)
-        for swp in sweeps
-    ]
+    # todo: only open once! Needs new xarray built in datatree!
+    ds = []
+    for swp in sweeps:
+        try:
+            dsx = xr.open_dataset(filename_or_obj, group=swp, engine=engine, **kwargs)
+        except IndexError:
+            break
+        else:
+            ds.append(dsx)
 
     ds.insert(0, xr.Dataset())
 

problem_statement: Bugs in NEXRAD L2 reader
* xradar version: 0.5.0
* Python version: 3.11
* Operating System: Linux

### Description
 
I identified two bugs affecting the NEXRAD L2 reader. 

- The first bug cause the `time` coordinates and `time_coverage` variables to be shifted by 1 day compared to the actual time. **This impacts all NEXRAD L2 files**.
- The second bug is related to an indexing error arising with some NEXRAD files. 

Can someone have a look at it ? Maybe @mgrover1 who implemented the reader? 

Here below I provide MCVE and error logs. 

----------------------------------------------------------------------------
**MCVE - Time is shifted by 1 day**

```
import xradar as xd
import fsspec # s3fs need to be installed 
filepath = 'noaa-nexrad-level2/2023/08/20/KNKX/KNKX20230820_220808_V06' 
file = fsspec.open_local(
    f"simplecache::s3://{filepath}",
    s3={"anon": True},
    filecache={"cache_storage": "."},
dt_gr = xd.io.open_nexradlevel2_datatree(file)
print(dt_gr["time_coverage_start"])  # '2023-08-21T22:08:08Z'
print(dt_gr["time_coverage_end"]) # '2023-08-21T22:13:33Z'
print(dt_gr["sweep_0"]["time"]) # you will see the date is +1 day
```

----------------------------------------------------------------------------
**MCVE - `IndexError: list index out of range`**

```
import xradar as xd
import fsspec # s3fs need to be installed 
filepath = 'noaa-nexrad-level2/2023/08/19/KNKX/KNKX20230819_220909_V06'
file = fsspec.open_local(
    f"simplecache::s3://{filepath}",
    s3={"anon": True},
    filecache={"cache_storage": "."},
dt_gr = xd.io.open_nexradlevel2_datatree(file)
```
Error log:
```
  File ~/micromamba/envs/gpm-api-dev/lib/python3.11/site-packages/xradar/io/backends/nexrad_level2.py:485 in get_sweep
    moments = self.msg_31_data_header[sweep_number]["msg_31_data_header"].keys()

IndexError: list index out of range
```
repo: openradar/xradar
test_cmd: pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
test_patch: diff --git a/tests/io/test_io.py b/tests/io/test_io.py
index 291919d..3417c57 100644
--- a/tests/io/test_io.py
+++ b/tests/io/test_io.py
@@ -940,8 +940,8 @@ def test_open_nexradlevel2_datatree(nexradlevel2_files):
     assert rvars["volume_number"] == 0
     assert rvars["platform_type"] == "fixed"
     assert rvars["instrument_type"] == "radar"
-    assert rvars["time_coverage_start"] == "2016-06-02T15:00:25Z"
-    assert rvars["time_coverage_end"] == "2016-06-02T15:06:06Z"
+    assert rvars["time_coverage_start"] == "2016-06-01T15:00:25Z"
+    assert rvars["time_coverage_end"] == "2016-06-01T15:06:06Z"
     np.testing.assert_almost_equal(rvars["latitude"].values, np.array(33.65414047))
     np.testing.assert_almost_equal(rvars["longitude"].values, np.array(-101.81416321))
     np.testing.assert_almost_equal(rvars["altitude"].values, np.array(1029))
diff --git a/tests/io/test_nexrad_level2.py b/tests/io/test_nexrad_level2.py
index 54307be..f46842a 100644
--- a/tests/io/test_nexrad_level2.py
+++ b/tests/io/test_nexrad_level2.py
@@ -24,6 +24,9 @@ def test_open_nexradlevel2_datatree(nexradlevel2_files):
     dtree = open_nexradlevel2_datatree(nexradlevel2_files)
     ds = dtree["sweep_0"].ds
     assert ds.attrs["instrument_name"] == "KLBB"
+    assert ds["time"].min() == np.array(
+        "2016-06-01T15:00:25.232000000", dtype="datetime64[ns]"
+    )
     assert ds["DBZH"].shape == (720, 1832)
     assert ds["DBZH"].dims == ("azimuth", "range")
     assert int(ds.sweep_number.values) == 0