установка st_birthtime в macOS

Вопрос или проблема

В 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

Примечания и Рекомендации

  1. Совместимость: Обратите внимание на совместимость вашего скрипта с текущими версиями macOS. Системные обновления могут изменить поведение работы с метками.

  2. Тестирование: Прежде чем применять изменения к важным файлам, протестируйте скрипт на резервной копии.

  3. Логирование: Настройте логирование в вашем приложении для отслеживания любых ошибок, которые могут возникнуть при работе со старыми временными метками.

  4. Обратная связь: Если метод окажется успешным или нет, обратите внимание на возможные улучшения, которые помогут другим пользователям.

Заключение

Изменение метаданных файлов в macOS может быть сложной задачей, особенно когда дело касается взаимодействия с временными метками, меньшими 1970 года. Приведенный выше способ с использованием Python с библиотекой Objective-C предлагает один из возможных подходов к решению данной задачи.

Оцените материал
Добавить комментарий

Капча загружается...