Sprievodca SimpleDateFormat

1. Úvod

V tomto výučbe sa budeme venovať hĺbková prehliadka SimpleDateFormat trieda.

Pozrime sa na to jednoduchá inštanciaa štýly formátovania ako aj užitočné metódy, ktorým trieda vystavuje spracovanie miestnych a časových pásiem.

2. Jednoduché vytvorenie inštancie

Najprv sa pozrime, ako vytvoriť nový SimpleDateFormat objekt.

Existujú 4 možné konštruktory - ale v súlade s menom urobme veci jednoduché. Všetko, čo potrebujeme, aby sme mohli začať, je String reprezentácia požadovaného vzoru dátumu.

Začneme vzorom dátumu oddeleným pomlčkou, napríklad takto:

„dd-MM-rrrr“

Týmto sa správne naformátuje dátum začínajúci aktuálnym dňom v mesiaci, aktuálnym mesiacom v roku a nakoniec aktuálnym rokom. Náš nový formátovač môžeme otestovať jednoduchým testom jednotky. Vytvoríme novú inštanciu SimpleDateFormat objekt a odovzdať v známom dátume:

SimpleDateFormat formatter = nový SimpleDateFormat ("dd-MM-rrrr"); assertEquals ("24-05-1977", formatter.format (nový dátum (233345223232L))); 

Vo vyššie uvedenom kóde je formátovač prevádza milisekundy ako long do dátumu čitateľného pre človeka - 24. mája 1977.

2.1. Továrenské metódy

Hoci SimpleDateFormat je šikovná trieda na rýchle zostavenie formátovača dátumov, sa odporúča používať továrenské metódy na serveri Formát dátumu triedagetDateFormat (), getDateTimeFormat (), getTimeFormat ().

Vyššie uvedený príklad vyzerá trochu inak pri použití týchto továrenských metód:

DateFormat formatter = DateFormat.getDateInstance (DateFormat.SHORT); assertEquals ("24.5. 77", formatter.format (nový dátum (233345223232L)));

Ako je zrejmé z vyššie uvedeného, ​​počet možností formátovania je vopred určený poľami na Formát dátumu trieda. Toto do značnej miery obmedzuje naše dostupné možnosti formátovania a preto sa budeme držať SimpleDateFormat v tomto článku.

2.2. Bezpečnosť závitov

JavaDoc pre SimpleDateFormat výslovne uvádza:

Formáty dátumu sa nesynchronizujú. Odporúča sa vytvoriť samostatné inštancie formátu pre každé vlákno. Ak viac vlákien pristupuje k formátu súčasne, musí sa externe synchronizovať.

Takže SimpleDateFormat inštancie nie sú bezpečné pre vláknaa mali by sme ich opatrne používať v súbežných prostrediach.

Najlepší prístup k vyriešeniu tohto problémuje použiť ich v kombinácii s a ThreadLocal. Takto každé vlákno končí svojim vlastným SimpleDateFormat a nedostatok zdieľania robí program bezpečným pre vlákna:

private final ThreadLocal formatter = ThreadLocal .withInitial (() -> new SimpleDateFormat ("dd-MM-rrrr"));

Argument pre withInitial metóda je dodávateľom SimpleDateFormat inštancie. Zakaždým, keď ThreadLocal potrebuje vytvoriť inštanciu, použije tohto dodávateľa.

Potom môžeme použiť formátovač pomocou ThreadLocal inštancia:

formatter.get (). format (date)

The ThreadLocal.get () metóda inicializuje SimpleDateFormat najskôr pre aktuálne vlákno a potom túto inštanciu znova použije.

Hovoríme tomu technika uväznenie nití pretože obmedzujeme použitie každej inštancie na jedno konkrétne vlákno.

Existujú dva ďalšie prístupy k riešeniu rovnakého problému:

  • Použitím synchronizované bloky alebo ReentrantLocks
  • Vytvára sa vyhodenie inštancií SimpleDateFormat na požiadanie

Oba tieto prístupy sa neodporúčajú: Prvý spôsobí výrazný výkonnostný zásah, keď je tvrdenie vysoké, a druhý vytvorí veľa objektov, čím vytvorí tlak na odvoz odpadu.

Za zmienku stojí, od Java 8, nový DateTimeFormatter triedy. Nové DateTimeFormatter trieda je nemenné a bezpečné pre vlákna. Ak pracujeme s jazykom Java 8 alebo novším, používame nový DateTimeFormatter triedy sa odporúča.

3. Analýza dátumov

