Java как получить дату создания файла
Мне кажется любопытным, что наиболее очевидный способ создания объектов 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 - лучшая альтернатива?
Я слышал о время йода недавно и подумал, что я бы сравнить. Два момента:
- Лучше быть строгим в отношении недопустимых символов в строке даты, в отличие от SimpleDateFormat
- Пока не могу найти способ применить 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 + Вы можете использовать этот код, чтобы получить время создания файла!
Читайте также: