| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF 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.apache.drill.exec.vector; |
| |
| import java.time.Instant; |
| import java.time.LocalDate; |
| import java.time.LocalTime; |
| |
| import org.joda.time.Period; |
| |
| /** |
| * Utility class for Date, DateTime, TimeStamp, Interval data types. |
| * <p> |
| * WARNING: This class is included from the JDBC driver. There is another, similar |
| * class called <tt>org.apache.drill.exec.expr.fn.impl.DateUtility</tt>. If vectors refer |
| * to that class, they will fail when called from JDBC. So, place code here if |
| * it is needed by JDBC, in the other class if only needed by the Drill engine. |
| * (This is a very poor design, but it is what it is.) |
| */ |
| |
| public class DateUtilities { |
| |
| public static final int yearsToMonths = 12; |
| public static final int yearsToQuarter = 4; |
| public static final int daysToWeeks = 7; |
| public static final int hoursToMillis = 60 * 60 * 1000; |
| public static final int minutesToMillis = 60 * 1000; |
| public static final int secondsToMillis = 1000; |
| public static final int monthToStandardDays = 30; |
| public static final long monthsToMillis = 2592000000L; // 30 * 24 * 60 * 60 * 1000 |
| public static final int daysToStandardMillis = 24 * 60 * 60 * 1000; |
| |
| public static int monthsFromPeriod(Period period){ |
| return (period.getYears() * yearsToMonths) + period.getMonths(); |
| } |
| |
| public static int periodToMillis(final Period period){ |
| return (period.getHours() * hoursToMillis) + |
| (period.getMinutes() * minutesToMillis) + |
| (period.getSeconds() * secondsToMillis) + |
| (period.getMillis()); |
| } |
| |
| public static int toMonths(int years, int months) { |
| return years * yearsToMonths + months; |
| } |
| |
| public static int periodToMonths(Period value) { |
| return value.getYears() * yearsToMonths + value.getMonths(); |
| } |
| |
| public static Period fromIntervalYear(int value) { |
| final int years = (value / yearsToMonths); |
| final int months = (value % yearsToMonths); |
| return new Period() |
| .plusYears(years) |
| .plusMonths(months); |
| } |
| |
| public static StringBuilder intervalYearStringBuilder(int months) { |
| final int years = months / yearsToMonths; |
| months %= yearsToMonths; |
| |
| return new StringBuilder() |
| .append(years) |
| .append(pluralify("year", years)) |
| .append(" ") |
| .append(months) |
| .append(pluralify("month", months)); |
| } |
| |
| public static StringBuilder intervalYearStringBuilder(Period value) { |
| return intervalYearStringBuilder( |
| value.getYears() * 12 + value.getMonths()); |
| } |
| |
| public static String pluralify(String term, int value) { |
| term = (Math.abs(value) == 1) ? term : term + "s"; |
| return " " + term; |
| } |
| |
| public static Period fromIntervalDay(int days, int millis) { |
| return new Period() |
| .plusDays(days) |
| .plusMillis(millis); |
| } |
| |
| public static StringBuilder intervalDayStringBuilder(int days, int millis) { |
| |
| final int hours = millis / (hoursToMillis); |
| millis %= (hoursToMillis); |
| |
| final int minutes = millis / (minutesToMillis); |
| millis %= (minutesToMillis); |
| |
| final int seconds = millis / (secondsToMillis); |
| millis %= (secondsToMillis); |
| |
| final StringBuilder buf = new StringBuilder() |
| .append(days) |
| .append(pluralify("day", days)) |
| .append(" ") |
| .append(hours) |
| .append(":") |
| .append(asTwoDigits(minutes)) |
| .append(":") |
| .append(asTwoDigits(seconds)); |
| if (millis != 0) { |
| buf.append(".") |
| .append(millis); |
| } |
| return buf; |
| } |
| |
| public static StringBuilder intervalDayStringBuilder(Period value) { |
| return intervalDayStringBuilder( |
| value.getDays(), |
| periodToMillis(value)); |
| } |
| |
| public static Period fromInterval(int months, int days, int millis) { |
| return new Period() |
| .plusMonths(months) |
| .plusDays(days) |
| .plusMillis(millis); |
| } |
| |
| public static String asTwoDigits(int value) { |
| return String.format("%02d", value); |
| } |
| |
| public static StringBuilder intervalStringBuilder(int months, int days, int millis) { |
| |
| final int years = months / yearsToMonths; |
| months %= yearsToMonths; |
| |
| final int hours = millis / hoursToMillis; |
| millis %= hoursToMillis; |
| |
| final int minutes = millis / minutesToMillis; |
| millis %= minutesToMillis; |
| |
| final int seconds = millis / secondsToMillis; |
| millis %= secondsToMillis; |
| |
| final StringBuilder buf = new StringBuilder() |
| .append(years) |
| .append(pluralify("year", years)) |
| .append(" ") |
| .append(months) |
| .append(pluralify("month", months)) |
| .append(" ") |
| .append(days) |
| .append(pluralify("day", days)) |
| .append(" ") |
| .append(hours) |
| .append(":") |
| .append(asTwoDigits(minutes)) |
| .append(":") |
| .append(asTwoDigits(seconds)); |
| if (millis != 0) { |
| buf.append(".") |
| .append(millis); |
| } |
| return buf; |
| } |
| |
| public static StringBuilder intervalStringBuilder(Period value) { |
| return intervalStringBuilder( |
| value.getYears() * 12 + value.getMonths(), |
| value.getDays(), |
| periodToMillis(value)); |
| } |
| |
| public static int timeToMillis(int hours, int minutes, int seconds, int millis) { |
| return ((hours * 60 + |
| minutes) * 60 + |
| seconds) * 1000 + |
| millis; |
| } |
| |
| /** |
| * Convert from Java LocalTime to the ms-since-midnight format which Drill uses |
| * @param localTime Java local time |
| * @return Drill form of the time |
| */ |
| public static int toDrillTime(LocalTime localTime) { |
| return (int) ((localTime.toNanoOfDay() + 500_000L) / 1_000_000L); // round to milliseconds |
| } |
| |
| public static LocalTime fromDrillTime(int value) { |
| return LocalTime.ofNanoOfDay(value * 1_000_000L); |
| } |
| |
| public static long toDrillDate(LocalDate localDate) { |
| return localDate.toEpochDay() * daysToStandardMillis; |
| } |
| |
| public static LocalDate fromDrillDate(long value) { |
| return LocalDate.ofEpochDay(value / daysToStandardMillis); |
| } |
| |
| public static long toDrillTimestamp(Instant instant) { |
| return instant.toEpochMilli(); |
| } |
| |
| public static Instant fromDrillTimestamp(long value) { |
| return Instant.ofEpochMilli(value); |
| } |
| } |