[java] Java에서 모든 날짜 구문 분석

나는이 질문이 꽤 많이 요구된다는 것을 알고 있으며 분명히 임의의 날짜를 구문 분석 할 수 없습니다. 그러나 python-dateutil 라이브러리는 내가 던지는 모든 날짜를 구문 분석 할 수 있으며 날짜 형식 문자열을 알아내는 데 전혀 노력을 기울이지 않아도됩니다. Joda 시간은 항상 훌륭한 Java 날짜 파서로 판매되지만 형식을 선택하거나 직접 작성하기 전에 날짜 형식을 결정해야합니다. DateFormatter.parse (mydate)를 호출하고 마술처럼 Date 객체를 다시 가져올 수는 없습니다.

예를 들어 “Wed Mar 04 05:09:06 GMT-06 : 00 2009″날짜는 python-dateutil로 올바르게 구문 분석됩니다.

import dateutil.parser
print dateutil.parser.parse('Wed Mar 04 05:09:06 GMT-06:00 2009')

그러나 다음 Joda 시간 호출은 작동하지 않습니다.

    String date = "Wed Mar 04 05:09:06 GMT-06:00 2009";
    DateTimeFormatter fmt = ISODateTimeFormat.dateTime();
    DateTime dt = fmt.parseDateTime(date);
    System.out.println(date);

고유 한 DateTimeFormatter를 만드는 것은 올바른 형식 문자열과 함께 SimpleDateFormatter를 사용하는 것과 동일한 것처럼 보이기 때문에 목적에 맞지 않습니다.

python-dateutil과 같이 Java에서 날짜를 구문 분석하는 비슷한 방법이 있습니까? 나는 오류에 대해 신경 쓰지 않고 대부분 완벽하기를 원합니다.



답변

가장 좋은 방법은 날짜 형식 패턴과 일치하거나 무차별 대입을 수행하기 위해 정규식에 도움을 요청하는 것입니다.

몇 년 전에 나는 그 일을 하는 약간 어리석은 DateUtil수업 을 썼다 . 관련성 추출은 다음과 같습니다.

private static final Map<String, String> DATE_FORMAT_REGEXPS = new HashMap<String, String>() {{
    put("^\\d{8}$", "yyyyMMdd");
    put("^\\d{1,2}-\\d{1,2}-\\d{4}$", "dd-MM-yyyy");
    put("^\\d{4}-\\d{1,2}-\\d{1,2}$", "yyyy-MM-dd");
    put("^\\d{1,2}/\\d{1,2}/\\d{4}$", "MM/dd/yyyy");
    put("^\\d{4}/\\d{1,2}/\\d{1,2}$", "yyyy/MM/dd");
    put("^\\d{1,2}\\s[a-z]{3}\\s\\d{4}$", "dd MMM yyyy");
    put("^\\d{1,2}\\s[a-z]{4,}\\s\\d{4}$", "dd MMMM yyyy");
    put("^\\d{12}$", "yyyyMMddHHmm");
    put("^\\d{8}\\s\\d{4}$", "yyyyMMdd HHmm");
    put("^\\d{1,2}-\\d{1,2}-\\d{4}\\s\\d{1,2}:\\d{2}$", "dd-MM-yyyy HH:mm");
    put("^\\d{4}-\\d{1,2}-\\d{1,2}\\s\\d{1,2}:\\d{2}$", "yyyy-MM-dd HH:mm");
    put("^\\d{1,2}/\\d{1,2}/\\d{4}\\s\\d{1,2}:\\d{2}$", "MM/dd/yyyy HH:mm");
    put("^\\d{4}/\\d{1,2}/\\d{1,2}\\s\\d{1,2}:\\d{2}$", "yyyy/MM/dd HH:mm");
    put("^\\d{1,2}\\s[a-z]{3}\\s\\d{4}\\s\\d{1,2}:\\d{2}$", "dd MMM yyyy HH:mm");
    put("^\\d{1,2}\\s[a-z]{4,}\\s\\d{4}\\s\\d{1,2}:\\d{2}$", "dd MMMM yyyy HH:mm");
    put("^\\d{14}$", "yyyyMMddHHmmss");
    put("^\\d{8}\\s\\d{6}$", "yyyyMMdd HHmmss");
    put("^\\d{1,2}-\\d{1,2}-\\d{4}\\s\\d{1,2}:\\d{2}:\\d{2}$", "dd-MM-yyyy HH:mm:ss");
    put("^\\d{4}-\\d{1,2}-\\d{1,2}\\s\\d{1,2}:\\d{2}:\\d{2}$", "yyyy-MM-dd HH:mm:ss");
    put("^\\d{1,2}/\\d{1,2}/\\d{4}\\s\\d{1,2}:\\d{2}:\\d{2}$", "MM/dd/yyyy HH:mm:ss");
    put("^\\d{4}/\\d{1,2}/\\d{1,2}\\s\\d{1,2}:\\d{2}:\\d{2}$", "yyyy/MM/dd HH:mm:ss");
    put("^\\d{1,2}\\s[a-z]{3}\\s\\d{4}\\s\\d{1,2}:\\d{2}:\\d{2}$", "dd MMM yyyy HH:mm:ss");
    put("^\\d{1,2}\\s[a-z]{4,}\\s\\d{4}\\s\\d{1,2}:\\d{2}:\\d{2}$", "dd MMMM yyyy HH:mm:ss");
}};

