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

org.elasticsearch.common.joda.Joda Maven / Gradle / Ivy

There is a newer version: 8.13.2
Show newest version
/*
 * Licensed to Elasticsearch under one or more contributor
 * license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright
 * ownership. Elasticsearch licenses this file to you under
 * the Apache License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.elasticsearch.common.joda;

import org.apache.logging.log4j.LogManager;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.logging.DeprecationLogger;
import org.elasticsearch.common.time.DateFormatter;
import org.elasticsearch.common.time.FormatNames;
import org.joda.time.Chronology;
import org.joda.time.DateTime;
import org.joda.time.DateTimeField;
import org.joda.time.DateTimeFieldType;
import org.joda.time.DateTimeZone;
import org.joda.time.DurationField;
import org.joda.time.DurationFieldType;
import org.joda.time.ReadablePartial;
import org.joda.time.field.DividedDateTimeField;
import org.joda.time.field.OffsetDateTimeField;
import org.joda.time.field.ScaledDurationField;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.DateTimeFormatterBuilder;
import org.joda.time.format.DateTimeParser;
import org.joda.time.format.DateTimeParserBucket;
import org.joda.time.format.DateTimePrinter;
import org.joda.time.format.ISODateTimeFormat;
import org.joda.time.format.StrictISODateTimeFormat;

import java.io.IOException;
import java.io.Writer;
import java.math.BigDecimal;
import java.util.Locale;
import java.util.regex.Pattern;

public class Joda {

    private static DeprecationLogger deprecationLogger = new DeprecationLogger(LogManager.getLogger(Joda.class));

    /**
     * Parses a joda based pattern, including some named ones (similar to the built in Joda ISO ones).
     */
    public static JodaDateFormatter forPattern(String input) {
        if (Strings.hasLength(input)) {
            input = input.trim();
        }
        if (input == null || input.length() == 0) {
            throw new IllegalArgumentException("No date pattern provided");
        }

        DateTimeFormatter formatter;
        if (FormatNames.BASIC_DATE.matches(input)) {
            formatter = ISODateTimeFormat.basicDate();
        } else if (FormatNames.BASIC_DATE_TIME.matches(input) ) {
            formatter = ISODateTimeFormat.basicDateTime();
        } else if (FormatNames.BASIC_DATE_TIME_NO_MILLIS.matches(input) ) {
            formatter = ISODateTimeFormat.basicDateTimeNoMillis();
        } else if (FormatNames.BASIC_ORDINAL_DATE.matches(input) ) {
            formatter = ISODateTimeFormat.basicOrdinalDate();
        } else if (FormatNames.BASIC_ORDINAL_DATE_TIME.matches(input) ) {
            formatter = ISODateTimeFormat.basicOrdinalDateTime();
        } else if (FormatNames.BASIC_ORDINAL_DATE_TIME_NO_MILLIS.matches(input) ) {
            formatter = ISODateTimeFormat.basicOrdinalDateTimeNoMillis();
        } else if (FormatNames.BASIC_TIME.matches(input) ) {
            formatter = ISODateTimeFormat.basicTime();
        } else if (FormatNames.BASIC_TIME_NO_MILLIS.matches(input) ) {
            formatter = ISODateTimeFormat.basicTimeNoMillis();
        } else if (FormatNames.BASIC_T_TIME.matches(input) ) {
            formatter = ISODateTimeFormat.basicTTime();
        } else if (FormatNames.BASIC_T_TIME_NO_MILLIS.matches(input) ) {
            formatter = ISODateTimeFormat.basicTTimeNoMillis();
        } else if (FormatNames.BASIC_WEEK_DATE.matches(input)) {
            formatter = ISODateTimeFormat.basicWeekDate();
        } else if (FormatNames.BASIC_WEEK_DATE_TIME.matches(input) ) {
            formatter = ISODateTimeFormat.basicWeekDateTime();
        } else if (FormatNames.BASIC_WEEK_DATE_TIME_NO_MILLIS.matches(input)) {
            formatter = ISODateTimeFormat.basicWeekDateTimeNoMillis();
        } else if (FormatNames.DATE.matches(input)) {
            formatter = ISODateTimeFormat.date();
        } else if (FormatNames.DATE_HOUR.matches(input)) {
            formatter = ISODateTimeFormat.dateHour();
        } else if (FormatNames.DATE_HOUR_MINUTE.matches(input)) {
            formatter = ISODateTimeFormat.dateHourMinute();
        } else if (FormatNames.DATE_HOUR_MINUTE_SECOND.matches(input)) {
            formatter = ISODateTimeFormat.dateHourMinuteSecond();
        } else if (FormatNames.DATE_HOUR_MINUTE_SECOND_FRACTION.matches(input)) {
            formatter = ISODateTimeFormat.dateHourMinuteSecondFraction();
        } else if (FormatNames.DATE_HOUR_MINUTE_SECOND_MILLIS.matches(input) ) {
            formatter = ISODateTimeFormat.dateHourMinuteSecondMillis();
        } else if (FormatNames.DATE_OPTIONAL_TIME.matches(input)) {
            // in this case, we have a separate parser and printer since the dataOptionalTimeParser can't print
            // this sucks we should use the root local by default and not be dependent on the node
            return new JodaDateFormatter(input,
                    ISODateTimeFormat.dateOptionalTimeParser().withLocale(Locale.ROOT).withZone(DateTimeZone.UTC).withDefaultYear(1970),
                    ISODateTimeFormat.dateTime().withLocale(Locale.ROOT).withZone(DateTimeZone.UTC).withDefaultYear(1970));
        } else if (FormatNames.DATE_TIME.matches(input)) {
            formatter = ISODateTimeFormat.dateTime();
        } else if (FormatNames.DATE_TIME_NO_MILLIS.matches(input) ) {
            formatter = ISODateTimeFormat.dateTimeNoMillis();
        } else if (FormatNames.HOUR.matches(input)) {
            formatter = ISODateTimeFormat.hour();
        } else if (FormatNames.HOUR_MINUTE.matches(input)) {
            formatter = ISODateTimeFormat.hourMinute();
        } else if (FormatNames.HOUR_MINUTE_SECOND.matches(input) ) {
            formatter = ISODateTimeFormat.hourMinuteSecond();
        } else if (FormatNames.HOUR_MINUTE_SECOND_FRACTION.matches(input)) {
            formatter = ISODateTimeFormat.hourMinuteSecondFraction();
        } else if (FormatNames.HOUR_MINUTE_SECOND_MILLIS.matches(input)) {
            formatter = ISODateTimeFormat.hourMinuteSecondMillis();
        } else if (FormatNames.ORDINAL_DATE.matches(input)) {
            formatter = ISODateTimeFormat.ordinalDate();
        } else if (FormatNames.ORDINAL_DATE_TIME.matches(input)) {
            formatter = ISODateTimeFormat.ordinalDateTime();
        } else if (FormatNames.ORDINAL_DATE_TIME_NO_MILLIS.matches(input) ) {
            formatter = ISODateTimeFormat.ordinalDateTimeNoMillis();
        } else if (FormatNames.TIME.matches(input)) {
            formatter = ISODateTimeFormat.time();
        } else if (FormatNames.TIME_NO_MILLIS.matches(input)) {
            formatter = ISODateTimeFormat.timeNoMillis();
        } else if (FormatNames.T_TIME.matches(input)) {
            formatter = ISODateTimeFormat.tTime();
        } else if (FormatNames.T_TIME_NO_MILLIS.matches(input)) {
            formatter = ISODateTimeFormat.tTimeNoMillis();
        } else if (FormatNames.WEEK_DATE.matches(input)) {
            formatter = ISODateTimeFormat.weekDate();
        } else if (FormatNames.WEEK_DATE_TIME.matches(input)) {
            formatter = ISODateTimeFormat.weekDateTime();
        } else if (FormatNames.WEEK_DATE_TIME_NO_MILLIS.matches(input)) {
            formatter = ISODateTimeFormat.weekDateTimeNoMillis();
        } else if (FormatNames.WEEK_YEAR.matches(input)) {
            formatter = ISODateTimeFormat.weekyear();
        } else if (FormatNames.WEEK_YEAR_WEEK.matches(input)) {
            formatter = ISODateTimeFormat.weekyearWeek();
        } else if (FormatNames.WEEKYEAR_WEEK_DAY.matches(input)) {
            formatter = ISODateTimeFormat.weekyearWeekDay();
        } else if (FormatNames.YEAR.matches(input)) {
            formatter = ISODateTimeFormat.year();
        } else if (FormatNames.YEAR_MONTH.matches(input) ) {
            formatter = ISODateTimeFormat.yearMonth();
        } else if (FormatNames.YEAR_MONTH_DAY.matches(input)) {
            formatter = ISODateTimeFormat.yearMonthDay();
        } else if (FormatNames.EPOCH_SECOND.matches(input)) {
            formatter = new DateTimeFormatterBuilder().append(new EpochTimePrinter(false),
                new EpochTimeParser(false)).toFormatter();
        } else if (FormatNames.EPOCH_MILLIS.matches(input)) {
            formatter = new DateTimeFormatterBuilder().append(new EpochTimePrinter(true),
                new EpochTimeParser(true)).toFormatter();
        // strict date formats here, must be at least 4 digits for year and two for months and two for day
        } else if (FormatNames.STRICT_BASIC_WEEK_DATE.matches(input) ) {
            formatter = StrictISODateTimeFormat.basicWeekDate();
        } else if (FormatNames.STRICT_BASIC_WEEK_DATE_TIME.matches(input)) {
            formatter = StrictISODateTimeFormat.basicWeekDateTime();
        } else if (FormatNames.STRICT_BASIC_WEEK_DATE_TIME_NO_MILLIS.matches(input)) {
            formatter = StrictISODateTimeFormat.basicWeekDateTimeNoMillis();
        } else if (FormatNames.STRICT_DATE.matches(input)) {
            formatter = StrictISODateTimeFormat.date();
        } else if (FormatNames.STRICT_DATE_HOUR.matches(input)) {
            formatter = StrictISODateTimeFormat.dateHour();
        } else if (FormatNames.STRICT_DATE_HOUR_MINUTE.matches(input)) {
            formatter = StrictISODateTimeFormat.dateHourMinute();
        } else if (FormatNames.STRICT_DATE_HOUR_MINUTE_SECOND.matches(input)) {
            formatter = StrictISODateTimeFormat.dateHourMinuteSecond();
        } else if (FormatNames.STRICT_DATE_HOUR_MINUTE_SECOND_FRACTION.matches(input)) {
            formatter = StrictISODateTimeFormat.dateHourMinuteSecondFraction();
        } else if (FormatNames.STRICT_DATE_HOUR_MINUTE_SECOND_MILLIS.matches(input)) {
            formatter = StrictISODateTimeFormat.dateHourMinuteSecondMillis();
        } else if (FormatNames.STRICT_DATE_OPTIONAL_TIME.matches(input)) {
            // in this case, we have a separate parser and printer since the dataOptionalTimeParser can't print
            // this sucks we should use the root local by default and not be dependent on the node
            return new JodaDateFormatter(input,
                    StrictISODateTimeFormat.dateOptionalTimeParser().withLocale(Locale.ROOT).withZone(DateTimeZone.UTC)
                        .withDefaultYear(1970),
                    StrictISODateTimeFormat.dateTime().withLocale(Locale.ROOT).withZone(DateTimeZone.UTC).withDefaultYear(1970));
        } else if (FormatNames.STRICT_DATE_TIME.matches(input)) {
            formatter = StrictISODateTimeFormat.dateTime();
        } else if (FormatNames.STRICT_DATE_TIME_NO_MILLIS.matches(input)) {
            formatter = StrictISODateTimeFormat.dateTimeNoMillis();
        } else if (FormatNames.STRICT_HOUR.matches(input)) {
            formatter = StrictISODateTimeFormat.hour();
        } else if (FormatNames.STRICT_HOUR_MINUTE.matches(input)) {
            formatter = StrictISODateTimeFormat.hourMinute();
        } else if (FormatNames.STRICT_HOUR_MINUTE_SECOND.matches(input)) {
            formatter = StrictISODateTimeFormat.hourMinuteSecond();
        } else if (FormatNames.STRICT_HOUR_MINUTE_SECOND_FRACTION.matches(input)) {
            formatter = StrictISODateTimeFormat.hourMinuteSecondFraction();
        } else if (FormatNames.STRICT_HOUR_MINUTE_SECOND_MILLIS.matches(input)) {
            formatter = StrictISODateTimeFormat.hourMinuteSecondMillis();
        } else if (FormatNames.STRICT_ORDINAL_DATE.matches(input)) {
            formatter = StrictISODateTimeFormat.ordinalDate();
        } else if (FormatNames.STRICT_ORDINAL_DATE_TIME.matches(input)) {
            formatter = StrictISODateTimeFormat.ordinalDateTime();
        } else if (FormatNames.STRICT_ORDINAL_DATE_TIME_NO_MILLIS.matches(input)) {
            formatter = StrictISODateTimeFormat.ordinalDateTimeNoMillis();
        } else if (FormatNames.STRICT_TIME.matches(input)) {
            formatter = StrictISODateTimeFormat.time();
        } else if (FormatNames.STRICT_TIME_NO_MILLIS.matches(input)) {
            formatter = StrictISODateTimeFormat.timeNoMillis();
        } else if (FormatNames.STRICT_T_TIME.matches(input) ) {
            formatter = StrictISODateTimeFormat.tTime();
        } else if (FormatNames.STRICT_T_TIME_NO_MILLIS.matches(input)) {
            formatter = StrictISODateTimeFormat.tTimeNoMillis();
        } else if (FormatNames.STRICT_WEEK_DATE.matches(input)) {
            formatter = StrictISODateTimeFormat.weekDate();
        } else if (FormatNames.STRICT_WEEK_DATE_TIME.matches(input)) {
            formatter = StrictISODateTimeFormat.weekDateTime();
        } else if (FormatNames.STRICT_WEEK_DATE_TIME_NO_MILLIS.matches(input)) {
            formatter = StrictISODateTimeFormat.weekDateTimeNoMillis();
        } else if (FormatNames.STRICT_WEEKYEAR.matches(input) ) {
            formatter = StrictISODateTimeFormat.weekyear();
        } else if (FormatNames.STRICT_WEEKYEAR_WEEK.matches(input)) {
            formatter = StrictISODateTimeFormat.weekyearWeek();
        } else if (FormatNames.STRICT_WEEKYEAR_WEEK_DAY.matches(input)) {
            formatter = StrictISODateTimeFormat.weekyearWeekDay();
        } else if (FormatNames.STRICT_YEAR.matches(input)) {
            formatter = StrictISODateTimeFormat.year();
        } else if (FormatNames.STRICT_YEAR_MONTH.matches(input)) {
            formatter = StrictISODateTimeFormat.yearMonth();
        } else if (FormatNames.STRICT_YEAR_MONTH_DAY.matches(input)) {
            formatter = StrictISODateTimeFormat.yearMonthDay();
        } else if (Strings.hasLength(input) && input.contains("||")) {
            String[] formats = Strings.delimitedListToStringArray(input, "||");
            DateTimeParser[] parsers = new DateTimeParser[formats.length];

            if (formats.length == 1) {
                formatter = forPattern(input).parser;
            } else {
                DateTimeFormatter dateTimeFormatter = null;
                for (int i = 0; i < formats.length; i++) {
                    JodaDateFormatter currentFormatter = forPattern(formats[i]);
                    DateTimeFormatter currentParser = currentFormatter.parser;
                    if (dateTimeFormatter == null) {
                        dateTimeFormatter = currentFormatter.printer;
                    }
                    parsers[i] = currentParser.getParser();
                }

                DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder()
                    .append(dateTimeFormatter.withZone(DateTimeZone.UTC).getPrinter(), parsers);
                formatter = builder.toFormatter();
            }
        } else {
            try {
                maybeLogJodaDeprecation(input);
                formatter = DateTimeFormat.forPattern(input);
            } catch (IllegalArgumentException e) {
                throw new IllegalArgumentException("Invalid format: [" + input + "]: " + e.getMessage(), e);
            }
        }

        formatter = formatter.withLocale(Locale.ROOT).withZone(DateTimeZone.UTC).withDefaultYear(1970);
        return new JodaDateFormatter(input, formatter, formatter);
    }

    private static void maybeLogJodaDeprecation(String format) {
        if (JodaDeprecationPatterns.isDeprecatedPattern(format)) {
            String suggestion = JodaDeprecationPatterns.formatSuggestion(format);
            deprecationLogger.deprecatedAndMaybeLog("joda-pattern-deprecation",
                suggestion + " " + JodaDeprecationPatterns.USE_NEW_FORMAT_SPECIFIERS);
        }
    }

    public static DateFormatter getStrictStandardDateFormatter() {
        // 2014/10/10
        DateTimeFormatter shortFormatter = new DateTimeFormatterBuilder()
                .appendFixedDecimal(DateTimeFieldType.year(), 4)
                .appendLiteral('/')
                .appendFixedDecimal(DateTimeFieldType.monthOfYear(), 2)
                .appendLiteral('/')
                .appendFixedDecimal(DateTimeFieldType.dayOfMonth(), 2)
                .toFormatter()
                .withZoneUTC();

        // 2014/10/10 12:12:12
        DateTimeFormatter longFormatter = new DateTimeFormatterBuilder()
                .appendFixedDecimal(DateTimeFieldType.year(), 4)
                .appendLiteral('/')
                .appendFixedDecimal(DateTimeFieldType.monthOfYear(), 2)
                .appendLiteral('/')
                .appendFixedDecimal(DateTimeFieldType.dayOfMonth(), 2)
                .appendLiteral(' ')
                .appendFixedSignedDecimal(DateTimeFieldType.hourOfDay(), 2)
                .appendLiteral(':')
                .appendFixedSignedDecimal(DateTimeFieldType.minuteOfHour(), 2)
                .appendLiteral(':')
                .appendFixedSignedDecimal(DateTimeFieldType.secondOfMinute(), 2)
                .toFormatter()
                .withZoneUTC();

        DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder().append(longFormatter.withZone(DateTimeZone.UTC).getPrinter(),
            new DateTimeParser[]{longFormatter.getParser(), shortFormatter.getParser(), new EpochTimeParser(true)});

        DateTimeFormatter formatter = builder.toFormatter().withLocale(Locale.ROOT).withZone(DateTimeZone.UTC).withDefaultYear(1970);
        return new JodaDateFormatter("yyyy/MM/dd HH:mm:ss||yyyy/MM/dd||epoch_millis", formatter, formatter);
    }


    public static final DurationFieldType Quarters = new DurationFieldType("quarters") {
        @Override
        public DurationField getField(Chronology chronology) {
            return new ScaledDurationField(chronology.months(), Quarters, 3);
        }
    };

    public static final DateTimeFieldType QuarterOfYear = new DateTimeFieldType("quarterOfYear") {
        @Override
        public DurationFieldType getDurationType() {
            return Quarters;
        }

        @Override
        public DurationFieldType getRangeDurationType() {
            return DurationFieldType.years();
        }

        @Override
        public DateTimeField getField(Chronology chronology) {
            return new OffsetDateTimeField(
                new DividedDateTimeField(new OffsetDateTimeField(chronology.monthOfYear(), -1), QuarterOfYear, 3), 1);
        }
    };

    public static class EpochTimeParser implements DateTimeParser {

        private static final Pattern scientificNotation = Pattern.compile("[Ee]");

        private final boolean hasMilliSecondPrecision;

        public EpochTimeParser(boolean hasMilliSecondPrecision) {
            this.hasMilliSecondPrecision = hasMilliSecondPrecision;
        }

        @Override
        public int estimateParsedLength() {
            return hasMilliSecondPrecision ? 19 : 16;
        }

        @Override
        public int parseInto(DateTimeParserBucket bucket, String text, int position) {
            boolean isPositive = text.startsWith("-") == false;
            int firstDotIndex = text.indexOf('.');
            boolean isTooLong = (firstDotIndex == -1 ? text.length() : firstDotIndex) > estimateParsedLength();

            if (bucket.getZone() != DateTimeZone.UTC) {
                String format = hasMilliSecondPrecision ? "epoch_millis" : "epoch_second";
                throw new IllegalArgumentException("time_zone must be UTC for format [" + format + "]");
            } else if (isPositive && isTooLong) {
                return -1;
            }

            int factor = hasMilliSecondPrecision ? 1 : 1000;
            try {
                long millis = new BigDecimal(text).longValue() * factor;
                // check for deprecations, but after it has parsed correctly so invalid values aren't counted as deprecated
                if (millis < 0) {
                    deprecationLogger.deprecatedAndMaybeLog("epoch-negative", "Use of negative values" +
                        " in epoch time formats is deprecated and will not be supported in the next major version of Elasticsearch.");
                }
                if (scientificNotation.matcher(text).find()) {
                    deprecationLogger.deprecatedAndMaybeLog("epoch-scientific-notation", "Use of scientific notation" +
                        " in epoch time formats is deprecated and will not be supported in the next major version of Elasticsearch.");
                }
                DateTime dt = new DateTime(millis, DateTimeZone.UTC);
                bucket.saveField(DateTimeFieldType.year(), dt.getYear());
                bucket.saveField(DateTimeFieldType.monthOfYear(), dt.getMonthOfYear());
                bucket.saveField(DateTimeFieldType.dayOfMonth(), dt.getDayOfMonth());
                bucket.saveField(DateTimeFieldType.hourOfDay(), dt.getHourOfDay());
                bucket.saveField(DateTimeFieldType.minuteOfHour(), dt.getMinuteOfHour());
                bucket.saveField(DateTimeFieldType.secondOfMinute(), dt.getSecondOfMinute());
                bucket.saveField(DateTimeFieldType.millisOfSecond(), dt.getMillisOfSecond());
                bucket.setZone(DateTimeZone.UTC);
            } catch (Exception e) {
                return -1;
            }
            return text.length();
        }
    }

    public static class EpochTimePrinter implements DateTimePrinter {

        private boolean hasMilliSecondPrecision;

        public EpochTimePrinter(boolean hasMilliSecondPrecision) {
            this.hasMilliSecondPrecision = hasMilliSecondPrecision;
        }

        @Override
        public int estimatePrintedLength() {
            return hasMilliSecondPrecision ? 19 : 16;
        }


        /**
         * We adjust the instant by displayOffset to adjust for the offset that might have been added in
         * {@link DateTimeFormatter#printTo(Appendable, long, Chronology)} when using a time zone.
         */
        @Override
        public void printTo(StringBuffer buf, long instant, Chronology chrono, int displayOffset, DateTimeZone displayZone, Locale locale) {
            if (hasMilliSecondPrecision) {
                buf.append(instant - displayOffset);
            } else {
                buf.append((instant  - displayOffset) / 1000);
            }
        }

        /**
         * We adjust the instant by displayOffset to adjust for the offset that might have been added in
         * {@link DateTimeFormatter#printTo(Appendable, long, Chronology)} when using a time zone.
         */
        @Override
        public void printTo(Writer out, long instant, Chronology chrono, int displayOffset,
                            DateTimeZone displayZone, Locale locale) throws IOException {
            if (hasMilliSecondPrecision) {
                out.write(String.valueOf(instant - displayOffset));
            } else {
                out.append(String.valueOf((instant - displayOffset) / 1000));
            }
        }

        @Override
        public void printTo(StringBuffer buf, ReadablePartial partial, Locale locale) {
            if (hasMilliSecondPrecision) {
                buf.append(String.valueOf(getDateTimeMillis(partial)));
            } else {
                buf.append(String.valueOf(getDateTimeMillis(partial) / 1000));
            }
        }

        @Override
        public void printTo(Writer out, ReadablePartial partial, Locale locale) throws IOException {
            if (hasMilliSecondPrecision) {
                out.append(String.valueOf(getDateTimeMillis(partial)));
            } else {
                out.append(String.valueOf(getDateTimeMillis(partial) / 1000));
            }
        }

        private long getDateTimeMillis(ReadablePartial partial) {
            int year = partial.get(DateTimeFieldType.year());
            int monthOfYear = partial.get(DateTimeFieldType.monthOfYear());
            int dayOfMonth = partial.get(DateTimeFieldType.dayOfMonth());
            int hourOfDay = partial.get(DateTimeFieldType.hourOfDay());
            int minuteOfHour = partial.get(DateTimeFieldType.minuteOfHour());
            int secondOfMinute = partial.get(DateTimeFieldType.secondOfMinute());
            int millisOfSecond = partial.get(DateTimeFieldType.millisOfSecond());
            return partial.getChronology().getDateTimeMillis(year, monthOfYear, dayOfMonth,
                hourOfDay, minuteOfHour, secondOfMinute, millisOfSecond);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy