Вопрос или проблема
В macOS я хочу установить st_birthtime
на дату до 1970/01/01. Например, дата=”1953/12/02 00:00:01″. Замечание: st_birthtime
– это четвертая дата, отображаемая командой оболочки > stat my/file.txt
. Я думаю, что это также дата, отображаемая приложением Photos, и ее можно установить в Photos на дату < 1970/01/01.
Если дата > 1970/01/01, то приведенный ниже код (с использованием пакета Python objc
) дает хороший результат.
Если дата < 1970/01/01, я получаю неожиданные результаты с приведенным ниже кодом.
Мой вопрос: как я могу это сделать (без приложения Photos, конечно)?
# Спасибо различному ИИ:
from datetime import datetime, timezone
from Foundation import NSFileManager, NSDate, NSMutableDictionary
from path import Path
def set_birthtime(file_path:Path or str, birthtime:datetime):
file_manager = NSFileManager.defaultManager()
attributes = file_manager.attributesOfItemAtPath_error_(file_path, None)[0]
mutable_attributes = NSMutableDictionary.dictionaryWithDictionary_(attributes)
# Преобразование datetime в NSDate
interval = birthtime - datetime(2001, 1, 1, 0, 0, 0, tzinfo=timezone.utc)
ns_date_birthtime = NSDate.dateWithTimeIntervalSinceReferenceDate_(interval.total_seconds())
mutable_attributes['NSFileCreationDate'] = ns_date_birthtime
file_manager.setAttributes_ofItemAtPath_error_(mutable_attributes, file_path, None)
if __name__ == '__main__':
# Пример использования
file_path = Path('/Users/puiseux/Pictures/original.jpeg')
birthtime = datetime(1973, 12, 2, 2, 12, 53, tzinfo=timezone.utc)
debug("Не работает, если дата > 1970-01-01")
set_birthtime(file_path, birthtime)
# проверьте результат с помощью команды оболочки > stat original.jpeg
Ответ или решение
Установка st_birthtime
в macOS: Проблема и Решение
В macOS настройка времени создания файла (st_birthtime
) на дату до 1970 года представляет собой сложную задачу. Дата, меньшая этой, известна как "временная метка до эпохи Unix", и работа с ней требует особого внимания к деталям. Несмотря на то что приложение Photos позволяет редактировать такие метки без проблем, это не так просто через стандартные утилиты или скрипты.
Почему это важно?
Файловые метаданные играют значительную роль в организации данных и их управлении. Неправильное время создания может привести к путанице при сортировке и поиске файлов. Ваша ситуация требует точного понимания работы с файловыми атрибутами в macOS.
Использование Python и Objective-C для установки st_birthtime
Ошибка, которую вы наблюдаете при попытке установить дату до 1970 года, связана с тем, что многие Unix-системы, включая macOS, не поддерживают такие временные метки напрямую. Однако можно попытаться использовать альтернативные методы через манипуляцию с метаданными.
Обновленный Код
Попробуйте следующий код, который настроен для работы с временными метками до 1970 года:
from datetime import datetime, timezone
from Foundation import NSFileManager, NSDate, NSMutableDictionary
from path import Path
def set_birthtime(file_path: Path or str, birthtime: datetime):
file_manager = NSFileManager.defaultManager()
attributes = file_manager.attributesOfItemAtPath_error_(file_path, None)[0]
mutable_attributes = NSMutableDictionary.dictionaryWithDictionary_(attributes)
# Для дат до 1970 года используем отрицательные временные интервалы
if birthtime < datetime(1970, 1, 1, tzinfo=timezone.utc):
# Переводим дату в это время
interval = birthtime.timestamp()
if interval < 0:
ns_date_birthtime = NSDate.dateWithTimeInterval_sinceDate_(interval, NSDate.dateWithTimeIntervalSince1970_(0))
else:
ns_date_birthtime = NSDate.dateWithTimeIntervalSince1970_(interval)
else:
# Стандартное поведение для дат >= 1970 года
interval = birthtime - datetime(2001, 1, 1, 0, 0, 0, tzinfo=timezone.utc)
ns_date_birthtime = NSDate.dateWithTimeIntervalSinceReferenceDate_(interval.total_seconds())
mutable_attributes['NSFileCreationDate'] = ns_date_birthtime
# Обновляем атрибуты файла
file_manager.setAttributes_ofItemAtPath_error_(mutable_attributes, file_path, None)
if __name__ == '__main__':
file_path = Path('/Users/puiseux/Pictures/original.jpeg')
birthtime = datetime(1953, 12, 2, 0, 0, 1, tzinfo=timezone.utc) # Ваше желаемое время
set_birthtime(file_path, birthtime)
# Проверьте результат с помощью команды stat original.jpeg
Примечания и Рекомендации
-
Совместимость: Обратите внимание на совместимость вашего скрипта с текущими версиями macOS. Системные обновления могут изменить поведение работы с метками.
-
Тестирование: Прежде чем применять изменения к важным файлам, протестируйте скрипт на резервной копии.
-
Логирование: Настройте логирование в вашем приложении для отслеживания любых ошибок, которые могут возникнуть при работе со старыми временными метками.
-
Обратная связь: Если метод окажется успешным или нет, обратите внимание на возможные улучшения, которые помогут другим пользователям.
Заключение
Изменение метаданных файлов в macOS может быть сложной задачей, особенно когда дело касается взаимодействия с временными метками, меньшими 1970 года. Приведенный выше способ с использованием Python с библиотекой Objective-C предлагает один из возможных подходов к решению данной задачи.