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

时间:2017-01-24 20:01:50

标签: java date format locale

我有多元文化应用程序,项目使用Java 7.我需要显示日期,但仅限日期和月份。例如在Locale.UK今天的日期看起来像:24/01,但在Locale.US中如:1/24。如何在Java 7中实现这一目标?我尝试使用DateFormat.getDateInstance(dateFormat,locale),但在这种情况下,我只能使用预定义的日期格式,例如DateFormat.SHORT,DateFormat.DEFAULT等。没有预定义的格式,只有月和月的日期。接下来我尝试将SimpleDateFormat与locale一起使用,但这不起作用,因为我不知道,它只是根据语言环境翻译一些文本。这是我的示例代码:

  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)。怎么做到这一点?

4 个答案:

答案 0 :(得分:2)

您的代码使用相同的格式,因为 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

答案 1 :(得分:1)

将您的第三行改为

SimpleDateFormat sdfus = new SimpleDateFormat("MM/dd", Locale.US);

克服标准Java提供的缺点:

getDateInstance()方法接受style的参数。最短的风格似乎是DateFormat.SHORT。你可以争辩说也许他们应该提供一个更短的(DateFormat.SHORTER或许?)c.f。

http://docs.oracle.com/javase/6/docs/api/java/text/DateFormat.html#getDateInstance(int)

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

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

}

输出结果为:

for locale en_GB the shorter date/month display is: 01/24
for locale en_US the shorter date/month display is: 24/01
for locale fr the shorter date/month display is: 24/01

答案 2 :(得分:1)

TL;博士

MonthDay.from( 
    LocalDate.now( ZoneId.of( "America/Montreal" ) ) 
).format( DateTimeFormatter.ofPattern( "MM/dd" ) )
  

01/24

MonthDay

有一个课程:MonthDay

MonthDay代表一个月和一个月的组合。

MonthDay md = MonthDay.of( Month.JANUARY , 24 );

避免使用旧版日期时间类。

避免麻烦的旧日期时间类,例如SimpleDateFormat,现在是遗留的,被java.time类取代。

MonthDay类是Java 8及更高版本中内置的java.time框架的一部分。大部分java.time都被反向移植到Java 6&amp; Java 7(见下文)。

ISO 8601

  

md.toString(): - 01-24

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

当前日期

您想要当前日期的月日。对于当前日期,我们将使用LocalDate类。 LocalDate类表示没有时间且没有时区的仅限日期的值。

时区

时区对于确定日期至关重要。对于任何给定的时刻,日期在全球范围内因地区而异。例如,在Paris France午夜后的几分钟是新的一天,而Montréal Québec中仍然是“昨天”。

continent/region的格式指定proper time zone name,例如America/MontrealAfrica/CasablancaPacific/Auckland。切勿使用诸如ESTIST之类的3-4字母缩写,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。

请注意,Locale 没有与时区有关。 Locale仅在生成字符串时适用于文本格式,但与时区分开且不同。

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

现在提取一个MonthDay对象。

MonthDay md = MonthDay.from( today );
  

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日。

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

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

String output = md.format( fUS );

实时代码

请参阅此示例code run live at IdeOne.com

关于java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendar和&amp; SimpleDateFormat

现在位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore

答案 3 :(得分:0)

我最终修改了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个语言环境,据我所知,生成的日期模式对所有这些语言环境都很好。

一些示例将原始短模式与修改后的短模式进行了比较:

         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