местное время в формате Java без года - PullRequest
7 голосов
/ 15 марта 2012

Мне нравится форматировать местный формат времени в строку без года. На данный момент я могу показать локальный формат, содержащий год:

java.text.DateFormat df = java.text.DateFormat.getDateInstance(java.text.DateFormat.SHORT);
String dateString = df.format(date);

поэтому я получаю вывод строки времени как

12.03.2012
03/12/2012

для разных стран. Теперь я хотел бы получить короткую форму, как

12.03.
03/12

как бы мне это сделать?

спасибо за вашу помощь!

Ответы [ 7 ]

13 голосов
/ 15 марта 2012

Вы можете использовать SimpleDateFormat:

Date date = new Date();
java.text.SimpleDateFormat df = new java.text.SimpleDateFormat("MM/dd");
String dateString = df.format(date);

Вывод:

03/15

РЕДАКТИРОВАТЬ:

После дальнейшего изучения форматов локали,и, расширив ответ Петерса, вот код различий между toPattern() и toLocalizedPattern():

import java.text.*
import java.util.*

ArrayList<Locale> locales = new ArrayList<Locale>();
locales.add(Locale.US);
locales.add(Locale.UK);
locales.add(Locale.GERMANY);
locales.add(Locale.CHINA);

Date date = new Date();

for(Locale l : locales)
{
    SimpleDateFormat sdf = (SimpleDateFormat) SimpleDateFormat.getDateInstance(DateFormat.SHORT, l);
    String pattern = sdf.toPattern();
    String localizedPattern = sdf.toLocalizedPattern()
    println "country: " + l.getDisplayName();
    println "pattern: " + pattern;
    println "localizedPattern: " + localizedPattern;

    try {
        SimpleDateFormat temp = new SimpleDateFormat(localizedPattern, l);
        println "localized pattern re-parsed successfully"
    } catch (IllegalArgumentException e) {
        println "localized pattern re-parsed unsuccessfully: " + e.getMessage();
    }
    SimpleDateFormat df = new SimpleDateFormat(pattern, l);
    String dateString = df.format(date);
    println "resulting date: " + dateString
    String yearlessPattern = pattern.replaceAll("\\W?[Yy]+\\W?", "");
    println "yearlessPattern = " + yearlessPattern;
    SimpleDateFormat yearlessSDF = new SimpleDateFormat(yearlessPattern, l);
    println "resulting date without year: " + yearlessSDF.format(date) + "\n";
}

Создает следующий вывод:

country: English (United States)
pattern: M/d/yy
localizedPattern: M/d/yy
localized pattern re-parsed successfully
resulting date: 3/15/12
yearlessPattern = M/d
resulting date without year: 3/15

country: English (United Kingdom)
pattern: dd/MM/yy
localizedPattern: dd/MM/yy
localized pattern re-parsed successfully
resulting date: 15/03/12
yearlessPattern = dd/MM
resulting date without year: 15/03

country: German (Germany)
pattern: dd.MM.yy
localizedPattern: tt.MM.uu
localized pattern re-parsed unsuccessfully: Illegal pattern character 't'
resulting date: 15.03.12
yearlessPattern = dd.MM
resulting date without year: 15.03

country: Chinese (China)
pattern: yy-M-d
localizedPattern: aa-n-j
localized pattern re-parsed unsuccessfully: Illegal pattern character 'n'
resulting date: 12-3-15
yearlessPattern = M-d
resulting date without year: 3-15

Итак, для выводалокализованная дата без года:

String yearlessPattern = DateFormat.getDateInstance(DateFormat.SHORT).toPattern().replaceAll("\\W?[Yy]+\\W?", "");

8 голосов
/ 19 сентября 2012

Мне нужно было преобразовать дату в год удаления строки. Строка должна сохранять настройки локали. Формат даты имеет тип DateFormat.LONG, а не DateFormat.SHORT. Например, полная строка September 18, 2012, а не 09/18/12.

Мое решение (на основе Alex post):

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.regex.Pattern;

public class Test {


private static void testLocaleDates() {
    String fmtString = "%-20s %-25s %-25s %-20s %-20s";
    System.out.println(String.format(fmtString, "Locale", "Complete date", "Pattern", "Yearless date", "Yearless pattern"));
    Pattern regExpPattern = Pattern.compile("Sweden|Spain|Russia|Ukraine|States|France|German|Japan|China", Pattern.CASE_INSENSITIVE);

    for (Locale locale : Locale.getAvailableLocales()) {
        boolean isPrint = regExpPattern.matcher(locale.getDisplayCountry()).find(); 
        if (!isPrint)
            continue;
        Date date = new Date();
        String dateTxt = DateFormat.getDateInstance(DateFormat.LONG, locale).format(date);
        SimpleDateFormat sdf = (SimpleDateFormat) SimpleDateFormat.getDateInstance(DateFormat.LONG, locale);
        String pattern = sdf.toPattern();
        // Checking 'de' we omit problems with Spain locale
        String regExpPatternTxt = pattern.contains("de") ? "[^Mm]*[Yy]+[^Mm]*" : "[^DdMm]*[Yy]+[^DdMm]*";
        String yearlessPattern = pattern.replaceAll(regExpPatternTxt, "");
        SimpleDateFormat yearlessSDF = new SimpleDateFormat(yearlessPattern, locale);

        System.out.println(String.format(fmtString, locale.getDisplayCountry(), dateTxt, pattern, yearlessSDF.format(date), yearlessPattern));
    }
}

public static void main(String[] args) {
    testLocaleDates();
}
}

Вывод программы:

