SimpleDateFormat 및 로케일 기반 형식 문자열


83

주어진 로케일에 따라 다른 방식으로 Java에서 날짜 형식을 지정하려고합니다. 예를 들어 영어 사용자는 "2009 년 11 월 1 일"( "MMM d, yyyy"형식)을, 노르웨이 사용자는 "1. nov. 2009"( "d. MMM. yyyy")를 확인하고 싶습니다.

SimpleDateFormat 생성자에 로케일을 추가하면 월 부분은 정상적으로 작동하지만 나머지는 어떻습니까?

로케일과 쌍을 이루는 형식 문자열을 SimpleDateFormat에 추가 할 수 있기를 바랐지만이를 수행 할 방법을 찾을 수 없습니다. 가능합니까 아니면 내 코드가 로케일을 확인하고 해당 형식 문자열을 추가하도록해야합니까?


1
참고로, 같은 귀찮은 된 날짜 - 시간 수업 java.util.Date, java.util.Calendar그리고 java.text.SimpleDateFormat지금 기존 에 의해 대체, java.time의 자바 8 자바 9 페이지에 내장 된 클래스 튜토리얼 오라클 .
Basil Bourque

답변:


86

를 사용 하여 고유 한 패턴을 만드는 대신 DateFormat.getDateInstance (int style, Locale locale)를 사용합니다 SimpleDateFormat.


1
감사합니다. 정상적으로 작동합니다. 내 요구에 가장 적합한 DateFormat.LONG을 선택했습니다. BTW, 노르웨이어 로케일 및 DateFormat.MEDIUM은 쓰레기 (!)
fiskeben 2009

네 말이 맞아, 노르웨이의 이상한 MEDIUM 패턴은 나에게 결코 발생하지 않았다. 대부분의 다른 로케일과 달리 평일은 FULL 형식에서도 누락되었습니다.
jarnbjo 2009

2
참고로,의 번잡 한 클래스 java.util.DateSimpleDateFormat지금 유산은 java.time 클래스에 의해 대체.
Basil Bourque

88

SimpleDateFormat dateFormat = new SimpleDateFormat("EEEE dd MMM yyyy", Locale.ENGLISH);
String formatted = dateFormat.format(the_date_you_want_here);

29

사용 스타일 + 로케일 : DateFormat.getDateInstance (INT 스타일, 로케일 로케일)

http://java.sun.com/j2se/1.5.0/docs/api/java/text/DateFormat.html 확인

다음 예제를 실행하여 차이점을 확인하십시오.

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));
  }
}

산출:

United Kingdom: 25-Sep-2017
USA: Sep 25, 2017
France: 25 sept. 2017
Italy: 25-set-2017
Japan: 2017/09/25

1
DateFormat.LONGDateFormat.DEFAULT스타일을 잊지 마세요 !
JDJ

6
코드의 출력을 추가하면 더 완료되었을 것입니다
sam

1
스타일과 로케일을 지정하는 올바른 아이디어. 그러나 사용되는 클래스는 이제 구식입니다. 같은 귀찮은 된 날짜 - 시간 수업 java.util.Date, java.util.Calendar그리고 java.text.SimpleDateFormat지금 기존 에 의해 대체, java.time의 자바 8 자바 9 페이지에 내장 된 클래스 튜토리얼 오라클 .
Basil Bourque

15

tl; dr

LocalDate.now().format(
    DateTimeFormatter.ofLocalizedDate( FormatStyle.MEDIUM )
                     .withLocale( new Locale( "no" , "NO" ) )
)

의 번잡 한 클래스 java.util.Date와는 SimpleDateFormat이제 java.time 클래스에 의해 대체 유산이다.

LocalDate

LocalDate클래스는 시간이 하루의 시간 영역없이없이 날짜 만 값을 나타냅니다.

시간대는 날짜를 결정하는 데 중요합니다. 주어진 순간에 날짜는 지역별로 전 세계적으로 다릅니다. 예를 들어, 파리 에서 자정 이후 몇 분이 지나면 프랑스몬트리올 퀘벡 에서는 여전히 '어제'인 새로운 날 입니다.

ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );

DateTimeFormatter

DateTimeFormatter날짜 부분 또는 시간 부분 만 나타내는 문자열을 생성하는 데 사용 합니다.

DateTimeFormatter클래스는 자동으로 할 수 지역화 .

현지화하려면 다음을 지정하십시오.

  • FormatStyle 문자열의 길이 또는 약자를 결정합니다.
  • Locale (a) 요일, 월 이름 등의 번역을위한 인간 언어, (b) 약어, 대문자, 구두점 등의 문제를 결정하는 문화적 규범을 결정합니다.

예:

Locale l = Locale.CANADA_FRENCH ; 
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDate( FormatStyle.FULL ).withLocale( l );
String output = ld.format( f );

다른 방향으로 가면 현지화 된 문자열을 구문 분석 할 수 있습니다.

LocalDate ld = LocalDate.parse( input , f );

로케일과 시간대는 완전히 직교하는 문제입니다. 몬트리올 순간을 일본어로 발표하거나 오클랜드 뉴질랜드 순간을 힌디어로 발표 할 수 있습니다.

또 다른 예 : 6 junio 2012(스페인어)를 2012-06-06(표준 ISO 8601 형식)으로 변경합니다. java.time 클래스는 문자열 구문 분석 / 생성에 기본적으로 ISO 8601 형식을 사용합니다.

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. 

형식 정독

다음은 자동으로 현지화 된 여러 로케일에서 여러 형식의 결과를 정독하는 몇 가지 예제 코드입니다.

An EnumSet은 객체를 Set수집 할 때 낮은 메모리 사용량과 빠른 실행 속도 모두에 최적화 된 의 구현입니다 Enum. 따라서 루프 할 EnumSet.allOf( FormatStyle.class )네 가지 FormatStyle열거 형 개체 의 컬렉션을 모두 제공 합니다. 자세한 내용 은 enum 유형에 대한 Oracle Tutorial을 참조하십시오 .

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() );

산출.

------|  LOCALE: fr_CA — French (Canada)  |----------------------------------

mardi 23 janvier 2018
23 janvier 2018
23 janv. 2018
18-01-23

------|  LOCALE: no_NO — Norwegian (Norway)  |----------------------------------

tirsdag 23. januar 2018
23. januar 2018
23. jan. 2018
23.01.2018

------|  LOCALE: en_US — English (United States)  |----------------------------------

Tuesday, January 23, 2018
January 23, 2018
Jan 23, 2018
1/23/18

« fin »

java.time 정보

java.time의 프레임 워크는 나중에 자바 8에 내장되어 있습니다. 이 클래스는 까다로운 기존에 대신 기존 과 같은 날짜 - 시간의 수업을 java.util.Date, Calendar, SimpleDateFormat.

Joda 타임 프로젝트는 지금에 유지 관리 모드 의로 마이그레이션을 조언 java.time의 클래스.

자세한 내용은 Oracle Tutorial을 참조하십시오 . 그리고 많은 예제와 설명을 위해 Stack Overflow를 검색하십시오. 사양은 JSR 310 입니다.

java.time 객체를 데이터베이스와 직접 교환 할 수 있습니다 . JDBC 4.2 이상을 준수 하는 JDBC 드라이버를 사용하십시오 . 문자열이나 클래스 가 필요하지 않습니다 .java.sql.*

java.time 클래스는 어디서 구할 수 있습니까?

ThreeTen - 추가 프로젝트 추가 클래스와 java.time를 확장합니다. 이 프로젝트는 java.time에 향후 추가 될 수있는 가능성을 입증하는 근거입니다. 당신은 여기에 몇 가지 유용한 클래스와 같은 찾을 수 있습니다 Interval, YearWeek, YearQuarter, 그리고 .


7

날짜 문자열 현지화 :

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"));

2013 년 5 월 5 일


4

사용자의 현재 로케일 에 따라 날짜가 표시 됩니다 .

날짜와 시간을 반환하려면 :

import java.text.DateFormat;    
import java.util.Date;

Date date = new Date();
DateFormat df = DateFormat.getDateTimeInstance();
String myDate = df.format(date);

1969 년 12 월 31 일 오후 7:00:02

날짜 만 반환하려면 다음을 사용하십시오.

DateFormat.getDateInstance() 

1969 년 12 월 31 일


1

주어진 날짜에 대한 Java 8 스타일

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)));

저는 1 년 전에 이런 종류의 솔루션을 다루었 다고 생각 합니다.
Basil Bourque


0

이것이 누군가를 돕기를 바랍니다. 로케일 인스턴스를 허용하고 로케일 특정 날짜 형식 / 패턴을 리턴하는 아래 코드에서 찾으십시오.

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;
}

-2

자바 8

 import java.time.format.DateTimeFormatter;         
 myDate.format(DateTimeFormatter.ofPattern("dd-MMM-YYYY",new Locale("ar")))

ofPattern로케일 인수와 함께 사용 하면 원하는 언어로 월 이름이 제공되지만 질문에서 요청한대로 다른 형식은 제공되지 않습니다. 대문자 YYYY를 사용하면 코너 케이스에서 정확하고 놀라운 결과를 얻을 수 있습니다. Java 8을 사용하는 것이 좋습니다.
Ole VV
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.