Java: String in TimeStamp konvertieren

75

Ich habe ein Problem, während ich versuche, einen String in einen TimeStamp zu konvertieren. Ich habe ein Array, dessen Datum im Format von liegt, yyyy-MM-ddund ich möchte das Format von ändern yyyy-MM-dd HH:mm:ss.SSS. Also benutze ich diesen Code:

final String OLD_FORMAT = "yyyy-MM-dd";
final String NEW_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS";
String oldDateString = createdArray[k];
String newDateString;

DateFormat formatter = new SimpleDateFormat(OLD_FORMAT);
Date d = formatter.parse(oldDateString);
((SimpleDateFormat) formatter).applyPattern(NEW_FORMAT);
newDateString = formatter.format(d);
System.out.println(newDateString);

Timestamp ts = Timestamp.valueOf(newDateString);
System.out.println(ts);

und ich bekomme folgendes Ergebnis.

2009-10-20 00: 00: 00.000

2009-10-20 00: 00: 00.0

aber wenn ich es einfach versuche

String text = "2011-10-02 18:48:05.123";
ts = Timestamp.valueOf(text);
System.out.println(ts);

Ich bekomme das richtige Ergebnis:

2011-10-02 18: 48: 05.123

Weißt du, was ich falsch machen könnte? Danke für die Hilfe.

Dimitra Micha
quelle
Nichts ist falsch. Was erwarten Sie im ersten Fall? Sie erstellen einen Zeitstempel ab dem Datum 2009-10-20, sodass der Zeitteil des Zeitstempels nicht festgelegt ist. Im zweiten Fall erstellen Sie einen Zeitstempel aus einer Zeichenfolge, in der die Zeit festgelegt ist.
Piro sagt Reinstate Monica
Verwenden Sie einfach zwei Instanzen von (Simple) DateFormat, mit denen Sie nicht herumspielen müssen applyPattern().
Gyro Gearless
@ GyroGearless Ich bin nicht sicher, was du meinst? Wie ist es möglich, ApplyPattern nicht anzuwenden?
Dimitra Micha
@ Piro Das falsche Problem ist, dass ich 2009-10-20 00: 00: 00.0 anstelle von 2009-10-20 00: 00: 00.000
Dimitra Micha
Warum brauchst du drei Stellen / Nullen? Der Zeitstempel verwendet ein eigenes Format. Dieses Format ist korrekt und kann nicht geändert werden. Wenn Sie einen formatierten Zeitstempel drucken müssen, konvertieren Sie ihn von Zeitstempel zurück in Datum und formatieren Sie ihn. Aktuelle Antworten scheinen völlig zu verfehlen, was Sie brauchten, da Ihre Frage nicht offensichtlich ist
Piro sagt Reinstate Monica

Antworten:

117

Befolgen Sie diese Schritte, um ein korrektes Ergebnis zu erzielen:

try {
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSS");
    Date parsedDate = dateFormat.parse(yourString);
    Timestamp timestamp = new java.sql.Timestamp(parsedDate.getTime());
} catch(Exception e) { //this generic but you can control another types of exception
    // look the origin of excption 
}

Bitte beachten Sie, dass ein .parse(String)werfen könnte ParseException.

ZaoTaoBao
quelle
Ich habe versucht, was du vorgeschlagen hast, aber es löst eine Ausnahme aus. Könnte ich das beheben?
Dimitra Micha
1
Dieses Datumsmuster ist gefährlich: hhinterpretiert die Stunde "in am / pm (1-12)". Sie sollten verwenden HH, um "Stunde am Tag (0-23)" wie in der Frage zu erhalten.
Scolytus
20
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Util {
  public static Timestamp convertStringToTimestamp(String strDate) {
    try {
      DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
       // you can change format of date
      Date date = formatter.parse(strDate);
      Timestamp timeStampDate = new Timestamp(date.getTime());

      return timeStampDate;
    } catch (ParseException e) {
      System.out.println("Exception :" + e);
      return null;
    }
  }
}
Hart
quelle
2
Ich bevorzuge diese Antwort, da sie die im Code verwendeten Klassen zeigt. Ich bekam immer wieder Fehler, weil ich java.sql.Date anstelle von java.util.Date importierte .
tartaruga_casco_mole
13

Ich möchte die moderne Antwort beitragen. Als diese Frage 2013 gestellt wurde, war die Verwendung der TimestampKlasse richtig, beispielsweise zum Speichern einer Datums- und Uhrzeitangabe in Ihrer Datenbank. Heute ist die Klasse längst veraltet. Die moderne Java-API für Datum und Uhrzeit wurde im Frühjahr 2014, vor dreieinhalb Jahren, mit Java 8 herausgebracht. Ich empfehle Ihnen, dies stattdessen zu verwenden.

Abhängig von Ihrer Situation und den genauen Anforderungen gibt es zwei natürliche Ersetzungen für Timestamp:

  • Instantist ein Punkt auf der Zeitachse. Für die meisten Zwecke würde ich es als am sichersten betrachten, dies zu verwenden. Ein Instantist unabhängig von der Zeitzone und funktioniert normalerweise auch in Situationen, in denen Ihr Clientgerät und Ihr Datenbankserver unterschiedliche Zeitzonen ausführen.
  • LocalDateTime ist ein Datum und eine Uhrzeit ohne Zeitzone, wie 2011-10-02 18: 48: 05.123 (um die Frage zu zitieren).

Ein moderner JDBC-Treiber (JDBC 4.2 oder höher) und andere moderne Tools für den Datenbankzugriff speichern gerne entweder einen Instantoder einen LocalDateTimein Ihrer Datenbankspalte des Datentyps timestamp. Beide Klassen und die anderen Datums- / Uhrzeitklassen, die ich in dieser Antwort verwende, gehören zur modernen API java.timeJSR-310.

Es ist am einfachsten, Ihre Zeichenfolge in zu konvertieren. LocalDateTimeNehmen wir das zuerst:

    DateTimeFormatter formatter
            = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSS");
    String text = "2011-10-02 18:48:05.123";
    LocalDateTime dateTime = LocalDateTime.parse(text, formatter);
    System.out.println(dateTime);

Dies wird gedruckt

2011-10-02T18:48:05.123

Wenn Ihre Zeichenfolge im Format JJJJ-MM-TT vorliegt, gehen Sie stattdessen wie folgt vor:

    String text = "2009-10-20";
    LocalDateTime dateTime = LocalDate.parse(text).atStartOfDay();
    System.out.println(dateTime);

Dies wird gedruckt

2009-10-20T00:00

Oder noch besser, nehmen Sie die Ausgabe von LocalDate.parse()und speichern Sie sie in einer Datenbankspalte vom Datentyp date.

In beiden Fällen lautet das Verfahren zum Konvertieren von a LocalDateTimenach a Instant:

    Instant ts = dateTime.atZone(ZoneId.systemDefault()).toInstant();
    System.out.println(ts);

Ich habe eine Konvertierung unter Verwendung der Standardzeitzone der JVM angegeben, da dies die veraltete Klasse verwendet hätte. Dies ist jedoch fragil, da die Zeitzoneneinstellung unter unseren Füßen durch andere Teile Ihres Programms oder durch andere Programme, die in derselben JVM ausgeführt werden, geändert werden kann. Wenn Sie können, geben Sie stattdessen eine Zeitzone im Format Region / Stadt an , zum Beispiel:

    Instant ts = dateTime.atZone(ZoneId.of("Europe/Athens")).toInstant();
Ole VV
quelle
Die Antworten wurden auf der Grundlage der Frage des OP gegeben. Nicht was richtig oder falsch ist
Ojonugwa Jude Ochalifu
2
Sie sind völlig richtig, @OjonugwaJudeOchalifu. Da die Frage und die Antwort für die Nachwelt hier bleiben, stellt sich die Frage, ob wir zukünftigen Lesern am besten helfen, indem wir die Antworten von 2013 für sich allein lassen oder durch eine Antwort ergänzen, die die gute Lösung für die Zukunft zeigt.
Ole VV
3
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");

Date date = formatter.parse(dateString);

Timestamp timestamp = new Timestamp(date.getTime());

System.out.println(timestamp);
Akshay Misal
quelle
Möglicherweise möchten Sie beim Formatieren des Zeichenfolgendatums eine Parsing-Ausnahme abfangen.
Eyoeldefare
3

Der einfache Weg, um String in java.sql.Timestamp zu konvertieren:

Timestamp t = new Timestamp(DateUtil.provideDateFormat().parse("2019-01-14T12:00:00.000Z").getTime());

DateUtil.java:

import java.text.SimpleDateFormat;
import java.util.TimeZone;

public interface DateUtil {

  String ISO_DATE_FORMAT_ZERO_OFFSET = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
  String UTC_TIMEZONE_NAME = "UTC";

  static SimpleDateFormat provideDateFormat() {
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(ISO_DATE_FORMAT_ZERO_OFFSET);
    simpleDateFormat.setTimeZone(TimeZone.getTimeZone(UTC_TIMEZONE_NAME));
    return simpleDateFormat;
  }
}
Yuliia Ashomok
quelle
Aus welcher Bibliothek stammt DateUtil?
Christoph Raab
Es ist eine großartige Lösung.
Vinicius Gati
2
DateFormat formatter;
formatter = new SimpleDateFormat("dd/MM/yyyy");
Date date = (Date) formatter.parse(str_date);
java.sql.Timestamp timeStampDate = new Timestamp(date.getTime());
Mahesh Narwade
quelle
1

Konvertieren Sie zuerst Ihre Datumszeichenfolge, dateum sie dann timestampmithilfe der folgenden Zeile zu konvertieren

Date date=new Date();
Timestamp timestamp = new Timestamp(date.getTime());//instead of date put your converted date
Timestamp myTimeStamp= timestamp;
KhAn SaAb
quelle
2
Ich bin nicht sicher, wie ich mein konvertiertes Datum setzen soll. Ich denke mein Problem beginnt mit ((SimpleDateFormat) formatter).applyPattern(NEW_FORMAT); ? Wenn ich mein Datum, Datum d, verwende, führt es immer noch zu einem falschen Ergebnis: 2009-10-20 00: 00: 00.0
Dimitra Micha
1

