11//! Types related to a time zone.
22
3- use std:: fs:: { self , File } ;
4- use std:: io:: { self , Read } ;
5- use std:: path:: { Path , PathBuf } ;
63use std:: { cmp:: Ordering , fmt, str} ;
74
85use super :: rule:: { AlternateTime , TransitionRule } ;
@@ -22,43 +19,8 @@ pub(crate) struct TimeZone {
2219}
2320
2421impl TimeZone {
25- /// Returns local time zone.
26- ///
27- /// This method in not supported on non-UNIX platforms, and returns the UTC time zone instead.
28- pub ( crate ) fn local ( env_tz : Option < & str > ) -> Result < Self , Error > {
29- match env_tz {
30- Some ( tz) => Self :: from_posix_tz ( tz) ,
31- None => Self :: from_posix_tz ( "localtime" ) ,
32- }
33- }
34-
3522 /// Construct a time zone from a POSIX TZ string, as described in [the POSIX documentation of the `TZ` environment variable](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html).
36- fn from_posix_tz ( tz_string : & str ) -> Result < Self , Error > {
37- if tz_string. is_empty ( ) {
38- return Err ( Error :: InvalidTzString ( "empty TZ string" ) ) ;
39- }
40-
41- if tz_string == "localtime" {
42- return Self :: from_tz_data ( & fs:: read ( "/etc/localtime" ) ?) ;
43- }
44-
45- // attributes are not allowed on if blocks in Rust 1.38
46- #[ cfg( target_os = "android" ) ]
47- {
48- if let Ok ( bytes) = android_tzdata:: find_tz_data ( tz_string) {
49- return Self :: from_tz_data ( & bytes) ;
50- }
51- }
52-
53- let mut chars = tz_string. chars ( ) ;
54- if chars. next ( ) == Some ( ':' ) {
55- return Self :: from_file ( & mut find_tz_file ( chars. as_str ( ) ) ?) ;
56- }
57-
58- if let Ok ( mut file) = find_tz_file ( tz_string) {
59- return Self :: from_file ( & mut file) ;
60- }
61-
23+ pub ( crate ) fn from_tz_string ( tz_string : & str ) -> Result < Self , Error > {
6224 // TZ string extensions are not allowed
6325 let tz_string = tz_string. trim_matches ( |c : char | c. is_ascii_whitespace ( ) ) ;
6426 let rule = TransitionRule :: from_tz_string ( tz_string. as_bytes ( ) , false ) ?;
@@ -85,13 +47,6 @@ impl TimeZone {
8547 Ok ( new)
8648 }
8749
88- /// Construct a time zone from the contents of a time zone file
89- fn from_file ( file : & mut File ) -> Result < Self , Error > {
90- let mut bytes = Vec :: new ( ) ;
91- file. read_to_end ( & mut bytes) ?;
92- Self :: from_tz_data ( & bytes)
93- }
94-
9550 /// Construct a time zone from the contents of a time zone file
9651 ///
9752 /// Parse TZif data as described in [RFC 8536](https://datatracker.ietf.org/doc/html/rfc8536).
@@ -606,34 +561,6 @@ impl LocalTimeType {
606561 pub ( super ) const UTC : LocalTimeType = Self { ut_offset : 0 , is_dst : false , name : None } ;
607562}
608563
609- /// Open the TZif file corresponding to a TZ string
610- fn find_tz_file ( path : impl AsRef < Path > ) -> Result < File , Error > {
611- // Don't check system timezone directories on non-UNIX platforms
612- #[ cfg( not( unix) ) ]
613- return Ok ( File :: open ( path) ?) ;
614-
615- #[ cfg( unix) ]
616- {
617- let path = path. as_ref ( ) ;
618- if path. is_absolute ( ) {
619- return Ok ( File :: open ( path) ?) ;
620- }
621-
622- for folder in & ZONE_INFO_DIRECTORIES {
623- if let Ok ( file) = File :: open ( PathBuf :: from ( folder) . join ( path) ) {
624- return Ok ( file) ;
625- }
626- }
627-
628- Err ( Error :: Io ( io:: ErrorKind :: NotFound . into ( ) ) )
629- }
630- }
631-
632- // Possible system timezone directories
633- #[ cfg( unix) ]
634- const ZONE_INFO_DIRECTORIES : [ & str ; 4 ] =
635- [ "/usr/share/zoneinfo" , "/share/zoneinfo" , "/etc/zoneinfo" , "/usr/share/lib/zoneinfo" ] ;
636-
637564/// Number of seconds in one week
638565pub ( crate ) const SECONDS_PER_WEEK : i64 = SECONDS_PER_DAY * DAYS_PER_WEEK ;
639566/// Number of seconds in 28 days
@@ -844,34 +771,6 @@ mod tests {
844771 Ok ( ( ) )
845772 }
846773
847- #[ test]
848- fn test_time_zone_from_posix_tz ( ) -> Result < ( ) , Error > {
849- #[ cfg( unix) ]
850- {
851- // if the TZ var is set, this essentially _overrides_ the
852- // time set by the localtime symlink
853- // so just ensure that ::local() acts as expected
854- // in this case
855- if let Ok ( tz) = std:: env:: var ( "TZ" ) {
856- let time_zone_local = TimeZone :: local ( Some ( tz. as_str ( ) ) ) ?;
857- let time_zone_local_1 = TimeZone :: from_posix_tz ( & tz) ?;
858- assert_eq ! ( time_zone_local, time_zone_local_1) ;
859- }
860-
861- // `TimeZone::from_posix_tz("UTC")` will return `Error` if the environment does not have
862- // a time zone database, like for example some docker containers.
863- // In that case skip the test.
864- if let Ok ( time_zone_utc) = TimeZone :: from_posix_tz ( "UTC" ) {
865- assert_eq ! ( time_zone_utc. find_local_time_type( 0 ) ?. offset( ) , 0 ) ;
866- }
867- }
868-
869- assert ! ( TimeZone :: from_posix_tz( "EST5EDT,0/0,J365/25" ) . is_err( ) ) ;
870- assert ! ( TimeZone :: from_posix_tz( "" ) . is_err( ) ) ;
871-
872- Ok ( ( ) )
873- }
874-
875774 #[ test]
876775 fn test_leap_seconds ( ) -> Result < ( ) , Error > {
877776 let time_zone = TimeZone :: new (
0 commit comments