Jak uzyskać rok, miesiąc, dzień, godziny, minuty, sekundy i milisekundy bieżącej chwili w Javie?

104

Jak uzyskać informacje o roku, miesiącu, dniu, godzinach, minutach, sekundach i milisekundach bieżącego momentu w Javie? Chciałbym mieć je jako Strings.

rzymski
źródło

Odpowiedzi:

255

Możesz użyć do tego getterów java.time.LocalDateTime.

LocalDateTime now = LocalDateTime.now();
int year = now.getYear();
int month = now.getMonthValue();
int day = now.getDayOfMonth();
int hour = now.getHour();
int minute = now.getMinute();
int second = now.getSecond();
int millis = now.get(ChronoField.MILLI_OF_SECOND); // Note: no direct getter available.

System.out.printf("%d-%02d-%02d %02d:%02d:%02d.%03d", year, month, day, hour, minute, second, millis);

Lub, jeśli nie jesteś jeszcze w Javie 8, skorzystaj z java.util.Calendar.

Calendar now = Calendar.getInstance();
int year = now.get(Calendar.YEAR);
int month = now.get(Calendar.MONTH) + 1; // Note: zero based!
int day = now.get(Calendar.DAY_OF_MONTH);
int hour = now.get(Calendar.HOUR_OF_DAY);
int minute = now.get(Calendar.MINUTE);
int second = now.get(Calendar.SECOND);
int millis = now.get(Calendar.MILLISECOND);

System.out.printf("%d-%02d-%02d %02d:%02d:%02d.%03d", year, month, day, hour, minute, second, millis);

Tak czy inaczej, to się teraz drukuje:

2010-04-16 15: 15: 17.816

Aby przekonwertować intna String, użyj String#valueOf().


Jeśli mimo wszystko zamierzasz ułożyć i wyświetlić je w przyjaznym dla człowieka formacie ciągu, lepiej użyj Java8 java.time.format.DateTimeFormatter( samouczek tutaj ),

LocalDateTime now = LocalDateTime.now();
String format1 = now.format(DateTimeFormatter.ISO_DATE_TIME);
String format2 = now.atZone(ZoneId.of("GMT")).format(DateTimeFormatter.RFC_1123_DATE_TIME);
String format3 = now.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss", Locale.ENGLISH));

System.out.println(format1);
System.out.println(format2);
System.out.println(format3);

lub jeśli nie korzystasz jeszcze z Javy 8, użyj java.text.SimpleDateFormat:

Date now = new Date(); // java.util.Date, NOT java.sql.Date or java.sql.Timestamp!
String format1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.ENGLISH).format(now);
String format2 = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z", Locale.ENGLISH).format(now);
String format3 = new SimpleDateFormat("yyyyMMddHHmmss", Locale.ENGLISH).format(now);

System.out.println(format1);
System.out.println(format2);
System.out.println(format3);

Tak czy inaczej, daje to:

2010-04-16T15: 15: 17.816
Piątek, 16 kwietnia 2010 15:15:17 GMT
20100416151517

Zobacz też:

BalusC
źródło
Jeśli zamierzasz używać printf, równie dobrze możesz po prostu użyć formatów daty / czasu zamiast używać kroku pośredniego, tj. "% 1 $ tm% 1 $ te,% 1 $ tY", c (zobacz java.util. Formatter dla pełnej składni)
M. Jessup
1
@M. Jessup: To naprawdę fajniejsze. Jednak nigdy go nie używałem, więc nie mogłem wejść do niego od góry głowy, powyższe jest tylko dla celów demonstracyjnych. Niezależnie od tego, wolałbym raczej chwycić SimpleDateFormatlub DateTimeFormatterza to konkretne zadanie :)
BalusC
Zdecydowanie sugerowałbym użycie czasu joda, ponieważ jest to znacznie ładniejsze i bardziej zrozumiałe API w porównaniu do źle zaprojektowanych dat i kalendarzy, które bezpośrednio oferuje Java.
Kaitsu,
Wolę ten, szczególnie w pracy i18n, aby zacząćTime lub endTime:new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ENGLISH).format(new Date());
Eddy
1
Znaczna część funkcjonalności java.time jest przenoszona z powrotem do Java 6 i 7 w projekcie ThreeTen-Backport .
Basil Bourque
30