Der Vollständigkeit halber hier eine Lösung mit Lambda und Methodenreferenz:

ISO-Format?

Beschreibung : Die folgende Methode

  • konvertiert a Stringmit dem Muster yyyy-MM-ddin a Timestamp, wenn eine gültige Eingabe gegeben ist,
  • gibt a zurück null, wenn ein nullWert angegeben ist,
  • löst a aus DateTimeParseException, wenn eine ungültige Eingabe gegeben wird

Code :

static Timestamp convertStringToTimestamp(String strDate) {
    return Optional.ofNullable(strDate) // wrap the String into an Optional
                   .map(str -> LocalDate.parse(str).atStartOfDay()) // convert into a LocalDate and fix the hour:minute:sec to 00:00:00
                   .map(Timestamp::valueOf) // convert to Timestamp
                   .orElse(null); // if no value is present, return null
}


Validierung : Diese Methode kann mit folgenden Komponententests getestet werden: (mit Junit5 und Hamcrest )

@Test
void convertStringToTimestamp_shouldReturnTimestamp_whenValidInput() {
    // given
    String strDate = "2020-01-30";

    // when
    final Timestamp result = convertStringToTimestamp(strDate);

    // then
    final LocalDateTime dateTime = LocalDateTime.ofInstant(result.toInstant(), ZoneId.systemDefault());
    assertThat(dateTime.getYear(), is(2020));
    assertThat(dateTime.getMonthValue(), is(1));
    assertThat(dateTime.getDayOfMonth(), is(30));
}

@Test
void convertStringToTimestamp_shouldReturnTimestamp_whenInvalidInput() {
    // given
    String strDate = "7770-91-30";

    // when, then
    assertThrows(DateTimeParseException.class, () -> convertStringToTimestamp(strDate));
}

@Test
void convertStringToTimestamp_shouldReturnTimestamp_whenNullInput() {
    // when
    final Timestamp result = convertStringToTimestamp(null);

    // then
    assertThat(result, is(nullValue()));
}


Ein anderes Format?

Normalerweise hat die zu analysierende Zeichenfolge ein anderes Format. Eine Möglichkeit, damit umzugehen, besteht darin, einen Formatierer zu verwenden, um es in ein anderes Format zu konvertieren. Hier ist ein Beispiel:

Eingang: 20200130 11:30

Muster: yyyyMMdd HH:mm

Ausgabe: Zeitstempel dieser Eingabe

Code :

static Timestamp convertStringToTimestamp(String strDate) {
    final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd HH:mm");
    return Optional.ofNullable(strDate) //
                   .map(str -> LocalDateTime.parse(str, formatter))
                   .map(Timestamp::valueOf) //
                   .orElse(null);
}

Test :

@Test
void convertStringToTimestamp_shouldReturnTimestamp_whenValidInput() {
    // given
    String strDate = "20200130 11:30";

    // when
    final Timestamp result = convertStringToTimestamp(strDate);

    // then
    final LocalDateTime dateTime = LocalDateTime.ofInstant(result.toInstant(), ZoneId.systemDefault());
    assertThat(dateTime.getYear(), is(2020));
    assertThat(dateTime.getMonthValue(), is(1));
    assertThat(dateTime.getDayOfMonth(), is(30));
    assertThat(dateTime.getHour(), is(11));
    assertThat(dateTime.getMinute(), is(30));
}
KeyMaker00
quelle
0

Ich bin sicher, die Lösung ist, dass Ihr oldDateString so etwas wie "2009-10-20" ist. Offensichtlich enthält dies keine Zeitdaten, die niedriger als Tage sind. Wenn Sie diese Zeichenfolge mit Ihrem neuen Formatierer formatieren, woher sollen die Minuten, Sekunden und Millisekunden stammen?

Das Ergebnis ist also absolut korrekt: 2009-10-20 00: 00: 00.000

Um dies zu lösen, benötigen Sie den ursprünglichen Zeitstempel (einschließlich Zeitdaten) vor Ihrer ersten Formatierung.

Löser
quelle
1
Dieses Problem ist 9 Monate alt, und aus den Kommentaren geht hervor, dass es sich bei dem eigentlichen Problem um das Format der Datumszeichenfolge und nicht um die tatsächlichen Werte handelt.
Robby Cornelissen
0

kannst du es mal probieren ...

String dob="your date String";
String dobis=null;
final DateFormat df = new SimpleDateFormat("yyyy-MMM-dd");
final Calendar c = Calendar.getInstance();
try {
    if(dob!=null && !dob.isEmpty() && dob != "")
    {
    c.setTime(df.parse(dob));
    int month=c.get(Calendar.MONTH);
    month=month+1;
    dobis=c.get(Calendar.YEAR)+"-"+month+"-"+c.get(Calendar.DAY_OF_MONTH);
    }

}
Suresh U.
quelle
8
dob != ""ist superfluos und falsch - vergleiche niemals Strings mit ==oder !=. Und Sie sollten Dates nicht so formatieren, dafür ist (Simple) DateFormat gedacht.
Gyro Gearless