Jak uzyskać aktualny moment w formacie ISO 8601 z datą, godziną i minutą?

323

Jaki jest najbardziej elegancki sposób uzyskania aktualnego momentu w formacie ISO 8601 , UTC? Powinno to wyglądać tak: 2010-10-12T08:50Z.

Przykład:

String iso8601 = DateFormat.getDateTimeInstance(DateFormat.ISO_8601).format(date);
yegor256
źródło
5
@marcolopes Uwaga: użycie a private static SimpleDateFormatnie jest bezpieczne dla wątków.
vegemite4me
Możliwy duplikat Konwertowania łańcucha zgodnego
Antonio
Podobne do tego drugiego pytania , ale to obcina się na całą sekundę, podczas gdy to pytanie obcina się na całą minutę.
Basil Bourque,

Odpowiedzi:

292

Służy SimpleDateFormatdo formatowania dowolnego Dateobiektu:

TimeZone tz = TimeZone.getTimeZone("UTC");
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'"); // Quoted "Z" to indicate UTC, no timezone offset
df.setTimeZone(tz);
String nowAsISO = df.format(new Date());

Użycie przycisku new Date()jak pokazano powyżej spowoduje sformatowanie bieżącej godziny.

Joachim Sauer
źródło
8
@ Joachim Negatywną stroną tego „standardowego” podejścia jest to, że muszę mieć wiele wystąpień "yyyy-MM-dd'T'HH:mmZ"w mojej aplikacji, za każdym razem, gdy potrzebuję daty w formacie ISO-8601. Z JodaTime, jak widzę, mogę użyć wstępnie zdefiniowanego formatyzatora ISODateTimeFormat, który wykonuje tę pracę za mnie ..
yegor256
8
@Joachim, Zjest prawidłowy wzór w SimpleDateFormat, raczej to zrobić: yyyy-MM-dd'T'HH:mm'Z'.
Buhake Sindi
33
-1 Podaje datę / godzinę w bieżącej strefie czasowej - nie w UTC. Odpowiedź Carlosa zawiera niezbędny kod UTC.
Scott Rippey
16
Właśnie naprawiłem błąd strefy czasowej - ponieważ jest to zaakceptowana odpowiedź, myślę, że to było właściwe.
BoD
2
Z musi być cytowane jak „rrrr-MM-dd'T'HH: mm'Z” ”
Kimball Robinson
224

W systemach, w których domyślną strefą czasową nie jest UTC:

TimeZone tz = TimeZone.getTimeZone("UTC");
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'");
df.setTimeZone(tz);
String nowAsISO = df.format(new Date());

The SimpleDateFormat razie potrzeby instancję można zadeklarować jako stałą globalną, ale należy pamiętać, że ta klasa nie jest bezpieczna dla wątków. Musi być zsynchronizowany, jeśli dostęp do niego prowadzi jednocześnie przez wiele wątków.

EDYCJA: Wolałbym Joda Time, jeśli
wykonuję wiele różnych manipulacji Times / Date ... EDIT2: poprawiony: setTimeZonenie akceptuje ciągu (poprawiony przez Paula)

użytkownik85421
źródło
9
Ten format nie jest stały w żadnej wbudowanej bibliotece?
Daniel Kaplan
Istnieją dwa różne pakiety dla „DateFormat”, pamiętaj, aby użyć „import java.text.DateFormat”
oabarca
3
Jeśli chcesz mieć bieżącą strefę czasową, użyj TimeZone tz = TimeZone.getDefault (); zamiast tego
oabarca
Należy nie zacytować „Z” w formacie ponieważ to sprawia, że logicznie nieistotne. Jeśli strefą czasową jest UTC jak w powyższym przykładzie, wówczas niecytowana Z spowoduje tylko Z na wyjściu ... jednak jeśli strefa czasowa nie jest UTC, wówczas Z będzie nadal wyprowadzane jako literał sugerujący UTC, gdy czas może nie być. Jeśli system konsumujący odczytuje Z jako UTC, ale nie jest to czas, czas zostanie przesunięty. I odwrotnie, jeśli parser używa cytowanego Z bez ustawiania strefy czasowej, będzie analizował czasy UTC jako czasy lokalne (ponownie przesuwając). Ten cytat nie jest potrzebny, jeśli TZ jest ustawiony, ale jest niebezpieczny, jeśli nie jest ustawiony.
Matt Whipple,
@MattWhipple - ale jeśli użyjesz nie cytowanego Z, wynik będzie podobny: 2016-06-14T13:56+0000- pytamy o coś takiego2016-06-14T13:56Z
użytkownik85421
184

