Fix memory filename date extraction
This commit is contained in:
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user