我有多元文化应用程序,项目使用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)。怎么做到这一点?
答案 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)
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(见下文)。
md.toString(): - 01-24
toString
方法以标准ISO 8601格式生成字符串。 MonthDay
类也可以解析这些字符串。
您想要当前日期的月日。对于当前日期,我们将使用LocalDate
类。 LocalDate
类表示没有时间且没有时区的仅限日期的值。
时区对于确定日期至关重要。对于任何给定的时刻,日期在全球范围内因地区而异。例如,在Paris France午夜后的几分钟是新的一天,而Montréal Québec中仍然是“昨天”。
以continent/region
的格式指定proper time zone name,例如America/Montreal
,Africa/Casablanca
或Pacific/Auckland
。切勿使用诸如EST
或IST
之类的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 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和&amp; SimpleDateFormat
现在位于Joda-Time的maintenance mode项目建议迁移到java.time类。
要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。
从哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如Interval
,YearWeek
,YearQuarter
和more。
答案 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