在我的网络应用中,日期&用户特定活动的时间被存储(在数据库中)作为时间戳Long
,其被显示回用户需要被转换为正常的日期/时间格式。
(实际上我的数据库Cassandra存储了一个列写入时的时间戳,作为一个长值(自1970年以来的微秒),我将用它来查找相应用户活动的时间)
我正在使用JSF 2.0(+ primefaces),我认为它有可能对此转换有帮助的转换器?或者我怎样才能充其量实现这些转换呢?
答案 0 :(得分:57)
让我为您提出这个解决方案。所以在你的托管bean中,这样做
public String convertTime(long time){
Date date = new Date(time);
Format format = new SimpleDateFormat("yyyy MM dd HH:mm:ss");
return format.format(date);
}
所以在你的JSF页面中,你可以这样做(假设foo
是包含你time
的对象)
<h:dataTable value="#{myBean.convertTime(myBean.foo.time)}" />
如果您有多个页面想要使用此方法,可以将其放在abstract class
中,并让托管bean扩展此abstract class
。
编辑:使用TimeZone返回时间
不幸的是,我认为SimpleDateFormat
将始终以当地时间格式化时间,因此我们不能再使用SimpleDateFormat
了。因此,要在不同的TimeZone中显示时间,我们可以这样做
public String convertTimeWithTimeZome(long time){
Calendar cal = Calendar.getInstance();
cal.setTimeZone(TimeZone.getTimeZone("UTC"));
cal.setTimeInMillis(time);
return (cal.get(Calendar.YEAR) + " " + (cal.get(Calendar.MONTH) + 1) + " "
+ cal.get(Calendar.DAY_OF_MONTH) + " " + cal.get(Calendar.HOUR_OF_DAY) + ":"
+ cal.get(Calendar.MINUTE));
}
更好的解决方案是使用JodaTime
。在我看来,这个API比Calendar更好(重量更轻,速度更快,功能更多)。 Calendar.Month
January
的{{1}}加0
,迫使开发者将1
添加到结果中,您必须自己格式化时间。使用JodaTime
,您可以解决所有问题。如果我错了,请纠正我,但我认为JodaTime
已纳入JDK7
答案 1 :(得分:1)
不确定JSF是否提供内置功能,但您可以使用java.sql.Date
的构造函数转换为日期对象:http://download.oracle.com/javase/1.5.0/docs/api/java/sql/Date.html#Date(long)
然后,您应该能够使用Java SE,Java EE提供的更高级别功能来显示和格式化提取的日期。您可以实例化java.util.Calendar
并明确设置时间:http://download.oracle.com/javase/1.5.0/docs/api/java/util/Calendar.html#setTime(java.util.Date)
编辑:JSF组件不应该处理转换。您的数据访问层(持久层)应该处理这个问题。换句话说,您的JSF组件不应该处理long
类型的属性,而只能处理Date
或Calendar
类型的属性。
答案 2 :(得分:1)
ZoneId usersTimeZone = ZoneId.of("Asia/Tashkent");
Locale usersLocale = Locale.forLanguageTag("ga-IE");
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM)
.withLocale(usersLocale);
long microsSince1970 = 1_512_345_678_901_234L;
long secondsSince1970 = TimeUnit.MICROSECONDS.toSeconds(microsSince1970);
long remainingMicros = microsSince1970 - TimeUnit.SECONDS.toMicros(secondsSince1970);
ZonedDateTime dateTime = Instant.ofEpochSecond(secondsSince1970,
TimeUnit.MICROSECONDS.toNanos(remainingMicros))
.atZone(usersTimeZone);
String dateTimeInUsersFormat = dateTime.format(formatter);
System.out.println(dateTimeInUsersFormat);
以上代码段打印:
4 Noll 2017 05:01:18
“Noll”是12月的盖尔语,所以这应该让你的用户满意。除了居住在塔什干的盖尔语人士很少,所以请自行指定用户的正确时区和地点。
我正在认真对待您从数据库中获得的微秒数。如果第二个精度很好,则可以不使用remainingMicros
,只需使用one-arg Instant.ofEpochSecond()
,这将使代码缩短几行。由于Instant
和ZonedDateTime
确实支持纳秒精度,因此我发现保持时间戳的完整精度是最正确的。如果你的时间戳是以毫秒而不是微秒(它们经常是),你可以使用Instant.ofEpochMilli()
。
7年前提出这个问题时,使用Date
,Calendar
和/或SimpleDateFormat
的答案都很好。今天这些课程都已经过时了,我们在java.time
,现代Java日期和时间API方面做得更好。
对于大多数用途,我建议您使用内置的本地化格式,就像我在代码中一样。您可以尝试传递SHORT
,LONG
或FULL
格式样式。 Yo甚至可以使用重载的ofLocalizedDateTime
方法分别指定日期和时间的格式样式。如果需要特定的格式(这在a duplicate question中提出),您可以拥有:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss, dd/MM/uuuu");
使用此格式化程序,我们得到
05:01:18,04/12/2017
链接: Oracle tutorial: Date Time解释如何使用java.time
。
答案 3 :(得分:0)
要显示小时,分钟和秒前面的前导零,请使用以下修改后的代码。这里的技巧是我们将整数转换(或更准确地格式化)为字符串,以便在适用时显示前导零:
public String convertTimeWithTimeZome(long time) {
Calendar cal = Calendar.getInstance();
cal.setTimeZone(TimeZone.getTimeZone("UTC"));
cal.setTimeInMillis(time);
String curTime = String.format("%02d:%02d:%02d", cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND));
return curTime;
}
结果如下:00:01:30
答案 4 :(得分:0)
我尝试过并为我工作。
echo json_encode(array(
'qwe' => 1,
'asd' => 2,
'zxc' => 3
));