com.hazelcast.sql.impl.expression.datetime.ExtractField Maven / Gradle / Ivy
/*
* Copyright 2024 Hazelcast Inc.
*
* Licensed under the Hazelcast Community License (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://hazelcast.com/hazelcast-community-license
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hazelcast.sql.impl.expression.datetime;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.temporal.ChronoField;
import java.time.temporal.IsoFields;
import java.time.temporal.Temporal;
import java.time.temporal.TemporalField;
import java.time.temporal.WeekFields;
@SuppressWarnings("DuplicatedCode")
public enum ExtractField {
CENTURY {
@Override
public double extract(OffsetDateTime time) {
return extractCentury(time);
}
@Override
public double extract(LocalDateTime time) {
return extractCentury(time);
}
@Override
public double extract(LocalDate date) {
return extractCentury(date);
}
@Override
public double extract(LocalTime time) {
throw new IllegalArgumentException("Cannot extract CENTURY from TIME");
}
private double extractCentury(Temporal temporal) {
int year = temporal.get(ChronoField.YEAR);
int absYear = Math.abs(year);
double sign = year < 0. ? -1. : 1.;
int quotient = absYear / YEARS_IN_CENTURY;
int remainder = absYear % YEARS_IN_CENTURY;
int absCentury = quotient + (remainder == 0 ? -1 : 0) + FIRST_CENTURY;
return sign * absCentury;
}
},
DAY {
@Override
public double extract(OffsetDateTime time) {
return time.getDayOfMonth();
}
@Override
public double extract(LocalDateTime time) {
return time.getDayOfMonth();
}
@Override
public double extract(LocalDate date) {
return date.getDayOfMonth();
}
@Override
public double extract(LocalTime time) {
throw new IllegalArgumentException("Cannot extract DAY from TIME");
}
},
DECADE {
@Override
public double extract(OffsetDateTime time) {
return extractDecade(time);
}
@Override
public double extract(LocalDateTime time) {
return extractDecade(time);
}
@Override
public double extract(LocalDate date) {
return extractDecade(date);
}
@Override
public double extract(LocalTime time) {
throw new IllegalArgumentException("Cannot extract DECADE from TIME");
}
private double extractDecade(Temporal temporal) {
int year = temporal.get(ChronoField.YEAR);
return Math.floorDiv(year, YEARS_IN_DECADE);
}
},
DOW {
@Override
public double extract(OffsetDateTime time) {
return extractDow(time);
}
@Override
public double extract(LocalDateTime time) {
return extractDow(time);
}
@Override
public double extract(LocalDate date) {
return extractDow(date);
}
@Override
public double extract(LocalTime time) {
throw new IllegalArgumentException("Cannot extract DOW from TIME");
}
private double extractDow(Temporal temporal) {
int dayOfWeekUnadjusted = temporal.get(WeekFields.SUNDAY_START.dayOfWeek());
return dayOfWeekUnadjusted - FIRST_DAY_OF_WEEK;
}
},
DOY {
@Override
public double extract(OffsetDateTime time) {
return time.getDayOfYear();
}
@Override
public double extract(LocalDateTime time) {
return time.getDayOfYear();
}
@Override
public double extract(LocalDate date) {
return date.getDayOfYear();
}
@Override
public double extract(LocalTime time) {
throw new IllegalArgumentException("Cannot extract DOY from TIME");
}
},
EPOCH {
@Override
public double extract(OffsetDateTime time) {
long secondsSince = time.getLong(ChronoField.INSTANT_SECONDS);
int carryNanoseconds = time.get(ChronoField.NANO_OF_SECOND);
double carrySeconds = ((double) carryNanoseconds / (double) NANOSECONDS_IN_SECOND);
return carrySeconds + secondsSince;
}
@Override
public double extract(LocalDateTime time) {
return EPOCH.extract(OffsetDateTime.of(time, ZoneOffset.UTC));
}
@Override
public double extract(LocalDate date) {
return EPOCH.extract(LocalDateTime.of(date, LocalTime.MIDNIGHT));
}
@Override
public double extract(LocalTime time) {
return EPOCH.extract(LocalDateTime.of(LocalDate.ofEpochDay(0), time));
}
},
HOUR {
@Override
public double extract(OffsetDateTime time) {
return time.getHour();
}
@Override
public double extract(LocalDateTime time) {
return time.getHour();
}
@Override
public double extract(LocalDate date) {
return 0;
}
@Override
public double extract(LocalTime time) {
return time.getHour();
}
},
ISODOW {
@Override
public double extract(OffsetDateTime time) {
return time.get(ISODOW_FIELD);
}
@Override
public double extract(LocalDateTime time) {
return time.get(ISODOW_FIELD);
}
@Override
public double extract(LocalDate date) {
return date.get(ISODOW_FIELD);
}
@Override
public double extract(LocalTime time) {
throw new IllegalArgumentException("Cannot extract ISODOW from TIME");
}
},
ISOYEAR {
@Override
public double extract(OffsetDateTime time) {
return time.get(ISOYEAR_FIELD);
}
@Override
public double extract(LocalDateTime time) {
return time.get(ISOYEAR_FIELD);
}
@Override
public double extract(LocalDate date) {
return date.get(ISOYEAR_FIELD);
}
@Override
public double extract(LocalTime time) {
throw new IllegalArgumentException("Cannot extract ISOYEAR from TIME");
}
},
MICROSECOND {
@Override
public double extract(OffsetDateTime time) {
return extractMicrosecond(time);
}
@Override
public double extract(LocalDateTime time) {
return extractMicrosecond(time);
}
@Override
public double extract(LocalDate date) {
return 0;
}
@Override
public double extract(LocalTime time) {
return extractMicrosecond(time);
}
private double extractMicrosecond(Temporal temporal) {
int fractionMicroseconds = temporal.get(ChronoField.MICRO_OF_SECOND);
int seconds = temporal.get(ChronoField.SECOND_OF_MINUTE);
return (double) fractionMicroseconds + (seconds * MICROSECONDS_IN_SECOND);
}
},
MILLENNIUM {
@Override
public double extract(OffsetDateTime time) {
return extractMillennium(time);
}
@Override
public double extract(LocalDateTime time) {
return extractMillennium(time);
}
@Override
public double extract(LocalDate date) {
return extractMillennium(date);
}
@Override
public double extract(LocalTime time) {
throw new IllegalArgumentException("Cannot extract MILLENNIUM from TIME");
}
private double extractMillennium(Temporal temporal) {
int year = temporal.get(ChronoField.YEAR);
int absYear = Math.abs(year);
double sign = year < 0. ? -1. : 1.;
int quotient = absYear / YEARS_IN_MILLENNIUM;
int remainder = absYear % YEARS_IN_MILLENNIUM;
int absMillennium = quotient + (remainder == 0 ? -1 : 0) + FIRST_MILLENNIUM;
return sign * absMillennium;
}
},
MILLISECOND {
@Override
public double extract(OffsetDateTime time) {
int fractionMilliseconds = time.get(ChronoField.MILLI_OF_SECOND);
int seconds = time.getSecond();
return (double) fractionMilliseconds + (seconds * MILLISECONDS_IN_SECOND);
}
@Override
public double extract(LocalDateTime time) {
return extract(OffsetDateTime.of(time, ZoneOffset.UTC));
}
@Override
public double extract(LocalDate date) {
return 0;
}
@Override
public double extract(LocalTime time) {
return extract(LocalDateTime.of(LocalDate.ofEpochDay(0), time));
}
},
MINUTE {
@Override
public double extract(OffsetDateTime time) {
return time.getMinute();
}
@Override
public double extract(LocalDateTime time) {
return time.getMinute();
}
@Override
public double extract(LocalDate date) {
return 0;
}
@Override
public double extract(LocalTime time) {
return time.getMinute();
}
},
MONTH {
@Override
public double extract(OffsetDateTime time) {
return time.getMonthValue();
}
@Override
public double extract(LocalDateTime time) {
return time.getMonthValue();
}
@Override
public double extract(LocalDate date) {
return date.getMonthValue();
}
@Override
public double extract(LocalTime time) {
throw new IllegalArgumentException("Cannot extract MONTH from TIME");
}
},
QUARTER {
@Override
public double extract(OffsetDateTime time) {
return time.get(QUARTER_FIELD);
}
@Override
public double extract(LocalDateTime time) {
return time.get(QUARTER_FIELD);
}
@Override
public double extract(LocalDate date) {
return date.get(QUARTER_FIELD);
}
@Override
public double extract(LocalTime time) {
throw new IllegalArgumentException("Cannot extract QUARTER from TIME");
}
},
SECOND {
@Override
public double extract(OffsetDateTime time) {
return time.getSecond();
}
@Override
public double extract(LocalDateTime time) {
return time.getSecond();
}
@Override
public double extract(LocalDate date) {
return 0;
}
@Override
public double extract(LocalTime time) {
return time.getSecond();
}
},
WEEK {
@Override
public double extract(OffsetDateTime time) {
return time.get(WEEK_FIELD);
}
@Override
public double extract(LocalDateTime time) {
return time.get(WEEK_FIELD);
}
@Override
public double extract(LocalDate date) {
return date.get(WEEK_FIELD);
}
@Override
public double extract(LocalTime time) {
throw new IllegalArgumentException("Cannot extract WEEK from TIME");
}
},
YEAR {
@Override
public double extract(OffsetDateTime time) {
return time.getYear();
}
@Override
public double extract(LocalDateTime time) {
return time.getYear();
}
@Override
public double extract(LocalDate date) {
return date.getYear();
}
@Override
public double extract(LocalTime time) {
throw new IllegalArgumentException("Cannot extract YEAR from TIME");
}
};
protected static final int YEARS_IN_MILLENNIUM = 1000;
protected static final int YEARS_IN_CENTURY = 100;
protected static final int YEARS_IN_DECADE = 10;
protected static final int NANOSECONDS_IN_SECOND = 1_000_000_000;
protected static final int MICROSECONDS_IN_SECOND = 1_000_000;
protected static final int MILLISECONDS_IN_SECOND = 1_000;
protected static final int FIRST_MILLENNIUM = 1;
protected static final int FIRST_CENTURY = 1;
protected static final double FIRST_DAY_OF_WEEK = 1.;
protected static final TemporalField WEEK_FIELD = WeekFields.ISO.weekOfWeekBasedYear();
protected static final TemporalField QUARTER_FIELD = IsoFields.QUARTER_OF_YEAR;
protected static final TemporalField ISOYEAR_FIELD = WeekFields.ISO.weekBasedYear();
protected static final TemporalField ISODOW_FIELD = WeekFields.ISO.dayOfWeek();
public abstract double extract(OffsetDateTime time);
public abstract double extract(LocalDateTime time);
public abstract double extract(LocalDate date);
public abstract double extract(LocalTime time);
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy