带区域设置的Java DateFormat/SimpleDateFormat(仅显示月份中的日期)

带区域设置的Java DateFormat/SimpleDateFormat(仅显示月份中的日期),java,date,format,locale,Java,Date,Format,Locale,我有一个多文化应用程序,该项目使用Java7。我需要显示日期,但只显示月份中的日期。例如,在Locale.UK中,今天的日期看起来像:24/01,但在Locale.US中像:1/24。如何在Java7中实现这一点?我尝试使用DateFormat.getDateInstance(DateFormat,locale),但在这种情况下,我只能使用预定义的日期格式,例如DateFormat.SHORT,DateFormat.DEFAULT等。没有预定义的格式,只有月份中的日期和月份。接下来,我尝试将Si

我有一个多文化应用程序,该项目使用Java7。我需要显示日期,但只显示月份中的日期。例如,在
Locale.UK
中,今天的日期看起来像:24/01,但在
Locale.US
中像:1/24。如何在Java7中实现这一点?我尝试使用
DateFormat.getDateInstance(DateFormat,locale)
,但在这种情况下,我只能使用预定义的日期格式,例如
DateFormat.SHORT
DateFormat.DEFAULT
等。没有预定义的格式,只有月份中的日期和月份。接下来,我尝试将SimpleDataFormat与区域设置一起使用,但这并没有起到作用,因为我想知道,它只是根据区域设置翻译一些文本。以下是我的示例代码:

DateFormat dfuk = DateFormat.getDateInstance(DateFormat.SHORT, Locale.UK);
DateFormat dfus = DateFormat.getDateInstance(DateFormat.SHORT, Locale.US);
System.out.println(dfuk.format(new Date()));  // 24/01/17
System.out.println(dfus.format(new Date()));  // 1/24/17
SimpleDateFormat sdfuk = new SimpleDateFormat("dd/MM", Locale.UK);
SimpleDateFormat sdfus = new SimpleDateFormat("dd/MM", Locale.US);
System.out.println(sdfuk.format(new Date()));  // 24/01
System.out.println(sdfus.format(new Date()));  // 24/01

我希望最后一行打印01/24(或1/24)。如何做到这一点?

将您的最后三行更改为

SimpleDateFormat sdfus = new SimpleDateFormat("MM/dd", Locale.US);
克服标准Java的缺点:

getDateInstance()
方法接受
style
的参数。最短的样式似乎是
DateFormat.SHORT
。你可以说,也许他们应该提供一个更短的(
DateFormat.shorter
也许?)c.f

在此之前,您可以为较短的样式构建模式枚举。以下是一个例子:

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

enum PatternShorter { // or PatternMonthDayOnly
    MM_SLASH_DD     ("MM/dd")
    , DD_SLASH_MM   ("dd/MM")
    ;
    private String pattern;

    public String getPattern() {
        return pattern;
    }

    private PatternShorter(String pattern) {
        this.pattern = pattern;
    }

    public static PatternShorter getDefault() { return DD_SLASH_MM; }
}

public class DateFormatEx {
    private static Map<Locale, PatternShorter> patternShorter = new HashMap<>();

    static {
        patternShorter.put(Locale.UK, PatternShorter.DD_SLASH_MM);
        patternShorter.put(Locale.UK, PatternShorter.MM_SLASH_DD);
        // any locale not listed here will get the default pattern
    }

    private static String getPattern (Locale locale) {      
        if (patternShorter.get(locale)!=null) {
            return patternShorter.get(locale).getPattern();
        } else {
            return PatternShorter.getDefault().getPattern();
        }
    }

    public static void main(String[] args) {
        List<Locale> listOfLocale = Arrays.asList(Locale.UK, Locale.US, Locale.FRENCH);
        for (Locale locale : listOfLocale) {
            SimpleDateFormat fmt 
            = new SimpleDateFormat(getPattern(locale), locale);
            System.out.format("for locale %s the shorter date/month display is: %s%n"
                    , locale.toString()
                    , fmt.format(new Date()));  
        }
    }

}

您的代码抛出了相同的格式,因为两个DateFormat都是用相同的模式构造的,这是不正确的

SimpleDateFormat sdfuk = new SimpleDateFormat("dd/MM", Locale.UK);
SimpleDateFormat sdfus = new SimpleDateFormat("dd/MM", Locale.US);
如果您有一个字符串要转换为日期,则需要本地字符串。。。对于您试图进行的解析(字符串->日期),只有模式是可以的

示例

DateFormat sdfuk = new SimpleDateFormat("dd/MM");
DateFormat sdfus = new SimpleDateFormat("MM/d");
System.out.println(sdfuk.format(new Date())); // 24/01
System.out.println(sdfus.format(new Date())); // 01/24
tl;博士 01/24

MonthDay
这有一个类:

MonthDay
表示一个月和一个月中的一天的组合

MonthDay md = MonthDay.of( Month.JANUARY , 24 );
避免遗留日期时间类。 避免麻烦的旧日期时间类,例如
SimpleDateFormat
,它们现在是遗留的,被java.time类取代

MonthDay
类是java 8及更高版本中内置的java.time框架的一部分。大部分java.time被向后移植到Java6和Java7(见下文)

ISO 8601 md.toString():--01-24

toString
方法生成标准格式的字符串。
MonthDay
类也可以解析这样的字符串

当前日期 您需要当前日期的月日。对于当前日期,我们将使用
LocalDate
类。该类表示一个仅限日期的值,不包含一天中的时间和时区

ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );
时区 时区对于确定日期至关重要。在任何一个特定的时刻,世界各地的日期都因地区而异。例如,中午夜后几分钟是新的一天,而中仍然是“昨天”

大陆/地区
的格式指定,例如,或
太平洋/奥克兰
。切勿使用3-4个字母的缩写,如
EST
IST
,因为它们不是真正的时区,也不是标准化的,甚至不是唯一的(!)

请明确,
Locale
与时区无关。
Locale
仅适用于生成字符串时的文本格式,但与时区不同

ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );
现在提取一个
MonthDay
对象

MonthDay md = MonthDay.from( today );
今天。toString():2017-01-25

md.toString():--01-25

其它格式 您可以生成其他格式的字符串

java.time类可以通过
Locale
自动本地化某些日期时间值。不幸的是,这不适用于
MonthDay
。对于
MonthDay
,如果需要标准ISO 8601格式以外的格式,则必须在
DateTimeFormatter
对象中明确指定所需的格式。顺便说一句,我鼓励您在可能的情况下坚持使用标准格式,尤其是在交换数据时。你甚至可以考虑训练你的用户接受这个格式。标准格式是明确的,而您的英国-美国格式(dd/MM,MM/dd)可能完全不明确,例如01/02为1月2日或2月1日

确定(a)用于翻译日名、月名等的人类语言,以及(b)决定缩写、大写、标点等问题的文化规范。通常,我建议始终为
DateTimeFormatter
指定
Locale
,而不是隐式地依赖JVM的当前默认
Locale
。但是我不认为
语言环境
会影响这种特定格式的输出。因此,在本例中我省略了
Locale

DateTimeFormatter fUS = DateTimeFormatter.ofPattern( "MM/dd" );
DateTimeFormatter fUK = DateTimeFormatter.ofPattern( "dd/MM" );

String output = md.format( fUS );
实时代码 看看这个例子


关于java.time 该框架内置于Java8及更高版本中。这些类取代了麻烦的旧日期时间类,例如,&

该项目现已启动,建议迁移到类

要了解更多信息,请参阅。并搜索堆栈溢出以获得许多示例和解释。规格是

从哪里获得java.time类

  • 后来
    • 内置的
    • 标准JavaAPI的一部分,带有捆绑实现
    • Java9添加了一些次要功能和修复
    • 大部分java.time功能都在中向后移植到Java6和Java7
    • 该项目专门为Android采用了ThreeTen Backport(如上所述)

该项目使用其他类扩展了java.time。这个项目是java.time将来可能添加的一个试验场。您可以在这里找到一些有用的类,例如、、和。

我最终修改了
DateFormat.getDateInstance(DateFormat.SHORT)
提供的本地化格式字符串,从格式中删除了年份部分:

DateFormat shortDateFormat = DateFormat.getDateInstance(DateFormat.SHORT);
String shortPattern = ((SimpleDateFormat) shortDateFormat).toLocalizedPattern();
String shorterPattern = shortPattern.replaceAll("[/\\- ]*[yY]+[^a-zA-Z]*", "");
DateFormat shorterDateFormat = new SimpleDateFormat(shorterPattern);
我浏览了所有734个地方
DateFormat shortDateFormat = DateFormat.getDateInstance(DateFormat.SHORT);
String shortPattern = ((SimpleDateFormat) shortDateFormat).toLocalizedPattern();
String shorterPattern = shortPattern.replaceAll("[/\\- ]*[yY]+[^a-zA-Z]*", "");
DateFormat shorterDateFormat = new SimpleDateFormat(shorterPattern);
         short      shorter
en_US    M/d/yy     M/d
en_GB    dd/MM/y    dd/MM
de_DE    dd.MM.yy   dd.MM.
fr_FR    dd/MM/y    dd/MM
nl_NL    dd-MM-y    dd-MM
ja_JP    y/MM/dd    MM/dd