1 package com.fasterxml.jackson.datatype.jsr310.ser;
2
3 import com.fasterxml.jackson.annotation.JsonFormat;
4 import java.io.IOException;
5 import java.time.ZonedDateTime;
6 import java.time.format.DateTimeFormatter;
7
8 import com.fasterxml.jackson.core.JsonGenerator;
9 import com.fasterxml.jackson.core.JsonToken;
10 import com.fasterxml.jackson.databind.SerializationFeature;
11 import com.fasterxml.jackson.databind.SerializerProvider;
12
13 public class ZonedDateTimeSerializer extends InstantSerializerBase<ZonedDateTime> {
14     private static final long serialVersionUID = 1L;
15
16     public static final ZonedDateTimeSerializer INSTANCE = new ZonedDateTimeSerializer();
17
18     /**
19      * Flag for <code>JsonFormat.Feature.WRITE_DATES_WITH_ZONE_ID</code>
20      *
21      * @since 2.8
22      */

23     protected final Boolean _writeZoneId;
24     
25     protected ZonedDateTimeSerializer() {
26         // ISO_ZONED_DATE_TIME is not the ISO format, it is an extension of it
27         this(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
28     }
29
30     public ZonedDateTimeSerializer(DateTimeFormatter formatter) {
31         super(ZonedDateTime.class, dt -> dt.toInstant().toEpochMilli(),
32               ZonedDateTime::toEpochSecond, ZonedDateTime::getNano,
33               formatter);
34         _writeZoneId = null;
35     }
36
37     protected ZonedDateTimeSerializer(ZonedDateTimeSerializer base,
38             Boolean useTimestamp, DateTimeFormatter formatter, Boolean writeZoneId) {
39         this(base, useTimestamp, null, formatter, writeZoneId);
40     }
41
42     protected ZonedDateTimeSerializer(ZonedDateTimeSerializer base,
43             Boolean useTimestamp, Boolean useNanoseconds, DateTimeFormatter formatter,
44             Boolean writeZoneId) {
45         super(base, useTimestamp, useNanoseconds, formatter);
46         _writeZoneId = writeZoneId;
47     }
48
49     @Override
50     protected JSR310FormattedSerializerBase<?> withFormat(
51         Boolean useTimestamp,
52         DateTimeFormatter formatter,
53         JsonFormat.Shape shape) {
54         return new ZonedDateTimeSerializer(this, useTimestamp, formatter, _writeZoneId);
55     }
56
57     @Override
58     @Deprecated
59     protected JSR310FormattedSerializerBase<?> withFeatures(Boolean writeZoneId) {
60         return new ZonedDateTimeSerializer(this, _useTimestamp, _formatter, writeZoneId);
61     }
62
63     @Override
64     protected JSR310FormattedSerializerBase<?> withFeatures(Boolean writeZoneId, Boolean writeNanoseconds) {
65         return new ZonedDateTimeSerializer(this, _useTimestamp, writeNanoseconds, _formatter, writeZoneId);
66     }
67
68     @Override
69     public void serialize(ZonedDateTime value, JsonGenerator g, SerializerProvider provider)
70         throws IOException
71     {
72         if (!useTimestamp(provider)) {
73             if (shouldWriteWithZoneId(provider)) {
74                 // write with zone
75                 g.writeString(DateTimeFormatter.ISO_ZONED_DATE_TIME.format(value));
76                 return;
77             }
78         }
79         super.serialize(value, g, provider);
80     }
81
82     /**
83      * @since 2.8
84      */

85     public boolean shouldWriteWithZoneId(SerializerProvider ctxt) {
86         return (_writeZoneId != null) ? _writeZoneId :
87             ctxt.isEnabled(SerializationFeature.WRITE_DATES_WITH_ZONE_ID);
88     }
89
90     @Override // since 2.9
91     protected JsonToken serializationShape(SerializerProvider provider) {
92         if (!useTimestamp(provider) && shouldWriteWithZoneId(provider)) {
93             return JsonToken.VALUE_STRING;
94         }
95         return super.serializationShape(provider);
96     }
97 }
98