So analysieren Sie Daten in mehreren Formaten mit SimpleDateFormat

Lesezeit: 7 Minuten

So analysieren Sie Daten in mehreren Formaten mit SimpleDateFormat
Derek

Ich versuche, einige Daten zu analysieren, die aus einem Dokument stammen. Es scheint, dass Benutzer diese Daten in einem ähnlichen, aber nicht genauen Format eingegeben haben.

hier sind die formate:

9/09
9/2009
09/2009
9/1/2009
9-1-2009 

Was ist der beste Weg, um zu versuchen, all diese zu analysieren? Diese scheinen am häufigsten zu sein, aber ich denke, was mich aufhängt, ist, dass, wenn ich ein Muster von “M/yyyy” habe, das nicht immer vor “MM/yyyy” fängt. Muss ich meine try/catch-Blöcke einrichten verschachtelt in einer am wenigsten restriktiven bis am restriktivsten Weise? Es scheint, als würde es sicher eine Menge Code-Duplizierung erfordern, um dies richtig zu machen.

  • Nun, Sie könnten einfach eine Liste mit Mustern haben und dann eine einfache Schleife, um es weiter zu versuchen, bis Sie eines finden, das funktioniert.

    – Spitze

    26. Oktober 2010 um 14:14 Uhr

  • Und dann einfach die Schleife unterbrechen?

    – Derek

    26. Oktober 2010 um 14:16 Uhr

So analysieren Sie Daten in mehreren Formaten mit SimpleDateFormat
Mattball

Sie müssen eine andere verwenden SimpleDateFormat Objekt für jedes verschiedene Muster. Das heißt, Sie brauchen nicht so viele verschiedene, Danke dafür:

Anzahl: Für die Formatierung ist die Anzahl der Musterbuchstaben die Mindestanzahl von Ziffern, und kürzere Zahlen werden mit Nullen aufgefüllt. Beim Parsen wird die Anzahl der Musterbuchstaben ignoriert, es sei denn, sie wird benötigt, um zwei benachbarte Felder zu trennen.

Sie benötigen also diese Formate:

  • "M/y" (das deckt 9/09, 9/2009und 09/2009)
  • "M/d/y" (das deckt 9/1/2009)
  • "M-d-y" (das deckt 9-1-2009)

Mein Rat wäre also, eine Methode zu schreiben, die in etwa so funktioniert (ungetestet):

// ...
List<String> formatStrings = Arrays.asList("M/y", "M/d/y", "M-d-y");
// ...

Date tryParse(String dateString)
{
    for (String formatString : formatStrings)
    {
        try
        {
            return new SimpleDateFormat(formatString).parse(dateString);
        }
        catch (ParseException e) {}
    }

    return null;
}

  • Viele der Antworten hier bieten eine Form davon als Lösung an, aber es wird leider nicht funktionieren. Wenn die zu analysierende Zeichenfolge mit Format Nr. 3 übereinstimmt, ist es sehr wahrscheinlich, dass SimpleDateFormat erfolgreich mit Format Nr. 1 analysiert wird, aber Sie haben das falsche Datum.

    – Ben Bynum

    31. Mai 2021 um 16:36 Uhr

Wie wäre es, wenn Sie einfach mehrere Muster definieren? Sie könnten aus einer Konfigurationsdatei stammen, die bekannte Muster enthält, fest codiert lautet sie wie folgt:

