Czy nie ma wygodnej metody przejścia z pliku java.util.Date do XMLGregorianCalendar?
java
xml
date
xmlgregoriancalendar
prochowiec
źródło
źródło
ZonedDateTime
klasę i nowe metody konwersji dodane do klas starszych. Szczegóły w tej odpowiedzi Ole VVOdpowiedzi:
Chciałbym cofnąć się i spojrzeć nowocześnie na to 10-letnie pytanie. Wymienione klasy
Date
iXMLGregorianCalendar
są już stare. Rzucam wyzwanie ich wykorzystaniu i oferuję alternatywy.Date
był zawsze źle zaprojektowany i ma ponad 20 lat. To proste: nie używaj go.XMLGregorianCalendar
też jest stary i ma staromodny design. Jak rozumiem, był używany do tworzenia dat i godzin w formacie XML dla dokumentów XML. Jak2009-05-07T19:05:45.678+02:00
lub2009-05-07T17:05:45.678Z
. Formaty te są wystarczająco zgodne z ISO 8601, że klasy java.time, nowoczesny interfejs API daty i godziny Java, mogą je wytwarzać, co preferujemy.Nie jest wymagana konwersja
Dla wielu (większości?) Celów współczesnym zamiennikiem
Date
będzieInstant
. JestInstant
momentem w czasie (tak jakDate
jest).Przykładowe dane wyjściowe z tego fragmentu:
Jest taki sam jak drugi z moich
XMLGregorianCalendar
ciągów przykładów powyżej. Jak większość z was wie, pochodzi odInstant.toString
niejawnego wezwaniaSystem.out.println
. Z java.time, w wielu przypadkach nie musimy konwersje, że w dawnych czasach mamy dokonane pomiędzyDate
,Calendar
,XMLGregorianCalendar
i innych klas (w niektórych przypadkach możemy zrobić konwersje potrzebę, choć ja pokazując parę w następnej części) .Kontrolowanie przesunięcia
Ani wejście
Date
aniInstant
nie ma strefy czasowej ani przesunięcia UTC. Poprzednio zaakceptowana i wciąż najwyżej głosowana odpowiedź Bena Nolanda używa bieżącej domyślnej strefy czasowej JVM do wyboru przesunięciaXMLGregorianCalendar
. Aby uwzględnić przesunięcie w nowoczesnym obiekcie, używamyOffsetDateTime
. Na przykład:Ponownie jest to zgodne z formatem XML. Jeśli chcesz ponownie użyć bieżącego ustawienia strefy czasowej JVM, ustaw
zone
naZoneId.systemDefault()
.Co jeśli absolutnie potrzebuję XMLGregorianCalendar?
Istnieje więcej sposobów, aby konwertować
Instant
doXMLGregorianCalendar
. Przedstawię parę, z których każda ma swoje zalety i wady. Po pierwsze, podobnie jakXMLGregorianCalendar
ciąg, taki jak łańcuch2009-05-07T17:05:45.678Z
, można go również zbudować z takiego łańcucha:Pro: jest krótki i nie sądzę, że daje jakieś niespodzianki. Przeciw: Dla mnie to marnotrawstwo formatowania chwili w ciąg i parsowania go z powrotem.
Pro: To oficjalna konwersja. Kontrolowanie przesunięcia przychodzi naturalnie. Przeciw: Przechodzi przez kolejne kroki i dlatego jest dłuższy.
Co jeśli mamy randkę?
Jeśli masz staromodny
Date
obiekt ze starszego interfejsu API, którego nie możesz sobie teraz zmienić, przekonwertuj go naInstant
:Dane wyjściowe są takie same jak poprzednio:
Jeśli chcesz kontrolować przesunięcie, przekonwertuj dalej na
OffsetDateTime
taki sam sposób jak powyżej.Jeśli masz staroświecki
Date
i absolutnie potrzebujesz staromodnegoXMLGregorianCalendar
, skorzystaj z odpowiedzi Bena Nolanda.Spinki do mankietów
źródło
źródło
Dla tych, którzy mogą tu skończyć, szukając odwrotnej konwersji (z
XMLGregorianCalendar
naDate
):źródło
Oto metoda konwersji z GregorianCalendar na XMLGregorianCalendar; Opuszczę część konwersji z java.util.Date na GregorianCalendar jako ćwiczenie dla ciebie:
EDYCJA: Slooow :-)
źródło
Przykład w jednym wierszu z wykorzystaniem biblioteki Joda-Time :
Podziękowania dla Nicolasa Mommaertsa z jego komentarza w zaakceptowanej odpowiedzi .
źródło
Pomyślałem, że dodam moje rozwiązanie poniżej, ponieważ powyższe odpowiedzi nie spełniają moich dokładnych potrzeb. Mój schemat Xml wymagał osobnych elementów daty i godziny, a nie pojedynczego pola daty i godziny. Standardowy konstruktor XMLGregorianCalendar użyty powyżej wygeneruje pole DateTime
Zauważ, że jest kilka gotyckich, na przykład konieczność dodania jednego do miesiąca (ponieważ Java liczy miesiące od 0).
źródło
Mam nadzieję, że moje kodowanie tutaj jest poprawne; D Aby przyspieszyć, po prostu użyj brzydkiego wywołania getInstance () GregorianCalendar zamiast wywołania konstruktora:
źródło
GregorianCalendar.getInstance()
jest odpowiednikiemCalendar.getInstance()
. NieCalendar.getInstance()
może przyspieszyć, ponieważ używa tego samegonew GregorianCalendar()
, ale zanim sprawdzi domyślne ustawienia regionalne i może zamiast tego utworzyć kalendarz japoński lub buddyjski, więc dla niektórych szczęśliwych użytkowników będzieClassCastException
!Zakładając, że dekodujesz lub kodujesz xml i używasz
JAXB
, możliwe jest całkowite zastąpienie powiązania dateTime i użycie czegoś innego niż `XMLGregorianCalendar 'dla każdej daty w schemacie.W ten sposób możesz mieć
JAXB
wykonywać powtarzalne czynności, a jednocześnie poświęcić czas na pisanie niesamowitego kodu, który zapewnia wartość.Przykład dla jodatime
DateTime
: (Robiąc to z java.util.Date również by działało - ale z pewnymi ograniczeniami. Wolę jodatime i jest on kopiowany z mojego kodu, więc wiem, że działa ...)I konwerter:
Zobacz tutaj: jak zastąpić XmlGregorianCalendar według daty?
Jeśli z przyjemnością po prostu mapujesz na chwilę na podstawie strefy czasowej + znacznika czasu, a oryginalna strefa czasowa nie jest tak naprawdę istotna,
java.util.Date
prawdopodobnie również jest w porządku.źródło
Sprawdź ten kod: -
Pełny przykład możesz zobaczyć tutaj
źródło