Próbuję sformatować datę w Javie na różne sposoby w oparciu o podane ustawienia regionalne. Na przykład chcę, aby użytkownicy angielscy widzieli „1 listopada 2009” (sformatowany jako „d MMM, rrrr”), a użytkownicy norwescy - „1. listopad 2009” („d. MMM. Rrrr”).
Część miesiąca działa dobrze, jeśli dodam ustawienia regionalne do konstruktora SimpleDateFormat, ale co z resztą?
Miałem nadzieję, że uda mi się dodać ciągi formatujące połączone z lokalizacjami do SimpleDateFormat, ale nie mogę znaleźć żadnego sposobu, aby to zrobić. Czy jest to możliwe, czy też muszę pozwolić mojemu kodowi sprawdzić ustawienia regionalne i dodać odpowiedni ciąg formatu?
java
date
locale
simpledateformat
fiskeben
źródło
źródło
java.util.Date
,java.util.Calendar
ijava.text.SimpleDateFormat
są teraz starsze , zastąpione przez klasy java.time wbudowane w Java 8 i Java 9. Zobacz samouczek Oracle .Odpowiedzi:
Użyj DateFormat.getDateInstance (styl int, locale locale) zamiast tworzyć własne wzorce z
SimpleDateFormat
.źródło
java.util.Date
iSimpleDateFormat
są teraz starsze, wyparte przez klasy java.time.SimpleDateFormat dateFormat = new SimpleDateFormat("EEEE dd MMM yyyy", Locale.ENGLISH); String formatted = dateFormat.format(the_date_you_want_here);
źródło
Użyj style + locale : DateFormat.getDateInstance (styl int, locale locale)
Sprawdź http://java.sun.com/j2se/1.5.0/docs/api/java/text/DateFormat.html
Uruchom następujący przykład, aby zobaczyć różnice:
import java.text.DateFormat; import java.util.Date; import java.util.Locale; public class DateFormatDemoSO { public static void main(String args[]) { int style = DateFormat.MEDIUM; //Also try with style = DateFormat.FULL and DateFormat.SHORT Date date = new Date(); DateFormat df; df = DateFormat.getDateInstance(style, Locale.UK); System.out.println("United Kingdom: " + df.format(date)); df = DateFormat.getDateInstance(style, Locale.US); System.out.println("USA: " + df.format(date)); df = DateFormat.getDateInstance(style, Locale.FRANCE); System.out.println("France: " + df.format(date)); df = DateFormat.getDateInstance(style, Locale.ITALY); System.out.println("Italy: " + df.format(date)); df = DateFormat.getDateInstance(style, Locale.JAPAN); System.out.println("Japan: " + df.format(date)); } }
Wynik:
United Kingdom: 25-Sep-2017 USA: Sep 25, 2017 France: 25 sept. 2017 Italy: 25-set-2017 Japan: 2017/09/25
źródło
DateFormat.LONG
iDateFormat.DEFAULT
!java.util.Date
,java.util.Calendar
ijava.text.SimpleDateFormat
są teraz starsze , zastąpione przez klasy java.time wbudowane w Java 8 i Java 9. Zobacz samouczek firmy Oracle .tl; dr
LocalDate.now().format( DateTimeFormatter.ofLocalizedDate( FormatStyle.MEDIUM ) .withLocale( new Locale( "no" , "NO" ) ) )
Kłopotliwego klasy
java.util.Date
iSimpleDateFormat
są teraz Legacy, wyparta przez klasy java.time.LocalDate
LocalDate
Klasa reprezentuje wartość data-tylko bez time-of-day i bez strefy czasowej.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 Paryżu Francja jest nowym dniem, podczas gdy w Montrealu Quebec wciąż trwa „wczoraj” .
ZoneId z = ZoneId.of( "America/Montreal" ); LocalDate today = LocalDate.now( z );
DateTimeFormatter
Służy
DateTimeFormatter
do generowania ciągów reprezentujących tylko część daty lub część czasu.DateTimeFormatter
Klasa może automatycznie zlokalizować .Aby zlokalizować, określ:
FormatStyle
aby określić, jak długi lub jak skrócony powinien być ciąg.Locale
określenie (a) języka ludzkiego do przetłumaczenia nazwy dnia, nazwy miesiąca itp. oraz (b) norm kulturowych decydujących o kwestiach skrótów, wielkich liter, interpunkcji i tym podobnych.Przykład:
Idąc w drugą stronę, możesz przeanalizować zlokalizowany ciąg.
Zwróć uwagę, że ustawienia regionalne i strefa czasowa są całkowicie ortogonalne. Możesz mieć moment z Montrealu przedstawiony w języku japońskim lub moment z Auckland w Nowej Zelandii przedstawiony w języku hindi.
Inny przykład: Zmień
6 junio 2012
(hiszpański) na2012-06-06
(standardowy format ISO 8601 ). Klasy java.time używają domyślnie formatów ISO 8601 do analizowania / generowania ciągów.String input = "6 junio 2012"; Locale l = new Locale ( "es" , "ES" ); DateTimeFormatter f = DateTimeFormatter.ofPattern ( "d MMMM uuuu" , l ); LocalDate ld = LocalDate.parse ( input , f ); String output = ld.toString(); // 2012-06-06.
Przeglądaj formaty
Oto przykładowy kod do przeglądania wyników w wielu formatach w wielu lokalizacjach, automatycznie zlokalizowany.
An
EnumSet
to implementacjaSet
wysoce zoptymalizowana zarówno pod kątem niskiego zużycia pamięci, jak i dużej szybkości wykonywania podczas zbieraniaEnum
obiektów. WięcEnumSet.allOf( FormatStyle.class )
daje nam kolekcję wszystkich czterechFormatStyle
obiektów enum do zapętlenia. Aby uzyskać więcej informacji, zobacz samouczek Oracle dotyczący typów wyliczeń .LocalDate ld = LocalDate.of( 2018 , Month.JANUARY , 23 ); List < Locale > locales = new ArrayList <>( 3 ); locales.add( Locale.CANADA_FRENCH ); locales.add( new Locale( "no" , "NO" ) ); locales.add( Locale.US ); // Or use all locales (almost 800 of them, for about 120K text results). // Locale[] locales = Locale.getAvailableLocales(); // All known locales. Almost 800 of them. for ( Locale locale : locales ) { System.out.println( "------| LOCALE: " + locale + " — " + locale.getDisplayName() + " |----------------------------------" + System.lineSeparator() ); for ( FormatStyle style : EnumSet.allOf( FormatStyle.class ) ) { DateTimeFormatter f = DateTimeFormatter.ofLocalizedDate( style ).withLocale( locale ); String output = ld.format( f ); System.out.println( output ); } System.out.println( "" ); } System.out.println( "« fin »" + System.lineSeparator() );
Wynik.
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
, iSimpleDateFormat
.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?
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 .źródło
Lokalizacja ciągu daty:
Na podstawie postu redsonic:
private String localizeDate(String inputdate, Locale locale) { Date date = new Date(); SimpleDateFormat dateFormatCN = new SimpleDateFormat("dd-MMM-yyyy", locale); SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MMM-yyyy"); try { date = dateFormat.parse(inputdate); } catch (ParseException e) { log.warn("Input date was not correct. Can not localize it."); return inputdate; } return dateFormatCN.format(date); } String localizedDate = localizeDate("05-Sep-2013", new Locale("zh","CN"));
będzie jak 05- 九月 -2013
źródło
Spowoduje to wyświetlenie daty zgodnie z aktualnymi ustawieniami regionalnymi użytkownika :
Aby zwrócić datę i godzinę:
import java.text.DateFormat; import java.util.Date; Date date = new Date(); DateFormat df = DateFormat.getDateTimeInstance(); String myDate = df.format(date);
31 grudnia 1969 19:00:02
Aby zwrócić tylko datę, użyj:
31 grudnia 1969
źródło
Styl Java 8 dla danego dnia
LocalDate today = LocalDate.of(1982, Month.AUGUST, 31); System.out.println(today.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).withLocale(Locale.ENGLISH))); System.out.println(today.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).withLocale(Locale.FRENCH))); System.out.println(today.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).withLocale(Locale.JAPANESE)));
źródło
String text = new SimpleDateFormat("E, MMM d, yyyy").format(date);
źródło
Mam nadzieję, że to komuś pomoże. Znajdź w poniższym kodzie, który akceptuje instancję Locale i zwraca format / wzorzec daty specyficzny dla lokalizacji.
public static String getLocaleDatePattern(Locale locale) { // Validating if Locale instance is null if (locale == null || locale.getLanguage() == null) { return "MM/dd/yyyy"; } // Fetching the locale specific date pattern String localeDatePattern = ((SimpleDateFormat) DateFormat.getDateInstance( DateFormat.SHORT, locale)).toPattern(); // Validating if locale type is having language code for Chinese and country // code for (Hong Kong) with Date Format as - yy'?'M'?'d'?' if (locale.toString().equalsIgnoreCase("zh_hk")) { // Expected application Date Format for Chinese (Hong Kong) locale type return "yyyy'MM'dd"; } // Replacing all d|m|y OR Gy with dd|MM|yyyy as per the locale date pattern localeDatePattern = localeDatePattern.replaceAll("d{1,2}", "dd") .replaceAll("M{1,2}", "MM") .replaceAll("y{1,4}|Gy", "yyyy"); // Replacing all blank spaces in the locale date pattern localeDatePattern = localeDatePattern.replace(" ", ""); // Validating the date pattern length to remove any extract characters if (localeDatePattern.length() > 10) { // Keeping the standard length as expected by the application localeDatePattern = localeDatePattern.substring(0, 10); } return localeDatePattern; }
źródło
Java8
import java.time.format.DateTimeFormatter; myDate.format(DateTimeFormatter.ofPattern("dd-MMM-YYYY",new Locale("ar")))
źródło
ofPattern
z argumentem locale da ci nazwę miesiąca w żądanym języku, ale nie w innych formatach, jak żądano w pytaniu. Używanie wielkich literYYYY
da niepoprawne i bardzo zaskakujące wyniki w przypadkach narożnych. Używanie Java 8 to dobry pomysł.