자바에서 날짜를 온전하게 확인하는 방법


84

DateJava에서 객체 를 생성하는 가장 명백한 방법 이 더 이상 사용되지 않고 관대 한 달력을 사용하기에는 그렇게 분명하지 않은 것으로 "대체"된 것으로 보이는 것이 궁금합니다 .

일, 월, 연도의 조합으로 제공된 날짜가 유효한 날짜인지 어떻게 확인합니까?

예를 들어 2008-02-31 (예 : yyyy-mm-dd)은 잘못된 날짜입니다.


비슷한 질문이있는 사람은 그레고리력이 아닌 달력 지원이 필요한지 고려하십시오.
MSalters

@JasonC 나는 당신과 완전히 동의합니다. 병합하는 것이 가장 좋은 방법 인 것 같습니다.
acm

답변:


36

현재 방법은 캘린더 클래스를 사용하는 것입니다. 예제에서와 같이 범위를 벗어난 경우 날짜 및 throw 및 예외를 확인 하는 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"객체를 가져올 때 문자열에서 이미 변환이 이루어졌습니다.
tardate

33
예제 코드의 3 가지 문제 : 1. Calendar 인스턴스를 가져온 후 cal.setLenient (false)를 호출해야합니다. 그렇지 않으면 2007 년 2 월 31 일과 같은 날짜가 유효한 것으로 간주됩니다. 2. cal.setTime ()에 의해 예외가 발생하지 않습니다. 유효하지 않은 날짜에 예외를 발생시키는 setTime () 호출 후에 cal.getTime ()을 호출해야합니다. 3. 오타 : 캐치 전에 '}'가 누락되었습니다.
Liron Yahdav 2010

이것은 또한 다른 접근 방식보다 느립니다. stackoverflow.com/questions/2149680/을
despot

5
참고로, 같은 귀찮은 된 날짜 - 시간 수업 java.util.Date, java.util.Calendar그리고 java.text.SimpleDateFormat지금 기존 에 의해 대체, java.time의 나중에 자바 8에 내장 된 클래스. Oracle의 Tutorial 참조하십시오 .
Basil Bourque

3
2월 31일 같은 날짜를 확인하지 않습니다
shikha을 싱

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-201a"로 시도하십시오. 그것은 미친 데이트를 만들 것입니다.
ceklock 2014

그것이 작동하는 방법 @ceklock, 당신이 사용하는 경우에 상관없이 setLenient여부는 : SimpleDateFormat항상 이렇게 당신이 얻을, 패턴이 일치 될 때까지 구문 분석하고 문자열의 나머지 부분을 무시 201해있다.
Daniel Naber

@ceklock 방금 내 솔루션 에서 해결했습니다 . 누군가에게 1 ~ 2 분을 절약 할 수 있습니다.
Sufian

1
예외 처리를 통합하면 성능이 크게 저하되므로 정상적인 작업 (예 : 사용자 입력 유효성 검사)에서 잘못된 입력을 예상하는 경우 잘못된 설계 일 수 있습니다. 그러나 메서드가 항상 유효해야하는 입력 (버그 제외)에 대한 이중 검사로 사용된다면 괜찮습니다.
아론

2
참고로, 같은 몹시 귀찮은 된 날짜 - 시간 수업 java.util.Date, java.util.Calendar그리고 java.text.SimpleDateFormat지금 기존 에 의해 대체, java.time의 나중에 자바 8에 내장 된 클래스. Oracle의 Tutorial 참조하십시오 .
Basil Bourque

48

@Maglob에서 볼 수 있듯이 기본 접근 방식은 SimpleDateFormat.parse를 사용하여 문자열에서 날짜로의 변환을 테스트하는 것 입니다. 이는 2008-02-31과 같은 잘못된 일 / 월 조합을 포착합니다.

그러나 실제로는 SimpleDateFormat.parse가 매우 자유롭기 때문에 충분하지 않습니다. 우려 할 수있는 두 가지 동작이 있습니다.

날짜 문자열의 잘못된 문자 놀랍게도 2008-02-2x는 로케일 형식이 "yyyy-MM-dd"인 유효한 날짜로 "통과"됩니다. isLenient == false 인 경우에도 마찬가지입니다.

