Как проверить работоспособность даты в Java [закрыто]


83

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

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

Например, 31 февраля 2008 г. (как в формате гггг-мм-дд) будет недопустимой датой.


Если у вас возникнет подобный вопрос, подумайте, нужна ли вам поддержка не григорианского календаря.
MSalters

@JasonC Я полностью согласен с вами, их объединение выглядит лучшим способом.
acm

Ответы:


37

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

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

Calendar cal = Calendar.getInstance();
cal.setLenient(false);
cal.setTime(yourDate);
try {
    cal.getTime();
}
catch (Exception e) {
  System.out.println("Invalid date");
}

2
не думаю, что это работает как есть. Calendar.setTime принимает java.util.Date, поэтому преобразование из строки уже произошло к тому времени, когда вы получите объект yourDate.
позднее

33
Три проблемы с примером кода: 1. После получения экземпляра Calendar вы должны вызвать cal.setLenient (false). В противном случае дата, подобная 31 февраля 2007 г., будет считаться действительной. 2. Cal.setTime () не генерирует исключение. Вы должны вызвать cal.getTime () после вызова setTime (), который вызывает исключение в недопустимую дату. 3. Опечатка: отсутствует знак "}" перед уловкой.
Лирон Яхдав

Это также медленнее, чем другие подходы. См. Stackoverflow.com/questions/2149680/…
деспот

5
К вашему сведению, неприятные старые классы даты и времени, такие как java.util.Date, java.util.Calendarи java.text.SimpleDateFormat, теперь являются устаревшими , вытесненными классами java.time, встроенными в Java 8 и новее. См. Учебник Oracle .
Basil Bourque

3
не проверяет такие даты, как 31 февраля
шикха

78

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

final static String DATE_FORMAT = "dd-MM-yyyy";

public static boolean isDateValid(String date) 
{
        try {
            DateFormat df = new SimpleDateFormat(DATE_FORMAT);
            df.setLenient(false);
            df.parse(date);
            return true;
        } catch (ParseException e) {
            return false;
        }
}

2
Попробуйте с "09-04-201а". Это создаст безумное свидание.
ceklock

@ceklock, как это работает, независимо от того, используете вы setLenientили нет: SimpleDateFormatвсегда будет анализировать, пока шаблон не будет сопоставлен, и игнорирует остальную часть строки, таким образом, вы получите 201год.
Daniel Naber

@ceklock Я только что обратился к нему в своем решении . Это может сэкономить кому-то минуту или две.
Суфиан

1
Включение обработки исключений влечет за собой большой удар производительности, поэтому это, вероятно, плохой дизайн, ЕСЛИ вы ожидаете неправильного ввода при нормальной работе (например, при проверке пользовательского ввода). Но если этот метод используется для двойной проверки входных данных, которые должны быть действительными все время (кроме ошибок), это нормально.
Аарон

2
К вашему сведению, ужасно неприятные старые классы даты и времени, такие как java.util.Date, java.util.Calendarи java.text.SimpleDateFormat, теперь являются устаревшими , вытесненными классами java.time, встроенными в Java 8 и более поздних версий . См. Учебник Oracle .
Basil Bourque

48

Как показывает @Maglob, основной подход состоит в том, чтобы протестировать преобразование строки в дату с помощью SimpleDateFormat.parse . Это приведет к обнаружению недопустимых комбинаций дня / месяца, например 31.02.2008.

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

Недопустимые символы в строке даты. Удивительно, но 2008-02-2x будет "проходить" как допустимую дату, например, с locale format = "yyyy-MM-dd". Даже когда isLenient == false.

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

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

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

  Date parseDate(String maybeDate, String format, boolean lenient) {
    Date date = null;

    // test date string matches format structure using regex
    // - weed out illegal characters and enforce 4-digit year
    // - create the regex based on the local format string
    String reFormat = Pattern.compile("d+|M+").matcher(Matcher.quoteReplacement(format)).replaceAll("\\\\d{1,2}");
    reFormat = Pattern.compile("y+").matcher(reFormat).replaceAll("\\\\d{4}");
    if ( Pattern.compile(reFormat).matcher(maybeDate).matches() ) {

      // date string matches format structure, 
      // - now test it can be converted to a valid date
      SimpleDateFormat sdf = (SimpleDateFormat)DateFormat.getDateInstance();
      sdf.applyPattern(format);
      sdf.setLenient(lenient);
      try { date = sdf.parse(maybeDate); } catch (ParseException e) { }
    } 
    return date;
  } 

  // used like this:
  Date date = parseDate( "21/5/2009", "d/M/yyyy", false);

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

