在angularJs视图中格式化Java 8 LocalDateTime

时间:2019-02-08 09:23:41

标签: angularjs spring-boot java-8

我正在使用带有angularJs UI的spring boot,我的应用程序将java.time.LocalDateTime传递到了环形视图。

我正尝试使用angularjs'的日期过滤器,如下所示:

{{ localDateTime | date : 'yyyy/MM/dd hh:mm:ss' }}

但是它不起作用。输出结果如下:

{"dayOfMonth":8,"dayOfWeek":"FRIDAY","dayOfYear":39,"month":"FEBRUARY","year":2019,"monthValue":2,"hour":14,"minute":48,"nano":87000000,"second":24,"chronology":{"id":"ISO","calendarType":"iso8601"}}

我什至尝试将application.property添加为建议的here。仍然像上面的JSON所示。有人可以帮忙吗。

3 个答案:

答案 0 :(得分:2)

问题在于,默认情况下,杰克逊不知道如何正确地将Java 8日期结构(JSR 310)序列化为JSON。结果,它返回了一个包含dayOfMonthdayOfWeek……的完整对象结构。

一种解决方案是将日期序列化为众所周知的格式,例如ISO-8601字符串。为此,您首先必须通过添加以下依赖项来添加对这些Java 8类型的支持:

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
</dependency>

在那之后,您应该注意到日期已被序列化为数组,例如:

[2019, 2, 8, 11, 0, 0, 0, 0]

这是一个包含年,月的月日等的数组。但是,AngularJS日期过滤器尚不能使用这些结果。正确的解决方案是将它们格式化为没有时区的ISO-8601字符串(考虑为LocalDateTime)。您可以通过在 application.properties 中配置以下属性来禁用Jackson的WRITE_DATES_AS_TIMESTAMPS序列化功能:

spring.jackson.serialization.write-dates-as-timestamps=false

现在,您的日期将被设置为字符串格式,例如:

"2019-02-08T11:00:00.000"

如果您查看AngularJS日期过滤器的the documentation,您会发现它已得到正确支持:

  

日期格式为日期对象,毫秒(字符串或数字)或各种ISO 8601日期时间字符串格式(例如yyyy-MM-ddTHH:mm:ss.sssZ及其较短的版本,例如yyyy -MM-ddTHH:mmZ,yyyy-MM-dd或yyyyMMddTHHmmssZ)。

请注意,由于您使用的是LocalDateTime,因此没有给出任何时区信息,因此AngularJS日期过滤器将其视为本地浏览器时间,如同一文档中所述:

  

如果在字符串输入中未指定时区,则该时间将视为本地时区。

这意味着如果服务器时区与浏览器时区不同,则给定时间会有问题。

答案 1 :(得分:0)

您可以创建一个自定义日期过滤器,该过滤器包装有角度的日期过滤器以支持Jackson序列化对象的方式。在添加jackson-datatype-jsr310依赖项之后,这应该可以解决问题:

角度过滤器

angular.module('YourModule')
    .filter('localDateTime', localDateTime);

localDateTime.$inject = ['$filter'];
function localDateTime($filter) {
    return function (input, format) {
        if(!input){
            return '';
        }


        const year   = input[0] || 0;
        const month  = input[1] || 0;
        const day    = input[2] || 0;
        const hour   = input[3] || 0;
        const minute = input[4] || 0;
        const second = input[5] || 0;
        const nano   = input[6] || 0;

        const date = new Date(year, month-1, day, hour, minute, second, nano);
        return $filter('date')(date, format);
    };
}

HTML

{{yourTimeField | localDateTime: 'yyyy/MM/dd hh:mm:ss'}}

如果您不想添加jackson-datatype-jsr310依赖关系,则可以修改const日期值以使用对象上的属性。

注意:我以前遇到过以对象格式将数据发布到服务器的问题,并被迫更新依赖项

答案 2 :(得分:0)

实际上,杰克逊(至少在版本不是太过时的情况下)确实知道如何处理它。您只需要正确注释您的媒体资源即可:

@JsonFormat(shape= JsonFormat.Shape.STRING, pattern="EEE MMM dd HH:mm:ss Z yyyy")
@JsonProperty("created_at") 
ZonedDateTime created_at; 

看到这个问题:Jackson deserialize date from Twitter to `ZonedDateTime`