Skip to content

Commit aa4a8c5

Browse files
Fix issue with reading dates from files (#1936)
Co-authored-by: Rémi Kazeroni <70641264+remi-kazeroni@users.noreply.github.com>
1 parent 638a399 commit aa4a8c5

File tree

3 files changed

+33
-20
lines changed

3 files changed

+33
-20
lines changed

esmvalcore/_recipe/check.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ def data_availability(dataset, log=True):
172172
available_years = set()
173173

174174
for file in input_files:
175-
start, end = _get_start_end_year(file.name)
175+
start, end = _get_start_end_year(file)
176176
available_years.update(range(start, end + 1))
177177

178178
missing_years = required_years - available_years

esmvalcore/local.py

+25-9
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ def _replace_years_with_timerange(variable):
162162
variable.pop('end_year', None)
163163

164164

165-
def _get_start_end_year(filename):
165+
def _get_start_end_year(file):
166166
"""Get the start and end year from a file name.
167167
168168
Examples of allowed dates : 1980, 198001, 19801231,
@@ -174,26 +174,42 @@ def _get_start_end_year(filename):
174174
175175
Look first for two dates separated by - or _, then for one single
176176
date, and if they are multiple, for one date at start or end.
177+
178+
Parameters
179+
----------
180+
file: LocalFile or esmvalcore.esgf.ESGFFile
181+
The file to read the start and end year from.
182+
183+
Returns
184+
-------
185+
tuple[int, int]
186+
The start and end year.
187+
188+
Raises
189+
------
190+
ValueError
191+
When start or end year cannot be determined.
192+
177193
"""
178-
stem = Path(filename).stem
179194
start_year = end_year = None
180-
#
195+
181196
time_pattern = (r"(?P<hour>[0-2][0-9]"
182197
r"(?P<minute>[0-5][0-9]"
183198
r"(?P<second>[0-5][0-9])?)?Z?)")
184199
date_pattern = (r"(?P<year>[0-9]{4})"
185200
r"(?P<month>[01][0-9]"
186201
r"(?P<day>[0-3][0-9]"
187202
rf"(T?{time_pattern})?)?)?")
188-
#
203+
189204
end_date_pattern = date_pattern.replace(">", "_end>")
190205
date_range_pattern = date_pattern + r"[-_]" + end_date_pattern
191206
start_year, end_year = _get_from_pattern(date_pattern, date_range_pattern,
192-
stem, 'year')
207+
Path(file.name).stem, 'year')
193208
# As final resort, try to get the dates from the file contents
194-
if (start_year is None or end_year is None) and Path(filename).exists():
195-
logger.debug("Must load file %s for daterange ", filename)
196-
cubes = iris.load(filename)
209+
if ((start_year is None or end_year is None) and isinstance(file, Path)
210+
and file.exists()):
211+
logger.debug("Must load file %s for daterange ", file)
212+
cubes = iris.load(file)
197213

198214
for cube in cubes:
199215
logger.debug(cube)
@@ -206,7 +222,7 @@ def _get_start_end_year(filename):
206222
break
207223

208224
if start_year is None or end_year is None:
209-
raise ValueError(f'File {filename} dates do not match a recognized '
225+
raise ValueError(f'File {file} dates do not match a recognized '
210226
'pattern and time can not be read from the file')
211227

212228
return int(start_year), int(end_year)

tests/unit/local/test_time.py

+7-10
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import pytest
44

55
from esmvalcore.local import (
6+
LocalFile,
67
_dates_to_timerange,
78
_get_start_end_date,
89
_get_start_end_year,
@@ -64,6 +65,7 @@
6465
def test_get_start_end_year(case):
6566
"""Tests for _get_start_end_year function."""
6667
filename, case_start, case_end = case
68+
filename = LocalFile(filename)
6769
if case_start is None and case_end is None:
6870
# If the filename is inconclusive or too difficult
6971
# we resort to reading the file, which fails here
@@ -80,6 +82,7 @@ def test_get_start_end_year(case):
8082
def test_get_start_end_date(case):
8183
"""Tests for _get_start_end_date function."""
8284
filename, case_start, case_end = case
85+
filename = LocalFile(filename)
8386
if case_start is None and case_end is None:
8487
# If the filename is inconclusive or too difficult
8588
# we resort to reading the file, which fails here
@@ -95,7 +98,7 @@ def test_get_start_end_date(case):
9598
def test_read_time_from_cube(monkeypatch, tmp_path):
9699
"""Try to get time from cube if no date in filename."""
97100
monkeypatch.chdir(tmp_path)
98-
temp_file = 'test.nc'
101+
temp_file = LocalFile('test.nc')
99102
cube = iris.cube.Cube([0, 0], var_name='var')
100103
time = iris.coords.DimCoord([0, 366],
101104
'time',
@@ -142,9 +145,7 @@ def test_fails_if_no_date_present():
142145
def test_get_timerange_from_years():
143146
"""Test a `timerange` tag with value `start_year/end_year` can be built
144147
from tags `start_year` and `end_year`."""
145-
variable = {
146-
'start_year': 2000,
147-
'end_year': 2002}
148+
variable = {'start_year': 2000, 'end_year': 2002}
148149

149150
_replace_years_with_timerange(variable)
150151

@@ -156,9 +157,7 @@ def test_get_timerange_from_years():
156157
def test_get_timerange_from_start_year():
157158
"""Test a `timerange` tag with value `start_year/start_year` can be built
158159
from tag `start_year` when an `end_year` is not given."""
159-
variable = {
160-
'start_year': 2000
161-
}
160+
variable = {'start_year': 2000}
162161

163162
_replace_years_with_timerange(variable)
164163

@@ -169,9 +168,7 @@ def test_get_timerange_from_start_year():
169168
def test_get_timerange_from_end_year():
170169
"""Test a `timerange` tag with value `end_year/end_year` can be built from
171170
tag `end_year` when a `start_year` is not given."""
172-
variable = {
173-
'end_year': 2002
174-
}
171+
variable = {'end_year': 2002}
175172

176173
_replace_years_with_timerange(variable)
177174

0 commit comments

Comments
 (0)