From 7c25e77e041bc43663ca5d4358737fb02ed80076 Mon Sep 17 00:00:00 2001 From: liyong <1506100524@qq.com> Date: Wed, 16 Sep 2026 17:17:45 +0800 Subject: [PATCH] =?UTF-8?q?fix(common):=20=E4=BF=AE=E5=A4=8D=E6=97=A5?= =?UTF-8?q?=E6=9C=9F=E8=A7=A3=E6=9E=90=20int=20=E6=BA=A2=E5=87=BA=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/util/json/WxDateTypeAdapter.java | 4 +- .../util/json/WxDateTypeAdapterTest.java | 76 +++++++++++++++++++ 2 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 weixin-java-common/src/test/java/me/chanjar/weixin/common/util/json/WxDateTypeAdapterTest.java diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxDateTypeAdapter.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxDateTypeAdapter.java index fd54cf3f43..73321ec444 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxDateTypeAdapter.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxDateTypeAdapter.java @@ -35,7 +35,9 @@ public Date read(JsonReader in) throws IOException { in.nextNull(); return null; case NUMBER: - return new Date(in.nextInt() * 1000); + // 微信返回的是秒级时间戳,需转为毫秒;此处必须用 long 读取并运算, + // 否则 in.nextInt() * 1000 会发生 int 溢出,导致解析出错误的时间 + return new Date(in.nextLong() * 1000L); default: throw new JsonParseException("Expected NUMBER but was " + peek); } diff --git a/weixin-java-common/src/test/java/me/chanjar/weixin/common/util/json/WxDateTypeAdapterTest.java b/weixin-java-common/src/test/java/me/chanjar/weixin/common/util/json/WxDateTypeAdapterTest.java new file mode 100644 index 0000000000..4248b15128 --- /dev/null +++ b/weixin-java-common/src/test/java/me/chanjar/weixin/common/util/json/WxDateTypeAdapterTest.java @@ -0,0 +1,76 @@ +package me.chanjar.weixin.common.util.json; + +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; +import org.testng.annotations.Test; + +import java.io.IOException; +import java.io.StringReader; +import java.io.StringWriter; +import java.util.Date; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * WxDateTypeAdapter 的单元测试. + * + * @author liyong + */ +public class WxDateTypeAdapterTest { + + private final WxDateTypeAdapter adapter = new WxDateTypeAdapter(); + + private Date read(String json) throws IOException { + JsonReader reader = new JsonReader(new StringReader(json)); + reader.setLenient(true); + return adapter.read(reader); + } + + private String write(Date date) throws IOException { + StringWriter out = new StringWriter(); + JsonWriter writer = new JsonWriter(out); + writer.setLenient(true); + adapter.write(writer, date); + return out.toString(); + } + + /** + * 秒级时间戳转成毫秒时如果按 int 运算会溢出,导致解析出的时间错误(甚至早于 1970 年)。 + */ + @Test + public void testReadCurrentTimestamp() throws IOException { + long seconds = 1481013459L; + Date date = read(String.valueOf(seconds)); + assertThat(date).isNotNull(); + assertThat(date.getTime()).isEqualTo(seconds * 1000L); + } + + @Test + public void testReadTimestampAfterYear2038() throws IOException { + long seconds = 4102444800L; + Date date = read(String.valueOf(seconds)); + assertThat(date).isNotNull(); + assertThat(date.getTime()).isEqualTo(seconds * 1000L); + } + + @Test + public void testReadNull() throws IOException { + assertThat(read("null")).isNull(); + } + + @Test + public void testWrite() throws IOException { + long seconds = 1481013459L; + assertThat(write(new Date(seconds * 1000L))).isEqualTo(String.valueOf(seconds)); + assertThat(write(null)).isEqualTo("null"); + } + + /** + * 序列化与反序列化应当可以互相还原。 + */ + @Test + public void testWriteThenRead() throws IOException { + Date now = new Date(1600000000L * 1000L); + assertThat(read(write(now))).isEqualTo(now); + } +}