我正在尝试根据用户的设置获取格式化日期(年,月,日)和时间(小时,分钟,秒)字符串。 Android开发者Google小组中的This帖子描述了我遇到的确切问题,但没有人帮助该人解决问题。我将总结一下:
Android有这些类尝试执行上述操作,但没有使用用户首选项并显示秒数。
java.text.DateFormat中
不使用在“设置”应用
android.text.format.DateFormat
获取java.text.DateFormat
对象,使用getDateFormat()
和getTimeFormat()
正确格式化输出,但getTimeFormat()
不包含秒。
android.text.format.DateUtils
没有使用设置应用中显示日期的首选项,也无法显示秒数。
例如,如果设置中的首选项设置为DD / MM / YYYY且24小时格式=开启,则运行以下代码:
long timestamp=System.currentTimeMillis();
sometextview.setText(
java.text.format.DateFormat.getDateTimeInstance().format(new Date(timestamp))
+"\n"+
android.text.format.DateFormat.getDateFormat(this).format(new Date(timestamp))
+" "+
android.text.format.DateFormat.getTimeFormat(this).format(new Date(timestamp))
+"\n"+
android.text.format.DateUtils.formatDateTime(this,
timestamp,
DateUtils.FORMAT_SHOW_DATE|
DateUtils.FORMAT_SHOW_TIME|
DateUtils.FORMAT_SHOW_YEAR)
);
在textview中给出了以下输出:
Apr 27,2014 5:47:18 PM
27/04/2014 17:47
April 27,2014, 17:47
None给出了所需的输出,使用上述首选项就是这样的:
27/04/2014 17:47:18
我也查看了joda-time-android图书馆,但它似乎没有做我需要的事情(如果我错了,请纠正我。)
TL; DR:如何根据Android上的用户偏好以秒格式化日期/时间?
答案 0 :(得分:4)
使用@I wish I could think of a good
的建议,我制作了以下代码,使用区域设置和用户设置格式化日期:
public static String timeDateStringFromTimestamp(Context applicationContext,long timestamp){
String timeDate;
String androidDateTime=android.text.format.DateFormat.getDateFormat(applicationContext).format(new Date(timestamp))+" "+
android.text.format.DateFormat.getTimeFormat(applicationContext).format(new Date(timestamp));
String javaDateTime = DateFormat.getDateTimeInstance().format(new Date(timestamp));
String AmPm="";
if(!Character.isDigit(androidDateTime.charAt(androidDateTime.length()-1))) {
if(androidDateTime.contains(new SimpleDateFormat().getDateFormatSymbols().getAmPmStrings()[Calendar.AM])){
AmPm=" "+new SimpleDateFormat().getDateFormatSymbols().getAmPmStrings()[Calendar.AM];
}else{
AmPm=" "+new SimpleDateFormat().getDateFormatSymbols().getAmPmStrings()[Calendar.PM];
}
androidDateTime=androidDateTime.replace(AmPm, "");
}
if(!Character.isDigit(javaDateTime.charAt(javaDateTime.length()-1))){
javaDateTime=javaDateTime.replace(" "+new SimpleDateFormat().getDateFormatSymbols().getAmPmStrings()[Calendar.AM], "");
javaDateTime=javaDateTime.replace(" "+new SimpleDateFormat().getDateFormatSymbols().getAmPmStrings()[Calendar.PM], "");
}
javaDateTime=javaDateTime.substring(javaDateTime.length()-3);
timeDate=androidDateTime.concat(javaDateTime);
return timeDate.concat(AmPm);
}
答案 1 :(得分:4)
试试这个:
long timestamp = System.currentTimeMillis();
DateFormat dateFormat = android.text.format.DateFormat.getDateFormat(getApplicationContext());
DateFormat timeFormat = DateFormat.getTimeInstance();
String currentTimeString = dateFormat.format(timestamp) + " - " +
timeFormat.format(timestamp);
答案 2 :(得分:3)
为什么不使用混合解决方案
android.text.format.DateFormat.getDateFormat(this).format(new Date(timestamp));
和
java.text.format.DateFormat.getDateTimeInstance().format(new Date(timestamp))
对于getDateTimeInstance
将其另存为字符串并提取秒数,然后将其附加到getDateFormat
答案 3 :(得分:0)
ZonedDateTime.now( ZoneId.of( "America/Montreal" ) )
.format( DateTimeFormatter.ofPattern( "dd/MM/uuuu HH:mm:ss" ) )
23/01/2017 12:34:56
添加ThreeTenABP项目(见下文)以访问java.time框架的现代日期时间类。旧的遗留日期时间类是出了名的麻烦,令人困惑和有缺陷。
时区对于确定日期至关重要。对于任何给定的时刻,日期在全球范围内因地区而异。例如,在Paris France午夜后的几分钟是新的一天,而Montréal Québec中仍然是“昨天”。
以continent/region
的格式指定proper time zone name,例如America/Montreal
,Africa/Casablanca
或Pacific/Auckland
。切勿使用诸如EST
或IST
之类的3-4字母缩写,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。
ZoneId z = ZoneId.of( "America/Montreal" ); // Or ZoneId.systemDefault()
ZonedDateTime zdt = ZonedDateTime.now( z );
使用DateTimeFormatter
生成表示该ZonedDateTime
对象值的字符串。指定自定义格式设置模式,或调用toLocalized…
方法自动本地化为用户的人类语言和文化规范。
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/uuuu HH:mm:ss" ) ;
String output = zdt.format( f );
23/01/2017 12:34:56
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和& SimpleDateFormat
现在位于Joda-Time的maintenance mode项目建议迁移到java.time类。
要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。
从哪里获取java.time类?
更新:现在位于Joda-Time的maintenance mode项目建议迁移到java.time类。
Joda-Time可以以区域设置敏感的方式轻松格式化日期时间值。查看DateTimeFormat
类。
DateTimeFormatter formatter = DateTimeFormat.forStyle( "SM" );
DateTime dateTime = DateTime.now();
String output = formatter.print( dateTime );
使用这两个字母序列来获取您想要的格式。第一个字符是日期样式,第二个字符是时间样式。为短格式指定'S'字符,为中等指定'M',为长指定'L',为完整指定'F'。通过指定样式字符' - '可以省略日期或时间。
Locale
根据文化规范控制格式,并控制用于翻译日期名称,月份名称等的语言。
如果未指定Locale,则会以静默方式应用JVM的当前默认Locale。由于此默认值可能会在运行时之前或甚至在运行时期间发生更改,因此我建议您指定所需/预期的区域设置。如果您确实想要当前的默认值,我建议您同时调用Locale.getDefault
,以便让您的代码自我记录。
formatter = formatter.withLocale( Locale.CANADA_FRENCH );
答案 4 :(得分:0)
有点黑客,但这似乎有效:
Date date = ...;
String dateStr = DateFormat.getLongDateFormat(context).format(date);
String timeStr;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
String timeFormat = DateFormat.getBestDateTimePattern(Locale.getDefault(), DateFormat.is24HourFormat(context) ? "Hms" : "hmsa");
timeStr = new SimpleDateFormat(timeFormat, Locale.getDefault()).format(date);
}
else {
String timeFormat = DateFormat_getTimeFormatString(context).replace("mm", "mm:ss");
timeStr = new SimpleDateFormat(timeFormat, Locale.getDefault()).format(date);
}
return dateStr + " " + timeStr;
它依赖于`DateFormat中的隐藏函数,我们可以通过反射使用
private static String DateFormat_getTimeFormatString(Context context) {
try {
final Method method = DateFormat.class.getDeclaredMethod("getTimeFormatString");
method.setAccessible(true);
return (String) method.invoke(context);
}
catch (Exception ignored) {
return "HH:mm";
}
}
从API 18开始,您可以使用新的getBestDateTimePattern()
函数,该函数只需要显示您想要显示的数据列表,并返回最佳匹配模式。
如果查看is24HourFormat()
源代码,它有点疯狂(它检查用户首选模式字符串中是否有大写的 H ),所以它可能值得如果您需要显示许多日期,请存储其值而不是重复调用它。
当然,您可以通过调用其他实例或使用DateUtils.formatDateTime()
来确定日期所需的格式。
is24HourFormat()
。应用程序上下文不会这样做。