在angularJs视图中格式化Java 8 LocalDateTime

在angularJs视图中格式化Java 8 LocalDateTime,angularjs,spring-boot,java-8,Angularjs,Spring Boot,Java 8,我将spring boot与angularJs UI一起使用,我的应用程序将java.time.LocalDateTime传递到anular视图 我正在尝试使用angularjs's日期过滤器,如下所示: {"dayOfMonth":8,"dayOfWeek":"FRIDAY","dayOfYear":39,"month":"FEBRUARY","year":2019,"monthValue":2,"hour":14,"minute":48,"nano":87000000,"second":24

我将spring boot与angularJs UI一起使用,我的应用程序将
java.time.LocalDateTime
传递到anular视图

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

{"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"}}
{{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
。但它仍然显示为上面的JSON。有人能帮忙吗。

问题是默认情况下Jackson不知道如何将Java8日期结构()正确序列化为JSON。因此,它返回一个完整的对象结构,其中包含
dayOfMonth
dayOfWeek
。。。正如你所观察到的

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

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
这是一个数组,包含年、月、日等。但是,AngularJS日期过滤器还不能使用这些结果。正确的解决方案是将它们格式化为不带时区的ISO-8601字符串(考虑到它是
LocalDateTime
)。您可以通过禁用Jackson中的
将日期写入时间戳
序列化功能,在应用程序中配置以下属性。属性

spring.jackson.serialization.write-dates-as-timestamps=false
现在,您的日期将格式化为字符串,例如:

[2019, 2, 8, 11, 0, 0, 0, 0]
"2019-02-08T11:00:00.000"
如果您查看AngularJS日期过滤器,您会发现它得到了正确的支持:

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

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

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


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

您可以创建一个自定义日期筛选器,该筛选器包装角度日期筛选器,以支持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
日期值,以使用对象上的属性

注意:我以前在将数据以对象格式发布到服务器时遇到过问题,并被迫更新依赖项。实际上,Jackson(至少在版本不太过时的情况下)确实知道如何处理该问题。您只需正确注释您的属性:

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

请参阅此问题:

JSR-310的
LocalDateTime
不是时间戳,除非服务器时区是静态的且各方都知道。因此,将
LocalDateTime
序列化为一个数字是不正确的。@M.Prokhorov您是对的,我没有对实际使用的类型给予足够的注意。我重新措辞了我的回答,以恰当地解决你提到的问题。