Locale locale = Locale.getDefault();
SimpleDateFormat sdf = (SimpleDateFormat)DateFormat.getDateInstance(DateFormat.SHORT, locale );
String format = sdf.toPattern();

Джода Тайм - лучшая альтернатива?

Я недавно слышал о joda time и подумал, что сравню . Два момента:

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

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

import org.joda.time.format.*;
import org.joda.time.DateTime;

org.joda.time.DateTime parseDate(String maybeDate, String format) {
  org.joda.time.DateTime date = null;
  try {
    DateTimeFormatter fmt = DateTimeFormat.forPattern(format);
    date =  fmt.parseDateTime(maybeDate);
  } catch (Exception e) { }
  return date;
}

Я остановился на альтернативе joda и сам проверил, что значение соответствует длине шаблона ...
Xtreme Biker

Обновление: ужасные старые устаревшие классы ( Date, SimpleDateFormatи т.д.) теперь заменены современными классами java.time . Точно так же проект Joda-Time находится в режиме обслуживания и рекомендует перейти на классы java.time .
Basil Bourque

39

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

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

boolean isLegalDate(String s) {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    sdf.setLenient(false);
    return sdf.parse(s, new ParsePosition(0)) != null;
}

2
Одна из проблем с этим подходом заключается в том, что он принимает 0003-0002-001.
деспот

1
Другая проблема заключается в том, что установка 13 в месяце возвращает дату, в которой месяц равен 01 в следующем году.
8bitjunkie

К вашему сведению, ужасно неприятные старые классы даты и времени, такие как java.util.Date, java.util.Calendarи java.text.SimpleDateFormat, теперь являются устаревшими , вытесненными классами java.time, встроенными в Java 8 и более поздних версий . См. Учебник Oracle .
Basil Bourque

29

tl; dr

Используйте строгий режим на java.time.DateTimeFormatterразобрать LocalDate. Ловушка для DateTimeParseException.

LocalDate.parse(                   // Represent a date-only value, without time-of-day and without time zone.
    "31/02/2000" ,                 // Input string.
    DateTimeFormatter              // Define a formatting pattern to match your input string.
    .ofPattern ( "dd/MM/uuuu" )
    .withResolverStyle ( ResolverStyle.STRICT )  // Specify leniency in tolerating questionable inputs.
)

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

birthDate.isAfter( LocalDate.now().minusYears( 100 ) )

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

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

LocalDate& DateTimeFormatter&ResolverStyle

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

String input = "31/02/2000";
DateTimeFormatter f = DateTimeFormatter.ofPattern ( "dd/MM/uuuu" );
try {
    LocalDate ld = LocalDate.parse ( input , f );
    System.out.println ( "ld: " + ld );
} catch ( DateTimeParseException e ) {
    System.out.println ( "ERROR: " + e );
}

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

f = f.withResolverStyle ( ResolverStyle.LENIENT );

Результаты:

  • ResolverStyle.LENIENT
    ld: 2000-03-02
  • ResolverStyle.SMART
    ld: 2000-02-29
  • ResolverStyle.STRICT
    ОШИБКА: java.time.format.DateTimeParseException: текст '31/02/2000' не может быть проанализирован: недопустимая дата '31 февраля'

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

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


Таблица всех типов даты и времени в Java, как современных, так и устаревших.


О java.time

Java.time каркас встроен в Java 8 и более поздних версий. Эти классы вытеснять неприятные старые устаревшие классы даты и времени , такие как java.util.Date, Calendar, и SimpleDateFormat.

