Формат даты без года - PullRequest
       8

Формат даты без года

28 голосов
/ 25 сентября 2010

Как создать текстовое представление некоторой даты, которая учитывает локаль и содержит только день и месяц (без года)?

Следующий код дает мне что-то вроде 23/ 09/2010

DateFormat.getDateInstance(DateFormat.SHORT, Locale.getDefault()).format(date);

Хочу получить 23/09

Ответы [ 10 ]

44 голосов
/ 26 апреля 2014

Это будет работать для Android , если кому-то это нужно:

int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NO_YEAR;
String monthAndDayText = DateUtils.formatDateTime(context, date, flags);
23 голосов
/ 25 сентября 2010

Вы можете использовать регулярные выражения, чтобы обрезать все y и любые не алфавитные символы до и после, если таковые имеются. Вот пример начала:

public static void main(String[] args) throws Exception {
    for (Locale locale : Locale.getAvailableLocales()) {
        DateFormat df = getShortDateInstanceWithoutYears(locale);
        System.out.println(locale + ": " + df.format(new Date()));      
    }
}

public static DateFormat getShortDateInstanceWithoutYears(Locale locale) {
    SimpleDateFormat sdf = (SimpleDateFormat) DateFormat.getDateInstance(DateFormat.SHORT, locale);
    sdf.applyPattern(sdf.toPattern().replaceAll("[^\\p{Alpha}]*y+[^\\p{Alpha}]*", ""));
    return sdf;
}

Вы видите, что этот фрагмент также тестирует его для всех локалей. Здесь все работает нормально.

8 голосов
/ 24 декабря 2012

Просто хотел внести еще одну модификацию, удалив год из шаблона, что хорошо работает для DateFormat.MEDIUM, даже в таких локалях, как pt_PT (d 'de' MMM 'de' yyyy) или lv_LV (y. 'Gada' d. МММ).

public static DateFormat getMediumDateInstanceWithoutYears()
 {
   SimpleDateFormat sdf = (SimpleDateFormat) DateFormat.getDateInstance(DateFormat.MEDIUM);
   sdf.applyPattern(sdf.toPattern().replaceAll(
       "([^\\p{Alpha}']|('[\\p{Alpha}]+'))*y+([^\\p{Alpha}']|('[\\p{Alpha}]+'))*",
       ""));
   return sdf;
 }
4 голосов
/ 19 марта 2013

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

Locale[] locales = SimpleDateFormat.getAvailableLocales();
for (int i = 0; i < locales.length; i++) {
    Locale locale = locales[i];
    DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.FULL, locale);
}

, а затем вручную удаляю часть года.Он возвращает два варианта формата даты, обычный и сокращенный, т.е. понедельник, 18 марта, против понедельника, 18 марта.

public class DateFormatWithoutYear {

    private static Map<String, String> formats = new HashMap<String, String>();
    private static String DEFAULT_FORMAT = "EEEE, d MMMM";
    static {
        formats.put("_af", "EEEE dd MMMM");
        formats.put("_am", "EEEE, d MMMM");
        formats.put("_az", "EEEE, d, MMMM");
        formats.put("_be", "EEEE, d MMMM");
        formats.put("_bg", "dd MMMM, EEEE");
        formats.put("BG_bg", "dd MMMM, EEEE");
        formats.put("_ca", "EEEE d MMMM");
        formats.put("ES_ca", "EEEE d MMMM");
        formats.put("_cs", "EEEE, d. MMMM");
        formats.put("CZ_cs", "EEEE, d. MMMM");
        formats.put("_da", "EEEE 'den' d. MMMM");
        formats.put("DK_da", "EEEE 'den' d. MMMM");
        formats.put("_de", "EEEE, d. MMMM");
        formats.put("AT_de", "EEEE, dd. MMMM");
        formats.put("BE_de", "EEEE, d. MMMM");
        formats.put("CH_de", "EEEE, d. MMMM");
        formats.put("DE_de", "EEEE, d. MMMM");
        formats.put("LI_de", "EEEE, d. MMMM");
        formats.put("LU_de", "EEEE, d. MMMM");
        formats.put("_el", "EEEE, d MMMM");
        formats.put("GR_el", "EEEE, d MMMM");
        formats.put("_en", "EEEE, MMMM d");
        formats.put("AU_en", "EEEE, d MMMM");
        formats.put("BE_en", "EEEE d MMMM");
        formats.put("BW_en", "EEEE dd MMMM");
        formats.put("BZ_en", "EEEE, MMMM d");
        formats.put("CA_en", "EEEE, d MMMM");
        formats.put("GB_en", "EEEE, d MMMM");
        formats.put("HK_en", "EEEE, d MMMM");
        formats.put("IE_en", "EEEE d MMMM");
        formats.put("IN_en", "EEEE d MMMM");
        formats.put("JM_en", "EEEE, MMMM d");
        formats.put("MH_en", "EEEE, MMMM d");
        formats.put("MT_en", "EEEE, d MMMM");
        formats.put("NA_en", "EEEE, MMMM d");
        formats.put("NZ_en", "EEEE, d MMMM");
        formats.put("PH_en", "EEEE, MMMM d");
        formats.put("PK_en", "EEEE, MMMM d");
        formats.put("RH_en", "EEEE dd MMMM");
        formats.put("SG_en", "EEEE, d MMMM");
        formats.put("TT_en", "EEEE, MMMM d");
        formats.put("US_en", "EEEE, MMMM d");
        formats.put("VI_en", "EEEE, MMMM d");
        formats.put("ZA_en", "EEEE dd MMMM");
        formats.put("ZW_en", "EEEE dd MMMM");
        formats.put("_es", "EEEE d 'de' MMMM");
        formats.put("AR_es", "EEEE d 'de' MMMM");
        formats.put("BO_es", "EEEE d 'de' MMMM");
        formats.put("CL_es", "EEEE d 'de' MMMM");
        formats.put("CO_es", "EEEE d 'de' MMMM");
        formats.put("CR_es", "EEEE d 'de' MMMM");
        formats.put("DO_es", "EEEE d 'de' MMMM");
        formats.put("EC_es", "EEEE d 'de' MMMM");
        formats.put("ES_es", "EEEE d 'de' MMMM");
        formats.put("GT_es", "EEEE d 'de' MMMM");
        formats.put("HN_es", "EEEE dd 'de' MMMM");
        formats.put("MX_es", "EEEE d 'de' MMMM");
        formats.put("NI_es", "EEEE d 'de' MMMM");
        formats.put("PA_es", "EEEE d 'de' MMMM");
        formats.put("PE_es", "EEEE d 'de' MMMM");
        formats.put("PR_es", "EEEE d 'de' MMMM");
        formats.put("PY_es", "EEEE d 'de' MMMM");
        formats.put("SV_es", "EEEE d 'de' MMMM");
        formats.put("US_es", "EEEE d 'de' MMMM");
        formats.put("UY_es", "EEEE d 'de' MMMM");
        formats.put("VE_es", "EEEE d 'de' MMMM");
        formats.put("_et", "EEEE, d. MMMM");
        formats.put("_eu", "EEEE, MMMM'ren' dd'a'");
        formats.put("_fi", "cccc, d. MMMM");
        formats.put("FI_fi", "cccc, d. MMMM");
        formats.put("_fil", "EEEE, MMMM dd");
        formats.put("PH_fil", "EEEE, MMMM dd");
        formats.put("_fr", "EEEE d MMMM");
        formats.put("BE_fr", "EEEE d MMMM");
        formats.put("CA_fr", "EEEE d MMMM");
        formats.put("CH_fr", "EEEE, d MMMM");
        formats.put("FR_fr", "EEEE d MMMM");
        formats.put("LU_fr", "EEEE d MMMM");
        formats.put("MC_fr", "EEEE d MMMM");
        formats.put("_gl", "EEEE dd MMMM");
        formats.put("_iw", "EEEE, d בMMMM");
        formats.put("IL_iw", "EEEE, d בMMMM");
        formats.put("_hi", "EEEE, d MMMM");
        formats.put("IN_hi", "EEEE, d MMMM");
        formats.put("_hr", "EEEE, d. MMMM");
        formats.put("HR_hr", "EEEE, d. MMMM");
        formats.put("_hu", "MMMM d., EEEE");
        formats.put("HU_hu", "MMMM d., EEEE");
        formats.put("_hy", "EEEE, MMMM d");
        formats.put("_in", "EEEE, dd MMMM");
        formats.put("ID_in", "EEEE, dd MMMM");
        formats.put("_it", "EEEE d MMMM");
        formats.put("CH_it", "EEEE, d MMMM");
        formats.put("IT_it", "EEEE d MMMM");
        formats.put("_ja", "M月d日EEEE");
        formats.put("JP_ja", "M月d日EEEE");
        formats.put("_ka", "EEEE, MMMM dd");
        formats.put("_kk", "EEEE, d MMMM");
        formats.put("_ko", "M월 d일 EEEE");
        formats.put("KR_ko", "M월 d일 EEEE");
        formats.put("_lt", "'m'. MMMM d 'd'., EEEE");
        formats.put("LT_lt", "'m'. MMMM d 'd'., EEEE");
        formats.put("_lv", "EEEE, d. MMMM");
        formats.put("LV_lv", "EEEE, d. MMMM");
        formats.put("_mk", "EEEE, dd MMMM");
        formats.put("_ms", "EEEE, d MMMM");
        formats.put("_nb", "EEEE d. MMMM");
        formats.put("NO_nb", "EEEE d. MMMM");
        formats.put("_nl", "EEEE d MMMM");
        formats.put("BE_nl", "EEEE d MMMM");
        formats.put("NL_nl", "EEEE d MMMM");
        formats.put("_pl", "EEEE, d MMMM");
        formats.put("PL_pl", "EEEE, d MMMM");
        formats.put("_ps", "EEEE د MMMM d");
        formats.put("_pt", "EEEE, d 'de' MMMM");
        formats.put("BR_pt", "EEEE, d 'de' MMMM");
        formats.put("PT_pt", "EEEE, d 'de' MMMM");
        formats.put("_rm", "EEEE, d. MMMM");
        formats.put("_ro", "EEEE, d MMMM");
        formats.put("RO_ro", "EEEE, d MMMM");
        formats.put("_ru", "EEEE, d MMMM");
        formats.put("RU_ru", "EEEE, d MMMM");
        formats.put("UA_ru", "EEEE, d MMMM");
        formats.put("_sk", "EEEE, d. MMMM");
        formats.put("SK_sk", "EEEE, d. MMMM");
        formats.put("_sl", "EEEE, dd. MMMM");
        formats.put("SI_sl", "EEEE, dd. MMMM");
        formats.put("_sr", "EEEE, dd. MMMM");
        formats.put("BA_sr", "EEEE, dd. MMMM");
        formats.put("CS_sr", "EEEE, dd. MMMM");
        formats.put("CYRL_sr", "EEEE, dd. MMMM");
        formats.put("CYRL_sr", "EEEE, dd. MMMM");
        formats.put("CYRL_sr", "EEEE, dd. MMMM");
        formats.put("CYRL_sr", "EEEE, dd. MMMM");
        formats.put("CYRL_sr", "EEEE, dd. MMMM");
        formats.put("CYRL_sr", "EEEE, dd. MMMM");
        formats.put("LATN_sr", "EEEE, dd. MMMM");
        formats.put("LATN_sr", "EEEE, dd. MMMM");
        formats.put("LATN_sr", "EEEE, dd. MMMM");
        formats.put("LATN_sr", "EEEE, dd. MMMM");
        formats.put("LATN_sr", "EEEE, dd. MMMM");
        formats.put("LATN_sr", "EEEE, dd. MMMM");
        formats.put("ME_sr", "EEEE, dd. MMMM");
        formats.put("RS_sr", "EEEE, dd. MMMM");
        formats.put("YU_sr", "EEEE, dd. MMMM");
        formats.put("_sv", "EEEE'en' 'den' d:'e' MMMM");
        formats.put("FI_sv", "EEEE'en' 'den' d:'e' MMMM");
        formats.put("SE_sv", "EEEE'en' 'den' d:'e' MMMM");
        formats.put("_sw", "EEEE, d MMMM");
        formats.put("_th", "EEEEที่ d MMMM G");
        formats.put("TH_th", "EEEEที่ d MMMM G");
        formats.put("_tr", "d MMMM EEEE");
        formats.put("TR_tr", "d MMMM EEEE");
        formats.put("_uk", "EEEE, d MMMM");
        formats.put("UA_uk", "EEEE, d MMMM");
        formats.put("_uz", "EEEE, MMMM dd");
        formats.put("_vi", "EEEE, 'ngày' dd MMMM");
        formats.put("VN_vi", "EEEE, 'ngày' dd MMMM");
        formats.put("_zh", "M月d日EEEE");
        formats.put("CN_zh", "M月d日EEEE");
        formats.put("HK_zh", "M月d日EEEE");
        formats.put("HANS_zh", "M月d日EEEE");
        formats.put("HANS_zh", "M月d日EEEE");
        formats.put("HANS_zh", "M月d日EEEE");
        formats.put("HANS_zh", "M月d日EEEE");
        formats.put("HANT_zh", "M月d日EEEE");
        formats.put("HANT_zh", "M月d日EEEE");
        formats.put("HANT_zh", "MM月dd日EEEE");
        formats.put("HANT_zh", "M月d日EEEE");
        formats.put("MO_zh", "MM月dd日EEEE");
        formats.put("SG_zh", "M月d日EEEE");
        formats.put("TW_zh", "M月d日EEEE");
        formats.put("_zu", "EEEE dd MMMM");
    }

