Fix memory filename date extraction

This commit is contained in:
Cameron
2026-01-02 19:29:42 -05:00
parent 878465fea9
commit 0dfec4c8c5

View File

@@ -204,16 +204,21 @@ pub fn extract_date_from_filename(filename: &str) -> Option<DateTime<FixedOffset
return Some(captures);
}
// 4. Timestamp format: 1401638400.jpeg
if let Some(captures) = regex::Regex::new(r"(\d{10}|\d{13})\.")
.ok()?
.captures(filename)
{
// 4. Timestamp format: 1401638400.jpeg, att_1422489664680106.jpeg, att_142248967186928.jpeg
// Matches timestamps with 10-16 digits (seconds, milliseconds, microseconds)
if let Some(captures) = regex::Regex::new(r"(\d{10,16})\.").ok()?.captures(filename) {
let timestamp_str = captures.get(1)?.as_str();
let len = timestamp_str.len();
// Millisecond timestamp (13 digits)
if timestamp_str.len() >= 13
&& let Some(date_time) = timestamp_str[0..13]
// Skip autogenerated filenames that start with "10000" (e.g., 1000004178.jpg)
// These are not timestamps but auto-generated file IDs
if timestamp_str.starts_with("10000") {
return None;
}
// Try milliseconds first (13 digits exactly)
if len == 13
&& let Some(date_time) = timestamp_str
.parse::<i64>()
.ok()
.and_then(DateTime::from_timestamp_millis)
@@ -222,8 +227,10 @@ pub fn extract_date_from_filename(filename: &str) -> Option<DateTime<FixedOffset
return Some(date_time);
}
// Second timestamp (10 digits)
if timestamp_str.len() >= 10
// For 14-16 digits, treat first 10 digits as seconds to avoid far future dates
// Examples: att_1422489664680106 (16 digits), att_142248967186928 (15 digits)
if len >= 14
&& len <= 16
&& let Some(date_time) = timestamp_str[0..10]
.parse::<i64>()
.ok()
@@ -232,6 +239,28 @@ pub fn extract_date_from_filename(filename: &str) -> Option<DateTime<FixedOffset
{
return Some(date_time);
}
// Exactly 10 digits - seconds since epoch
if len == 10
&& let Some(date_time) = timestamp_str
.parse::<i64>()
.ok()
.and_then(|timestamp_secs| DateTime::from_timestamp(timestamp_secs, 0))
.map(|naive_dt| naive_dt.fixed_offset())
{
return Some(date_time);
}
// 11-12 digits: try as milliseconds (might be partial millisecond timestamp)
if (len == 11 || len == 12)
&& let Some(date_time) = timestamp_str
.parse::<i64>()
.ok()
.and_then(DateTime::from_timestamp_millis)
.map(|naive_dt| naive_dt.fixed_offset())
{
return Some(date_time);
}
}
None
@@ -752,6 +781,55 @@ mod tests {
assert_eq!(date_time.second(), 0);
}
#[test]
fn test_extract_date_from_filename_attachment_15_digits() {
// att_142248967186928.jpeg - 15 digits, should parse first 10 as seconds
// 1422489671 = 2015-01-28 23:07:51 UTC (converts to local timezone)
let filename = "att_142248967186928.jpeg";
let date_time = extract_date_from_filename(filename).unwrap();
// Verify year and month are correct (2015-01)
assert_eq!(date_time.year(), 2015);
assert_eq!(date_time.month(), 1);
// Day may be 28 or 29 depending on timezone
assert!(date_time.day() >= 28 && date_time.day() <= 29);
// Verify timestamp is within expected range (should be around 1422489671)
let timestamp = date_time.timestamp();
assert!(timestamp >= 1422480000 && timestamp <= 1422576000); // Jan 28-29, 2015
}
#[test]
fn test_extract_date_from_filename_attachment_16_digits() {
// att_1422489664680106.jpeg - 16 digits, should parse first 10 as seconds
// 1422489664 = 2015-01-28 23:07:44 UTC (converts to local timezone)
let filename = "att_1422489664680106.jpeg";
let date_time = extract_date_from_filename(filename).unwrap();
// Verify year and month are correct (2015-01)
assert_eq!(date_time.year(), 2015);
assert_eq!(date_time.month(), 1);
// Day may be 28 or 29 depending on timezone
assert!(date_time.day() >= 28 && date_time.day() <= 29);
// Verify timestamp is within expected range (should be around 1422489664)
let timestamp = date_time.timestamp();
assert!(timestamp >= 1422480000 && timestamp <= 1422576000); // Jan 28-29, 2015
}
#[test]
fn test_extract_date_from_filename_autogenerated_should_not_match() {
// Autogenerated filenames like 1000004178.jpg should NOT be parsed as timestamps
// These start with "10000" which would be Sept 2001 if parsed literally
let filename = "1000004178.jpg";
let date_time = extract_date_from_filename(filename);
assert!(
date_time.is_none(),
"Autogenerated filenames starting with 10000 should not be parsed as dates"
);
}
#[test]
fn test_memory_date_priority_filename() {
let temp_dir = tempdir().unwrap();