1
1
"""Shared functions for fixes."""
2
2
import logging
3
3
import os
4
- from datetime import datetime
4
+ from datetime import datetime , timedelta
5
5
from functools import lru_cache
6
6
7
7
import dask .array as da
@@ -453,12 +453,12 @@ def get_next_month(month: int, year: int) -> tuple[int, int]:
453
453
def get_time_bounds (time : Coord , freq : str ) -> np .ndarray :
454
454
"""Get bounds for time coordinate.
455
455
456
- For monthly data, use the first day of the current month and the first day
457
- of the next month. For yearly or decadal data, use 1 January of the current
458
- year and 1 January of the next year or 10 years from the current year. For
459
- other frequencies (daily, 6-hourly, 3 -hourly, hourly), half of the
460
- frequency is subtracted/added from the current point in time to get the
461
- bounds.
456
+ For decadal data, use 1 January 5 years before/after the current year. For
457
+ yearly data, use 1 January of the current year and 1 January of the next
458
+ year. For monthly data, use the first day of the current month and the
459
+ first day of the next month. For other frequencies (daily or `n` -hourly,
460
+ where `n` is a divisor of 24), half of the frequency is subtracted/added
461
+ from the current point in time to get the bounds.
462
462
463
463
Parameters
464
464
----------
@@ -480,39 +480,38 @@ def get_time_bounds(time: Coord, freq: str) -> np.ndarray:
480
480
"""
481
481
bounds = []
482
482
dates = time .units .num2date (time .points )
483
- for step , date in enumerate (dates ):
484
- month = date .month
485
- year = date .year
486
- if freq in ['mon' , 'mo' ]:
487
- next_month , next_year = get_next_month (month , year )
488
- min_bound = date2num (datetime (year , month , 1 , 0 , 0 ),
489
- time .units , time .dtype )
490
- max_bound = date2num (datetime (next_year , next_month , 1 , 0 , 0 ),
491
- time .units , time .dtype )
492
- elif freq == 'yr' :
493
- min_bound = date2num (datetime (year , 1 , 1 , 0 , 0 ),
494
- time .units , time .dtype )
495
- max_bound = date2num (datetime (year + 1 , 1 , 1 , 0 , 0 ),
496
- time .units , time .dtype )
497
- elif freq == 'dec' :
498
- min_bound = date2num (datetime (year , 1 , 1 , 0 , 0 ),
499
- time .units , time .dtype )
500
- max_bound = date2num (datetime (year + 10 , 1 , 1 , 0 , 0 ),
501
- time .units , time .dtype )
502
- else :
503
- delta = {
504
- 'day' : 12.0 / 24 ,
505
- '6hr' : 3.0 / 24 ,
506
- '3hr' : 1.5 / 24 ,
507
- '1hr' : 0.5 / 24 ,
508
- }
509
- if freq not in delta :
483
+
484
+ for date in dates :
485
+ if 'dec' in freq :
486
+ min_bound = datetime (date .year - 5 , 1 , 1 , 0 , 0 )
487
+ max_bound = datetime (date .year + 5 , 1 , 1 , 0 , 0 )
488
+ elif 'yr' in freq :
489
+ min_bound = datetime (date .year , 1 , 1 , 0 , 0 )
490
+ max_bound = datetime (date .year + 1 , 1 , 1 , 0 , 0 )
491
+ elif 'mon' in freq or freq == 'mo' :
492
+ next_month , next_year = get_next_month (date .month , date .year )
493
+ min_bound = datetime (date .year , date .month , 1 , 0 , 0 )
494
+ max_bound = datetime (next_year , next_month , 1 , 0 , 0 )
495
+ elif 'day' in freq :
496
+ min_bound = date - timedelta (hours = 12.0 )
497
+ max_bound = date + timedelta (hours = 12.0 )
498
+ elif 'hr' in freq :
499
+ (n_hours_str , _ , _ ) = freq .partition ('hr' )
500
+ if not n_hours_str :
501
+ n_hours = 1
502
+ else :
503
+ n_hours = int (n_hours_str )
504
+ if 24 % n_hours :
510
505
raise NotImplementedError (
511
- f"Cannot guess time bounds for frequency '{ freq } '"
506
+ f"For `n`-hourly data, `n` must be a divisor of 24, got "
507
+ f"'{ freq } '"
512
508
)
513
- point = time .points [step ]
514
- min_bound = point - delta [freq ]
515
- max_bound = point + delta [freq ]
509
+ min_bound = date - timedelta (hours = n_hours / 2.0 )
510
+ max_bound = date + timedelta (hours = n_hours / 2.0 )
511
+ else :
512
+ raise NotImplementedError (
513
+ f"Cannot guess time bounds for frequency '{ freq } '"
514
+ )
516
515
bounds .append ([min_bound , max_bound ])
517
516
518
- return np .array (bounds )
517
+ return date2num ( np .array (bounds ), time . units , time . dtype )
0 commit comments