@@ -208,10 +208,25 @@ impl Tzif {
208
208
209
209
pub fn get ( & self , epoch_seconds : & Seconds ) -> TemporalResult < TimeZoneOffset > {
210
210
let db = self . get_data_block2 ( ) ?;
211
+
211
212
let result = db. transition_times . binary_search ( epoch_seconds) ;
212
213
213
214
match result {
214
215
Ok ( idx) => Ok ( get_timezone_offset ( db, idx - 1 ) ) ,
216
+ // <https://datatracker.ietf.org/doc/html/rfc8536#section-3.2>
217
+ // If there are no transitions, local time for all timestamps is specified by the TZ
218
+ // string in the footer if present and nonempty; otherwise, it is
219
+ // specified by time type 0.
220
+ Err ( _) if db. transition_times . is_empty ( ) => {
221
+ if let Some ( posix_tz_string) = self . posix_tz_string ( ) {
222
+ resolve_posix_tz_string_for_epoch_seconds ( posix_tz_string, epoch_seconds. 0 )
223
+ } else {
224
+ Ok ( TimeZoneOffset {
225
+ offset : db. local_time_type_records [ 0 ] . utoff . 0 ,
226
+ transition_epoch : None ,
227
+ } )
228
+ }
229
+ }
215
230
Err ( idx) if idx == 0 => Ok ( get_timezone_offset ( db, idx) ) ,
216
231
Err ( idx) => {
217
232
if db. transition_times . len ( ) <= idx {
@@ -308,12 +323,11 @@ impl Tzif {
308
323
309
324
#[ inline]
310
325
fn get_timezone_offset ( db : & DataBlock , idx : usize ) -> TimeZoneOffset {
311
- let transition_epoch = db. transition_times [ idx] ;
312
326
// NOTE: Transition type can be empty. If no transition_type exists,
313
327
// then use 0 as the default index of local_time_type_records.
314
328
let offset = db. local_time_type_records [ db. transition_types . get ( idx) . copied ( ) . unwrap_or ( 0 ) ] ;
315
329
TimeZoneOffset {
316
- transition_epoch : Some ( transition_epoch . 0 ) ,
330
+ transition_epoch : db . transition_times . get ( idx ) . map ( |s| s . 0 ) ,
317
331
offset : offset. utoff . 0 ,
318
332
}
319
333
}
@@ -370,7 +384,11 @@ fn resolve_posix_tz_string_for_epoch_seconds(
370
384
TransitionDay :: NoLeap ( day) => i32:: from ( day) - 1 ,
371
385
TransitionDay :: WithLeap ( day) => i32:: from ( day) ,
372
386
TransitionDay :: Mwd ( _month, _week, _day) => {
373
- return Err ( TemporalError :: general ( "unimplemented" ) ) ;
387
+ // TODO: build transition epoch from month, week and day.
388
+ return Ok ( TimeZoneOffset {
389
+ offset : offset. offset ,
390
+ transition_epoch : None ,
391
+ } ) ;
374
392
}
375
393
} ;
376
394
let transition_epoch = i64:: from ( year_epoch) + i64:: from ( days) * 3600 + transition. time . 0 ;
0 commit comments