我试图根据给定的语言环境以不同的方式格式化Java中的日期。例如,我希望英语用户看到“ 2009年11月1日”(格式为“ MMM d,yyyy”),而挪威用户希望看到“ 1. nov。2009”(“ d。MMM。yyyy”)。
如果我将语言环境添加到SimpleDateFormat构造函数中,则月份部分工作正常,但是其余部分呢?
我希望可以将与语言环境配对的格式字符串添加到SimpleDateFormat中,但是找不到任何方法。有可能还是我需要让我的代码检查语言环境并添加相应的格式字符串?
Answers:
使用DateFormat.getDateInstance(int style,Locale locale)而不是使用创建自己的模式SimpleDateFormat
。
java.util.Date
和SimpleDateFormat
现在的遗产,由java.time类取代。
使用样式+语言环境:DateFormat.getDateInstance(int style,Locale locale)
检查 http://java.sun.com/j2se/1.5.0/docs/api/java/text/DateFormat.html
运行以下示例以查看差异:
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
public class DateFormatDemoSO {
public static void main(String args[]) {
int style = DateFormat.MEDIUM;
//Also try with style = DateFormat.FULL and DateFormat.SHORT
Date date = new Date();
DateFormat df;
df = DateFormat.getDateInstance(style, Locale.UK);
System.out.println("United Kingdom: " + df.format(date));
df = DateFormat.getDateInstance(style, Locale.US);
System.out.println("USA: " + df.format(date));
df = DateFormat.getDateInstance(style, Locale.FRANCE);
System.out.println("France: " + df.format(date));
df = DateFormat.getDateInstance(style, Locale.ITALY);
System.out.println("Italy: " + df.format(date));
df = DateFormat.getDateInstance(style, Locale.JAPAN);
System.out.println("Japan: " + df.format(date));
}
}
输出:
United Kingdom: 25-Sep-2017
USA: Sep 25, 2017
France: 25 sept. 2017
Italy: 25-set-2017
Japan: 2017/09/25
DateFormat.LONG
和DateFormat.DEFAULT
样式!
java.util.Date
,java.util.Calendar
和java.text.SimpleDateFormat
现在的遗产,由取代java.time内置到Java 8的Java 9.请参见类教程由Oracle。
LocalDate.now().format(
DateTimeFormatter.ofLocalizedDate( FormatStyle.MEDIUM )
.withLocale( new Locale( "no" , "NO" ) )
)
的麻烦类java.util.Date
和SimpleDateFormat
现在的遗产,由java.time类取代。
LocalDate
该LocalDate
级表示没有时间一天和不同时区的日期,唯一的价值。
时区对于确定日期至关重要。在任何给定时刻,日期都会在全球范围内变化。例如,法国巴黎午夜过后的几分钟是新的一天,而在魁北克蒙特利尔仍然是“昨天” 。
ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );
DateTimeFormatter
使用DateTimeFormatter
来生成表示只有日期部分或时间部分的字符串。
该DateTimeFormatter
类别可自动定位。
要本地化,请指定:
FormatStyle
确定字符串应为多长或缩写。Locale
确定(a)日名,月名等的翻译所用的人类语言,以及(b)决定缩写,大写,标点符号等问题的文化规范。例:
Locale l = Locale.CANADA_FRENCH ;
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDate( FormatStyle.FULL ).withLocale( l );
String output = ld.format( f );
换个方向,您可以解析本地化的字符串。
LocalDate ld = LocalDate.parse( input , f );
请注意,区域设置和时区是完全正交的问题。您可以用日语显示蒙特利尔时刻,也可以用印地语显示奥克兰新西兰时刻。
另一个示例:将6 junio 2012
(西班牙语)更改为2012-06-06
(标准ISO 8601格式)。默认情况下,java.time类使用ISO 8601格式来解析/生成字符串。
String input = "6 junio 2012";
Locale l = new Locale ( "es" , "ES" );
DateTimeFormatter f = DateTimeFormatter.ofPattern ( "d MMMM uuuu" , l );
LocalDate ld = LocalDate.parse ( input , f );
String output = ld.toString(); // 2012-06-06.
这是一些示例代码,用于在自动本地化的多个区域中浏览多种格式的结果。
一个EnumSet
是的实现Set
,对于低内存使用和收集当快速执行速度两者高度优化的Enum
对象。因此,EnumSet.allOf( FormatStyle.class )
为我们提供了所有四个要FormatStyle
枚举的枚举对象的集合。有关更多信息,请参见有关枚举类型的Oracle教程。
LocalDate ld = LocalDate.of( 2018 , Month.JANUARY , 23 );
List < Locale > locales = new ArrayList <>( 3 );
locales.add( Locale.CANADA_FRENCH );
locales.add( new Locale( "no" , "NO" ) );
locales.add( Locale.US );
// Or use all locales (almost 800 of them, for about 120K text results).
// Locale[] locales = Locale.getAvailableLocales(); // All known locales. Almost 800 of them.
for ( Locale locale : locales )
{
System.out.println( "------| LOCALE: " + locale + " — " + locale.getDisplayName() + " |----------------------------------" + System.lineSeparator() );
for ( FormatStyle style : EnumSet.allOf( FormatStyle.class ) )
{
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDate( style ).withLocale( locale );
String output = ld.format( f );
System.out.println( output );
}
System.out.println( "" );
}
System.out.println( "« fin »" + System.lineSeparator() );
输出。
------| LOCALE: fr_CA — French (Canada) |----------------------------------
mardi 23 janvier 2018
23 janvier 2018
23 janv. 2018
18-01-23
------| LOCALE: no_NO — Norwegian (Norway) |----------------------------------
tirsdag 23. januar 2018
23. januar 2018
23. jan. 2018
23.01.2018
------| LOCALE: en_US — English (United States) |----------------------------------
Tuesday, January 23, 2018
January 23, 2018
Jan 23, 2018
1/23/18
« fin »
该java.time框架是建立在Java 8和更高版本。这些类取代麻烦的老传统日期时间类,如java.util.Date
,Calendar
,和SimpleDateFormat
。
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
要了解更多信息,请参见Oracle教程。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310。
您可以直接与数据库交换java.time对象。使用与JDBC 4.2或更高版本兼容的JDBC驱动程序。不需要字符串,不需要类。java.sql.*
在哪里获取java.time类?
该ThreeTen-额外项目与其他类扩展java.time。该项目是将来可能向java.time添加内容的试验场。你可能在这里找到一些有用的类,比如Interval
,YearWeek
,YearQuarter
,和更多。
日期字符串的本地化:
根据redsonic的帖子:
private String localizeDate(String inputdate, Locale locale) {
Date date = new Date();
SimpleDateFormat dateFormatCN = new SimpleDateFormat("dd-MMM-yyyy", locale);
SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MMM-yyyy");
try {
date = dateFormat.parse(inputdate);
} catch (ParseException e) {
log.warn("Input date was not correct. Can not localize it.");
return inputdate;
}
return dateFormatCN.format(date);
}
String localizedDate = localizeDate("05-Sep-2013", new Locale("zh","CN"));
就像2013年9月5日
给定日期的Java 8样式
LocalDate today = LocalDate.of(1982, Month.AUGUST, 31);
System.out.println(today.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).withLocale(Locale.ENGLISH)));
System.out.println(today.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).withLocale(Locale.FRENCH)));
System.out.println(today.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).withLocale(Locale.JAPANESE)));
希望这对某人有帮助。请在下面的代码中找到,该代码接受Locale实例并返回特定于语言环境的日期格式/模式。
public static String getLocaleDatePattern(Locale locale) {
// Validating if Locale instance is null
if (locale == null || locale.getLanguage() == null) {
return "MM/dd/yyyy";
}
// Fetching the locale specific date pattern
String localeDatePattern = ((SimpleDateFormat) DateFormat.getDateInstance(
DateFormat.SHORT, locale)).toPattern();
// Validating if locale type is having language code for Chinese and country
// code for (Hong Kong) with Date Format as - yy'?'M'?'d'?'
if (locale.toString().equalsIgnoreCase("zh_hk")) {
// Expected application Date Format for Chinese (Hong Kong) locale type
return "yyyy'MM'dd";
}
// Replacing all d|m|y OR Gy with dd|MM|yyyy as per the locale date pattern
localeDatePattern = localeDatePattern.replaceAll("d{1,2}", "dd")
.replaceAll("M{1,2}", "MM")
.replaceAll("y{1,4}|Gy", "yyyy");
// Replacing all blank spaces in the locale date pattern
localeDatePattern = localeDatePattern.replace(" ", "");
// Validating the date pattern length to remove any extract characters
if (localeDatePattern.length() > 10) {
// Keeping the standard length as expected by the application
localeDatePattern = localeDatePattern.substring(0, 10);
}
return localeDatePattern;
}
import java.time.format.DateTimeFormatter;
myDate.format(DateTimeFormatter.ofPattern("dd-MMM-YYYY",new Locale("ar")))
ofPattern
了一个语言环境参数会给你月份名称在所需的语言,而不是不同的格式,在问题提出要求。在大写YYYY
情况下,使用大写会给您带来不正确且非常令人惊讶的结果。使用Java 8是个好主意。
java.util.Date
,java.util.Calendar
和java.text.SimpleDateFormat
现在的遗产,由取代java.time内置到Java 8的Java 9.请参见类教程由Oracle。