Konvertieren Sie eine Zeichenfolge in ein Kalenderobjekt in Java

174

Ich bin neu in Java, arbeite normalerweise mit PHP.

Ich versuche diesen String zu konvertieren:

Mon Mar 14 16:02:37 GMT 2011

In ein Kalenderobjekt, damit ich das Jahr und den Monat wie folgt abrufen kann:

String yearAndMonth = cal.get(Calendar.YEAR)+cal.get(Calendar.MONTH);

Wäre es eine schlechte Idee, es manuell zu analysieren? Verwenden Sie eine Teilstring-Methode?

Jeder Rat würde helfen, danke!

Doug Molineux
quelle

Antworten:

395
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy", Locale.ENGLISH);
cal.setTime(sdf.parse("Mon Mar 14 16:02:37 GMT 2011"));// all done

Hinweis: Je Localenach Umgebung / Anforderung einstellen


Siehe auch

Jigar Joshi
quelle
onlineconversion.com/unix_time.htm . Dies ist ein Online-Zeitstempelkonverter. Der Wert, der durch Java-Code und diese Online-Konvertierung berechnet wird, unterscheidet sich. Warum?? Können Sie das durchgehen? Danke :)
Sachin J
6
Beachten Sie, dass dadurch die Zeitzoneninformationen verloren gehen. Das Kalenderobjekt hat die Systemstandardzeitzone und nicht die analysierte.
Cristian Vrabie
Dies sollte nicht mehr die beste / akzeptierte Antwort sein. Da Java 8 bereits seit mehr als 4 Jahren verfügbar ist, sollte die Antwort aktualisiert werden, um sie zu erwähnen java.time. Diese Frage / Antwort kommt bei Google ziemlich gut zur Geltung.
Scolytus
18

tl; dr

Der moderne Ansatz verwendet die Klassen java.time .

YearMonth.from(
    ZonedDateTime.parse( 
        "Mon Mar 14 16:02:37 GMT 2011" , 
        DateTimeFormatter.ofPattern( "E MMM d HH:mm:ss z uuuu" )
     )
).toString()

2011-03

Vermeiden Sie ältere Datums- und Zeitklassen

Der moderne Weg ist mit java.time Klassen. Die alten Datums- Calendarund Uhrzeitklassen haben sich als schlecht gestaltet, verwirrend und problematisch erwiesen.

Definieren Sie einen benutzerdefinierten Formatierer, der Ihrer Zeichenfolgeneingabe entspricht.

String input = "Mon Mar 14 16:02:37 GMT 2011";
DateTimeFormatter f = DateTimeFormatter.ofPattern( "E MMM d HH:mm:ss z uuuu" );

Als analysieren ZonedDateTime.

ZonedDateTime zdt = ZonedDateTime.parse( input , f );

Sie interessieren sich für das Jahr und den Monat. Die java.time-Klassen enthalten YearMonthzu diesem Zweck eine Klasse.

YearMonth ym = YearMonth.from( zdt );

Bei Bedarf können Sie die Jahres- und Monatszahlen abfragen.

int year = ym.getYear();
int month = ym.getMonthValue();

Die toStringMethode generiert jedoch eine Zeichenfolge im Standardformat ISO 8601 .

String output = ym.toString();

Alles zusammen.

String input = "Mon Mar 14 16:02:37 GMT 2011";
DateTimeFormatter f = DateTimeFormatter.ofPattern( "E MMM d HH:mm:ss z uuuu" );
ZonedDateTime zdt = ZonedDateTime.parse( input , f );
YearMonth ym = YearMonth.from( zdt );
int year = ym.getYear();
int month = ym.getMonthValue();

Zur Konsole werfen.

System.out.println( "input: " + input );
System.out.println( "zdt: " + zdt );
System.out.println( "ym: " + ym );

Eingabe: Mo 14. März 16:02:37 GMT 2011

zdt: 2011-03-14T16: 02: 37Z [GMT]

ym: 2011-03

Live-Code

Siehe dieser Code ausgeführt wird in IdeOne.com .

Umwandlung

Wenn Sie ein Objekt haben müssenCalendar , können Sie es GregorianCalendarmit neuen Methoden konvertieren, die zu den alten Klassen hinzugefügt wurden.

GregorianCalendar gc = GregorianCalendar.from( zdt );

Über java.time

Das java.time- Framework ist in Java 8 und höher integriert. Diese Klassen verdrängen die lästigen alten Legacy - Datum-Zeit - Klassen wie java.util.Date, Calendar, & SimpleDateFormat.

Das Joda-Time- Projekt, das sich jetzt im Wartungsmodus befindet , empfiehlt die Migration zu java.time.

Weitere Informationen finden Sie im Oracle-Lernprogramm . Suchen Sie im Stapelüberlauf nach vielen Beispielen und Erklärungen. Die Spezifikation ist JSR 310 .

Woher bekomme ich die java.time-Klassen?

Das ThreeTen-Extra- Projekt erweitert java.time um zusätzliche Klassen. Dieses Projekt ist ein Testfeld für mögliche zukünftige Ergänzungen von java.time. Sie können einige nützliche Klassen hier wie finden Interval, YearWeek, YearQuarter, und mehr .

Basil Bourque
quelle
14

Nun, ich denke, es wäre eine schlechte Idee, den Code zu replizieren, der bereits in Klassen wie vorhanden ist SimpleDateFormat.

Auf der anderen Seite würde ich persönlich empfehlen, Joda Time zu vermeiden Calendarund Datevollständig zu verwenden, wenn Sie können, und stattdessen Joda Time als weitaus besser gestaltete Datums- und Uhrzeit-API zu verwenden. Sie müssen sich beispielsweise bewusst sein, dass dies nicht threadsicher SimpleDateFormatist. Daher benötigen Sie bei jeder Verwendung entweder Thread-Locals, Synchronisierung oder eine neue Instanz. Joda Parser und Formatierer sind threadsicher.

Jon Skeet
quelle
Vielen Dank für Ihre Eingabe, ich werde sicherlich in Zukunft Joda verwenden, sieht aus wie es sehr nützlich sein kann
Doug Molineux
@ Jon Skeet Joda wird in Android nicht deserialisiert. Joda ist wenig wert, es sei denn, Sie müssen keine Daten und Zeit sparen.
Frank Zappa
@FrankZappa: Dem würde ich nicht zustimmen - Sie können alle Ihre Datums- / Zeitberechnungen in Joda Time durchführen, dann aber zur Vereinfachung in andere Typen (der Einfachheit halber nur Zeichenfolgen) konvertieren.
Jon Skeet
Sorry, musste abstimmen, die Antwort ist zu alt, es ist veraltet, um die Antwort mit dem höchsten Rang zu sein. Heute java.timeist der richtige Weg, Basil Bourque gab eine ausgezeichnete Antwort.
Scolytus
2
@Scolytus: Die oberste (und akzeptierte) Antwort hat 332 Stimmen, verglichen mit 10 auf dieser. Ich denke, wenn Sie jede über 7 Jahre alte Antwort, die jetzt eine bessere Lösung hat, ablehnen, werden Ihnen die Abstimmungen ausgehen ... (Ich stimme zu, dass Basilius Antwort gut ist, und das habe ich positiv bewertet.)
Jon Skeet
10

Es muss kein neuer Kalender erstellt werden. SimpleDateFormat verwendet bereits einen Kalender darunter.

SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy", Locale.EN_US);
Date date = sdf.parse("Mon Mar 14 16:02:37 GMT 2011"));// all done
Calendar cal = sdf.getCalendar();

(Ich kann noch keinen Kommentar abgeben, deshalb habe ich eine neue Antwort erstellt.)

GoGoris
quelle
1
Ihre Lösung sieht elegant aus, hat jedoch zwei Nachteile: 1. JavaDoc garantiert nicht, dass das Verhalten wie erwartet ist. 2. Zumindest für Java 6 finden Sie in Zeile 1353 einen Pfad, in den das Kalenderobjekt geklont wird. Also dann dann! Date.equals (cal.getTime ()).
Niels
5

SimpleDateFormatist großartig, beachte nur, dass HHes sich von der hhArbeit mit Stunden unterscheidet. HHwird 24 Stunden Stunden und hh wird 12 Stunden Stunden zurückgeben.

Das Folgende gibt beispielsweise die 12-Stunden-Zeit zurück:

SimpleDateFormat sdf = new SimpleDateFormat("hh:mm aa");

Während dies 24 Stunden Zeit zurückgibt:

SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
Philip
quelle
4

Analysieren Sie eine Zeit mit der Zeitzone, Zim Muster für die Zeitzone

String aTime = "2017-10-25T11:39:00+09:00";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.getDefault());
try {
    Calendar cal = Calendar.getInstance();
    cal.setTime(sdf.parse(aTime));
    Log.i(TAG, "time = " + cal.getTimeInMillis()); 
} catch (ParseException e) {
    e.printStackTrace();
}

Ausgabe: Es wird die UTC-Zeit zurückgegeben

1508899140000

Geben Sie hier die Bildbeschreibung ein

Wenn wir die Zeitzone nicht wie folgt einstellen yyyy-MM-dd'T'HH:mm:ss. SimpleDateFormatverwendet die eingestellte ZeitzoneSetting

Phan Van Linh
quelle
3

Ja, es wäre eine schlechte Praxis, es selbst zu analysieren. Schauen Sie sich SimpleDateFormat an , es verwandelt den String in ein Datum und Sie können das Datum in eine Kalenderinstanz setzen.

John Vint
quelle
1

Einfache Methode:

public Calendar stringToCalendar(String date, String pattern) throws ParseException {
    String DEFAULT_LOCALE_NAME = "pt";
    String DEFAULT_COUNTRY = "BR";
    Locale DEFAULT_LOCALE = new Locale(DEFAULT_LOCALE_NAME, DEFAULT_COUNTRY);
    SimpleDateFormat format = new SimpleDateFormat(pattern, LocaleUtils.DEFAULT_LOCALE);
    Date d = format.parse(date);
    Calendar c = getCalendar();
    c.setTime(d);
    return c;
}
Alberto Cerqueira
quelle