SimpleDateFormat a Formát dátumu nielenže nám umožňujú formátovať dátumy, ale môžeme operáciu aj obrátiť. Pomocou analyzovať metóda, môžeme zadajte String reprezentácia dátumu a vrátenie Dátum ekvivalent objektu:

SimpleDateFormat formatter = nový SimpleDateFormat ("dd-MM-rrrr"); Dátum myDate = nový dátum (233276400000L); Dátum parsedDate = formatter.parse ("24-05-1977"); assertEquals (myDate.getTime (), parsedDate.getTime ());

Je dôležité si tu uvedomiť, že vzor dodaný v konštruktore by mal mať rovnaký formát ako analyzovaný dátum pomocou analyzovať metóda.

4. Vzory dátumu a času

SimpleDateFormat poskytuje pri formátovaní dátumov obrovské množstvo rôznych možností. Aj keď je celý zoznam k dispozícii v dokumente JavaDocs, poďme preskúmať niektoré z bežne používaných možností:

ListZložka dátumuPríklad
MMesiac12; Dec
rrok94
ddeň23; Pon
Hhodinu03
mminútu57

The výstup vrátený komponentom dátumu tiež veľmi závisí od počtu použitých znakov v rámci String. Vezmime si napríklad mesiac jún. Ak definujeme reťazec dátumu ako:

„MM“

Potom sa náš výsledok zobrazí ako číselný kód - 06. Ak však do nášho reťazca s dátumom pridáme ďalšie M:

„MMM“

Výsledný formátovaný dátum sa potom zobrazí ako slovo Jún.

5. Aplikácia miestnych nastavení

The SimpleDateFormat trieda tiež podporuje širokú škálu miestnych nastavení ktorá sa nastaví, keď sa volá konštruktor.

Urobíme to v praxi formátovaním dátumu vo francúzštine. Vytvoríme inštanciu a SimpleDateFormat predmet pri dodávaní Locale.FRANCE konštruktérovi.

SimpleDateFormat franceDateFormatter = nový SimpleDateFormat ("EEEEE dd-MMMMMMM-rrrr", Locale.FRANCE); Dátum myWednesday = nový dátum (1539341312904L); assertTrue (franceDateFormatter.format (myWednesday) .startsWith ("vendredi"));

Zadaním daného dátumu, v stredu popoludní, môžeme tvrdiť, že náš franceDateFormatter má správne naformátovaný dátum. Nový dátum sa správne začína na Vendredi -Francúzština na stredu!

Stojí za zmienku trochu gotcha v Locale verzii konštruktora - aj keď je podporovaných veľa miestnych nastavení, nie je zaručené úplné pokrytie. Spoločnosť Oracle odporúča používať výrobné metódy na Formát dátumu triedy, aby sa zabezpečilo miestne pokrytie.

6. Zmena časových pásiem

Odkedy SimpleDateFormat rozširuje Formát dátumu triedy, môžeme tiež manipulovať s časovým pásmom pomocou setTimeZone metóda. Poďme sa na to pozrieť v akcii:

Dátum teraz = nový Dátum (); SimpleDateFormat simpleDateFormat = nový SimpleDateFormat ("EEEE dd-MMM-rr HH: mm: ssZ"); simpleDateFormat.setTimeZone (TimeZone.getTimeZone ("Európa / Londýn")); logger.info (simpleDateFormat.format (teraz)); simpleDateFormat.setTimeZone (TimeZone.getTimeZone ("Amerika / New_York")); logger.info (simpleDateFormat.format (teraz));

Vo vyššie uvedenom príklade dodávame to isté Dátum do dvoch rôznych časových pásiem SimpleDateFormat objekt. Pridali sme tiež Znak „Z“ na koniec vzoru String na označenie rozdielov v časovom pásme. Výstup z formát používateľovi sa potom zaznamená metóda.

Po spustení môžeme vidieť súčasné časy vo vzťahu k dvom časovým pásmam:

INFO: Piatok 12. októbra-18 12:46:14 + 0100 INFO: Piatok 12. októbra-18 07:46: 14-0400

7. Zhrnutie

V tomto tutoriáli sme sa hlboko ponorili do zložitostí SimpleDateFormat.

Pozreli sme sa, ako na to vytvoriť inštanciu SimpleDateFormat ako aj ako vzor String má vplyv na formátovanie dátumu.

Hrali sme sa s zmena miestnych nastavení výstupu String predtým, ako budete konečne experimentovať s pomocou časových pásiem.

Celý zdrojový kód ako vždy nájdete na GitHub.


$config[zx-auto] not found$config[zx-overlay] not found