[JAVA] Ich werde die Zeitzeichenfolge unbedingt konvertieren!

Dies ist ubansi, der für den zweiten Tag des Java-Adventskalenders verantwortlich ist! Um letztes Jahr Kampf gegen teuflischen Java-Code.

Okay, ich werde Big Data analysieren!

Dump-Dateien verschiedener DBs werden in Bashibashi BigQuery abgelegt!

Eh, das Datum wird nicht von BigQuery analysiert ...? Kann ich die Ausgabe ändern, weil andere Systeme ausgeführt werden? Gibt es einen Zeitunterschied? Eh, DB hinzufügen?

・ ・ ・

Für diejenigen, die auf solche Dinge stoßen (Eher habe ich so ein Auge getroffen) Erstellen wir einen Prozess, um alle Datumszeichenfolgen in Java8 in "LocalDateTime" zu konvertieren.

Klasse für die Analyse verwendet

Vorstellung der coolen Zeitklasse! ZonedDateTime Eine Klasse, die ** Datumsangaben ** für jede Zeitzone verarbeitet. Es berücksichtigt auch die Sommerzeit.

OffsetDateTime Eine Klasse, die ** Datumsangaben ** für jeden Zeitunterschied behandelt. Wenn es eine Zeitdifferenzspezifikation anstelle einer Zeitzonenspezifikation gibt, ist dies an der Reihe.

LocalDateTime Unnötig zu erwähnen, dass sich diese Klasse mit ** Zeit ohne Zeitunterschied ** befasst. Dieses Mal werden wir in diese Klasse konvertieren.

LocalDate Eine Klasse, die ** Datum ** ohne Zeitunterschied behandelt. Wenn keine Zeit angegeben ist, wird diese Klasse für die Analyse verwendet. Sie können es mit LocalDate # atStartOfDay () als Mitternacht in LocalDateTime konvertieren.

Timestamp Wird für die Konvertierung von Unixtime verwendet.

fließen

Ja, fangen wir mit der Erklärung an. Als Prozedur wird versucht, die Konvertierung in absteigender Reihenfolge der Informationsmenge als Analyseergebnis durchzuführen. Wenn die Konvertierung abgeschlossen ist, wird das Ergebnis zurückgegeben. ** Nur wenn alle Analysen fehlschlagen ** Ich werde alle Fehler werfen.

Verfassung

Erstellen Sie eine abstrakte Klasse, um sie zu analysieren und zu erben.

クラス図

Code

Abstrakte Klasse der Analyseklasse

TimeParser.java



public abstract class TimeParser {

	/**
	 * fails info
	 */
	protected List<String> failsMessages = new ArrayList<>();

	/**
	 * This function forcibly converts a string to a date.
	 *<p>
	 * If the return value is null, please throw an {@code DateTimeParseException}.
	 * </p>
	 * @param input
	 * @return LocalDateTime instance or {@code null}
	 */
	public abstract LocalDateTime parse(String input);

	protected void addExceptionMessage(Exception e) {
		failsMessages.add(e.getMessage() + " ("+this.getClass().getSimpleName()+")");
	}

	public List<String> getExceptionInfo(){
		return failsMessages;
	};
}

Es besteht aus einem Analyseteil und einem Protokollerfassungsteil. Vorerst führe ich ein Protokoll, damit ich sehen kann, was passiert ist, wenn alles fehlgeschlagen ist.

Implementierung der Analyseklasse

LocalDateParser.java




public class LocalDateParser extends TimeParser {

	//Definieren Sie das Format von einem Ende
	private final static List<DateTimeFormatter> FORMATS = new ArrayList<DateTimeFormatter>() {
		{
			add(DateTimeFormatter.ISO_LOCAL_DATE);
			add(DateTimeFormatter.BASIC_ISO_DATE);
			add(DateTimeFormatter.ISO_DATE);
			add(DateTimeFormatter.ofPattern("yy-MM-dd"));
			add(DateTimeFormatter.ofPattern("yy-M-d"));
			add(DateTimeFormatter.ofPattern("yyyy/MM/dd"));
			add(DateTimeFormatter.ofPattern("yyyy/M/d"));
			add(DateTimeFormatter.ofPattern("JJJJ Jahr M Monat d Tag"));

		}
	};

	@Override
	public LocalDateTime parse(String input) {
		failsMessages.clear();

		//Versuchen Sie die Standardanalyse
		try {
			return LocalDate.parse(input).atStartOfDay();
		} catch (DateTimeParseException e) {
			addExceptionMessage(e);
		}

		//Im angegebenen Format analysieren
		for (DateTimeFormatter formatter : FORMATS) {
			try {
				return LocalDate.parse(input, formatter).atStartOfDay();
			} catch (DateTimeParseException e) {
				//Speichern Sie das fehlgeschlagene Protokoll in der Liste
				addExceptionMessage(e);
			}
		}
		return null;
	}
}

Wenn eine DateTimeParseException auftritt, lagern Sie einfach das Protokoll und Ich werde alles quetschen.

Der Grund, warum der Logger nicht ausgibt, wenn eine Ausnahme auftritt, ist, dass er ausgegeben wird, auch wenn bei der Verarbeitung keine Probleme auftreten.

Erstellen Sie eine Klasse, die TimeParser wie folgt in anderen Datumsklassen erbt.

Die Klasse, die die Fassade der Analyse sein wird

DateTimeParser.java



public class DateTimeParser {

	//Fehleraufbewahrungsliste
	private List<String> errors = new ArrayList<>();
	//Erstellen Sie eine Analyseklasse
	private final static List<TimeParser> PARSERS = new ArrayList<TimeParser>() {
		{
			//Analysieren Sie in absteigender Reihenfolge der Informationsmenge
			add(new ZonedDateTimeParser());
			add(new OffsetDateTimeParser());
			add(new LocalDateTimeParser());
			add(new LocalDateParser());
			add(new TimestampParser());
		}
	};

	public LocalDateTime parse(String input) {
		errors.clear();

		LocalDateTime result = null;

		for (TimeParser parser : PARSERS) {
			result = parser.parse(input);

			//Gibt das Ergebnis zurück, wenn es erfolgreich ist
			if (result != null) {
				return result;
			}
			errors.addAll(parser.getExceptionInfo());
		}

		throw new DateTimeParseException("Analyse fehlgeschlagen.(\"" + input + "\")", input, 0);

		//Es gibt keine Rückkehr!
	}

	public List<String> getErrors(){
		return errors;
	}

}

Es enthält eine Liste von Analyseklassen und Schleifen. Wenn die Analyse erfolgreich ist, wird eine Instanz von LocalDateTime zurückgegeben Gibt das Ergebnis zurück, wenn es nicht "null" ist.

Darüber hinaus kann die in der Mitte aufgetretene Analyse-Ausnahme nach der Analyse mit getErrors () abgerufen werden. (Es ist nicht threadsicher ...)

Und nur wenn es fehlschlägt, wird am Ende eine Ausnahme ausgelöst. Es ist eine seltsame Methode ohne "Rückkehr".

Prüfung

DateTimeParserTest.java


	@Test
	public void testDateFormat() {
		//Testen Sie, ob dieses Datum konvertiert werden kann
		List<String> dates = new ArrayList<String>() {
			{
				add("2017-12-02");
				add("17-12-02");
				add("17-12-2");
				add("20171202");
				add("2017/12/02");
				add("2017/12/2");
				add("2. Dezember 2017");
			}
		};

		for (String date : dates) {
			LocalDateTime time = dtp.parse(date);
			assertEquals("2017-12-02T00:00:00", time.format(formater));
		}

	}

Es ist ein grober Test, aber wenn Sie alle Daten wie folgt analysieren, Alle könnten als "2017-12-02T 00:00:00" analysiert werden. Sie sollten in der Lage sein, jedes Datum zu konvertieren, indem Sie der ArrayList der verschiedenen Parser-Klassen Formate hinzufügen.

Du hast es geschafft!

Der diesmal verwendete Beispielcode wird übrigens auf GitHub veröffentlicht. https://github.com/ubansi/DateTimeParser

Recommended Posts

Ich werde die Zeitzeichenfolge unbedingt konvertieren!
Ich habe die Quelle von String gelesen
Ich habe zum ersten Mal versucht, Docker zu berühren
[Rails] Ich habe zum ersten Mal versucht, die button_to-Methode zu verwenden
Stellen Sie Datum und Uhrzeit aus der Zeichenfolge mit POI ein
Ich habe versucht, in Java von einer Zeichenfolge in einen LocalDate-Typ zu konvertieren