/*
* Licensed 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.
*
* Other licenses:
* -----------------------------------------------------------------------------
* Commercial licenses for this work are available. These replace the above
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
* database integrations.
*
* For more information, please visit: http://www.jooq.org/licenses
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package org.jooq.types;
import java.time.Duration;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.jooq.Field;
import org.jooq.SQLDialect;
An implementation for the SQL standard INTERVAL YEAR TO MONTH
data type.
YearToMonth
is a Number
whose Number.intValue()
represents the number of months of the interval.
Note: only a few databases actually support this data type on its own. You can still use it for date time arithmetic in other databases, though, through Field.add(Field)
and Field.sub(Field)
Databases that have been observed to natively support INTERVAL
data types are:
-
SQLDialect.HSQLDB
-
SQLDialect.INGRES
-
SQLDialect.ORACLE
-
SQLDialect.POSTGRES
These dialects have been observed to partially support INTERVAL
data types in date time arithmetic functions, such as
TIMESTAMPADD
, and TIMESTAMPDIFF
:
Author: Lukas Eder See Also:
/**
* An implementation for the SQL standard <code>INTERVAL YEAR TO MONTH</code>
* data type.
* <p>
* <code>YearToMonth</code> is a {@link Number} whose {@link Number#intValue()}
* represents the number of months of the interval.
* <p>
* Note: only a few databases actually support this data type on its own. You
* can still use it for date time arithmetic in other databases, though, through
* {@link Field#add(Field)} and {@link Field#sub(Field)} Databases that have
* been observed to natively support <code>INTERVAL</code> data types are:
* <ul>
* <li> {@link SQLDialect#HSQLDB}</li>
* <li> {@link SQLDialect#INGRES}</li>
* <li> {@link SQLDialect#ORACLE}</li>
* <li> {@link SQLDialect#POSTGRES}</li>
* </ul>
* <p>
* These dialects have been observed to partially support <code>INTERVAL</code>
* data types in date time arithmetic functions, such as
* <code>TIMESTAMPADD</code>, and <code>TIMESTAMPDIFF</code>:
* <ul>
* <li> {@link SQLDialect#MARIADB}</li>
* <li> {@link SQLDialect#MYSQL}</li>
* </ul>
*
* @author Lukas Eder
* @see Interval
*/
public final class YearToMonth extends Number implements Interval, Comparable<YearToMonth> {
Generated UID
/**
* Generated UID
*/
private static final long serialVersionUID = 1308553645456594273L;
private static final Pattern PATTERN_SQL = Pattern.compile("^([+-])?(\\d+)-(\\d+)$");
private static final Pattern PATTERN_ISO = Pattern.compile("^([+-])?P(?:([+-]?\\d+)Y)?(?:([+-]?\\d+)M)?$", Pattern.CASE_INSENSITIVE);
private final boolean negative;
private final int years;
private final int months;
Create a new year-month interval.
/**
* Create a new year-month interval.
*/
public YearToMonth() {
this(0, 0, false);
}
Create a new year-month interval.
/**
* Create a new year-month interval.
*/
public YearToMonth(int years) {
this(years, 0, false);
}
Create a new year-month interval.
/**
* Create a new year-month interval.
*/
public YearToMonth(int years, int months) {
this(years, months, false);
}
YearToMonth(int years, int months, boolean negative) {
// Perform normalisation. Specifically, Postgres may return intervals
// such as 0-13
if (Math.abs(months) >= 12) {
years += (months / 12);
months %= 12;
}
this.negative = negative;
this.years = years;
this.months = months;
}
Parse a string representation of a INTERVAL YEAR TO MONTH
.
Params: - string – A string representation of the form
[+|-][years]-[months]
Returns: The parsed YEAR TO MONTH
object, or
null
if the string could not be parsed.
/**
* Parse a string representation of a <code>INTERVAL YEAR TO MONTH</code>.
*
* @param string A string representation of the form
* <code>[+|-][years]-[months]</code>
* @return The parsed <code>YEAR TO MONTH</code> object, or
* <code>null</code> if the string could not be parsed.
*/
public static YearToMonth valueOf(String string) {
if (string != null) {
Matcher matcher;
if ((matcher = PATTERN_SQL.matcher(string)).find())
return YearToSecond.parseYM(matcher, 0);
if ((matcher = PATTERN_ISO.matcher(string)).find()) {
boolean negative = "-".equals(matcher.group(1));
String group2 = matcher.group(2);
String group3 = matcher.group(3);
int years = group2 == null ? 0 : Integer.parseInt(group2);
int months = group3 == null ? 0 : Integer.parseInt(group3);
return new YearToMonth(years, months, negative);
}
return yearToMonth(string);
}
return null;
}
Parse a standard SQL string representation of a
INTERVAL YEAR
.
Params: - string – A string representation of the form
[+|-][years]
Returns: The parsed YEAR
object, or null
if the
string could not be parsed.
/**
* Parse a standard SQL string representation of a
* <code>INTERVAL YEAR</code>.
*
* @param string A string representation of the form
* <code>[+|-][years]</code>
* @return The parsed <code>YEAR</code> object, or <code>null</code> if the
* string could not be parsed.
*/
public static YearToMonth year(String string) {
try {
return string == null ? null : new YearToMonth(Integer.parseInt(string));
}
catch (NumberFormatException ignore) {
return null;
}
}
Parse a standard SQL string representation of a
INTERVAL YEAR TO MONTH
.
Params: - string – A string representation of the form
[+|-][years]-[months]
Returns: The parsed YEAR TO MONTH
object, or
null
if the string could not be parsed.
/**
* Parse a standard SQL string representation of a
* <code>INTERVAL YEAR TO MONTH</code>.
*
* @param string A string representation of the form
* <code>[+|-][years]-[months]</code>
* @return The parsed <code>YEAR TO MONTH</code> object, or
* <code>null</code> if the string could not be parsed.
*/
public static YearToMonth yearToMonth(String string) {
if (string != null) {
Matcher matcher;
if ((matcher = PATTERN_SQL.matcher(string)).find())
return YearToSecond.parseYM(matcher, 0);
}
return null;
}
Parse a standard SQL string representation of a
INTERVAL MONTH
.
Params: - string – A string representation of the form
[+|-][months]
Returns: The parsed MONTH
object, or null
if the
string could not be parsed.
/**
* Parse a standard SQL string representation of a
* <code>INTERVAL MONTH</code>.
*
* @param string A string representation of the form
* <code>[+|-][months]</code>
* @return The parsed <code>MONTH</code> object, or <code>null</code> if the
* string could not be parsed.
*/
public static YearToMonth month(String string) {
try {
return string == null ? null : new YearToMonth(0, Integer.parseInt(string));
}
catch (NumberFormatException ignore) {
return null;
}
}
@Override
public final Duration toDuration() {
long hours = years * 8766L // 365.25 * 24
+ months * 720L; // 30 * 24
if (negative)
hours = -hours;
return Duration.ofHours(hours);
}
// -------------------------------------------------------------------------
// XXX Interval API
// -------------------------------------------------------------------------
@Override
public final YearToMonth neg() {
return new YearToMonth(years, months, !negative);
}
@Override
public final YearToMonth abs() {
return new YearToMonth(years, months, false);
}
public final int getYears() {
return years;
}
public final int getMonths() {
return months;
}
@Override
public final int getSign() {
return negative ? -1 : 1;
}
// -------------------------------------------------------------------------
// XXX Number API
// -------------------------------------------------------------------------
@Override
public final int intValue() {
return (negative ? -1 : 1) * (12 * years + months);
}
@Override
public final long longValue() {
return intValue();
}
@Override
public final float floatValue() {
return intValue();
}
@Override
public final double doubleValue() {
return intValue();
}
// -------------------------------------------------------------------------
// XXX Comparable and Object API
// -------------------------------------------------------------------------
@Override
public final int compareTo(YearToMonth that) {
if (years < that.years) {
return -1;
}
if (years > that.years) {
return 1;
}
if (months < that.months) {
return -1;
}
if (months > that.months) {
return 1;
}
return 0;
}
@Override
public final int hashCode() {
final int prime = 31;
int result = 0;
if (months != 0)
result = prime * result + months;
if (years != 0)
result = prime * result + years;
return result;
}
@Override
public final boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() == obj.getClass()) {
YearToMonth other = (YearToMonth) obj;
if (months != other.months)
return false;
if (years != other.years)
return false;
return true;
}
else if (obj instanceof YearToSecond)
return obj.equals(this);
else
return false;
}
@Override
public final String toString() {
StringBuilder sb = new StringBuilder();
sb.append(negative ? "-" : "+");
sb.append(years);
sb.append("-");
sb.append(months);
return sb.toString();
}
}