/**
 * Determine SimpleDateFormat pattern matching with the given date string. Returns null if
 * format is unknown. You can simply extend DateUtil with more formats if needed.
 * @param dateString The date string to determine the SimpleDateFormat pattern for.
 * @return The matching SimpleDateFormat pattern, or null if format is unknown.
 * @see SimpleDateFormat
 */
public static String determineDateFormat(String dateString) {
    for (String regexp : DATE_FORMAT_REGEXPS.keySet()) {
        if (dateString.toLowerCase().matches(regexp)) {
            return DATE_FORMAT_REGEXPS.get(regexp);
        }
    }
    return null; // Unknown format.
}

(기침, 이중 중괄호 초기화, 기침, 100 자 최대 길이에 모두 맞추기위한 것이 었습니다.))

새로운 regex 및 dateformat 패턴을 사용하여 쉽게 확장 할 수 있습니다.


답변

귀하의 목적에 맞는 Natty 라는 멋진 라이브러리가 있습니다 .

Natty는 Java로 작성된 자연어 날짜 파서입니다. 날짜 표현식이 주어지면 natty는 표준 언어 인식 및 번역 기술을 적용하여 선택적 구문 분석 및 구문 정보와 함께 해당 날짜 목록을 생성합니다.

온라인으로 시도 할 수도 있습니다 !


답변

내가 본 것은 몇 가지 일반적인 날짜 형식을 포함하는 Date util 클래스입니다. 따라서 DateUtil.parse (date)가 호출되면 내부적으로 각 날짜 형식으로 날짜를 구문 분석하려고 시도하고 내부 형식 중 어느 것도 구문 분석 할 수없는 경우에만 예외를 발생시킵니다.

기본적으로 문제에 대한 무차별 대입 접근 방식입니다.


답변

dateparser를 시도해 볼 수 있습니다.

모든 문자열을 자동으로 인식 하고 Date , Calendar , LocalDateTime , OffsetDateTime으로 정확하고 빠르게 파싱 ​​할 수 있습니다 ( 1us~1.5us).

natural language analyzer또는 SimpleDateFormat또는을 기반으로하지 않습니다 regex.Pattern.

이를 통해 yyyy-MM-dd'T'HH:mm:ss.SSSZ또는 yyyy-MM-dd'T'HH:mm:ss.SSSZZ다음 과 같은 적절한 패턴을 준비 할 필요가 없습니다 .

Date date = DateParserUtils.parseDate("2015-04-29T10:15:00.500+0000");
Calendar calendar = DateParserUtils.parseCalendar("2015-04-29T10:15:00.500Z");
LocalDateTime dateTime = DateParserUtils.parseDateTime("2015-04-29 10:15:00.500 +00:00");

모든 것이 잘 작동합니다. 즐기십시오.


답변

이 구문 분석에 대해 파이썬에서 수행하는 방법에 대해 전혀 모릅니다. 자바에서는 이렇게 할 수 있습니다.

SimpleDateFormat sdf1 = new SimpleDateFormat("dd-MM-yyyy");
  java.util.Date normalDate = null;
  java.sql.Date sqlDate = null;
  normalDate = sdf1.parse(date);
  sqlDate = new java.sql.Date(normalDate.getTime());
  System.out.println(sqlDate);

나는 자바처럼 미리 정의 된 일부 함수가 파이썬에있을 것이라고 생각합니다. 이 방법을 따를 수 있습니다. 이 메서드는 문자열 날짜를 Sql 날짜 (dd-MM-yyyy)로 구문 분석합니다.

import java.text.SimpleDateFormat;
import java.text.ParseException;
public class HelloWorld{
     public static void main(String []args){
        String date ="26-12-2019";
         SimpleDateFormat sdf1 = new SimpleDateFormat("dd-MM-yyyy");
        java.util.Date normalDate = null;
        java.sql.Date sqlDate = null;
        if( !date.isEmpty()) {
            try {
                normalDate = sdf1.parse(date);
                sqlDate = new java.sql.Date(normalDate.getTime());
                System.out.println(sqlDate);
            } catch (ParseException e) {
            }
        }
     }
}

이것을 실행하십시오!


답변

//download library:   org.ocpsoft.prettytime.nlp.PrettyTimeParser
String str = "2020.03.03";
Date date = new PrettyTimeParser().parseSyntax(str).get(0).getDates().get(0);
System.out.println(date)


답변