Язык Полная дата Шаблон Годовая дата Годовой образец
Япония 2012/09/18 гггг / мм / дд 09/18 мм / дд
Япония H24.09.18 Гр.мм.дд 09.18 MM.dd
США 18 сентября 2012 г. ММММ д, гггг 18 сентября ММММ д
Испания 18 сентября 2012 года д 'де' ММММ 'года' * гг 18 сентября д 'де' ММММ
США 18 сентября 2012 г. d 'de' MMMM 'de' гггг 18 сентября d 'de' ММММ
Украина 18 вересня 2012 д ММММ гггг 18 вересня д ММММ
Испания 18 / сентябрь / 2012 d '/' ММММ '/' гггг 18 / сентябрь д '/' ММММ
Россия 18 Сентябрь 2012 г. d ММММ гггг 'г.' 18 Сентябрь д ММММ
Китай 2012 年 9 月 18 日 гггг '年' M '月' d '日' 9 月 18 日 М '月' д '日'
Франция 18 сентября 2012 д ММММ гггг 18 сентября Д ММММ
Германия 18. Сентябрь 2012 д. ММММ гггг 18. Сентябрь д. ММММ
Швеция день 18 сентября 2012 года день ММММ гггг день 18 сентября день ММММ

2 голосов
/ 15 марта 2012

Нет предопределенного формата для достижения этой цели.Вот обходной путь: Отформатируйте дату с помощью java.text.DateFormat.SHORT и с помощью специального средства форматирования с форматом yyyy.Теперь ищите результат первого для последнего.

Если год близок к началу, удалите следующую не цифру после года, в противном случае удалите не цифры перед годом.

Но это также не идеально, потому что это дает вам «12,3» вместо «12,3».для немецкого языка.

Если вам действительно нужно сделать все правильно, посмотрите исходный код Java, в частности пакет sun.text.resources в rt.jar и напечатайте все даты локали (вы можете просто создать DateFormatс типом SHORT для всех языков).

Это должно дать вам все данные, необходимые для создания собственного пакета ресурсов со строками формата дня / месяца для всех языков.

1 голос
/ 23 сентября 2016

Другие авторы правильно поняли, что платформа Java не управляет предопределенными шаблонами локализованного формата для комбинации месяца и дня без года, поэтому были предложены сложные обходные пути, такие как использование анализа данных и регулярных выражений.

У меня естьвстроил такие шаблоны формата в мою библиотеку Time4J на основе новейших CLDR-данных.Пример:

AnnualDate now = SystemClock.inLocalView().now(AnnualDate.chronology());
System.out.println("xml-schema: " + now); // --09-23

ChronoFormatter<AnnualDate> fEnglishUS =
    ChronoFormatter.ofStyle(DisplayMode.SHORT, Locale.US, AnnualDate.chronology());
ChronoFormatter<AnnualDate> fFrench =
    ChronoFormatter.ofStyle(DisplayMode.SHORT, Locale.FRENCH, AnnualDate.chronology());
ChronoFormatter<AnnualDate> fGerman =
    ChronoFormatter.ofStyle(DisplayMode.SHORT, Locale.GERMAN, AnnualDate.chronology());
System.out.println("us: " + fEnglishUS.format(now)); // 9/23
System.out.println("french:  " + fFrench.format(now)); // 23/09
System.out.println("german:  " + fGerman.format(now)); // 23.9.

Полезно знать: ICU4J тоже имеет эту возможность, но с гораздо более сложным API.

1 голос
/ 15 марта 2012

Вы можете извлечь шаблон и удалить год.

SimpleDateFormat df = (SimpleDateFormat)
                      DateFormat.getDateInstance(DateFormat.SHORT);
String pattern = df.toLocalizedPattern().replaceAll(".?[Yy].?", "");
System.out.println(pattern);
SimpleDateFormat mdf = new SimpleDateFormat(pattern);

печать

M/d

в моей системе.

0 голосов
/ 23 сентября 2016

java.time.MonthDay

Java предлагает класс для представления такого значения, месяца и дня месяца без какого-либо года: java.time.MonthDay

LocalDate ld = LocalDate.parse( "2012-12-03" );  // December 3rd.
MonthDay md = MonthDay.from( ld );

ISO 8601

Если вы позвоните toString, вы получите строку, сгенерированную в формате, соответствующем стандарту ISO 8601 , --MM-DD.Это расширенный формат, и стандарт также позволяет использовать базовый формат, сводя к минимуму использование разделителей, --MMDD.Ссылка: Раздел 5.2.1.3 Сокращенные представления d) Конкретный день месяца в подразумеваемом году стандарта ISO 8601: 2000.

String output = md.toString();

- 12-03

Пользовательские форматы

Я предлагаю по возможности использовать стандартные форматы.Но если вам необходимо использовать другие форматы, вы можете указать класс DateTimeFormatter.

DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM/dd" );
String output = md.format( f ); 

12/03

JavaКлассы .time обеспечивают автоматическую локализацию значений только для даты и значений даты и времени .К сожалению, нет такой поддержки значений месяца.Таким образом, вам придется явно определить свой собственный формат для желаемой локализации.Для альтернатив см. Ответ Мено Хохшильда .

0 голосов
/ 15 марта 2012

Как вы, вероятно, понимаете, короткие форматы зависят не только от языка, но и от страны.К сожалению, в Java нет таких шаблонов.Вместо этого вам может понадобиться использовать те, которые определены как CLDR - поиск по «шаблону» или «Md» (шаблон месяц / день).

Однако я должен предупредить вас, что эти шаблоныможет быть глючитВместо этого вы можете захотеть переместить их в файл ресурсов и позволить переводчикам разобраться с ними (потребуется соответствующий комментарий о том, что это такое и как с этим обращаться).

...