Java 8 Native

java.time sprawia, że ​​jest to łatwe od Java 8. I wątek jest bezpieczny.

ZonedDateTime.now( ZoneOffset.UTC ).format( DateTimeFormatter.ISO_INSTANT )

Wynik: 2015-04-14T11:07:36.639Z

Możesz mieć ochotę użyć lżejszych, Temporaltakich jak Instantlub LocalDateTime, ale brakuje im obsługi formatera lub danych strefy czasowej. ZonedDateTimeDziała tylko po wyjęciu z pudełka.

Dostosowując lub łącząc opcje / operacje ZonedDateTime i DateTimeFormatter , możesz łatwo kontrolować strefę czasową i dokładność , do pewnego stopnia:

ZonedDateTime.now( ZoneId.of( "Europe/Paris" ) )
             .truncatedTo( ChronoUnit.MINUTES )
             .format( DateTimeFormatter.ISO_DATE_TIME )

Wynik: 2015-04-14T11:07:00+01:00[Europe/Paris]

Ulepszone wymagania, takie jak usunięcie części sekund, muszą nadal być obsługiwane przez niestandardowe formaty lub niestandardowy proces post.

.format( DateTimeFormatter.ISO_LOCAL_DATE_TIME ) // 2015-04-14T11:07:00
.format( DateTimeFormatter.ISO_LOCAL_DATE ) // 2015-04-14
.format( DateTimeFormatter.ISO_LOCAL_TIME ) // 11:07:00
.format( DateTimeFormatter.ofPattern( "yyyy-MM-dd HH:mm" ) ) // 2015-04-14 11:07

W przypadku Java 6 i 7 można rozważyć użycie portów tylnych java.time, takich jak ThreeTen-Backport , który również ma port Androida . Oba są lżejsze niż Joda i nauczyły się z doświadczenia Jody - zwłaszcza. biorąc pod uwagę, że java.time został zaprojektowany przez autora Jody.

Owcze
źródło
9
Dobra odpowiedź. Zwróć uwagę na dobry zwyczaj jawnego określania strefy czasowej zamiast polegania w sposób dorozumiany na bieżącej domyślnej strefie czasowej JVM. W razie potrzeby możesz określić konkretną strefę czasową , np ZoneId.of( "America/Montreal" ).
Basil Bourque,
1
Instant pozwala sformatować go w formacie ISO 8601, po prostu wywołując metodę .toString ():return DateTimeFormatter.ISO_INSTANT.format(this);
VadymVL,
Jest to najlepsze, ponieważ unikasz wartości domyślnej.
Christophe Roussy
6
Ostrzeżenie: Rozwiązanie dla Java 8 korzystające z ISO_INSTANT ma irytujące dziwactwo. Kiedy milisekundy są równe 0, nie są uwzględniane w danych wyjściowych. Jest to dozwolone zgodnie ze standardem ISO 8601, ale wiele bibliotek i parserów w innych językach nie jest aż tak wybaczających. Jeśli konieczne jest zawsze uwzględnianie zer, użyj tego: DateTimeFormatter ISO_8601 = ofPattern ("rrrr-MM-dd'T'HH: mm: ss.SSSX"). WithZone (UTC);
jurgen
Po przejściu z Javy 8 na 11 widzę DateTimeFormatter.ISO_INSTANTi DateTimeFormatter.ISO_DATE_TIMEużywam 6 cyfr po sekundach, w przeciwieństwie do 3, które nie są już odbierane przez Springa @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME).
DanielM
126

Java 8:

thisMoment = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mmX")
                              .withZone(ZoneOffset.UTC)
                              .format(Instant.now());

Przed Java 8:

thisMoment = String.format("%tFT%<tRZ",
                           Calendar.getInstance(TimeZone.getTimeZone("Z")));

Z dokumentów :

'R'    Czas sformatowany dla zegara 24-godzinnego jako „% tH:% tM”
'F'    ISO 8601 pełna data sformatowana jako „% tY-% tm-% td”.

aioobe
źródło
26
Cóż, albo dołączasz dodatkową bibliotekę strony trzeciej jako zależność od swojego projektu (którą możesz chcieć być na bieżąco i dostarczasz z aplikacją, hej, to tylko dodatkowe 3,2 megabajta) i robisz DateTime dt = new DateTime(); DateTimeFormatter fmt = ISODateTimeFormat.dateTime(); String str = fmt.print(dt);, albo kapsułkujesz return String.format("%tFT%<tRZ", new Date());do klasy i rób str = Iso8601Time.now(), gdziekolwiek tego potrzebujesz. (To nie tak, że format ISO się zmieni.) Jeśli okaże się, że potrzebujesz czegoś więcej niż tylko bieżącej daty w formacie ISO, użyj lib.
aioobe,
2
Całkowicie się z tym zgadzam.
yegor256
3
Należy pamiętać, że można zmienić, która odpowiedź jest oznaczona jako zaakceptowana ;-)
aioobe
8
%tFT%<tTZbędzie zawierać sekundy; %tFT%<tTZ.%<tLobejmie milisekundy.
Patrick Linskey,
2
Bardzo fajne rozwiązanie, powinna już być przyjęta odpowiedź :)
AbdelHady
94

Od wersji Java 8 możesz po prostu:

Instant.now().toString();

Z java.time.Instantdokumentów:

teraz

public static Instant now()

Uzyskuje bieżącą chwilę z zegara systemowego.

Spowoduje to wysłanie zapytania do systemowego zegara UTC w celu uzyskania bieżącej chwili.

 


public String toString()

Reprezentacja ciągu tej chwili przy użyciu reprezentacji ISO-8601.

Używany format jest taki sam jak DateTimeFormatter.ISO_INSTANT.

Владимир Зайцев
źródło
11
To właściwa odpowiedź i to skandal, że nie był wyżej oceniany nad tymi wszystkimi wymyślonymi SimpleDateFormats.
David Moles,
Cieszę się, że czytam więcej odpowiedzi. Zgadzam się, to powinna być odpowiedź teraz.
Xan-Kun Clark-Davis
A ponieważ tak jest toString, w wielu przypadkach nie trzeba nawet wyraźnie nazywać tego.
kaya3
1
Dotyczy to również komentarza do poprzedniej odpowiedzi: „Ostrzeżenie: Rozwiązanie dla Java 8 przy użyciu ISO_INSTANT ma irytujące dziwactwo. Gdy milisekundy wynoszą 0, nie są uwzględniane w danych wyjściowych. Jest to dozwolone zgodnie z ISO 8601 standardowe, ale wiele bibliotek i parserów w innych językach nie jest aż tak wybaczających ”.
Dave L.
27

użyj JodaTime

System kalendarza ISO 8601 jest domyślną implementacją w Joda-Time

Tutaj dokument dla JodaTime Formatter

Edytować:

Jeśli nie chcesz dodawać lub nie widzisz wartości dodawania powyżej biblioteki, możesz po prostu użyć wbudowanej SimpleDateFormat klasy, aby sformatować datę na wymagany format ISO

zgodnie z sugestią @Joachim Sauer

DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mmZ");
String nowAsString = df.format(new Date());
Jigar Joshi
źródło
3
A w jaki sposób stworzyłbyś napis sformatowany jak pokazano w pytaniu?
Joachim Sauer,
4
Powiedziałbym, że nie dodawaj zależności biblioteki do czegoś tak prostego jak to (co można osiągnąć za pomocą dwóch wierszy kodu java). (Pewnie, jeśli wymagania
wzrosną
1
@ aioobe, jeśli jest używany tylko w kilku częściach aplikacji, to jest w porządku, aby przejść do domyślnych, w pozostałych przypadkach jodatime jest lepszy.
Jigar Joshi
5
@aioobe jodatime jest w każdym razie lepszy, ponieważ ma ISODateTimeFormat- predefiniowany formatator ISO-8601.
yegor256,
3
@ org.life.java: są istotne tylko wtedy, gdy można poprawnie przełączyć na czas Jode. Nie będziesz ich mieć, jeśli użyjesz tylko tej funkcji czasu Jody.
Joachim Sauer,
20

DateFormatUtils z Apache commons-lang3mają przydatne stałe, na przykład:DateFormatUtils.ISO_DATETIME_FORMAT

yegor256
źródło
3
Dokładniej, aktualny moment w UTC: DateFormatUtils.format(new Date(), "yyyy-MM-dd'T'HH:mm'Z'", TimeZone.getTimeZone("UTC"));aktualny moment w domyślnej strefie czasowej DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format(new Date()):; @ yegor256 dzięki za wzmiankę DateFormatUtils, mając na pokładzie apache commons-lang warto użyć formatu daty.
babinik
19

Jeśli nie chcesz dołączać Jodatime (choć jest to tak miłe)

javax.xml.bind.DatatypeConverter.printDateTime(
    Calendar.getInstance(TimeZone.getTimeZone("UTC"))
);

który zwraca ciąg:

2012-07-10T16:02:48.440Z

co nieco różni się od pierwotnego żądania, ale nadal jest ISO-8601.

Matthew Buckett
źródło
10

Joda-Time

Aktualizacja: Projekt Joda-Time jest teraz w trybie konserwacji , a zespół doradza migrację do klas java.time . W przypadku Java 6 i 7 zobacz projekt ThreeTen-Backport , dodatkowo dostosowany do systemu Android w projekcie ThreeTenABP .

Korzystanie z biblioteki Joda-Time

String output = new DateTime( DateTimeZone.UTC ).toString() ;

Jest to bezpieczne dla wątków. Joda-Time tworzy nowe niezmienne obiekty zamiast zmieniać istniejące.

Jeśli naprawdę chciałeś poprosić o format bez sekund, przeliczając na minuty, użyj jednego z wielu innych wbudowanych formatów w Joda-Time.

DateTime now = new DateTime( DateTimeZone.UTC ) ;
String output = ISODateTimeFormat.dateHourMinute.print( now ) ;

java.time

W przypadku Javy 8 i nowszych Joda-Time nadal działa. Ale wbudowany czas java.time framework zastępuje Joda-Time. Więc migruj swój kod z Joda-Time do java.time, gdy tylko będzie to wygodne.

Zobacz moje inne Odpowiedzi na nowoczesne rozwiązanie.


O java.time

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

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

Aby dowiedzieć się więcej, zobacz samouczek Oracle . I przeszukaj stos przepełnienia dla wielu 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 potrzeba ciągów, nie ma potrzeby java.sql.*klas.

Gdzie można uzyskać klasy java.time?

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
7

Dla wersji Java 7

Możesz śledzić dokumentację Oracle: http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html

X - jest używany dla strefy czasowej ISO 8601

TimeZone tz = TimeZone.getTimeZone("UTC");
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
df.setTimeZone(tz);
String nowAsISO = df.format(new Date());

System.out.println(nowAsISO);

DateFormat df1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
//nowAsISO = "2013-05-31T00:00:00Z";
Date finalResult = df1.parse(nowAsISO);

System.out.println(finalResult);
d.danailov
źródło
5

Możesz użyć SimpleDateFormat Java z następującym wzorcem yyyy-MM-dd'T'HH:mm:ssXXXdla ISO 8601.

Przykładowy kod: (wymienia dla wszystkich dostępnych stref czasowych)

for (String timeZone : TimeZone.getAvailableIDs())
{
    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
    dateFormat.setTimeZone(TimeZone.getTimeZone(timeZone));
    String formatted = dateFormat.format(new Date());
    System.out.print(formatted);

    if (formatted.endsWith("Z"))
    {
        // These time zone's have offset of '0' from GMT.
        System.out.print("\t(" + timeZone + ")");
    }

    System.out.println();
}

Możesz użyć:

TimeZone.getDefault ()

dla domyślnej strefy czasowej vm. Więcej tutaj

Możesz zauważyć datę i godzinę dla kilku stref czasowych, które się kończą 'Z'. Te strefy czasowe mają przesunięcie względem '0'GMT.

Więcej informacji można znaleźć tutaj .

always_a_rookie_to_learn
źródło
5

Wierzę, że najłatwiej jest najpierw przejść do instant, a następnie napisać:

String d = new Date().toInstant().toString();

Co spowoduje:

2017-09-08T12:56:45.331Z

Tuncay Göncüoğlu
źródło
4
Jeśli chcesz mieć aktualny czas, nie musisz przechodzić przez staromodny Dateobiekt. Po prostu zrób Instant.now().toString(). Jeśli masz starszą Datewersję interfejsu API, Twoja metoda jest najlepsza.
Ole VV,
Jak skomentował Ole VV, kłopotliwe stare klasy daty i czasu, takie jak java.util.Date, java.util.Calendari java.text.SimpleDateFormatsą teraz spuścizną , wyparte przez klasy java.time wbudowane w Javę 8 i nowsze wersje . Zobacz samouczek Oracle .
Basil Bourque,
5

tl; dr

Niektóre inne odpowiedzi są prawidłowe w polecaniu klas java.time , ale używają niepotrzebnych długości do konkretnych potrzeb.

Instant.now()                               // Capture the current moment in UTC with a resolution as fines nanoseconds but usually in microseconds or milliseconds.
       .truncatedTo( ChronoUnit.MINUTES )   // Lop off any seconds or fractional second, to get a value in whole minutes.
       .toString()                          // Generate a String in standard ISO 8601 format where a `T` separates the year-month-day from the hour-minute-second, and the `Z` on the end for “Zulu” means UTC.

2018-01-23T12: 34Z

Instant::toString

jav.time.InstantKlasa reprezentuje moment w UTC, zawsze w UTC.

Instant instant = Instant.now() ;

instant.toString (): 2018-01-23T12: 34: 56.123456Z

Na Zkońcu przykładowego łańcucha 2010-10-12T08:50Zjest wymawiane „Zulu” i oznacza UTC .

Wybrany format jest zgodny z normą ISO 8601 . W java.time klas użyć tych standardowych formatów domyślnie podczas parsowania / generowania ciągów. Nie trzeba więc określać wzorca formatowania. ZadzwońInstant::toString jak pokazano powyżej.

Jeśli chcesz całe minuty bez sekundy lub ułamka sekundy, skróć. Określ jednostkę czasu za pomocą ChronoUnitklasy.

Instant instant = Instant.now().truncatedTo( ChronoUnit.MINUTES ) ;
String output = instant.toString();  // Generate a `String` object in standard ISO 8601 format.

O java.time

Środowisko java.time jest wbudowane w Javę 8 i nowsze wersje . Klasy te zastępują kłopotliwe starsze klasowe daty i godziny, takie jak java.util.Date:Calendar , iSimpleDateFormat.

Projekt Joda-Time , teraz w trybie konserwacji , zaleca migrację do java.timeklas .

Aby dowiedzieć się więcej, zobacz samouczek Oracle . I przeszukaj stos przepełnienia dla wielu 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 potrzeba ciągów, nie ma potrzeby java.sql.*klas.

Gdzie można uzyskać klasy java.time?

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
2

Oto cała klasa zoptymalizowana tak, że wywołanie „now ()” nie robi nic więcej niż musi.

public class Iso8601Util
{
    private static TimeZone tz = TimeZone.getTimeZone("UTC");
    private static DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'");

    static
    {
        df.setTimeZone(tz);
    }

    public static String now()
    {
        return df.format(new Date());
    }
}
Gilbertpilz
źródło
9
Ustawienie statyczne może powodować problemy, ponieważ SimpleDateFormat nie jest bezpieczny dla wątków: „Formaty daty nie są zsynchronizowane. Zalecane jest utworzenie osobnych instancji formatu dla każdego wątku. Jeśli wiele wątków jednocześnie uzyskuje dostęp do formatu, musi zostać zsynchronizowany zewnętrznie”. docs.oracle.com/javase/7/docs/api/java/text/…
Juha Palomäki
2
Jak wspomniał @Juha Palomäki, nie jest to bezpieczne dla wątków. Jeśli używasz języka Java 8 lub nowszego, ThreadLocal.withInitial może to naprawić. Jeśli używasz Java 7 lub
starszej wersji
@ user393274 - jeśli używasz Java 8, powinieneś użyć Instant, DateTimeFormata drugi nowoczesny bezpieczny wątek zamienniki
Jestem trochę zdziwiony tym, na czym polega problem z tym, że SimpleDateFormat nie jest bezpieczny dla wątków. Jeśli dwa wątki wykonują inicjalizator statyczny w tym samym czasie, nie widzę nic gorszego niż konstruktor SimpleDateFormat jest wywoływany dwukrotnie, ale tylko jedna chwila (ostatnia do końca) jest rejestrowana jako „df”.
gilbertpilz
2
private static String getCurrentDateIso()
{
    // Returns the current date with the same format as Javascript's new Date().toJSON(), ISO 8601
    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US);
    dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
    return dateFormat.format(new Date());
}
cprcrack
źródło
1

Mimo to joda-time obsługuje tylko rozszerzony format: „2015-12-09T00: 22: 42.930Z”, a nie podstawowy: „20151209T002242.930Z” ... może lepiej byłoby przetestować listę formatów za pomocą Java SimpleDateFormat.

joão tiago viegas
źródło
1

Zrobiłem to w Androidzie za pomocą Kalendarza i SimpleDateFormat. Poniższa metoda zwraca kalendarz z strefą czasową „GMT” (jest to uniwersalna strefa czasowa). Następnie możesz użyć klasy Calendar, aby ustawić godzinę między różnymi strefami czasowymi, używając metody setTimeZone () klasy Calendar.

private static final String GMT = "GMT";
private static final String DATE_FORMAT_ISO = "yyyyMMdd'T'HHmmss";

public static Calendar isoToCalendar(final String inputDate) {
    Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone(GMT));
    try {
        SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT_ISO, Locale.US);
        dateFormat.setTimeZone(TimeZone.getTimeZone(GMT));
        Date date = dateFormat.parse(inputDate);
        calendar.setTime(date);
    } catch (ParseException e) {
        Log.e("TAG",e.getMessage());
    }
    return calendar;
}

PAMIĘTAJ: Klasa Date nie wie o istnieniu TimeZone. Z tego powodu, jeśli debugujesz jedną datę, zawsze widzisz datę swojej bieżącej strefy czasowej.