Przełącz się na czas joda i możesz to zrobić w trzech wierszach

DateTime jodaTime = new DateTime();

DateTimeFormatter formatter = DateTimeFormat.forPattern("YYYY-MM-dd HH:mm:ss.SSS");
System.out.println("jodaTime = " + formatter.print(jodaTime));

Masz również bezpośredni dostęp do poszczególnych pól daty bez korzystania z kalendarza.

System.out.println("year = " + jodaTime.getYear());
System.out.println("month = " + jodaTime.getMonthOfYear());
System.out.println("day = " + jodaTime.getDayOfMonth());
System.out.println("hour = " + jodaTime.getHourOfDay());
System.out.println("minute = " + jodaTime.getMinuteOfHour());
System.out.println("second = " + jodaTime.getSecondOfMinute());
System.out.println("millis = " + jodaTime.getMillisOfSecond());

Dane wyjściowe są następujące:

jodaTime = 2010-04-16 18:09:26.060

year = 2010
month = 4
day = 16
hour = 18
minute = 9
second = 26
millis = 60

Według http://www.joda.org/joda-time/

Joda-Time jest de facto standardową biblioteką daty i czasu dla języka Java. Począwszy od Java SE 8, użytkownicy są proszeni o migrację do java.time (JSR-310).

crowne
źródło
1
FYI, projekt Joda-Time jest obecnie w trakcie konserwacji, a jego zespół doradza migrację do klas java.time. Zarówno Joda-Time, jak i java.time są prowadzone przez tego samego człowieka, Stephena Colebourne'a.
Basil Bourque
7
    // Java 8
    System.out.println(LocalDateTime.now().getYear());       // 2015
    System.out.println(LocalDateTime.now().getMonth());      // SEPTEMBER
    System.out.println(LocalDateTime.now().getDayOfMonth()); // 29
    System.out.println(LocalDateTime.now().getHour());       // 7
    System.out.println(LocalDateTime.now().getMinute());     // 36
    System.out.println(LocalDateTime.now().getSecond());     // 51
    System.out.println(LocalDateTime.now().get(ChronoField.MILLI_OF_SECOND)); // 100

    // Calendar
    System.out.println(Calendar.getInstance().get(Calendar.YEAR));         // 2015
    System.out.println(Calendar.getInstance().get(Calendar.MONTH ) + 1);   // 9
    System.out.println(Calendar.getInstance().get(Calendar.DAY_OF_MONTH)); // 29
    System.out.println(Calendar.getInstance().get(Calendar.HOUR_OF_DAY));  // 7
    System.out.println(Calendar.getInstance().get(Calendar.MINUTE));       // 35
    System.out.println(Calendar.getInstance().get(Calendar.SECOND));       // 32
    System.out.println(Calendar.getInstance().get(Calendar.MILLISECOND));  // 481

    // Joda Time
    System.out.println(new DateTime().getYear());           // 2015
    System.out.println(new DateTime().getMonthOfYear());    // 9
    System.out.println(new DateTime().getDayOfMonth());     // 29
    System.out.println(new DateTime().getHourOfDay());      // 7
    System.out.println(new DateTime().getMinuteOfHour());   // 19
    System.out.println(new DateTime().getSecondOfMinute()); // 16
    System.out.println(new DateTime().getMillisOfSecond()); // 174

    // Formatted
    // 2015-09-28 17:50:25.756
    System.out.println(new Timestamp(System.currentTimeMillis()));

    // 2015-09-28T17:50:25.772
    System.out.println(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.ENGLISH).format(new Date()));

    // Java 8
    // 2015-09-28T17:50:25.810
    System.out.println(LocalDateTime.now());

    // joda time
    // 2015-09-28 17:50:25.839
    System.out.println(DateTimeFormat.forPattern("YYYY-MM-dd HH:mm:ss.SSS").print(new org.joda.time.DateTime()));
blueberry0xff
źródło
Ta odpowiedź naprawdę odnosi się do pytania, które dotyczyło dostępu do składników wartości daty i czasu (a nie zwykłych sformatowanych ciągów).
Basil Bourque
6

W przypadku wersji Java 8 i nowszych użyj pakietu java.time .

ZonedDateTime.now().getYear();
ZonedDateTime.now().getMonthValue();
ZonedDateTime.now().getDayOfMonth();
ZonedDateTime.now().getHour();
ZonedDateTime.now().getMinute();
ZonedDateTime.now().getSecond();

ZonedDateTime.now()jest metodą statyczną zwracającą bieżącą datę i godzinę z zegara systemowego w domyślnej strefie czasowej. Wszystkie metody get zwracają intwartość.

Ortomala Lokni
źródło
LocalDateTimejest do tego niewłaściwą klasą. Pozbawiona koncepcję strefy czasowej lub offsetu z-UTC, to nie może być wykorzystywane do śledzenia określonym momencie, to nie punkt na osi czasu. Użyj Instant, ZonedDateTimelub OffsetDateTimezamiast tego.
Basil Bourque
Masz rację. Zmodyfikowałem odpowiedź, aby użyć ZonedDateTime.
Ortomala Lokni
3

tl; dr

ZonedDateTime.now(                    // Capture current moment as seen in the wall-clock time used by the people of a particular region (a time zone).
    ZoneId.of( "America/Montreal" )   // Specify desired/expected time zone. Or pass `ZoneId.systemDefault` for the JVM’s current default time zone.
)                                     // Returns a `ZonedDateTime` object.
.getMinute()                          // Extract the minute of the hour of the time-of-day from the `ZonedDateTime` object.

42

ZonedDateTime

Aby uchwycić bieżący moment, jak widać na zegarze ściennym używanym przez mieszkańców określonego regionu (strefy czasowej), użyj ZonedDateTime.

Strefa czasowa ma kluczowe znaczenie przy ustalaniu daty. W dowolnym momencie data różni się na całym świecie według strefy. Na przykład, kilka minut po północy w Paryżu Francja jest nowym dniem, podczas gdy w Montrealu Quebec wciąż trwa „wczoraj” .

Jeśli nie określono strefy czasowej, maszyna JVM niejawnie stosuje swoją bieżącą domyślną strefę czasową. To ustawienie domyślne może się zmienić w dowolnym momencie w trakcie działania (!), Więc wyniki mogą się różnić. Lepiej jest jawnie określić żądaną / oczekiwaną strefę czasową jako argument.

Określ prawidłową nazwę strefy czasowej w formacie continent/region, takie jak America/Montreal, Africa/Casablancalub Pacific/Auckland. Nigdy nie używaj 3-4-literowego skrótu, takiego jak ESTlub, ISTponieważ nie są to prawdziwe strefy czasowe, nie znormalizowane, a nawet nie unikalne (!).

ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ;

Zadzwoń do dowolnego z wielu pobierających, aby wyciągnąć fragmenty daty i czasu.

int    year        = zdt.getYear() ;
int    monthNumber = zdt.getMonthValue() ;
String monthName   = zdt.getMonth().getDisplayName( TextStyle.FULL , Locale.JAPAN ) ;  // Locale determines human language and cultural norms used in localizing. Note that `Locale` has *nothing* to do with time zone.
int    dayOfMonth  = zdt.getDayOfMonth() ;
String dayOfWeek   = zdt.getDayOfWeek().getDisplayName( TextStyle.FULL , Locale.CANADA_FRENCH ) ; 
int    hour        = zdt.getHour() ;  // Extract the hour from the time-of-day.
int    minute      = zdt.getMinute() ;
int    second      = zdt.getSecond() ;
int    nano        = zdt.getNano() ;

W java.time klasy rozwiązania do nanosekund . Twoje pytanie zadawało ułamek sekundy w milisekundach . Oczywiście można podzielić przez milion, aby skrócić nanosekundy do milisekund, kosztem możliwej utraty danych. Lub użyj TimeUnitwyliczenia do takiej konwersji.

long millis = TimeUnit.NANOSECONDS.toMillis( zdt.getNano() ) ;

DateTimeFormatter

Aby utworzyć Stringłączenie fragmentów tekstu, użyj DateTimeFormatterclass. Wyszukaj przepełnienie stosu, aby uzyskać więcej informacji na ten temat.

Instant

Zwykle najlepiej jest śledzić momenty w UTC. Aby dostosować strefową datę i godzinę do UTC, wyodrębnij plik Instant.

Instant instant = zdt.toInstant() ;

I wróć ponownie.

ZonedDateTime zdt = instant.atZone( ZoneId.of( "Africa/Tunis" ) ) ;

LocalDateTime

Kilka innych odpowiedzi korzysta z tej LocalDateTimeklasy. Ta klasa nie jest odpowiednia do celów śledzenia rzeczywistych momentów, określonych momentów na osi czasu, ponieważ celowo nie ma pojęcia strefy czasowej lub przesunięcia względem czasu UTC.

Więc do czego jest LocalDateTimedobre? Użyj, LocalDateTimejeśli zamierzasz zastosować datę i godzinę w dowolnej lokalizacji lub we wszystkich lokalizacjach , a nie tylko w jednej określonej lokalizacji.

Na przykład Boże Narodzenie w tym roku zaczyna się o godz LocalDateTime.parse( "2018-12-25T00:00:00" ). Ta wartość nie ma znaczenia, dopóki nie zastosujesz strefy czasowej (a ZoneId), aby uzyskać ZonedDateTime. Boże Narodzenie przypada najpierw na Kiribati , a później w Nowej Zelandii i dalekowschodniej Azji. Kilka godzin później Boże Narodzenie zaczyna się w Indiach. Jeszcze godzinę później w Afryce i Europie. I nadal Boże Narodzenie w obu Amerykach dopiero kilka godzin później. Boże Narodzenie rozpoczynając w każdym jednym miejscu powinny być reprezentowane ZonedDateTime. Boże Narodzenie wszędzie jest reprezentowane przez LocalDateTime.


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?

Basil Bourque
źródło
2

Lub użyj java.sql.Timestamp. Kalendarz jest ciężki, odradzałbym używanie go w kodzie produkcyjnym. Joda jest lepsza.

import java.sql.Timestamp;

public class DateTest {

    /**
     * @param args
     */
    public static void main(String[] args) {
        System.out.println(new Timestamp(System.currentTimeMillis()));
    }
}
pavel
źródło
Myślę, że źle zrozumiałeś zarówno pytanie, jak i użycie znacznika czasu sql. Normalnie użyłbyś new Date()tutaj. Ale w jaki sposób można łatwo uzyskać z niego oddzielne części, zgodnie z życzeniem?
BalusC
FYI java.sql.Timestampzostał zastąpiony przez java.time.InstantJDBC 4.2.
Basil Bourque,
0

w java 7 Kalendarz jedna linia

new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS").format(Calendar.getInstance().getTime())
Lucke
źródło
1
Uciążliwe klasy Calendar i SimpleDateFormat są teraz przestarzałe i całkowicie zastąpione przez klasy java.time. Zobacz odpowiedź BalusC dotyczącą nowoczesnego podejścia. Znaczna część funkcjonalności java.time jest przenoszona z powrotem do Java 6 i 7 w projekcie ThreeTen-Backport .
Basil Bourque
-2

Zapoznaj się z dokumentacją API dotyczącą klasy java.util.Calendar i jej pochodnych (być może szczególnie zainteresuje Cię klasa GregorianCalendar).

M. Jessup
źródło
FYI, kłopotliwe stare klasy daty i godziny, takie jak java.util.Date, java.util.Calendari java.text.SimpleDateFormatsą teraz starsze , zastępowane przez klasy java.time wbudowane w Javę 8 i nowsze. Zobacz samouczek firmy Oracle .
Basil Bourque
-2

Calendar now = new Calendar () // lub new GregorianCalendar () lub jakikolwiek inny smak, jakiego potrzebujesz

teraz.MIESIĄC teraz.GODZINA

itp.

llappall
źródło
3
Cześć, trudno mi zrozumieć, dlaczego źle powtarzasz już udzieloną odpowiedź. Proszę rozwinąć :)
BalusC
3
MONTHi HOURsą stałymi statycznymi Calendar, a nie właściwościami instancji.
Joseph Earl