List<SimpleDateFormat> knownPatterns = new ArrayList<SimpleDateFormat>();
knownPatterns.add(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"));
knownPatterns.add(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm.ss'Z'"));
knownPatterns.add(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"));
knownPatterns.add(new SimpleDateFormat("yyyy-MM-dd' 'HH:mm:ss"));
knownPatterns.add(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX"));

for (SimpleDateFormat pattern : knownPatterns) {
    try {
        // Take a try
        return new Date(pattern.parse(candidate).getTime());

    } catch (ParseException pe) {
        // Loop on
    }
}
System.err.println("No known Date format found: " + candidate);
return null;

  • Hey, ich versuche, mir all diese Muster anzusehen "yyyy-MM-dd'T'HH:mm:ss'Z'" können Sie mich bitte auf ein Beispiel oder Dokumente dieser Muster @xybrek hinweisen

    – Totes Schwimmbad

    18. Juli 2018 um 15:24 Uhr

  • Tolle Lösung. Tausend Dank fürs Teilen.!

    – Ajay Kumar

    5. Juli 2020 um 20:09 Uhr

1646243827 797 So analysieren Sie Daten in mehreren Formaten mit SimpleDateFormat
ChrisR

Der obige Ansatz von Matt ist in Ordnung, aber bitte beachten Sie, dass Sie auf Probleme stoßen werden, wenn Sie ihn verwenden, um zwischen Datumsangaben des Formats zu unterscheiden y/M/d und d/M/y. Zum Beispiel ein Formatierer, der mit initialisiert wurde y/M/d akzeptiert ein Datum wie 01/01/2009 und Ihnen ein Datum zurückgeben, das eindeutig nicht das ist, was Sie wollten. Ich habe das Problem wie folgt behoben, aber ich habe nur begrenzt Zeit und bin mit der Lösung aus zwei Hauptgründen nicht zufrieden:

  1. Es verstößt gegen eine der Richtlinien von Josh Bloch, nämlich „keine Ausnahmen verwenden, um den Programmfluss zu handhaben“.
  2. Ich kann die sehen getDateFormat() -Methode zu einem Alptraum werden, wenn Sie viele andere Datumsformate verarbeiten müssen.

Wenn ich etwas machen müsste, das mit vielen, vielen verschiedenen Datumsformaten umgehen kann und hochleistungsfähig sein müsste, dann würde ich den Ansatz verwenden, eine Aufzählung zu erstellen, die jede unterschiedliche Datums-Regex mit ihrem Format verknüpft. Dann benutze MyEnum.values() um die Aufzählung zu durchlaufen und mit zu testen if(myEnum.getPattern().matches(date)) anstatt eine dateformatException abzufangen.

Abgesehen davon können die folgenden Daten mit den Formaten umgehen 'y/M/d' 'y-M-d' 'y M d' 'd/M/y' 'd-M-y' 'd M y' und alle anderen Variationen davon, die auch Zeitformate enthalten:

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

public class DateUtil {
    private static final String[] timeFormats = {"HH:mm:ss","HH:mm"};
    private static final String[] dateSeparators = {"https://stackoverflow.com/","-"," "};

    private static final String DMY_FORMAT = "dd{sep}MM{sep}yyyy";
    private static final String YMD_FORMAT = "yyyy{sep}MM{sep}dd";

    private static final String ymd_template = "\\d{4}{sep}\\d{2}{sep}\\d{2}.*";
    private static final String dmy_template = "\\d{2}{sep}\\d{2}{sep}\\d{4}.*";

    public static Date stringToDate(String input){
    Date date = null;
    String dateFormat = getDateFormat(input);
    if(dateFormat == null){
        throw new IllegalArgumentException("Date is not in an accepted format " + input);
    }

    for(String sep : dateSeparators){
        String actualDateFormat = patternForSeparator(dateFormat, sep);
        //try first with the time
        for(String time : timeFormats){
        date = tryParse(input,actualDateFormat + " " + time);
        if(date != null){
            return date;
        }
        }
        //didn't work, try without the time formats
        date = tryParse(input,actualDateFormat);
        if(date != null){
        return date;
        }
    }

    return date;
    }

    private static String getDateFormat(String date){
    for(String sep : dateSeparators){
        String ymdPattern = patternForSeparator(ymd_template, sep);
        String dmyPattern = patternForSeparator(dmy_template, sep);
        if(date.matches(ymdPattern)){
        return YMD_FORMAT;
        }
        if(date.matches(dmyPattern)){
        return DMY_FORMAT;
        }
    }
    return null;
    }

    private static String patternForSeparator(String template, String sep){
    return template.replace("{sep}", sep);
    }

    private static Date tryParse(String input, String pattern){
    try{
        return new SimpleDateFormat(pattern).parse(input);
    }
    catch (ParseException e) {}
    return null;
    }


}

So analysieren Sie Daten in mehreren Formaten mit SimpleDateFormat
Aaron G.

Wenn Sie in Java 1.8 arbeiten, können Sie den DateTimeFormatterBuilder nutzen

public static boolean isTimeStampValid(String inputString)
{
    DateTimeFormatterBuilder dateTimeFormatterBuilder = new DateTimeFormatterBuilder()
            .append(DateTimeFormatter.ofPattern("" + "[yyyy-MM-dd'T'HH:mm:ss.SSSZ]" + "[yyyy-MM-dd]"));

    DateTimeFormatter dateTimeFormatter = dateTimeFormatterBuilder.toFormatter();

    try {
        dateTimeFormatter.parse(inputString);
        return true;
    } catch (DateTimeParseException e) {
        return false;
    }
}

Siehe Beitrag: Java 8 Date entspricht Jodas DateTimeFormatterBuilder mit mehreren Parser-Formaten?

1646243827 862 So analysieren Sie Daten in mehreren Formaten mit SimpleDateFormat
SANN3

In Apache-Commons-Sprache, DateUtils Klasse haben wir eine Methode namens parseDate. Wir können dies zum Analysieren des Datums verwenden.

Auch eine andere Bibliothek Joda-Time hat ebenfalls die Methode dazu analysieren das Datum.

1646243828 921 So analysieren Sie Daten in mehreren Formaten mit SimpleDateFormat
Vinayak Dornala

Hier ist das vollständige Beispiel (mit Hauptmethode), das Ihrem Projekt als Hilfsklasse hinzugefügt werden kann. Alle genannten Formate in Einfaches Datumsformat API wird in der folgenden Methode unterstützt.

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

import org.apache.commons.lang.time.DateUtils;

public class DateUtility {

    public static Date parseDate(String inputDate) {

        Date outputDate = null;
        String[] possibleDateFormats =
              {
                    "yyyy.MM.dd G 'at' HH:mm:ss z",
                    "EEE, MMM d, ''yy",
                    "h:mm a",
                    "hh 'o''clock' a, zzzz",
                    "K:mm a, z",
                    "yyyyy.MMMMM.dd GGG hh:mm aaa",
                    "EEE, d MMM yyyy HH:mm:ss Z",
                    "yyMMddHHmmssZ",
                    "yyyy-MM-dd'T'HH:mm:ss.SSSZ",
                    "yyyy-MM-dd'T'HH:mm:ss.SSSXXX",
                    "YYYY-'W'ww-u",
                    "EEE, dd MMM yyyy HH:mm:ss z", 
                    "EEE, dd MMM yyyy HH:mm zzzz",
                    "yyyy-MM-dd'T'HH:mm:ssZ",
                    "yyyy-MM-dd'T'HH:mm:ss.SSSzzzz", 
                    "yyyy-MM-dd'T'HH:mm:sszzzz",
                    "yyyy-MM-dd'T'HH:mm:ss z",
                    "yyyy-MM-dd'T'HH:mm:ssz", 
                    "yyyy-MM-dd'T'HH:mm:ss",
                    "yyyy-MM-dd'T'HHmmss.SSSz",
                    "yyyy-MM-dd",
                    "yyyyMMdd",
                    "dd/MM/yy",
                    "dd/MM/yyyy"
              };

        try {

            outputDate = DateUtils.parseDate(inputDate, possibleDateFormats);
            System.out.println("inputDate ==> " + inputDate + ", outputDate ==> " + outputDate);

        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return outputDate;

    }

    public static String formatDate(Date date, String requiredDateFormat) {
        SimpleDateFormat df = new SimpleDateFormat(requiredDateFormat);
        String outputDateFormatted = df.format(date);
        return outputDateFormatted;
    }

    public static void main(String[] args) {

        DateUtility.parseDate("20181118");
        DateUtility.parseDate("2018-11-18");
        DateUtility.parseDate("18/11/18");
        DateUtility.parseDate("18/11/2018");
        DateUtility.parseDate("2018.11.18 AD at 12:08:56 PDT");
        System.out.println("");
        DateUtility.parseDate("Wed, Nov 18, '18");
        DateUtility.parseDate("12:08 PM");
        DateUtility.parseDate("12 o'clock PM, Pacific Daylight Time");
        DateUtility.parseDate("0:08 PM, PDT");
        DateUtility.parseDate("02018.Nov.18 AD 12:08 PM");
        System.out.println("");
        DateUtility.parseDate("Wed, 18 Nov 2018 12:08:56 -0700");
        DateUtility.parseDate("181118120856-0700");
        DateUtility.parseDate("2018-11-18T12:08:56.235-0700");
        DateUtility.parseDate("2018-11-18T12:08:56.235-07:00");
        DateUtility.parseDate("2018-W27-3");
    }

}

Diese Lösung überprüft alle möglichen Formate, bevor eine Ausnahme ausgelöst wird. Diese Lösung ist bequemer, wenn Sie versuchen, mehrere Datumsformate zu testen.

Date extractTimestampInput(String strDate){
    final List<String> dateFormats = Arrays.asList("yyyy-MM-dd HH:mm:ss.SSS", "yyyy-MM-dd");    

    for(String format: dateFormats){
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        try{
            return sdf.parse(strDate);
        } catch (ParseException e) {
             //intentionally empty
        }
    }
        throw new IllegalArgumentException("Invalid input for date. Given '"+strDate+"', expecting format yyyy-MM-dd HH:mm:ss.SSS or yyyy-MM-dd.");

}

914650cookie-checkSo analysieren Sie Daten in mehreren Formaten mit SimpleDateFormat

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy