Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
*
* @param part
* the part
* @param v1
* the first date-time value
* @param v2
* the second date-time value
* @return the number of crossed boundaries
*/
public static long datediff(String part, Value v1, Value v2) {
int field = getDatePart(part);
long[] a1 = DateTimeUtils.dateAndTimeFromValue(v1);
long dateValue1 = a1[0];
long absolute1 = DateTimeUtils.absoluteDayFromDateValue(dateValue1);
long[] a2 = DateTimeUtils.dateAndTimeFromValue(v2);
long dateValue2 = a2[0];
long absolute2 = DateTimeUtils.absoluteDayFromDateValue(dateValue2);
switch (field) {
case NANOSECOND:
case MICROSECOND:
case MILLISECOND:
case SECOND:
case EPOCH:
case MINUTE:
case HOUR:
long timeNanos1 = a1[1];
long timeNanos2 = a2[1];
switch (field) {
case NANOSECOND:
return (absolute2 - absolute1) * NANOS_PER_DAY + (timeNanos2 - timeNanos1);
case MICROSECOND:
return (absolute2 - absolute1) * (MILLIS_PER_DAY * 1_000)
+ (timeNanos2 / 1_000 - timeNanos1 / 1_000);
case MILLISECOND:
return (absolute2 - absolute1) * MILLIS_PER_DAY
+ (timeNanos2 / 1_000_000 - timeNanos1 / 1_000_000);
case SECOND:
case EPOCH:
return (absolute2 - absolute1) * 86_400
+ (timeNanos2 / NANOS_PER_SECOND - timeNanos1 / NANOS_PER_SECOND);
case MINUTE:
return (absolute2 - absolute1) * 1_440
+ (timeNanos2 / NANOS_PER_MINUTE - timeNanos1 / NANOS_PER_MINUTE);
case HOUR:
return (absolute2 - absolute1) * 24 + (timeNanos2 / NANOS_PER_HOUR - timeNanos1 / NANOS_PER_HOUR);
}
// Fake fall-through
// $FALL-THROUGH$
case DAY_OF_MONTH:
case DAY_OF_YEAR:
case DAY_OF_WEEK:
case DOW:
case ISO_DAY_OF_WEEK:
return absolute2 - absolute1;
case WEEK:
return weekdiff(absolute1, absolute2, 0);
case ISO_WEEK:
return weekdiff(absolute1, absolute2, 1);
case MONTH:
return (DateTimeUtils.yearFromDateValue(dateValue2) - DateTimeUtils.yearFromDateValue(dateValue1)) * 12
+ DateTimeUtils.monthFromDateValue(dateValue2) - DateTimeUtils.monthFromDateValue(dateValue1);
case QUARTER:
return (DateTimeUtils.yearFromDateValue(dateValue2) - DateTimeUtils.yearFromDateValue(dateValue1)) * 4
+ (DateTimeUtils.monthFromDateValue(dateValue2) - 1) / 3
- (DateTimeUtils.monthFromDateValue(dateValue1) - 1) / 3;
case YEAR:
return DateTimeUtils.yearFromDateValue(dateValue2) - DateTimeUtils.yearFromDateValue(dateValue1);
case TIMEZONE_HOUR:
case TIMEZONE_MINUTE:
case TIMEZONE_SECOND: {
int offsetSeconds1;
if (v1 instanceof ValueTimestampTimeZone) {
offsetSeconds1 = ((ValueTimestampTimeZone) v1).getTimeZoneOffsetSeconds();
} else if (v1 instanceof ValueTimeTimeZone) {
offsetSeconds1 = ((ValueTimeTimeZone) v1).getTimeZoneOffsetSeconds();
} else {
offsetSeconds1 = DateTimeUtils.getTimeZoneOffset(dateValue1, a1[1]);
}
int offsetSeconds2;
if (v2 instanceof ValueTimestampTimeZone) {
offsetSeconds2 = ((ValueTimestampTimeZone) v2).getTimeZoneOffsetSeconds();
} else if (v2 instanceof ValueTimeTimeZone) {
offsetSeconds2 = ((ValueTimeTimeZone) v2).getTimeZoneOffsetSeconds();
} else {
offsetSeconds2 = DateTimeUtils.getTimeZoneOffset(dateValue2, a2[1]);
}
if (field == TIMEZONE_HOUR) {
return (offsetSeconds2 / 3_600) - (offsetSeconds1 / 3_600);
} else if (field == TIMEZONE_MINUTE) {
return (offsetSeconds2 / 60) - (offsetSeconds1 / 60);
} else {
return offsetSeconds2 - offsetSeconds1;
}
}
default:
throw DbException.getUnsupportedException("DATEDIFF " + part);
}
}
/**
* Extracts specified field from the specified date-time value.
*
* @param part
* the date part
* @param value
* the date-time value
* @param mode
* the database mode
* @return extracted field
*/
public static Value extract(String part, Value value, Mode mode) {
Value result;
int field = getDatePart(part);
if (field != EPOCH) {
result = ValueInt.get(getIntDatePart(value, field, mode));
} else {
// Case where we retrieve the EPOCH time.
if (value instanceof ValueInterval) {
ValueInterval interval = (ValueInterval) value;
if (interval.getQualifier().isYearMonth()) {
interval = (ValueInterval) interval.convertTo(Value.INTERVAL_YEAR_TO_MONTH);
long leading = interval.getLeading();
long remaining = interval.getRemaining();
BigInteger bi = BigInteger.valueOf(leading).multiply(BigInteger.valueOf(31557600))
.add(BigInteger.valueOf(remaining * 2592000));
if (interval.isNegative()) {
bi = bi.negate();
}
return ValueDecimal.get(bi);
} else {
return ValueDecimal.get(new BigDecimal(IntervalUtils.intervalToAbsolute(interval))
.divide(BD_NANOS_PER_SECOND));
}
}
// First we retrieve the dateValue and his time in nanoseconds.
long[] a = DateTimeUtils.dateAndTimeFromValue(value);
long dateValue = a[0];
long timeNanos = a[1];
// We compute the time in nanoseconds and the total number of days.
// Case where the value is of type time e.g. '10:00:00'
if (value instanceof ValueTime) {
// In order to retrieve the EPOCH time we only have to convert the time
// in nanoseconds (previously retrieved) in seconds.
result = ValueDecimal.get(BigDecimal.valueOf(timeNanos).divide(BD_NANOS_PER_SECOND));
} else if (value instanceof ValueDate) {
// Case where the value is of type date '2000:01:01', we have to retrieve the
// total number of days and multiply it by the number of seconds in a day.
result = ValueDecimal.get(BigInteger.valueOf(DateTimeUtils.absoluteDayFromDateValue(dateValue))
.multiply(BI_SECONDS_PER_DAY));
} else {
BigDecimal bd = BigDecimal.valueOf(timeNanos).divide(BD_NANOS_PER_SECOND).add(BigDecimal
.valueOf(DateTimeUtils.absoluteDayFromDateValue(dateValue)).multiply(BD_SECONDS_PER_DAY));
if (value instanceof ValueTimestampTimeZone) {
// Case where the value is a of type ValueTimestampTimeZone
// ('2000:01:01 10:00:00+05').
// We retrieve the time zone offset in seconds
// Sum the time in nanoseconds and the total number of days in seconds
// and adding the timeZone offset in seconds.
result = ValueDecimal.get(bd.subtract(
BigDecimal.valueOf(((ValueTimestampTimeZone) value).getTimeZoneOffsetSeconds())));
} else if (value instanceof ValueTimeTimeZone) {
result = ValueDecimal.get(bd.subtract(
BigDecimal.valueOf(((ValueTimeTimeZone) value).getTimeZoneOffsetSeconds())));
} else {
// By default, we have the date and the time ('2000:01:01 10:00:00') if no type
// is given.
// We just have to sum the time in nanoseconds and the total number of days in
// seconds.
result = ValueDecimal.get(bd);
}
}
}
return result;
}
/**
* Truncate the given date to the unit specified
*
* @param datePartStr the time unit (e.g. 'DAY', 'HOUR', etc.)
* @param valueDate the date
* @return date truncated to 'day'
*/
public static Value truncateDate(String datePartStr, Value valueDate) {
int timeUnit = getDatePart(datePartStr);
// Retrieve the dateValue and the time in nanoseconds of the date.
long[] fieldDateAndTime = DateTimeUtils.dateAndTimeFromValue(valueDate);
long dateValue = fieldDateAndTime[0];
long timeNanosRetrieved = fieldDateAndTime[1];
// Variable used to the time in nanoseconds of the date truncated.
long timeNanos;
// Compute the number of time unit in the date, for example, the
// number of time unit 'HOUR' in '15:14:13' is '15'. Then convert the
// result to nanoseconds.
switch (timeUnit) {
case MICROSECOND:
long nanoInMicroSecond = 1_000L;
long microseconds = timeNanosRetrieved / nanoInMicroSecond;
timeNanos = microseconds * nanoInMicroSecond;
break;
case MILLISECOND:
long nanoInMilliSecond = 1_000_000L;
long milliseconds = timeNanosRetrieved / nanoInMilliSecond;
timeNanos = milliseconds * nanoInMilliSecond;
break;
case SECOND:
long seconds = timeNanosRetrieved / NANOS_PER_SECOND;
timeNanos = seconds * NANOS_PER_SECOND;
break;
case MINUTE:
long minutes = timeNanosRetrieved / NANOS_PER_MINUTE;
timeNanos = minutes * NANOS_PER_MINUTE;
break;
case HOUR:
long hours = timeNanosRetrieved / NANOS_PER_HOUR;
timeNanos = hours * NANOS_PER_HOUR;
break;
case DAY_OF_MONTH:
timeNanos = 0L;
break;
case WEEK:
long absoluteDay = DateTimeUtils.absoluteDayFromDateValue(dateValue);
int dayOfWeek = DateTimeUtils.getDayOfWeekFromAbsolute(absoluteDay, 1);
if (dayOfWeek != 1) {
dateValue = DateTimeUtils.dateValueFromAbsoluteDay(absoluteDay - dayOfWeek + 1);
}
timeNanos = 0L;
break;
case MONTH: {
long year = DateTimeUtils.yearFromDateValue(dateValue);
int month = DateTimeUtils.monthFromDateValue(dateValue);
dateValue = DateTimeUtils.dateValue(year, month, 1);
timeNanos = 0L;
break;
}
case QUARTER: {
long year = DateTimeUtils.yearFromDateValue(dateValue);
int month = DateTimeUtils.monthFromDateValue(dateValue);
month = ((month - 1) / 3) * 3 + 1;
dateValue = DateTimeUtils.dateValue(year, month, 1);
timeNanos = 0L;
break;
}
case YEAR: {
long year = DateTimeUtils.yearFromDateValue(dateValue);
dateValue = DateTimeUtils.dateValue(year, 1, 1);
timeNanos = 0L;
break;
}
case DECADE: {
long year = DateTimeUtils.yearFromDateValue(dateValue);
year = (year / 10) * 10;
dateValue = DateTimeUtils.dateValue(year, 1, 1);
timeNanos = 0L;
break;
}
case CENTURY: {
long year = DateTimeUtils.yearFromDateValue(dateValue);
year = ((year - 1) / 100) * 100 + 1;
dateValue = DateTimeUtils.dateValue(year, 1, 1);
timeNanos = 0L;
break;
}
case MILLENNIUM: {
long year = DateTimeUtils.yearFromDateValue(dateValue);
year = ((year - 1) / 1000) * 1000 + 1;
dateValue = DateTimeUtils.dateValue(year, 1, 1);
timeNanos = 0L;
break;
}
default:
// Return an exception in the timeUnit is not recognized
throw DbException.getUnsupportedException(datePartStr);
}
Value result;
if (valueDate instanceof ValueTimestampTimeZone) {
// Case we create a timestamp with timezone with the dateValue and
// timeNanos computed.
ValueTimestampTimeZone vTmp = (ValueTimestampTimeZone) valueDate;
result = ValueTimestampTimeZone.fromDateValueAndNanos(dateValue, timeNanos,
vTmp.getTimeZoneOffsetSeconds());
} else if (valueDate instanceof ValueTimeTimeZone) {
ValueTimeTimeZone vTmp = (ValueTimeTimeZone) valueDate;
result = ValueTimeTimeZone.fromNanos(timeNanos, vTmp.getTimeZoneOffsetSeconds());
} else {
// By default, we create a timestamp with the dateValue and
// timeNanos computed.
result = ValueTimestamp.fromDateValueAndNanos(dateValue, timeNanos);
}
return result;
}
/**
* Formats a date using a format string.
*
* @param date
* the date to format
* @param format
* the format string
* @param locale
* the locale
* @param timeZone
* the timezone
* @return the formatted date
*/
public static String formatDateTime(java.util.Date date, String format, String locale, String timeZone) {
SimpleDateFormat dateFormat = getDateFormat(format, locale, timeZone);
synchronized (dateFormat) {
return dateFormat.format(date);
}
}
private static SimpleDateFormat getDateFormat(String format, String locale, String timeZone) {
try {
// currently, a new instance is create for each call
// however, could cache the last few instances
SimpleDateFormat df;
if (locale == null) {
df = new SimpleDateFormat(format);
} else {
Locale l = new Locale(locale);
df = new SimpleDateFormat(format, l);
}
if (timeZone != null) {
df.setTimeZone(TimeZone.getTimeZone(timeZone));
}
return df;
} catch (Exception e) {
throw DbException.get(ErrorCode.PARSE_ERROR_1, e, format + "/" + locale + "/" + timeZone);
}
}
/**
* Get date part function number from part name.
*
* @param part
* name of the part
* @return function number
*/
public static int getDatePart(String part) {
Integer p = DATE_PART.get(StringUtils.toUpperEnglish(part));
if (p == null) {
throw DbException.getInvalidValueException("date part", part);
}
return p;
}
/**
* Get the specified field of a date, however with years normalized to positive
* or negative, and month starting with 1.
*
* @param date
* the date value
* @param field
* the field type, see {@link Function} for constants
* @param mode
* the database mode
* @return the value
*/
public static int getIntDatePart(Value date, int field, Mode mode) {
if (date instanceof ValueInterval) {
ValueInterval interval = (ValueInterval) date;
IntervalQualifier qualifier = interval.getQualifier();
boolean negative = interval.isNegative();
long leading = interval.getLeading(), remaining = interval.getRemaining();
long v;
switch (field) {
case YEAR:
v = IntervalUtils.yearsFromInterval(qualifier, negative, leading, remaining);
break;
case MONTH:
v = IntervalUtils.monthsFromInterval(qualifier, negative, leading, remaining);
break;
case DAY_OF_MONTH:
case DAY_OF_YEAR:
v = IntervalUtils.daysFromInterval(qualifier, negative, leading, remaining);
break;
case HOUR:
v = IntervalUtils.hoursFromInterval(qualifier, negative, leading, remaining);
break;
case MINUTE:
v = IntervalUtils.minutesFromInterval(qualifier, negative, leading, remaining);
break;
case SECOND:
v = IntervalUtils.nanosFromInterval(qualifier, negative, leading, remaining) / NANOS_PER_SECOND;
break;
case MILLISECOND:
v = IntervalUtils.nanosFromInterval(qualifier, negative, leading, remaining) / 1_000_000 % 1_000;
break;
case MICROSECOND:
v = IntervalUtils.nanosFromInterval(qualifier, negative, leading, remaining) / 1_000 % 1_000_000;
break;
case NANOSECOND:
v = IntervalUtils.nanosFromInterval(qualifier, negative, leading, remaining) % NANOS_PER_SECOND;
break;
default:
throw DbException.getUnsupportedException("getDatePart(" + date + ", " + field + ')');
}
return (int) v;
} else {
long[] a = DateTimeUtils.dateAndTimeFromValue(date);
long dateValue = a[0];
long timeNanos = a[1];
switch (field) {
case YEAR:
return DateTimeUtils.yearFromDateValue(dateValue);
case MONTH:
return DateTimeUtils.monthFromDateValue(dateValue);
case DAY_OF_MONTH:
return DateTimeUtils.dayFromDateValue(dateValue);
case HOUR:
return (int) (timeNanos / NANOS_PER_HOUR % 24);
case MINUTE:
return (int) (timeNanos / NANOS_PER_MINUTE % 60);
case SECOND:
return (int) (timeNanos / NANOS_PER_SECOND % 60);
case MILLISECOND:
return (int) (timeNanos / 1_000_000 % 1_000);
case MICROSECOND:
return (int) (timeNanos / 1_000 % 1_000_000);
case NANOSECOND:
return (int) (timeNanos % NANOS_PER_SECOND);
case DAY_OF_YEAR:
return DateTimeUtils.getDayOfYear(dateValue);
case DAY_OF_WEEK:
return DateTimeUtils.getSundayDayOfWeek(dateValue);
case DOW: {
int dow = DateTimeUtils.getSundayDayOfWeek(dateValue);
if (mode.getEnum() == ModeEnum.PostgreSQL) {
dow--;
}
return dow;
}
case WEEK:
GregorianCalendar gc = new GregorianCalendar();
return DateTimeUtils.getWeekOfYear(dateValue, gc.getFirstDayOfWeek() - 1,
gc.getMinimalDaysInFirstWeek());
case QUARTER:
return (DateTimeUtils.monthFromDateValue(dateValue) - 1) / 3 + 1;
case ISO_YEAR:
return DateTimeUtils.getIsoWeekYear(dateValue);
case ISO_WEEK:
return DateTimeUtils.getIsoWeekOfYear(dateValue);
case ISO_DAY_OF_WEEK:
return DateTimeUtils.getIsoDayOfWeek(dateValue);
case TIMEZONE_HOUR:
case TIMEZONE_MINUTE:
case TIMEZONE_SECOND: {
int offsetSeconds;
if (date instanceof ValueTimestampTimeZone) {
offsetSeconds = ((ValueTimestampTimeZone) date).getTimeZoneOffsetSeconds();
} else if (date instanceof ValueTimeTimeZone) {
offsetSeconds = ((ValueTimeTimeZone) date).getTimeZoneOffsetSeconds();
} else {
offsetSeconds = DateTimeUtils.getTimeZoneOffset(dateValue, timeNanos);
}
if (field == TIMEZONE_HOUR) {
return offsetSeconds / 3_600;
} else if (field == TIMEZONE_MINUTE) {
return offsetSeconds % 3_600 / 60;
} else {
return offsetSeconds % 60;
}
}
}
}
throw DbException.getUnsupportedException("getDatePart(" + date + ", " + field + ')');
}
/**
* Return names of month or weeks.
*
* @param field
* 0 for months, 1 for weekdays
* @return names of month or weeks
*/
public static String[] getMonthsAndWeeks(int field) {
String[][] result = MONTHS_AND_WEEKS;
if (result == null) {
result = new String[2][];
DateFormatSymbols dfs = DateFormatSymbols.getInstance(Locale.ENGLISH);
result[0] = dfs.getMonths();
result[1] = dfs.getWeekdays();
MONTHS_AND_WEEKS = result;
}
return result[field];
}
/**
* Check if a given string is a valid date part string.
*
* @param part
* the string
* @return true if it is
*/
public static boolean isDatePart(String part) {
return DATE_PART.containsKey(StringUtils.toUpperEnglish(part));
}
/**
* Parses a date using a format string.
*
* @param date
* the date to parse
* @param format
* the parsing format
* @param locale
* the locale
* @param timeZone
* the timeZone
* @return the parsed date
*/
public static java.util.Date parseDateTime(String date, String format, String locale, String timeZone) {
SimpleDateFormat dateFormat = getDateFormat(format, locale, timeZone);
try {
synchronized (dateFormat) {
return dateFormat.parse(date);
}
} catch (Exception e) {
// ParseException
throw DbException.get(ErrorCode.PARSE_ERROR_1, e, date);
}
}
private static long weekdiff(long absolute1, long absolute2, int firstDayOfWeek) {
absolute1 += 4 - firstDayOfWeek;
long r1 = absolute1 / 7;
if (absolute1 < 0 && (r1 * 7 != absolute1)) {
r1--;
}
absolute2 += 4 - firstDayOfWeek;
long r2 = absolute2 / 7;
if (absolute2 < 0 && (r2 * 7 != absolute2)) {
r2--;
}
return r2 - r1;
}
private DateTimeFunctions() {
}
}