java 格式化没有年份的日期

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3790918/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 03:22:56  来源:igfitidea点击:

Format date without year

javadate

提问by fhucho

How can create text representation of some date, that takes locale into accountand contains only day and month (no year)?

如何创建某个日期的文本表示,将区域设置考虑在内并且仅包含日和月(无年)?

Following code gives me something like 23/09/2010

以下代码给了我类似23/09/2010 的东西

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

I want to get 23/09

我想得到23/09

采纳答案by BalusC

You could use regex to trim off all y's and any non-alphabetic characters before and after, if any. Here's a kickoff example:

您可以使用正则表达式在y前后修剪掉所有's 和任何非字母字符(如果有)。这是一个启动示例:

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

You see that this snippet tests it for all locales as well. It looks to work fine for all locales here.

您会看到此代码段也针对所有语言环境对其进行了测试。它看起来适用于这里的所有语言环境。

回答by unify

This will work for Android, in case someone needs it:

这将适用于Android,以防有人需要它:

int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NO_YEAR;
String monthAndDayText = DateUtils.formatDateTime(context, date, flags);

回答by Andrzej Pronobis

Just wanted to contribute another modification removing year from the pattern, which works well for DateFormat.MEDIUM, even in locales such as pt_PT (d 'de' MMM 'de' yyyy) or lv_LV (y. 'gada' d. MMM).

只是想贡献另一个从模式中删除年份的修改,它适用于 DateFormat.MEDIUM,即使在 pt_PT (d 'de' MMM 'de' yyyy) 或 lv_LV (y. 'gada' d. MMM) 等语言环境中也是如此。

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

回答by Don

The following is a utility class which gives you the date format without year. I list all the date formats known to Java using the following code.

以下是一个实用程序类,它为您提供没有年份的日期格式。我使用以下代码列出了 Java 已知的所有日期格式。

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

And then manually remove the year part. It returns two flavors of date format, normal and abbreviated, ie Monday, March 18 vs Mon, Mar 18.

然后手动删除年份部分。它返回两种日期格式,正常和缩写,即星期一,3 月 18 日与星期一,3 月 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");
    }
}

回答by fhucho

I did it this way:

我是这样做的:

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
}

回答by Ayaz Alifov

The main difficulty here is that in some locales the order of month and day is different. I solved it in a way which differs from those which presented here and hope it works for all cases.

这里的主要困难是在某些语言环境中,月和日的顺序是不同的。我以一种与此处介绍的方式不同的方式解决了它,并希望它适用于所有情况。

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

回答by zelig74

Although Andrzej Pronobis's answer is very good, it doesn't work for instance with ZH local. I ended up with manual removing year from localized pattern. This function was tested for all locals for SHORT, MEDIUM, LONG and FULL formats.

尽管 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();
}

Function above can be tested by running:

可以通过运行来测试上述功能:

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

I know it is not as elegant as regex, but it is a little bit faster and works for all locals (if I am able to recognize).

我知道它不像正则表达式那么优雅,但它要快一点并且适用于所有本地人(如果我能够识别的话)。

回答by Maxim Kachurovskiy

Using com.ibm.iculibrary:

使用com.ibm.icu库:

import com.ibm.icu.text.DateFormat;

DateFormat.getPatternInstance(DateFormat.MONTH_DAY, locale).format(date);

回答by android developer

If you use Android, you might be able to use getBestDateTimePattern, and just put there all the fields you want to allow. It should automatically put the correct order and special characters according to the current locale.

如果您使用 Android,您也许可以使用getBestDateTimePattern,然后将您想要允许的所有字段放在那里。它应该根据当前语言环境自动放置正确的顺序和特殊字符。

Sadly, it requires API 18+ .

遗憾的是,它需要 API 18+ 。

EDIT: This seems like a not-so-good choice, sadly. I've written about it here: http://code.google.com/p/android/issues/detail?id=171591

编辑:可悲的是,这似乎是一个不太好的选择。我在这里写过:http: //code.google.com/p/android/issues/detail?id=171591



So, this is what I've done:

所以,这就是我所做的:

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

This code works on any locale available, on Android 5.0.2 .

此代码适用于 Android 5.0.2 上任何可用的语言环境。

Here's a sample of how to check it on on locales:

以下是如何在语言环境中检查它的示例:

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

回答by Puran

or

或者

   SimpleDateFormat dateFormat = new SimpleDateFormat("EEE MMM d');
    dateFormat.format(date);