Gerardo Suarez
źródło
1

Jeśli zależy Ci na wydajności, stworzyłem bibliotekę, która przewyższa standardowy parser Java i formatator w manipulowaniu datami sformatowanymi w ISO8601. Implementacje DatetimeProcessor są bezpieczne dla wątków i mogą być buforowane w równoległej mapie lub polach statycznych.

<dependency>
  <groupId>com.axibase</groupId>
  <artifactId>date-processor</artifactId>
  <version>1.0.3</version>
</dependency>
import com.axibase.date.DatetimeProcessor;
import com.axibase.date.PatternResolver;
import org.junit.Before;
import org.junit.Test;

import java.time.Clock;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZoneOffset;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;

public class DateFormatTest {
    private Clock clock;

    @Before
    public void prepare() {
        clock = Clock.fixed(Instant.ofEpochMilli(1571285405300L), ZoneId.of("Europe/Berlin"));
    }

    @Test
    public void testIsoMillis(){
        final DatetimeProcessor formatter = PatternResolver.createNewFormatter("iso");
        assertThat(formatter.print(clock.millis(), ZoneOffset.UTC), is("2019-10-17T04:10:05.300Z"));
    }

    @Test
    public void testIsoMillisLocalZone(){
        final DatetimeProcessor formatter = PatternResolver.createNewFormatter("iso");
        assertThat(formatter.print(clock.millis(), clock.getZone()), is("2019-10-17T06:10:05.300+02:00"));
    }

    @Test
    public void testIsoMinutes(){
        final DatetimeProcessor formatter = PatternResolver.createNewFormatter("yyyy-MM-ddTHH:mmXXX");
        assertThat(formatter.print(clock.millis(), ZoneOffset.UTC), is("2019-10-17T04:10Z"));
    }
}
Anton Rybochkin
źródło
0

Powinni byli dodać jakąś prostą metodę przejścia z Date na Instant, a także metodę o nazwie toISO8601, której szuka wielu ludzi. Jako uzupełnienie innych odpowiedzi, od java.util.Date do formatu ISO 8601:

Instant.ofEpochMilli(date.getTime()).toString();

Nie jest to tak naprawdę widoczne przy korzystaniu z autouzupełniania, ale java.time.Instant.toString():

Ciąg znaków tej chwili przy użyciu ISO-8601

Christophe Roussy
źródło
0
DateTimeFormatter.ISO_DATE_TIME
        .withZone(ZoneOffset.UTC)
        .format(yourDateObject.toInstant())
długopis
źródło
Chociaż ten kod może odpowiedzieć na pytanie, zapewnienie dodatkowego kontekstu dotyczącego tego, dlaczego i / lub jak ten kod odpowiada na pytanie, poprawia jego długoterminową wartość.
Vishal Chhodwani
-2

Spróbuj tego,

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSSSZ");
        String date=sdf.format (new Date() );

Jest w formacie ISO 8601

Surej
źródło
2
This would use dates in the wrong time zone, see answer by Carlos.
Stian Soiland-Reyes