    public static String getLongFormatWithoutYear(Locale locale) {
        if (locale != null) {
            String key = locale.getCountry() + "_" + locale.getLanguage();
            String format = formats.get(key);
            if (format != null) {
                return format;
            }
        }
        return DEFAULT_FORMAT;
    }

    public static String getShortFormatWithoutYear(Locale locale) {
        String longFormat = getLongFormatWithoutYear(locale);
        return longFormat.replaceAll("E+", "E").replaceAll("MMMM", "MMM");
    }
}
4 голосов
/ 25 сентября 2010

Я сделал это так:

DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.SHORT, Locale.getDefault());
if (dateFormat instanceof SimpleDateFormat) {
    SimpleDateFormat simpleDateFormat = (SimpleDateFormat) dateFormat;
    String pattern = simpleDateFormat.toPattern();

    // I modified the pattern here so that dd.MM.yyyy would result to dd.MM

    simpleDateFormat.applyPattern(modifiedPattern);

    ... etc
}
3 голосов
/ 22 июля 2016

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

    Date dateObject = ...;

    String dayMonthDateString = getDayMonthDateString(dateObject, Locale.GERMANY);
    Log.i("customDate", "dayMonthDateString = " + dayMonthDateString);

private String getDayMonthDateString(Date date, Locale locale)
{
    try
    {
        boolean dayBeforeMonth = defineDayMonthOrder(locale);

        SimpleDateFormat newDateFormat;

        if (dayBeforeMonth)
        {
            newDateFormat = new SimpleDateFormat("dd/MM", locale);
        }
        else
        {
            newDateFormat = new SimpleDateFormat("MM/dd", locale);
        }

        return newDateFormat.format(date);
    }
    catch (ParseException e)
    {
        e.printStackTrace();
    }

    return null;
}


