Java как получить дату создания файла

Обновлено: 04.07.2024

Мне кажется любопытным, что наиболее очевидный способ создания объектов Date в Java устарел и, по-видимому, был «заменен» не столь очевидным для использования мягким календарем.

Как вы проверяете, что дата, представленная как сочетание дня, месяца и года, является действительной датой?

Текущий способ - использовать класс календаря. У него есть метод setLenient , который будет проверять дату, выбрасывание и исключение, если оно выходит за пределы диапазона, как в вашем примере.

Забыл добавить: Если вы получаете экземпляр календаря и устанавливаете время, используя свою дату, вы получаете подтверждение.

Ключ df.setLenient (false);. Этого более чем достаточно для простых случаев. Если вы ищете более надежные (я сомневаюсь) и/или альтернативные библиотеки, такие как joda-time, тогда посмотрите на ответ пользователя "tardate"

Однако на практике этого достаточно редко, поскольку SimpleDateFormat.parse чрезвычайно либерален. Есть два поведения, которые могут вас заинтересовать:

Годы: 2, 3 или 4 цифры? Возможно, вы также захотите ввести 4-значные годы вместо того, чтобы разрешить поведение SimpleDateFormat по умолчанию (которое будет интерпретировать «12-02-31» по-разному в зависимости от того, был ли у вас формат «гггг-ММ-дд» или «гг»). -MM-дд ")

Строгое решение со стандартной библиотекой

Таким образом, полный тест строки на дату может выглядеть так: комбинация соответствия регулярному выражению, а затем принудительное преобразование даты. Уловка с регулярным выражением состоит в том, чтобы сделать его дружественным к локали.

Обратите внимание, что регулярное выражение предполагает, что строка формата содержит только день, месяц, год и символы-разделители. Кроме того, формат может быть в любом формате локали: "d/MM/yy", "yyyy-MM-dd" и так далее. Строка формата для текущей локали может быть получена следующим образом:

Joda Time - лучшая альтернатива?

Я слышал о время йода недавно и подумал, что я бы сравнить. Два момента:

  1. Лучше быть строгим в отношении недопустимых символов в строке даты, в отличие от SimpleDateFormat
  2. Пока не могу найти способ применить 4-значные годы (но я думаю, вы могли бы создать свой собственный DateTimeFormatter для этой цели)

Это довольно просто использовать:

Вы можете использовать SimpleDateFormat

Например что-то вроде:

Java.time

Используя Date и Time API ( Java.time classes), встроенные в Java 8 и более поздние версии, вы можете использовать LocalDate class.

тЛ; др

После синтаксического анализа вы можете проверить разумную стоимость. Например, дата рождения в течение последних ста лет.

Избегайте устаревших классов даты и времени

Избегайте использования проблемных старых классов даты и времени, поставляемых с самыми ранними версиями Java. Теперь вытеснены классами Java.time .

LocalDate & DateTimeFormatter & ResolverStyle

Класс LocalDate представляет значение только для даты без времени суток и без часового пояса.

Класс Java.time.DateTimeFormatter может быть настроен на анализ строк с любым из трех режимов снисхождения, определенных в ResolverStyle enum. Мы вставляем строку в приведенный выше код, чтобы попробовать каждый из режимов.

  • ResolverStyle.LENIENT
    лд: 2000-03-02
  • ResolverStyle.SMART
    лд: 2000-02-29
  • ResolverStyle.STRICT
    ОШИБКА: Java.time.format.DateTimeParseException: текст «31/02/2000» не может быть проанализирован: недопустимая дата «31 ФЕВРАЛЯ»

Мы видим, что в режиме ResolverStyle.LENIENT недопустимая дата перемещается на эквивалентное количество дней вперед. В режиме ResolverStyle.SMART (по умолчанию) принимается логическое решение сохранить дату в месяце и перейти к последнему возможному дню месяца, 29 февраля в високосном году, поскольку в этом году нет 31-го дня. месяц. Режим ResolverStyle.STRICT вызывает исключение, сообщающее, что такой даты нет.

Все три из них являются разумными в зависимости от вашей бизнес-проблемы и политики. Похоже, в вашем случае вы хотите, чтобы строгий режим отклонял недействительную дату, а не корректировал ее.

О Java.time

