我喜欢将本地时间格式格式化为没有年份的字符串。目前我能够显示包含年份的本地格式:
java.text.DateFormat df = java.text.DateFormat.getDateInstance(java.text.DateFormat.SHORT);
String dateString = df.format(date);
因此我收到时间字符串输出,如
12.03.2012
03/12/2012
适用于不同的国家/地区。现在我想得到像
这样的简短形式12.03.
03/12
我该怎么做?
感谢您的帮助!
答案 0 :(得分:13)
您可以使用SimpleDateFormat
:
Date date = new Date();
java.text.SimpleDateFormat df = new java.text.SimpleDateFormat("MM/dd");
String dateString = df.format(date);
输出:
03/15
修改强>
在进一步研究语言环境格式并扩展Peters答案之后,以下是toPattern()
和toLocalizedPattern()
之间示例差异的一些代码:
import java.text.*
import java.util.*
ArrayList<Locale> locales = new ArrayList<Locale>();
locales.add(Locale.US);
locales.add(Locale.UK);
locales.add(Locale.GERMANY);
locales.add(Locale.CHINA);
Date date = new Date();
for(Locale l : locales)
{
SimpleDateFormat sdf = (SimpleDateFormat) SimpleDateFormat.getDateInstance(DateFormat.SHORT, l);
String pattern = sdf.toPattern();
String localizedPattern = sdf.toLocalizedPattern()
println "country: " + l.getDisplayName();
println "pattern: " + pattern;
println "localizedPattern: " + localizedPattern;
try {
SimpleDateFormat temp = new SimpleDateFormat(localizedPattern, l);
println "localized pattern re-parsed successfully"
} catch (IllegalArgumentException e) {
println "localized pattern re-parsed unsuccessfully: " + e.getMessage();
}
SimpleDateFormat df = new SimpleDateFormat(pattern, l);
String dateString = df.format(date);
println "resulting date: " + dateString
String yearlessPattern = pattern.replaceAll("\\W?[Yy]+\\W?", "");
println "yearlessPattern = " + yearlessPattern;
SimpleDateFormat yearlessSDF = new SimpleDateFormat(yearlessPattern, l);
println "resulting date without year: " + yearlessSDF.format(date) + "\n";
}
产生以下输出:
country: English (United States)
pattern: M/d/yy
localizedPattern: M/d/yy
localized pattern re-parsed successfully
resulting date: 3/15/12
yearlessPattern = M/d
resulting date without year: 3/15
country: English (United Kingdom)
pattern: dd/MM/yy
localizedPattern: dd/MM/yy
localized pattern re-parsed successfully
resulting date: 15/03/12
yearlessPattern = dd/MM
resulting date without year: 15/03
country: German (Germany)
pattern: dd.MM.yy
localizedPattern: tt.MM.uu
localized pattern re-parsed unsuccessfully: Illegal pattern character 't'
resulting date: 15.03.12
yearlessPattern = dd.MM
resulting date without year: 15.03
country: Chinese (China)
pattern: yy-M-d
localizedPattern: aa-n-j
localized pattern re-parsed unsuccessfully: Illegal pattern character 'n'
resulting date: 12-3-15
yearlessPattern = M-d
resulting date without year: 3-15
总而言之,要显示没有一年的本地化日期:
String yearlessPattern = DateFormat.getDateInstance(DateFormat.SHORT).toPattern().replaceAll("\\W?[Yy]+\\W?", "");
答案 1 :(得分:8)
我需要将日期转换为字符串删除年份。字符串应保持区域设置。日期格式的类型为DateFormat.LONG
,而非DateFormat.SHORT
。例如,完整字符串为September 18, 2012
,而不是09/18/12
。
我的解决方案(基于Alex帖子):
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.regex.Pattern;
public class Test {
private static void testLocaleDates() {
String fmtString = "%-20s %-25s %-25s %-20s %-20s";
System.out.println(String.format(fmtString, "Locale", "Complete date", "Pattern", "Yearless date", "Yearless pattern"));
Pattern regExpPattern = Pattern.compile("Sweden|Spain|Russia|Ukraine|States|France|German|Japan|China", Pattern.CASE_INSENSITIVE);
for (Locale locale : Locale.getAvailableLocales()) {
boolean isPrint = regExpPattern.matcher(locale.getDisplayCountry()).find();
if (!isPrint)
continue;
Date date = new Date();
String dateTxt = DateFormat.getDateInstance(DateFormat.LONG, locale).format(date);
SimpleDateFormat sdf = (SimpleDateFormat) SimpleDateFormat.getDateInstance(DateFormat.LONG, locale);
String pattern = sdf.toPattern();
// Checking 'de' we omit problems with Spain locale
String regExpPatternTxt = pattern.contains("de") ? "[^Mm]*[Yy]+[^Mm]*" : "[^DdMm]*[Yy]+[^DdMm]*";
String yearlessPattern = pattern.replaceAll(regExpPatternTxt, "");
SimpleDateFormat yearlessSDF = new SimpleDateFormat(yearlessPattern, locale);
System.out.println(String.format(fmtString, locale.getDisplayCountry(), dateTxt, pattern, yearlessSDF.format(date), yearlessPattern));
}
}
public static void main(String[] args) {
testLocaleDates();
}
}
节目输出:
区域设置 完成日期 模式 无年级日期 无年级模式
日本 2012年9月18日 YYYY / MM / DD 09/18 MM / DD 大骨节病>
日本 H24.09.18 Gy.MM.dd 09.18 MM.DD
美国 2012年9月18日 MMMM d,yyyy 9月18日 MMMM d
西班牙 18 de septiembre de 2012 d'de'MMMM'de'yyyy 18 de septiembre d 'de'MMMM
美国 18 de septiembre de 2012 d'de'MMMM'de'yyyy 18 de septiembre d'de'MMMM
乌克兰 2012年12月 d MMMM yyyy 18вересня d MMMM
西班牙 18 / setembre / 2012 d'/'MMMM'/'yyyy 18 / setembre d '/'MMMM
俄罗斯 18Сентябрь2012г。 d MMMMyyyy'г。' 18Сентябрь d MMMM
中国 2012年9月18日 YYYY '年' M '月' d '日' 9月18日 M '月' d '日'
法国 18 septembre 2012 d MMMM yyyy 18 septembre d MMMM
德国 18。 2012年9月 d。 MMMM yyyy 18。九月 d。 MMMM
瑞典 2012年9月18日 'den'd MMMM yyyy den 18 september 'den'd MMMM
答案 2 :(得分:2)
没有预定义的格式来实现这一目标。以下是一种解决方法:使用java.text.DateFormat.SHORT
格式化日期,并使用格式为yyyy
的自定义格式化程序。现在为后者搜索前者的结果。
如果年份接近开头,则删除年后的下一个非数字,否则在年份之前删除非数字。
但这也不完美,因为它给你“12.3”而不是“12.3”。对于德国人。
如果你真的需要做对,请查看Java源代码,特别是sun.text.resources
中的包rt.jar
并打印所有语言环境日期(您只需创建一个DateFormat
所有语言环境都使用SHORT
类型。
这应该为您提供创建自己的资源包所需的所有数据,其中包含所有语言的日/月格式字符串。
答案 3 :(得分:1)
您可以提取模式并删除年份。
SimpleDateFormat df = (SimpleDateFormat)
DateFormat.getDateInstance(DateFormat.SHORT);
String pattern = df.toLocalizedPattern().replaceAll(".?[Yy].?", "");
System.out.println(pattern);
SimpleDateFormat mdf = new SimpleDateFormat(pattern);
打印
M/d
在我的系统上。
答案 4 :(得分:1)
其他作者已经正确认识到Java平台没有为一个月 - 日组合管理预定义的本地化格式模式而没有使用年份,因此建议使用数据分析和正则表达式模式等复杂的解决方法。
我已根据最新的CLDR数据将此类格式模式嵌入到我的库Time4J中。例如:
AnnualDate now = SystemClock.inLocalView().now(AnnualDate.chronology());
System.out.println("xml-schema: " + now); // --09-23
ChronoFormatter<AnnualDate> fEnglishUS =
ChronoFormatter.ofStyle(DisplayMode.SHORT, Locale.US, AnnualDate.chronology());
ChronoFormatter<AnnualDate> fFrench =
ChronoFormatter.ofStyle(DisplayMode.SHORT, Locale.FRENCH, AnnualDate.chronology());
ChronoFormatter<AnnualDate> fGerman =
ChronoFormatter.ofStyle(DisplayMode.SHORT, Locale.GERMAN, AnnualDate.chronology());
System.out.println("us: " + fEnglishUS.format(now)); // 9/23
System.out.println("french: " + fFrench.format(now)); // 23/09
System.out.println("german: " + fGerman.format(now)); // 23.9.
很高兴知道:ICU4J确实具备此功能,但API功能要复杂得多。
答案 5 :(得分:0)
您可能已经意识到,短格式不仅取决于语言,还取决于国家/地区。不幸的是,Java中没有内置的模式。相反,您可能需要使用CLDR定义的那些 - 搜索“模式”或“Md”(月/日模式)。
但是,我必须警告你,这些模式可能是错误的。相反,您可能希望将它们移动到资源文件中并让翻译人员处理它们(适当的评论它是什么以及如何处理它。)
答案 6 :(得分:0)
LocalDate ld = LocalDate.parse( "2012-12-03" ); // December 3rd.
MonthDay md = MonthDay.from( ld );
Java提供了一个类来表示没有任何年份的这样的值,月份和日期:java.time.MonthDay
--MM-DD
如果您致电toString
,则会获得以ISO 8601标准--MMDD
之后的格式生成的字符串。这是扩展格式,标准还允许使用基本格式最小化分隔符String output = md.toString();
的使用。参考:第5.2.1.3节截断的表示d)ISO 8601:2000标准的隐含年份中的特定日期。
DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM/dd" );
String output = md.format( f );
- 12-03
我建议尽可能使用标准格式。但是,如果必须使用其他格式,则可以使用DateTimeFormatter
类进行指定。
Y
12/03
java.time类提供date-only values和date-time values的自动本地化。不幸的是,没有对月日价值的支持。因此,您必须明确定义自己的自定义格式,以实现所需的本地化。有关替代方案,请参阅the Answer by Meno Hochschild。
答案 7 :(得分:0)
有关在设置为西班牙语区域设置的设备上使用 DateFormat.getDateInstance(DateFormat.LONG)
或 DateFormat.getDateInstance(DateFormat.FULL)
的说明。
来自 simpleDateFormat.toLocalizedPattern()
的文本文字的格式。
d 'de' MMMM 'de' y
在我正在看的情况下。
(e.g. 2021 年 1 月 15 日在西班牙语中是 15 de enero de 2021)
删除 y
和任何非单词字符会导致 java.lang.IllegalArgumentException: Unterminated quote
异常(因为最后一个 '
上的最后一个 'de'
将作为非单词字符被删除) .
因此,作为最糟糕的解决方案,在我们的非年份格式化程序中,如果模式包含单引号字符 '
,我们将删除任何文字。 (使用正则表达式 pattern.replaceAll("'\\w+'", "")
)。
我已经与其他一些当地人进行了测试,它似乎有效。 (de, ja, pt, en)