You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Jackson将ZoneId/ZoneOffset从+03:00序列化为+03.00格式?

Jackson序列化ZoneId/ZoneOffset:将冒号替换为点号的实现方式

一、自定义序列化器(推荐方案)

通过实现Jackson的JsonSerializer接口,精准控制ZoneOffset/ZoneId的序列化输出,将格式中的冒号替换为点号。

1. 针对ZoneOffset的序列化器

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
import java.time.ZoneOffset;

public class ZoneOffsetDotSerializer extends JsonSerializer<ZoneOffset> {
    @Override
    public void serialize(ZoneOffset value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        String formattedOffset = value.toString().replace(':', '.');
        gen.writeString(formattedOffset);
    }
}

2. 针对ZoneId的序列化器

ZoneId可能包含普通时区ID(如Europe/Paris)或偏移量(本质是ZoneOffset实例),因此序列化器需要区分处理:

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
import java.time.ZoneId;
import java.time.ZoneOffset;

public class ZoneIdDotSerializer extends JsonSerializer<ZoneId> {
    @Override
    public void serialize(ZoneId value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        if (value instanceof ZoneOffset) {
            String formattedOffset = value.toString().replace(':', '.');
            gen.writeString(formattedOffset);
        } else {
            gen.writeString(value.toString());
        }
    }
}

3. 注册序列化器到ObjectMapper

将自定义序列化器注册到Jackson的ObjectMapper中使其生效:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import java.time.ZoneId;
import java.time.ZoneOffset;

public class SerializationDemo {
    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        SimpleModule customModule = new SimpleModule();
        
        customModule.addSerializer(ZoneOffset.class, new ZoneOffsetDotSerializer());
        customModule.addSerializer(ZoneId.class, new ZoneIdDotSerializer());
        
        mapper.registerModule(customModule);
        
        ZoneOffset offset = ZoneOffset.of("+03:00");
        System.out.println(mapper.writeValueAsString(offset)); // 输出 "+03.00"
        
        ZoneId zoneIdOffset = ZoneId.of("+05:30");
        System.out.println(mapper.writeValueAsString(zoneIdOffset)); // 输出 "+05.30"
        
        ZoneId zoneId = ZoneId.of("Europe/Paris");
        System.out.println(mapper.writeValueAsString(zoneId)); // 输出 "Europe/Paris"
    }
}

二、其他实现方式

1. 序列化后字符串替换(简单场景适用)

如果仅单独序列化ZoneOffset/ZoneId,或能确保JSON中其他内容无需要保留的冒号,可在序列化完成后直接替换字符串:

import com.fasterxml.jackson.databind.ObjectMapper;
import java.time.ZoneOffset;

public class StringReplaceDemo {
    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        ZoneOffset offset = ZoneOffset.of("+03:00");
        
        String originalJson = mapper.writeValueAsString(offset);
        String modifiedJson = originalJson.replace(':', '.');
        
        System.out.println(modifiedJson); // 输出 "+03.00"
    }
}

注意:该方式存在误替换风险,若JSON中其他字段(如日期字符串)包含冒号会被一并修改,仅适合简单场景。

2. 自定义格式化器配合JavaTimeModule

基于Jackson的JavaTimeModule扩展默认序列化逻辑,结合字符串替换实现需求:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.ser.ZoneOffsetSerializer;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;

public class FormatterDemo {
    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        JavaTimeModule module = new JavaTimeModule();
        
        ZoneOffsetSerializer customSerializer = new ZoneOffsetSerializer(DateTimeFormatter.ISO_OFFSET_DATE_TIME) {
            @Override
            public void serialize(ZoneOffset value, com.fasterxml.jackson.core.JsonGenerator gen, com.fasterxml.jackson.databind.SerializerProvider serializers) throws IOException {
                String offsetStr = value.toString().replace(':', '.');
                gen.writeString(offsetStr);
            }
        };
        
        module.addSerializer(ZoneOffset.class, customSerializer);
        mapper.registerModule(module);
        
        ZoneOffset offset = ZoneOffset.of("+03:00");
        System.out.println(mapper.writeValueAsString(offset)); // 输出 "+03.00"
    }
}

内容的提问来源于stack exchange,提问作者trom

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 22:40:31