Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,20 @@
import com.alibaba.fastjson2.util.DateUtils;

import java.lang.reflect.Type;
import java.time.*;
import java.time.DateTimeException;
import java.time.Instant;
import java.time.Year;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

final class ObjectWriterImplInstant
extends DateTimeCodec
implements ObjectWriter {
static final ObjectWriterImplInstant INSTANCE = new ObjectWriterImplInstant(null, null);
static final ObjectWriterImplInstant INSTANCE =
new ObjectWriterImplInstant(null, null);

public ObjectWriterImplInstant(String format, Locale locale) {
super(format, locale);
}
Expand All @@ -36,8 +42,15 @@ public void write(JSONWriter jsonWriter, Object object, Object fieldName, Type f
: context.getDateFormat();

Instant instant = (Instant) object;
if (dateFormat == null) {
jsonWriter.writeInstant(instant);

if (formatUnixTime || (format == null && context.isDateFormatUnixTime())) {
long millis = instant.toEpochMilli();
jsonWriter.writeInt64(millis / 1000);
return;
}

if (formatMillis || (format == null && context.isDateFormatMillis())) {
jsonWriter.writeInt64(instant.toEpochMilli());
return;
}

Expand All @@ -63,7 +76,7 @@ public void write(JSONWriter jsonWriter, Object object, Object fieldName, Type f

long zeroDay = localEpochDay + DAYS_0000_TO_1970;
// find the march-based year
zeroDay -= 60; // adjust to 0000-03-01 so leap day is at end of four year cycle
zeroDay -= 60; // adjust to 0000-03-01 so leap day is at end of four year cycle
long adjust = 0;
if (zeroDay < 0) {
// adjust negative years to positive for calculation
Expand All @@ -78,7 +91,7 @@ public void write(JSONWriter jsonWriter, Object object, Object fieldName, Type f
yearEst--;
doyEst = zeroDay - (365 * yearEst + yearEst / 4 - yearEst / 100 + yearEst / 400);
}
yearEst += adjust; // reset any negative year
yearEst += adjust; // reset any negative year
int marchDoy0 = (int) doyEst;

// convert march-based values back to january-based
Expand Down Expand Up @@ -158,19 +171,6 @@ public void write(JSONWriter jsonWriter, Object object, Object fieldName, Type f

ZonedDateTime zdt = ZonedDateTime.ofInstant(instant, context.getZoneId());

if (formatUnixTime || (format == null && context.isDateFormatUnixTime())) {
long millis = zdt.toInstant().toEpochMilli();
jsonWriter.writeInt64(millis / 1000);
return;
}

if (formatMillis || (format == null && context.isDateFormatMillis())) {
jsonWriter.writeInt64(zdt
.toInstant()
.toEpochMilli());
return;
}

int year = zdt.getYear();
if (year >= 0 && year <= 9999) {
if (formatISO8601 || (format == null && context.isDateFormatISO8601())) {
Expand All @@ -195,7 +195,7 @@ public void write(JSONWriter jsonWriter, Object object, Object fieldName, Type f
}

if (formatter == null) {
jsonWriter.writeZonedDateTime(zdt);
jsonWriter.writeInstant(instant);
} else {
String str = formatter.format(zdt);
jsonWriter.writeString(str);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.alibaba.fastjson2.issues_4000;

import com.alibaba.fastjson2.JSONFactory;
import com.alibaba.fastjson2.JSONWriter;
import org.junit.jupiter.api.Test;

import java.time.Instant;
import java.time.ZoneId;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class Issue4003 {
private static String toJSONString(Instant instant, String format) {
JSONWriter.Context context = JSONFactory.createWriteContext();
context.setZoneId(ZoneId.of("UTC"));
if (format != null) {
context.setDateFormat(format);
}
try (JSONWriter writer = JSONWriter.of(context)) {
writer.writeAny(instant);
return writer.toString();
}
}

@Test
public void testInstantWithISO8601Format() {
Instant instant = Instant.parse("2026-02-24T14:50:00Z");
String json = toJSONString(instant, "iso8601");

assertEquals("\"2026-02-24T14:50:00Z\"", json);
}

@Test
public void testInstantWithISO8601FormatWithMillis() {
Instant instant = Instant.parse("2026-02-24T14:50:00.123Z");
String json = toJSONString(instant, "iso8601");
assertEquals("\"2026-02-24T14:50:00.123Z\"", json);
}

@Test
public void testInstantWithoutISO8601Format() {
Instant instant = Instant.parse("2026-02-24T14:50:00Z");
String json = toJSONString(instant, null);

assertEquals("\"2026-02-24T14:50:00Z\"", json);
}
}
Loading