将时间戳转换为正常日期格式

在我的Web应用程序中,用户的特定活动的日期和时间被存储(在数据库中)作为时间戳Long ,其被显示回用户需要被转换为正常的日期/时间格式。

(实际上我的数据库Cassandra存储了一个列写入时的时间戳,作为一个长值(自1970年以来的微秒),我将用它来查找相应用户活动的时间)

我正在使用JSF 2.0(+ primefaces),我认为它有可能对这种转换有帮助的转换器? 或者我怎样才能充其量实现这些转换呢?

让我为您提出这个解决方案。 所以在你的托管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的对象)

  

如果您有多个页面想要使用此方法,则可以将其放在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更好(重量更轻,速度更快,function更多)。 另外, January Calendar.Month0 ,迫使开发人员在结果中添加1 ,并且您必须自己格式化时间。 使用JodaTime ,您可以解决所有这些问题。 如果我错了,请纠正我,但我认为JodaTime已纳入JDK7

不确定JSF是否提供内置function,但您可以使用java.sql.Date的构造函数转换为日期对象: http : //download.oracle.com/javase/1.5.0/docs/api/的Java / SQL / Date.html#日期(长)

然后,您应该能够使用Java SE,Java EE提供的更高级别的function来显示和格式化提取的日期。 您可以实例化java.util.Calendar并显式设置时间: http : //download.oracle.com/javase/1.5.0/docs/api/java/util/Calendar.html#setTime( java.util.Calendar

编辑:JSF组件不应该负责转换。 您的数据访问层(持久层)应该处理这个问题。 换句话说,您的JSF组件不应处理long类型属性,而应仅处理DateCalendar类型属性。

java.time

  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

12月份的“Noll”是盖尔语,所以这应该让你的用户感到高兴。 除了生活在塔什干的盖尔语人士很少,所以请自己指定用户的正确时区和地区。

我认真对待你从数据库中得到的微秒。 如果第二个精度很好,你可以不使用Instant.ofEpochSecond() ,只使用一个方法Instant.ofEpochSecond() ,这将使代码更短几行。 由于InstantZonedDateTime确实支持纳秒精度,因此我发现保持时间戳的完整精度是最正确的。 如果你的时间戳是以毫秒而不是微秒(它们经常是),你可以使用Instant.ofEpochMilli()

7年前问这个问题时,使用DateCalendar和/或SimpleDateFormat的答案都很好。 今天这些类都已经过时了,我们在java.time ,现代Java日期和时间API方面做得更好。

对于大多数用途,我建议您使用内置的本地化格式,就像我在代码中一样。 您可以尝试为格式样式传递SHORTLONGFULL 。 Yo甚至可以使用重载的ofLocalizedDateTime方法分别指定日期和时间的格式样式。 如果需要特定的格式(这是在一个重复的问题中提出的 ),您可以:

  DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss, dd/MM/uuuu"); 

我们得到了这个格式化器

2017年1月4日05:01:18

链接: Oracle教程:Date Time解释如何使用java.time

要显示小时,分钟和秒前面的前导零,请使用以下修改后的代码。 这里的技巧是我们将整数转换(或更准确地格式化)为字符串,以便在适用时显示前导零:

 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