private boolean defineDayMonthOrder(Locale locale) throws ParseException
{
    String day = "10";
    String month = "11";
    String year = "12";

    String calendarDate = day + "." + month + "." + year;

    SimpleDateFormat format = new SimpleDateFormat("dd.MM.yy");
    Date date = format.parse(calendarDate);

    String localizedDate = SimpleDateFormat.getDateInstance(SimpleDateFormat.SHORT, locale).format(date);

    int indexOfDay = localizedDate.indexOf(day);
    int indexOfMonth = localizedDate.indexOf(month);

    return indexOfDay < indexOfMonth;
}
1 голос
/ 18 марта 2018

Хотя Andrzej Pronobis очень хороший ответ, он не работает, например, с ZH local.Я закончил с ручным удалением года из локализованного шаблона.Эта функция была протестирована для всех локальных форматов SHORT, MEDIUM, LONG и FULL.

public String removeYearFromPattern(String pattern) throws SCException {
    int yPos = 0;
    while (yPos < pattern.length() && pattern.charAt(yPos) != 'y' && pattern.charAt(yPos) != 'Y') {
        if (pattern.charAt(yPos) == '\'') {
            yPos++;
            while (yPos < pattern.length() && pattern.charAt(yPos) != '\'') yPos++;
        }
        yPos++;
    }
    if (yPos >= pattern.length()) throw new IllegalArgumentException("Did not find year in pattern");
    String validPatternLetters = "EMd";
    // go forward
    int endPos = yPos;
    while (endPos < pattern.length() && validPatternLetters.indexOf(pattern.charAt(endPos)) == -1) {
        endPos++;
        if (endPos < pattern.length() && pattern.charAt(endPos) == '\'') {
            endPos++;
            while (endPos < pattern.length() && pattern.charAt(endPos) != '\'')
                endPos++;
        }
    }
    if (endPos != pattern.length()) validPatternLetters += ',';
    // go backward
    int startPos = yPos;
    while (startPos >= 0 && validPatternLetters.indexOf(pattern.charAt(startPos)) == -1) {
        startPos--;
        if (startPos >= 0 && pattern.charAt(startPos) == '\'') {
            startPos--;
            while (startPos >= 0 && pattern.charAt(startPos) != '\'') startPos--;
        }
    }
    startPos++;
    String yLetters = pattern.substring(startPos, endPos);
    return pattern.replace(yLetters, " ").trim();
}

Функцию, описанную выше, можно проверить, запустив:

for (Locale locale : Locale.getAvailableLocales()) {
    SimpleDateFormat df = (SimpleDateFormat) DateFormat.getDateInstance(DateFormat.FULL, locale);
    String dfPattern = "?";
    String newPattern = "?";
    try {
        dfPattern = df.toPattern();
        newPattern = removeYearFromPattern(dfPattern);
        df.applyPattern(newPattern);
    } catch (IllegalArgumentException e) {
        Log.e(TAG, "Error removing year for " + locale + ": " + e.getMessage());
    }
    Log.d(TAG, locale + ": old  " + dfPattern + "; new " + newPattern + "; result " + df.format(new Date()));
}

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

1 голос
/ 04 мая 2015

Если вы используете Android, вы можете использовать getBestDateTimePattern и просто поместить туда все поля, которые хотите разрешить.Он должен автоматически ставить правильный порядок и специальные символы в соответствии с текущей локалью.

К сожалению, для этого требуется API 18+.

РЕДАКТИРОВАТЬ: это выглядит не очень хорошим выбором, к сожалению,Я написал об этом здесь: http://code.google.com/p/android/issues/detail?id=171591


Итак, вот что я сделал:

public static String convertDateToString(Context context, Locale locale, final Date date, boolean alsoShowYearIfPossible) {
    if (date == null)
        return "";
    String defaultDateFormat;
    if (locale != null) {
        defaultDateFormat = ((SimpleDateFormat) DateFormat.getDateInstance(DateFormat.SHORT, locale)).toLocalizedPattern();
    } else defaultDateFormat = getDefaultDateFormat(context);
    if (alsoShowYearIfPossible)
        return new SimpleDateFormat(defaultDateFormat, Locale.getDefault()).format(date);
    //need removal of year
    String removedYearFormat = defaultDateFormat.replaceAll("[^{mdMD}]*y+[^{mdMD}]*", "");
    String result = new SimpleDateFormat(removedYearFormat, Locale.getDefault()).format(date);
    //Log.d("AppLog", locale + ": \"" + defaultDateFormat + "\" => \"" + removedYearFormat + "\" =>" + result);
    return result;
}

private static String getDefaultDateFormat(final Context context) {
    String dateFormatString = Settings.System.getString(context.getContentResolver(), Settings.System.DATE_FORMAT);
    if (TextUtils.isEmpty(dateFormatString)) {
        // if device date format is available , use device date order,and if not available ,use default
        final char[] dateFormatOrder = android.text.format.DateFormat.getDateFormatOrder(context);
        if (dateFormatOrder.length == 0)
            dateFormatString = DEFAULT_DATE_FORMAT;
        else {
            // construct the date format based on the device date order
            final StringBuilder sb = new StringBuilder();
            for (int i = 0; i < dateFormatOrder.length; ++i) {
                final char c = dateFormatOrder[i];
                switch (Character.toLowerCase(c)) {
                    case 'y':
                        sb.append("yyyy");
                        break;
                    case 'm':
                        sb.append("MM");
                        break;
                    case 'd':
                        sb.append("dd");
                        break;
                }
                if (i != dateFormatOrder.length - 1)
                    sb.append('-');
            }
            dateFormatString = sb.toString();
        }
    }
    return dateFormatString;
}

Этот код работает в любой доступной локали на Android 5.0.2.

Вот пример того, как проверить это на локалях:

    Date date = new Date();
    for (Locale locale : Locale.getAvailableLocales()) {
        SimpleDateFormat sdf = (SimpleDateFormat) DateFormat.getDateInstance(DateFormat.SHORT, locale);
        String localizedDatePattern = sdf.toLocalizedPattern();
        convertDateToString(this,locale,date,false);
    }
1 голос
/ 20 апреля 2015

Использование com.ibm.icu библиотека:

import com.ibm.icu.text.DateFormat;

DateFormat.getPatternInstance(DateFormat.MONTH_DAY, locale).format(date);
0 голосов
/ 01 июня 2011

или

   SimpleDateFormat dateFormat = new SimpleDateFormat("EEE MMM d');
    dateFormat.format(date);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...