Чтобы узнать больше, см. Oracle Tutorial . И поищите в Stack Overflow множество примеров и объяснений. Спецификация - JSR 310 .

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

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

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

Таблица того, какая библиотека java.time использовать с какой версией Java или Android

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


Что ж, предположим, что проект компилируется с использованием java 8+, тогда ваш ответ правильный. Я тоже использую эти классы, когда проект находится на java 8. Но иногда мне приходится прикасаться к этим уродливым древним сценариям jsp (которые даже не поддерживают java 7). Проверка дат - это боль. Значит, я здесь. И все же ваш ответ - наиболее правильный подход ... Вывод: я облажался.
KarelG

@KarelG Перечитайте предпоследний абзац о обратном переносе на Java 6 и Java 7 . Я не проверял это поведение в бэк-порте, но предлагаю вам попробовать.
Basil

13

java.time

С помощью API даты и времени ( классы java.time ), встроенного в Java 8 и более поздних версий , вы можете использовать этот LocalDateкласс.

public static boolean isDateValid(int year, int month, int day) {
    boolean dateIsValid = true;
    try {
        LocalDate.of(year, month, day);
    } catch (DateTimeException e) {
        dateIsValid = false;
    }
    return dateIsValid;
}

2
По умолчанию в этом коде используется значение, ResolverStyle.SMARTкоторое настраивает полученное значение на допустимую дату, а не генерирует исключение. Таким образом, этот код не достигнет цели Вопроса. См. Мой ответ для примера и решения с использованием ResolverStyle.STRICT.
Basil Bourque,

7

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

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

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

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

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

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


Это определенно правильный путь, см. Также образец кода на dreamincode.net/forums/topic/…
Виктор Ионеску,

7

Основываясь на ответе Аравинда по устранению проблемы, указанной ceklock в его комментарии , я добавил метод, позволяющий убедиться, что dateStringон не содержит недопустимого символа.

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

private boolean isDateCorrect(String dateString) {
    try {
        Date date = mDateFormatter.parse(dateString);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return matchesOurDatePattern(dateString);    //added my method
    }
    catch (ParseException e) {
        return false;
    }
}

/**
 * This will check if the provided string matches our date format
 * @param dateString
 * @return true if the passed string matches format 2014-1-15 (YYYY-MM-dd)
 */
private boolean matchesDatePattern(String dateString) {
    return dateString.matches("^\\d+\\-\\d+\\-\\d+");
}

5

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

public boolean isDateValid(String dateString, String pattern)
{   
    try
    {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        if (sdf.format(sdf.parse(dateString)).equals(dateString))
            return true;
    }
    catch (ParseException pe) {}

    return false;
}

4

Предлагаю вам использовать org.apache.commons.validator.GenericValidatorкласс от apache.

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

Примечание: strict - должно ли быть точное соответствие datePattern.


2

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

package cruft;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class DateValidator
{
    private static final DateFormat DEFAULT_FORMATTER;

    static
    {
        DEFAULT_FORMATTER = new SimpleDateFormat("dd-MM-yyyy");
        DEFAULT_FORMATTER.setLenient(false);
    }

    public static void main(String[] args)
    {
        for (String dateString : args)
        {
            try
            {
                System.out.println("arg: " + dateString + " date: " + convertDateString(dateString));
            }
            catch (ParseException e)
            {
                System.out.println("could not parse " + dateString);
            }
        }
    }

    public static Date convertDateString(String dateString) throws ParseException
    {
        return DEFAULT_FORMATTER.parse(dateString);
    }
}

Вот результат, который я получаю:

java cruft.DateValidator 32-11-2010 31-02-2010 04-01-2011
could not parse 32-11-2010
could not parse 31-02-2010
arg: 04-01-2011 date: Tue Jan 04 00:00:00 EST 2011

Process finished with exit code 0

Как видите, он отлично справляется с обоими вашими случаями.


@duffymo второй оператор не генерирует исключение ... :(
maximus

@Pangea Не совсем .... попробуйте эту дату "31-01-2010", это не вызовет никаких исключений .......... Просто запустите его на своей машине и посмотрите ... это не так работа ....
sasidhar

Виноват. Я удалил свой комментарий. Но второе утверждение вызывает для меня исключение. @duffymo - какой jvm вы используете?
Аравинд Яррам,

@Pangea, я использую jdk1.6.0_23 Я пробовал это даже с этим joda-time.sourceforge.net, но даже это не сработало ....
sasidhar

1
Я понимаю, что это всего лишь простой тест, но чтобы просто убедиться, что люди не копируют это дословно, я хочу сказать, что «DateFormat» НЕ БЕЗОПАСЕН ДЛЯ ПОТОКА. Поэтому всегда создавайте его как локальную переменную или используйте с локальным потоком.
Аравинд Яррам,

2

Это отлично работает для меня. Подход, предложенный выше Беном.

private static boolean isDateValid(String s) {
    SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
    try {
        Date d = asDate(s);
        if (sdf.format(d).equals(s)) {
            return true;
        } else {
            return false;
        }
    } catch (ParseException e) {
        return false;
    }
}

1
не могу распознать asDate. Что это?
Susheel

2

похоже, что SimpleDateFormat не проверяет шаблон строго даже после setLenient (false); к нему применяется метод, поэтому я использовал метод ниже, чтобы проверить, является ли введенная дата действительной датой или нет в соответствии с предоставленным шаблоном.

import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
public boolean isValidFormat(String dateString, String pattern) {
    boolean valid = true;
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
    try {
        formatter.parse(dateString);
    } catch (DateTimeParseException e) {
        valid = false;
    }
    return valid;
}

1

Два комментария по использованию SimpleDateFormat.

он должен быть объявлен как статический экземпляр, если объявлен как статический, доступ должен быть синхронизирован, поскольку он не является потокобезопасным

IME, который лучше, чем создание экземпляра для каждого синтаксического анализа даты.


хорошее замечание Том. Я обновил пример, который я предоставил, чтобы постоянно использовать статический экземпляр.
позднее

Использование синхронизированной функции может не масштабироваться для некоторых проектов. Я бы рекомендовал поместить SimpleDateFormat в переменную ThreadLocal вместо статической переменной, доступ к которой осуществляется через синхронизированную функцию.
user327961

0

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

 public final boolean validateDateFormat(final String date) {
        String[] formatStrings = {"MM/dd/yyyy"};
        boolean isInvalidFormat = false;
        Date dateObj;
        for (String formatString : formatStrings) {
            try {
                SimpleDateFormat sdf = (SimpleDateFormat) DateFormat.getDateInstance();
                sdf.applyPattern(formatString);
                sdf.setLenient(false);
                dateObj = sdf.parse(date);
                System.out.println(dateObj);
                if (date.equals(sdf.format(dateObj))) {
                    isInvalidFormat = false;
                    break;
                }
            } catch (ParseException e) {
                isInvalidFormat = true;
            }
        }
        return isInvalidFormat;
    }

0

Вот что я сделал для среды Node без внешних библиотек:

Date.prototype.yyyymmdd = function() {
   var yyyy = this.getFullYear().toString();
   var mm = (this.getMonth()+1).toString(); // getMonth() is zero-based
   var dd  = this.getDate().toString();
   return zeroPad([yyyy, mm, dd].join('-'));  
};

function zeroPad(date_string) {
   var dt = date_string.split('-');
   return dt[0] + '-' + (dt[1][1]?dt[1]:"0"+dt[1][0]) + '-' + (dt[2][1]?dt[2]:"0"+dt[2][0]);
}

function isDateCorrect(in_string) {
   if (!matchesDatePattern) return false;
   in_string = zeroPad(in_string);
   try {
      var idate = new Date(in_string);
      var out_string = idate.yyyymmdd();
      return in_string == out_string;
   } catch(err) {
      return false;
   }

   function matchesDatePattern(date_string) {
      var dateFormat = /[0-9]+-[0-9]+-[0-9]+/;
      return dateFormat.test(date_string); 
   }
}

И вот как им пользоваться:

isDateCorrect('2014-02-23')
true

0
// to return valid days of month, according to month and year
int returnDaysofMonth(int month, int year) {
    int daysInMonth;
    boolean leapYear;
    leapYear = checkLeap(year);
    if (month == 4 || month == 6 || month == 9 || month == 11)
        daysInMonth = 30;
    else if (month == 2)
        daysInMonth = (leapYear) ? 29 : 28;
    else
        daysInMonth = 31;
    return daysInMonth;
}

// to check a year is leap or not
private boolean checkLeap(int year) {
    Calendar cal = Calendar.getInstance();
    cal.set(Calendar.YEAR, year);
    return cal.getActualMaximum(Calendar.DAY_OF_YEAR) > 365;
}

0

Вот я бы проверил формат даты:

 public static boolean checkFormat(String dateTimeString) {
    return dateTimeString.matches("^\\d{4}-\\d{2}-\\d{2}") || dateTimeString.matches("^\\d{4}-\\d{2}-\\d{2}\\s\\d{2}:\\d{2}:\\d{2}")
            || dateTimeString.matches("^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}") || dateTimeString
            .matches("^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z") ||
            dateTimeString.matches("^\\d{4}-\\d{2}-\\d{2}\\s\\d{2}:\\d{2}:\\d{2}Z");
}

Теперь у нас есть современные классы java.time для этой работы. Написание сложного регулярного выражения - не лучший вариант использования вашего времени. См. Однострочник в моем ответе .
Basil Bourque

0
        public static String detectDateFormat(String inputDate, String requiredFormat) {
        String tempDate = inputDate.replace("/", "").replace("-", "").replace(" ", "");
        String dateFormat;

        if (tempDate.matches("([0-12]{2})([0-31]{2})([0-9]{4})")) {
            dateFormat = "MMddyyyy";
        } else if (tempDate.matches("([0-31]{2})([0-12]{2})([0-9]{4})")) {
            dateFormat = "ddMMyyyy";
        } else if (tempDate.matches("([0-9]{4})([0-12]{2})([0-31]{2})")) {
            dateFormat = "yyyyMMdd";
        } else if (tempDate.matches("([0-9]{4})([0-31]{2})([0-12]{2})")) {
            dateFormat = "yyyyddMM";
        } else if (tempDate.matches("([0-31]{2})([a-z]{3})([0-9]{4})")) {
            dateFormat = "ddMMMyyyy";
        } else if (tempDate.matches("([a-z]{3})([0-31]{2})([0-9]{4})")) {
            dateFormat = "MMMddyyyy";
        } else if (tempDate.matches("([0-9]{4})([a-z]{3})([0-31]{2})")) {
            dateFormat = "yyyyMMMdd";
        } else if (tempDate.matches("([0-9]{4})([0-31]{2})([a-z]{3})")) {
            dateFormat = "yyyyddMMM";
        } else {
            return "Pattern Not Added";
//add your required regex
        }
        try {
            String formattedDate = new SimpleDateFormat(requiredFormat, Locale.ENGLISH).format(new SimpleDateFormat(dateFormat).parse(tempDate));

            return formattedDate;
        } catch (Exception e) {
            //
            return "";
        }

    }

0

С «устаревшим» форматом даты мы можем отформатировать результат и сравнить его с исходным.

    public boolean isValidFormat(String source, String pattern) {
    SimpleDateFormat sd = new SimpleDateFormat(pattern);
    sd.setLenient(false);
    try {
        Date date = sd.parse(source);
        return date != null && sd.format(date).equals(source);
    } catch (Exception e) {
        return false;
    }
}

Этот execerpt сообщает "false" для source = 01.01.04 с шаблоном '01 .01.2004 '


-1

setLenient в false, если вам нравится строгая проверка

public boolean isThisDateValid(String dateToValidate, String dateFromat){

    if(dateToValidate == null){
        return false;
    }

    SimpleDateFormat sdf = new SimpleDateFormat(dateFromat);
    sdf.setLenient(false);

    try {

        //if not valid, it will throw ParseException
        Date date = sdf.parse(dateToValidate);
        System.out.println(date);

    } catch (ParseException e) {

        e.printStackTrace();
        return false;
    }

    return true;
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.