연도 : 2, 3 또는 4 자리 숫자? 기본 SimpleDateFormat 동작을 허용하는 대신 4 자리 연도를 적용 할 수도 있습니다 (형식이 "yyyy-MM-dd"인지 "yy-MM-dd"인지에 따라 "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);

정규식은 형식 문자열에 일, 월, 연도 및 구분 문자 만 포함되어 있다고 가정합니다. 그 외에도 "d / MM / yy", "yyyy-MM-dd"등 모든 로케일 형식으로 형식을 지정할 수 있습니다. 현재 로케일의 형식 문자열은 다음과 같이 얻을 수 있습니다.

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

Joda 시간-더 나은 대안?

최근 에 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 대안으로 끝내었고, 값이 패턴 길이 나 자신을 일치 ... 것으로 확인
익스트림 자전거

업데이트 : 끔찍한 오래된 기존 클래스 ( 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을 수용한다는 것입니다.
despot

1
또 다른 문제는 월에 13을 설정하면 다음 해의 월이 01 인 날짜가 반환된다는 것입니다.
8bitjunkie

참고로, 같은 몹시 귀찮은 된 날짜 - 시간 수업 java.util.Date, java.util.Calendar그리고 java.text.SimpleDateFormat지금 기존 에 의해 대체, java.time의 나중에 자바 8에 내장 된 클래스. Oracle의 Tutorial 참조하십시오 .
Basil Bourque

30

tl; dr

사용 엄격 모드 에서 java.time.DateTimeFormatter구문 분석 A와 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.
)

구문 분석 후 합리적인 값을 확인할 수 있습니다. 예를 들어, 지난 100 년 이내의 생년월일입니다.

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 '을 구문 분석 할 수 없음 : 잘못된 날짜'FEBRUARY 31 '

ResolverStyle.LENIENT모드에서 유효하지 않은 날짜가 동일한 일 수만큼 앞으로 이동하는 것을 볼 수 있습니다 . 에ResolverStyle.SMART 모드 (기본), 논리적 인 결정은 개월 이내에 해당 월의 마지막 가능한 하루가는 날짜를 유지하기 위해 만든, 윤년 년 2 월 29 일, 그 달에는 31 일이 없기 때문에. ResolverStyle.STRICT모드는 예외가 그런 일이 없다고 불평 발생합니다.

이 세 가지 모두 비즈니스 문제와 정책에 따라 합리적입니다. 귀하의 경우에는 엄격 모드가 유효하지 않은 날짜를 조정하는 대신 거부하도록 원하는 것처럼 들립니다.


최신 및 레거시 Java의 모든 날짜-시간 유형 테이블입니다.


java.time

java.time의 프레임 워크는 나중에 자바 8에 내장되어 있습니다. 이 클래스는 까다로운 기존에 대신 기존 과 같은 날짜 - 시간의 수업을 java.util.Date,Calendar , SimpleDateFormat.

자세한 내용은 Oracle Tutorial을 참조하십시오. . 그리고 많은 예제와 설명을 위해 Stack Overflow를 검색하십시오. 사양은 JSR 310 입니다.

Joda 타임 지금 프로젝트, 유지 관리 모드는 의에 마이그레이션을 조언 java.time의 클래스.

java.time 객체를 데이터베이스와 직접 교환 할 수 있습니다 . JDBC 4.2 와 호환 되는 JDBC 드라이버 사용 이상을 . 문자열이나 java.sql.*클래스 가 필요하지 않습니다 .

java.time 클래스는 어디서 구할 수 있습니까?

Java 또는 Android 버전과 함께 사용할 java.time 라이브러리 표

ThreeTen - 추가 프로젝트 추가 클래스와 java.time를 확장합니다. 이 프로젝트는 java.time에 향후 추가 될 수있는 가능성을 입증하는 근거입니다. 당신은 여기에 몇 가지 유용한 클래스와 같은 찾을 수 있습니다 Interval, YearWeek, YearQuarter, 그리고 .


글쎄, 프로젝트가 Java 8+로 컴파일되고 있다고 가정하면 대답이 정확합니다. 프로젝트가 Java 8에있을 때도 이러한 클래스를 사용하고 있습니다. 그러나 때때로 저는 그 추악한 고대 jsp 스크립틀릿 (Java 7을 지원하지도 않음)을 만져야합니다. 날짜 확인에는 어려움이 있습니다. 그래서 여기에 있습니다. 그러나 당신의 대답은 가장 정확한 접근 방식입니다 ... 결론 : 나는 망했습니다.
KarelG

@KarelG Java 6 및 Java 7 로의 백 포트에 대한 마지막 두 번째 단락을 다시 읽으십시오 . 백 포트에서이 동작을 확인하지 않았지만 시도해 보시기 바랍니다.
Basil Bourque

13

java.time

으로 날짜 및 시간 API ( java.time의 클래스) 자바 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) 성공하면 동일한 날짜 형식 ((1)에서)을 사용하여 (2)에서 발생한 날짜를 다시 형식화하십시오.

