All Downloads are FREE. Search and download functionalities are using the official Maven repository.

shade.com.alibaba.fastjson2.writer.ObjectWriterImplInstant Maven / Gradle / Ivy

There is a newer version: 1.3.7
Show newest version
package com.alibaba.fastjson2.writer;

import com.alibaba.fastjson2.JSONWriter;
import com.alibaba.fastjson2.codec.DateTimeCodec;
import com.alibaba.fastjson2.util.DateUtils;

import java.lang.reflect.Type;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

final class ObjectWriterImplInstant
        extends DateTimeCodec
        implements ObjectWriter {
    static final ObjectWriterImplInstant INSTANCE = new ObjectWriterImplInstant(null, null);
    public ObjectWriterImplInstant(String format, Locale locale) {
        super(format, locale);
    }

    @Override
    public void writeJSONB(JSONWriter jsonWriter, Object object, Object fieldName, Type fieldType, long features) {
        jsonWriter.writeInstant((Instant) object);
    }

    @Override
    public void write(JSONWriter jsonWriter, Object object, Object fieldName, Type fieldType, long features) {
        if (object == null) {
            jsonWriter.writeNull();
            return;
        }

        JSONWriter.Context context = jsonWriter.context;

        String dateFormat = this.format != null
                ? this.format
                : context.getDateFormat();

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

        boolean yyyyMMddhhmmss19 = this.yyyyMMddhhmmss19 || (context.isFormatyyyyMMddhhmmss19() && this.format == null);
        if (yyyyMMddhhmmss14 || yyyyMMddhhmmss19 || yyyyMMdd8 || yyyyMMdd10) {
            final int SECONDS_PER_DAY = 60 * 60 * 24;
            ZoneId zoneId = context.getZoneId();
            long epochSecond = instant.getEpochSecond();
            int offsetTotalSeconds;
            if (zoneId == DateUtils.SHANGHAI_ZONE_ID || zoneId.getRules() == DateUtils.SHANGHAI_ZONE_RULES) {
                offsetTotalSeconds = DateUtils.getShanghaiZoneOffsetTotalSeconds(epochSecond);
            } else {
                offsetTotalSeconds = zoneId.getRules().getOffset(instant).getTotalSeconds();
            }

            long localSecond = epochSecond + offsetTotalSeconds;
            long localEpochDay = Math.floorDiv(localSecond, (long) SECONDS_PER_DAY);
            int secsOfDay = (int) Math.floorMod(localSecond, (long) SECONDS_PER_DAY);
            int year, month, dayOfMonth;
            {
                final int DAYS_PER_CYCLE = 146097;
                final long DAYS_0000_TO_1970 = (DAYS_PER_CYCLE * 5L) - (30L * 365L + 7L);

                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
                long adjust = 0;
                if (zeroDay < 0) {
                    // adjust negative years to positive for calculation
                    long adjustCycles = (zeroDay + 1) / DAYS_PER_CYCLE - 1;
                    adjust = adjustCycles * 400;
                    zeroDay += -adjustCycles * DAYS_PER_CYCLE;
                }
                long yearEst = (400 * zeroDay + 591) / DAYS_PER_CYCLE;
                long doyEst = zeroDay - (365 * yearEst + yearEst / 4 - yearEst / 100 + yearEst / 400);
                if (doyEst < 0) {
                    // fix estimate
                    yearEst--;
                    doyEst = zeroDay - (365 * yearEst + yearEst / 4 - yearEst / 100 + yearEst / 400);
                }
                yearEst += adjust;  // reset any negative year
                int marchDoy0 = (int) doyEst;

                // convert march-based values back to january-based
                int marchMonth0 = (marchDoy0 * 5 + 2) / 153;
                month = (marchMonth0 + 2) % 12 + 1;
                dayOfMonth = marchDoy0 - (marchMonth0 * 306 + 5) / 10 + 1;
                yearEst += marchMonth0 / 10;

                // check year now we are certain it is correct
                if (yearEst < Year.MIN_VALUE || yearEst > Year.MAX_VALUE) {
                    throw new DateTimeException("Invalid year " + yearEst);
                }

                year = (int) yearEst;
            }

            int hour, minute, second;
            {
                final int MINUTES_PER_HOUR = 60;
                final int SECONDS_PER_MINUTE = 60;
                final int SECONDS_PER_HOUR = SECONDS_PER_MINUTE * MINUTES_PER_HOUR;

                long secondOfDay = secsOfDay;
                if (secondOfDay < 0 || secondOfDay > 86399) {
                    throw new DateTimeException("Invalid secondOfDay " + secondOfDay);
                }
                int hours = (int) (secondOfDay / SECONDS_PER_HOUR);
                secondOfDay -= hours * SECONDS_PER_HOUR;
                int minutes = (int) (secondOfDay / SECONDS_PER_MINUTE);
                secondOfDay -= minutes * SECONDS_PER_MINUTE;

                hour = hours;
                minute = minutes;
                second = (int) secondOfDay;
            }

            if (yyyyMMddhhmmss19) {
                jsonWriter.writeDateTime19(
                        year,
                        month,
                        dayOfMonth,
                        hour,
                        minute,
                        second
                );
                return;
            }

            if (yyyyMMddhhmmss14) {
                jsonWriter.writeDateTime14(
                        year,
                        month,
                        dayOfMonth,
                        hour,
                        minute,
                        second
                );
                return;
            }

            if (yyyyMMdd10) {
                jsonWriter.writeDateYYYMMDD10(
                        year,
                        month,
                        dayOfMonth
                );
                return;
            }

            jsonWriter.writeDateYYYMMDD8(
                    year,
                    month,
                    dayOfMonth
            );
            return;
        }

        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())) {
                jsonWriter.writeDateTimeISO8601(
                        year,
                        zdt.getMonthValue(),
                        zdt.getDayOfMonth(),
                        zdt.getHour(),
                        zdt.getMinute(),
                        zdt.getSecond(),
                        zdt.getNano() / 1000_000,
                        zdt.getOffset().getTotalSeconds(),
                        true
                );
                return;
            }
        }

        DateTimeFormatter formatter = this.getDateFormatter();
        if (formatter == null) {
            formatter = context.getDateFormatter();
        }

        if (formatter == null) {
            jsonWriter.writeZonedDateTime(zdt);
        } else {
            String str = formatter.format(zdt);
            jsonWriter.writeString(str);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy