Przeanalizuj ciąg do daty w innym formacie w języku Java

93

Chcę przekonwertować Stringna Dateróżne formaty.

Na przykład,

Otrzymuję od użytkownika,

String fromDate = "19/05/2009"; // i.e. (dd/MM/yyyy) format

Chcę przekonwertować to fromDatejako obiekt "yyyy-MM-dd"formatu Date

Jak mogę to zrobić?

Gnaniyar Zubair
źródło
2
Obiekt Date nie ma formatu, jest po prostu liczbą reprezentującą datę. Datę można przedstawić w postaci ciągu znaków w formacie „rrrr-MM-dd”.
user85421

Odpowiedzi:

182

Spójrz na SimpleDateFormat. Kod wygląda mniej więcej tak:

SimpleDateFormat fromUser = new SimpleDateFormat("dd/MM/yyyy");
SimpleDateFormat myFormat = new SimpleDateFormat("yyyy-MM-dd");

try {

    String reformattedStr = myFormat.format(fromUser.parse(inputString));
} catch (ParseException e) {
    e.printStackTrace();
}
Michael Myers
źródło
1
zamiast pobierać format ciągu, czy mogę uzyskać dane wyjściowe w Dateformacie?
Rachel
4
@Rachel: Jasne, po prostu użyj parsei nie idź dalej format. parseanalizuje String do Date.
Michael Myers
3
Ale parsedaje mi date formatjak Fri Jan 06 00:01:00 EST 2012, ale trzeba w 2012-01-06formacie daty
Rachel
1
@Rachel dzieje się tak, ponieważ po wywołaniu System.out.println(anyDateObject)domyślnej metody toString () jest wywoływana metoda, o której powiedziano, że drukuje w tym formacie, np Fri Jan 06 00:01:00 EST 2012. Musisz go zmienić, aby odpowiadał Twoim potrzebom.
KNU
3
FYI, kłopotliwe stare klasy daty i godziny, takie jak java.util.Date, java.util.Calendari java.text.SimpleDateFormatsą teraz starsze , zastąpione przez klasy java.time wbudowane w Java 8 i Java 9. Zobacz samouczek Oracle .
Basil Bourque
14

tl; dr

LocalDate.parse( 
    "19/05/2009" , 
    DateTimeFormatter.ofPattern( "dd/MM/uuuu" ) 
)

Detale

Pozostałe odpowiedzi z java.util.Date, java.sql.Datei SimpleDateFormatsą obecnie nieaktualne.

LocalDate

Współczesnym sposobem określania daty i godziny jest praca z klasami java.time LocalDate. LocalDateKlasa reprezentuje wartość data-tylko bez time-of-day i bez strefy czasowej.

DateTimeFormatter

Aby przeanalizować lub wygenerować String reprezentujący wartość daty i godziny, użyj DateTimeFormatterklasy.

DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/uuuu" );
LocalDate ld = LocalDate.parse( "19/05/2009" , f );

Nie łącz obiektu daty i godziny z ciągiem znaków reprezentującym jego wartość. Obiekt daty i godziny nie ma formatu , podczas gdy String ma. Obiekt daty i godziny, taki jak LocalDate, może generować String w celu reprezentowania jego wartości wewnętrznej, ale obiekt daty i godziny i String są oddzielnymi odrębnymi obiektami.

Możesz określić dowolny format niestandardowy, aby wygenerować ciąg. Lub pozwól java.time wykonać automatyczną lokalizację.

DateTimeFormatter f = 
    DateTimeFormatter.ofLocalizedDate( FormatStyle.FULL )
                     .withLocale( Locale.CANADA_FRENCH ) ;
String output = ld.format( f );

Zrzuć na konsolę.

System.out.println( "ld: " + ld + " | output: " + output );

ld: 2009-05-19 | wyjście: mardi 19 maja 2009

Zobacz w akcji w IdeOne.com .


Informacje o java.time

Struktura java.time jest wbudowana w Javę 8 i nowsze. Klasy te kłopotliwe zastąpić stary starszych klas Date-Time, takich jak java.util.Date, Calendar, i SimpleDateFormat.

Projekt Joda-Time , obecnie w trybie konserwacji , zaleca migrację do klas java.time .

Aby dowiedzieć się więcej, zobacz samouczek Oracle . I przeszukaj Stack Overflow, aby znaleźć wiele przykładów i wyjaśnień. Specyfikacja to JSR 310 .