4) 형식이 변경된 날짜를 사용자가 입력 한 원래 값과 비교합니다. 같으면 입력 한 값이 패턴과 엄격하게 일치합니다.

이렇게하면 복잡한 정규식을 만들 필요가 없습니다. 제 경우에는 일, 월 및 연도와 같은 특정 유형으로 제한되는 대신 SimpleDateFormat의 모든 패턴 구문을 지원해야했습니다.


이것은 확실히 갈 수있는 방법에 또한 샘플 코드를 참조 dreamincode.net/forums/topic/...
빅터 Ionescu

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아파치의 클래스 를 사용하는 것이 좋습니다 .

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 아닙니다 ....이 날짜를 "2010 년 1 월 31 일"로 시도하면 예외가 발생하지 않습니다 .......... 그냥 컴퓨터에서 실행하고 확인하십시오. work ....
sasidhar 2010

내 잘못이야. 내 댓글을 삭제했습니다. 그러나 두 번째 진술은 나를 위해 예외를 던지고 있습니다. @duffymo-어떤 jvm을 사용하고 있습니까?
Aravind Yarram

내가 jdk1.6.0_23 사용하고 @Pangea 난이와 함께이 시도 joda-time.sourceforge.net .... 작동하지 않았다가 있지만,도
sasidhar

1
나는 이것이 단순한 테스트라는 것을 이해하지만 사람들이 이것을 그대로 복사하지 않도록하기 위해 "DateFormat"은 스레드로부터 안전하지 않다고 말하고 싶습니다. 따라서 항상 로컬 변수로 생성하거나 스레드 로컬과 함께 사용하십시오.
Aravind Yarram

2

이것은 나를 위해 잘 작동합니다. Ben이 위에서 제안한 접근 방식.

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

SimpleDateFormatsetLenient (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.


좋은 지적 톰. 정적 인스턴스를 일관되게 사용하도록 제공 한 예제를 업데이트했습니다.
tardate

동기화 된 기능을 사용하면 일부 프로젝트에서 확장되지 않을 수 있습니다. 동기화 된 함수를 통해 액세스하는 정적 변수 대신 ThreadLocal 변수에 SimpleDateFormat을 넣는 것이 좋습니다.
user327961

0

위의 날짜 구문 분석 방법은 훌륭합니다. 포맷터를 사용하여 변환 된 날짜를 원래 날짜로 다시 확인하는 기존 방법에 새로운 검사를 추가 했으므로 거의 모든 경우에 대해 확인했습니다. 예 : 2013 년 2 월 29 일은 유효하지 않은 날짜입니다. 주어진 함수는 현재 허용되는 날짜 형식에 따라 날짜를 구문 분석합니다. 날짜가 성공적으로 구문 분석되지 않으면 true를 반환합니다.

 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

다음은 외부 라이브러리를 사용하지 않는 노드 환경에서 수행 한 작업입니다.

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;
    }
}

이 발췌문은 '01 .01.2004 '패턴으로 source = 01.01.04에'false '라고 말합니다.


-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;
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.