Java.time framework встроен в Java 8 и более поздние версии. Эти классы вытесняют проблемные старые унаследованные классы даты и времени, такие как Java.util.Date , Calendar , & SimpleDateFormat .

Проект Joda-Time , теперь находящийся в режиме обслуживания , рекомендует выполнить переход к Java.time классам.

Чтобы узнать больше, см. Oracle Tutorial . И поиск переполнения стека для многих примеров и объяснений. Спецификация это JSR 310 .

Вы можете обмениваться объектами Java.time непосредственно с вашей базой данных. Используйте драйвер JDBC совместимый с JDBC 4.2 или новее. Нет необходимости в строках, нет необходимости в классах Java.sql.* .

Где взять классы Java.time?

    , Java SE 9 и более поздние версии
    • Встроенный.
    • Часть стандартного Java API со встроенной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
    • Большая часть функциональности Java.time перенесена в Java 6 & 7 в ThreeTen-Backport .
    • Более поздние версии Android связывают реализации классов Java.time.
    • Для более ранних версий Android (<26) ThreeTenABP project адаптируется ThreeTen-Backport (упоминалось выше). Смотрите Как использовать ThreeTenABP… .

    Проект ThreeTen-Extra расширяет Java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к Java.time. Здесь вы можете найти некоторые полезные классы, такие как Interval , YearWeek , YearQuarter , и more .

    Альтернативное строгое решение с использованием стандартной библиотеки - выполнить следующее:

    1) Создайте строгий SimpleDateFormat, используя ваш шаблон

    2) Попытка разобрать введенное пользователем значение с использованием объекта формата

    3) В случае успеха переформатируйте дату, полученную из (2), используя тот же формат даты (из (1))

    4) Сравните переформатированную дату с исходным введенным пользователем значением. Если они равны, то введенное значение строго соответствует вашему шаблону.

    Таким образом, вам не нужно создавать сложные регулярные выражения - в моем случае мне нужно было поддерживать весь синтаксис шаблона SimpleDateFormat, а не ограничиваться определенными типами, такими как дни, месяцы и годы.

    Вот как я это делаю:

    GenericValidator.isDate(String value, String datePattern, boolean strict);

    Примечание: строгое - иметь или нет точное соответствие datePattern.

    Я думаю, что самое простое - просто преобразовать строку в объект даты и преобразовать ее обратно в строку. Данная строка даты подходит, если обе строки все еще совпадают.

    Предполагая, что оба они являются строками (в противном случае они уже будут действительными датами), вот один из способов:

    First Gotcha: переход на второй месяц может дать вам что-то неожиданное: месяц основан на нулевом значении, что означает, что 2 фактически является мартом.

    Я не знаю, что такое "легкий" способ, который вы ищете, поскольку я чувствую, что использование Календаря уже достаточно легко.

    Не забудьте использовать правильные константы для месяца:

    Другой способ - использовать DateFormat, который я обычно использую следующим образом:

    чтобы я мог просто написать

    Еще одна альтернатива, которую я предпочитаю: больше не используйте Java Date/Calendar. Переключитесь на время JODA или Java Time (ака JSR310, доступное в JDK 8+). Вы можете использовать LocalDate для представления даты, которую можно легко создать с помощью

    Если вы хотите "легко", вы должны использовать Joda-Time или новый java.time package в Java 8, а не печально известные классы java.util.Date и .Calendar в комплекте с Java.

    Во-первых, Joda-Time использует разумную нумерацию, поэтому в феврале 2 not 1 . Другое дело, Joda-Time DateTime действительно знает свой назначенный часовой пояс в отличие от java.util.Date, который, кажется, имеет часовой пояс, но не делает.

    И не забудьте часовой пояс. В противном случае вы будете получать JVM по умолчанию.

    Дамп для консоли.

    Конверсия

    Если вам нужно преобразовать в java.util.Date для использования с другими классами.

    Структура java.time, встроенная в Java 8, а затем вытесняет неприятные старые классы java.util.Date/.Calendar. Новые классы вдохновлены чрезвычайно успешной структурой Joda-Time, предназначенной в качестве ее преемника, схожей по концепции, но повторно созданной. Определено JSR 310. Расширено в проекте ThreeTen-Extra. См. Tutorial.

    A LocalDate класс предлагается java.time для представления значения только для даты без какого-либо времени или часового пояса, Вам нужен часовой пояс, чтобы определить дату, поскольку новый день наступает раньше в Париже, чем, например, в Монреале. Класс ZoneId предназначен для часовых поясов.

    Дамп для консоли:

    сегодня: 2015-11-26 в зоне: Азия/Сингапур

    Или используйте метод factory, чтобы указать год, месяц, день.

    Или передайте месяц номер 1-12, а не объект DayOfWeek enum.

    A LocalDate не имеет реального значения, пока вы не настроите его на часовой пояс. В java.time мы применяем часовой пояс для создания объекта ZonedDateTime . Это также означает время суток, но в какое время? Обычно имеет смысл идти с первого момента дня. Вы можете подумать, что это означает время 00:00:00.000 , но не всегда истинное из-за летнего времени (DST) и, возможно, других аномалий. Вместо того, чтобы предполагать это время, мы запрашиваем java.time для определения первого момента дня, вызывая atStartOfDay .

    zdt: 2014-02-11T00: 00 + 08: 00 [Азия/Сингапур]

    Есть еще один похожий вопрос на StackOverflow ( как получить дату создания файла на Java ), но ответа на самом деле нет, поскольку у OP была другая потребность, которую можно было решить с помощью других механизмов. Я пытаюсь создать список файлов в каталоге, который можно отсортировать по возрасту, отсюда и необходимость в дате создания файла.

    Я не нашел хорошего способа сделать это после долгого рыскания в сети. Есть ли механизм получения дат создания файлов?

    Кстати, в настоящее время в системе Windows, возможно, это понадобится для работы и в системе Linux. Кроме того, я не могу гарантировать, что будет соблюдаться соглашение об именах файлов, если дата / время создания встроены в имя.

    Хорошо, после дальнейших обсуждений и исследований файловых систем мы решили, что достаточно использовать последнее изменение, так как его, вероятно, нужно было бы проверить вместе с датой создания. Оба должны быть проверены, чтобы определить, был ли старый файл недавно изменен и, следовательно, все еще активен. Итак, просто проверьте файл, измененный наиболее далеко в прошлом. Спасибо за ваш вклад. Кстати, я бы хотел использовать nio, но Linux здесь все равно не поддерживает создание файлов.

    В Java nio есть опции для доступа к createTime и другим метаданным, если их предоставляет файловая система. Проверить эту ссылку из

    Например (предоставлено на основе комментария @ ydaetskcoR):

    Это было бы лучше всего, но это Java 7. Мы все еще используем 6, но я изучу наши варианты обновления. используйте readAttributes(file.toPath(), BasicFileAttributes.class) еще вы получите: no suitable method found for readAttributes(File,Class<BasicFileAttributes>) method Files.<A>readAttributes(Path,Class<A>,LinkOption. ) is not applicable (cannot infer type-variable(s) A (argument mismatch; File cannot be converted to Path)) Дата создания файла недоступна в JDK 8 (по крайней мере), поскольку statx системный вызов был добавлен в более новую версию ядра Linux.

    Я решил эту проблему с помощью JDK 7 с помощью этого кода:

    В продолжение этого вопроса - поскольку он относится конкретно ко времени создания и обсуждает его получение с помощью новых классов nio - кажется, что прямо сейчас в реализации JDK7 вам не повезло. Приложение: такое же поведение и в OpenJDK7.

    В файловых системах Unix вы не можете получить метку времени создания, вы просто получаете копию времени последней модификации. Так грустно, но, к сожалению, это правда. Я не уверен, почему это так, но код специально делает это, как показано ниже.

    Вы знаете, как это сделать для Android? BasicFileAttributes недоступен как встроенный в API .

    Это базовый пример того, как получить дату создания файла с Java помощью BasicFileAttributes класса:

    Люди, желающие использовать этот класс, должны отметить, что он начал поставляться в Java 1.7.

    В системе Windows вы можете использовать бесплатные FileTimes библиотеку .

    Но помните, что большинство файловых систем Linux не поддерживают отметки времени создания файлов .

    Любой другой способ для Linux-машин, которые не поддерживают созданное время? Просто используйте файловую систему, которая поддерживает временные метки создания файлов. Связанная статья в Википедии предлагает ext4, который сейчас довольно распространен.

    API java.io.File поддерживает только получение времени последнего изменения . И в Интернете тоже очень тихо по этой теме.

    Если я не пропустил что-то существенное, библиотека Java как есть (вплоть до Java 7, но еще не включая) не включает эту возможность. Поэтому, если вы отчаянно в этом нуждались, одним из решений было бы написать код C (++) для вызова системных подпрограмм и вызвать его с помощью JNI. Однако большая часть этой работы, похоже, уже сделана за вас в библиотеке JNA .

    Тем не менее, вам может потребоваться немного кодирования для конкретной ОС на Java, поскольку вы, вероятно, не найдете те же системные вызовы, доступные в Windows и Unix / Linux / BSD / OS X.

    Да, Java 7 была бы замечательной, поскольку у nio, похоже, это есть в основных атрибутах. Никогда не думала, что буду жаловаться на то, что родилась слишком рано! ;) Причина, по которой File класс не имеет такой возможности, заключается в том, что большинство файловых систем даже не отслеживают эту информацию. А те, кто этого не делает, не всегда соглашаются, когда его следует обновлять. @Syntactic: На самом деле большинство файловых систем отслеживают эту информацию . Исключения включают ext <= 3 и Reiser. FAT, NTFS, HFS, ZFS и ext4 поддерживают его. Но он медленно распространяется на все уровни Linux, библиотеки и команды, чтобы сделать его универсальным. @Carl В Linux я получаю дату модификации и создания, как и при использовании Java NIO. Это нормальное поведение? @JayeshDhandha, если ничего не изменяет файл после его создания, я бы ожидал, что время создания и модификации будет одинаковым. Вы можете попробовать изменить это, используя touch для изменения времени мода, а затем снова проверить.

    в java1.7 + Вы можете использовать этот код, чтобы узнать время создания файла!

    Есть еще один похожий вопрос к моему на StackOverflow ( Как получить дату создания файла в Java ), но ответа на самом деле нет, так как у ОП была другая потребность, которую можно решить с помощью других механизмы. Я пытаюсь создать список файлов в каталоге, который можно отсортировать по возрасту, отсюда и необходимость в дате создания файла.

    Я не нашел ни одного хорошего способа сделать это после долгих тралений в Интернете. Есть ли механизм получения даты создания файла?

    Кстати, в настоящее время в системе Windows это может понадобиться и для работы в системе Linux. Кроме того, я не могу гарантировать, что будет соблюдаться соглашение об именовании файлов, когда в имени указана дата и время создания.

    Java nio имеет опции для доступа к creationTime и другим метаданным, если их предоставляет файловая система. Проверьте эта ссылка из

    Например (Предоставлено на основе комментария @ ydaetskcoR):

    Я решил эту проблему, используя JDK 7 с этим кодом:

    В качестве продолжения этого вопроса - поскольку он касается конкретно времени создания и обсуждает его получение с помощью новых классов nio - кажется, что в реализации JDK7 вам не повезло. Приложение: такое же поведение в OpenJDK7.

    В файловых системах Unix вы не можете получить метку времени создания, вы просто получаете копию времени последней модификации. Так грустно, но, к сожалению, правда. Я не уверен, почему это так, но код специально делает это, как продемонстрирует следующее.

    Это основной пример того, как получить дату создания файла в Java , используя BasicFileAttributes класс:

    В системе Windows вы можете использовать бесплатную библиотеку FileTimes .

    Но помните, что большинство файловых систем Linux не поддерживают временные метки создания файлов .

    API Java.io.File поддерживает только получение последнего измененного времени. И в Интернете очень тихо по этой теме.

    Если я не пропустил что-то существенное, библиотека Java, как есть (до, но не включая Java 7), не включает эту возможность. Так что, если бы вы отчаянно нуждались в этом, одним из решений было бы написать некоторый код C (++) для вызова системных подпрограмм и вызова его с использованием JNI. Похоже, что большая часть этой работы уже сделана для вас в библиотеке под названием JNA .

    Для этого вам все же может потребоваться выполнить небольшое кодирование, специфичное для ОС, в Java, поскольку вы, вероятно, не найдете те же системные вызовы, доступные в Windows и Unix/Linux/BSD/OS X.

    в Java1.7 + Вы можете использовать этот код, чтобы получить время создания файла!

    Читайте также: