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

时间:2011-07-21 20:16:18

标签: java jsf primefaces

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

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

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

5 个答案:

答案 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类型的属性,而只能处理DateCalendar类型的属性。

答案 2 :(得分:1)

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

“Noll”是12月的盖尔语,所以这应该让你的用户满意。除了居住在塔什干的盖尔语人士很少,所以请自行指定用户的正确时区和地点。

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

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

对于大多数用途,我建议您使用内置的本地化格式,就像我在代码中一样。您可以尝试传递SHORTLONGFULL格式样式。 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
));