|
5 | 5 | // spell-checker:ignore (formats) cymdhm cymdhms mdhm mdhms ymdhm ymdhms datetime mktime |
6 | 6 |
|
7 | 7 | use crate::common::util::{AtPath, TestScenario}; |
| 8 | +use chrono::NaiveDate; |
8 | 9 | #[cfg(not(target_os = "freebsd"))] |
9 | 10 | use filetime::set_symlink_file_times; |
10 | 11 | use filetime::FileTime; |
@@ -181,6 +182,47 @@ fn test_touch_2_digit_years_69() { |
181 | 182 | assert_eq!(mtime, expected); |
182 | 183 | } |
183 | 184 |
|
| 185 | +#[test] |
| 186 | +fn test_y2038_touch() { |
| 187 | + // Jan 19 2038, 03:14:07 UTC is the moment of the Y2038 bug |
| 188 | + // test 1 second before, at, and 1 second after |
| 189 | + let year = 2038; |
| 190 | + let month = 1; |
| 191 | + let day = 19; |
| 192 | + let hours = 3; |
| 193 | + let minutes = 14; |
| 194 | + let seconds = 7; |
| 195 | + for deltas in [-1i32, 0, 1] { |
| 196 | + let (at, mut ucmd) = at_and_ucmd!(); |
| 197 | + |
| 198 | + let date = NaiveDate::from_ymd_opt(year, month, day).unwrap(); |
| 199 | + let datetime = date |
| 200 | + .and_hms_opt(hours, minutes, (seconds + deltas).try_into().unwrap()) |
| 201 | + .unwrap(); |
| 202 | + let timestamp = datetime.and_utc().timestamp(); |
| 203 | + |
| 204 | + let date = format!( |
| 205 | + "{}{:02}{:02}{:02}{:02}.{:02}", |
| 206 | + year, |
| 207 | + month, |
| 208 | + day, |
| 209 | + hours, |
| 210 | + minutes, |
| 211 | + seconds + deltas |
| 212 | + ); |
| 213 | + let file = format!("Y2038_{}_{}", date, deltas); |
| 214 | + ucmd.args(&["-t", &date, &file]).succeeds().no_output(); |
| 215 | + |
| 216 | + assert!(at.file_exists(&file)); |
| 217 | + |
| 218 | + let expected = FileTime::from_unix_time(timestamp, 0); |
| 219 | + let (atime, mtime) = get_file_times(&at, &file); |
| 220 | + assert_eq!(atime, mtime); |
| 221 | + assert_eq!(atime, expected); |
| 222 | + assert_eq!(mtime, expected); |
| 223 | + } |
| 224 | +} |
| 225 | + |
184 | 226 | #[test] |
185 | 227 | fn test_touch_set_ymdhm_time() { |
186 | 228 | let (at, mut ucmd) = at_and_ucmd!(); |
|
0 commit comments