Możesz wymieniać obiekty java.time bezpośrednio ze swoją bazą danych. Użyj sterownika JDBC zgodnego z JDBC 4.2 lub nowszym. Nie ma potrzeby stosowania ciągów ani java.sql.*klas.

Skąd wziąć klasy java.time?

  • Java SE 8 , Java SE 9 i nowsze
    • Wbudowany.
    • Część standardowego interfejsu API języka Java z dołączoną implementacją.
    • Java 9 dodaje kilka drobnych funkcji i poprawek.
  • Java SE 6 i Java SE 7
    • Wiele funkcji java.time jest przenoszonych z powrotem do Java 6 i 7 w ThreeTen-Backport .
  • Android
    • Późniejsze wersje implementacji klas java.time w pakietach Androida.
    • Dla wcześniejszej Androida (<26), ThreeTenABP projekt dostosowuje ThreeTen-backportu (jak wyżej). Zobacz Jak używać ThreeTenABP… .

Projekt ThreeTen-Extra rozszerza java.time o dodatkowe klasy. Ten projekt jest poligonem doświadczalnym dla ewentualnych przyszłych dodatków do java.time. Można znaleźć kilka przydatnych klas tutaj takie jak Interval, YearWeek, YearQuarter, i więcej .

Basil Bourque
źródło
12

Skorzystaj z SimpleDateFormatzajęć:

private Date parseDate(String date, String format) throws ParseException
{
    SimpleDateFormat formatter = new SimpleDateFormat(format);
    return formatter.parse(date);
}

Stosowanie:

Date date = parseDate("19/05/2009", "dd/MM/yyyy");

Aby zwiększyć wydajność, chciałbyś przechowywać swoje elementy formatujące w skrócie. Hashmap to statyczny element członkowski Twojej klasy util.

private static Map<String, SimpleDateFormat> hashFormatters = new HashMap<String, SimpleDateFormat>();

public static Date parseDate(String date, String format) throws ParseException
{
    SimpleDateFormat formatter = hashFormatters.get(format);

    if (formatter == null)
    {
        formatter = new SimpleDateFormat(format);
        hashFormatters.put(format, formatter);
    }

    return formatter.parse(date);
}
Agora
źródło
9
UWAGA !! Pomysł jest dobry, ale realizacja nie. DateFormats nie mogą być przechowywane statycznie, ponieważ nie są bezpieczne dla wątków! Jeśli są używane z więcej niż jednego wątku (a przy statyce jest to zawsze ryzykowne). FindBugs zawiera wykrywacz tego (co zdarzyło mi się dawać na początku, po tym, jak zostałem ugryziony. Zobacz dschneller.blogspot.com/2007/04/… :-))
Daniel Schneller
Twój wpis na blogu to ciekawa lektura :-) A jeśli sama metoda parseDate została zsynchronizowana? Problem w tym, że prawdopodobnie spowolniłoby to działanie kodu ...
Agora
1
Tak długo, jak metoda parseDate była jedyną metodą dostępu do mapy, synchronizacja będzie działać. Jednak - jak powiedziałeś - wprowadziłoby to wąskie gardło.
Daniel Schneller
8

Przekonwertuj datę w postaci łańcucha na java.sql.Date

String fromDate = "19/05/2009";
DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
java.util.Date dtt = df.parse(fromDate);
java.sql.Date ds = new java.sql.Date(dtt.getTime());
System.out.println(ds);//Mon Jul 05 00:00:00 IST 2010
Ritesh Kaushik
źródło
3

Chociaż SimpleDateFormatrzeczywiście będzie działać dla twoich potrzeb, dodatkowo możesz chcieć sprawdzić Joda Time , który jest najwyraźniej podstawą przerobionej biblioteki Date w Javie 7. Chociaż nie używałem go zbyt często, nie słyszałem nic poza dobrymi rzeczami o tym i jeśli manipulujesz datami w swoich projektach, prawdopodobnie warto byłoby się temu przyjrzeć.

James McMahon
źródło
2

Załóżmy, że masz taki ciąg:

String mDate="2019-09-17T10:56:07.827088"

Teraz chcemy zmienić ten Stringformat oddzielnie dla daty i czasu w Javie i Kotlinie .

JAWA:

mamy metodę na wyodrębnienie daty :

public String getDate() {
    try {
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.US);
        Date date = dateFormat.parse(mDate);
        dateFormat = new SimpleDateFormat("MM/dd/yyyy", Locale.US);
        return dateFormat.format(date);
    } catch (ParseException e) {
        e.printStackTrace();
    }
    return null;
}

Return jest to: 17.09.2019

Mamy metodę na czas ekstrakcji :

public String getTime() {

    try {
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.US);
        Date date = dateFormat.parse(mCreatedAt);
        dateFormat = new SimpleDateFormat("h:mm a", Locale.US);
        return dateFormat.format(date);
    } catch (ParseException e) {
        e.printStackTrace();
    }
    return null;
}

Returnjest to: 10:56

KOTLIN:

mamy funkcję wyodrębniania daty :

fun getDate(): String? {

    var dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.US)
    val date = dateFormat.parse(mDate!!)
    dateFormat = SimpleDateFormat("MM/dd/yyyy", Locale.US)
    return dateFormat.format(date!!)
}

Return jest to: 17.09.2019

Mamy metodę na czas ekstrakcji :

fun getTime(): String {

    var dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.US)
    val time = dateFormat.parse(mDate!!)
    dateFormat = SimpleDateFormat("h:mm a", Locale.US)
    return dateFormat.format(time!!)
}

Returnjest to: 10:56

milad salimi
źródło
Proszę, nie uczcie młodych, aby korzystali z dawno przestarzałej i notorycznie kłopotliwej SimpleDateFormatklasy. Przynajmniej nie jako pierwsza opcja. I nie bez zastrzeżeń. Dziś mamy o wiele lepsze java.time, nowoczesne API daty i czasu w Javie i jego DateTimeFormatter. Nie SimpleDateFormatmożna również poprawnie przeanalizować 6 miejsc po przecinku w sekundach (mikrosekundach).
Ole VV
Kiedy uruchamiam twój drugi fragment kodu, nie otrzymuję tego, 10:56 AMco powiedziałeś, że powinienem, ale zamiast tego 11:09 AM(testowane na Oracle jdk-11.0.3).
Ole VV
@ OleV.V. , Jeśli metoda jest dawno nieaktualna, będzie przestarzała z linią na niej jako znakiem, jeśli metoda lub klasa nie jest przestarzała, możemy jej użyć, nie mówię, że to najlepszy sposób, może mamy lepszy sposób, ale w ten sposób jest prosta i zrozumiała, jeśli metoda lub klasa była stara, nie ma powodu, aby była kłopotliwa, a do jej użycia DateTimeFormatterpotrzebujemy minsdk 26lub wyżej, to nie jest to dobre
milad salimi
@ OleV.V. Ale dzięki za komentarz i co do drugiego komentarza mogę powiedzieć, że sprawdzam go wiele razy w dwóch aplikacjach i wraca10:56 AM
milad salimi
1
@ OleV.V. Ok, ale używam biblioteki, kiedy nie mam możliwości lub to API (biblioteka) jest bardzo lepsze niż mój kod, ponieważ kiedy dodajesz bibliotekę, dodajesz do swojego projektu kody, które mogą nie być używane i jest to przeciążenie dla twojego projekt, takie jest moje podejście i Twoje podejście jest dla mnie szacowne.
milad salimi
1

Prosty sposób na sformatowanie daty i przekształcenie w ciąg

    Date date= new Date();

    String dateStr=String.format("%td/%tm/%tY", date,date,date);

    System.out.println("Date with format of dd/mm/dd: "+dateStr);

wyjście: Data w formacie dd / mm / dd: 21/10/2015

Khalid Habib
źródło
1

DateObiekt ma żadnego wzoru , to jest reprezentacja. Datę można przedstawić Stringw formacie, który lubisz .

Np. „ yyyy-MM-dd”, „ yy-MMM-dd”, „ dd-MMM-yy” Itp.

Aby to osiągnąć, możesz skorzystać z SimpleDateFormat

Spróbuj tego,

        String inputString = "19/05/2009"; // i.e. (dd/MM/yyyy) format

        SimpleDateFormat fromUser = new SimpleDateFormat("dd/MM/yyyy"); 
        SimpleDateFormat myFormat = new SimpleDateFormat("yyyy-MM-dd");

        try {
            Date dateFromUser = fromUser.parse(inputString); // Parse it to the exisitng date pattern and return Date type
            String dateMyFormat = myFormat.format(dateFromUser); // format it to the date pattern you prefer
            System.out.println(dateMyFormat); // outputs : 2009-05-19

        } catch (ParseException e) {
            e.printStackTrace();
        }

To daje: 2009-05-19

Dulith De Costa
źródło