Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support function months_between/add_months #27134

Open
HackervvSKvasdlK opened this issue Aug 12, 2021 · 0 comments
Open

support function months_between/add_months #27134

HackervvSKvasdlK opened this issue Aug 12, 2021 · 0 comments
Labels
type/feature-request This is a feature requests on the product

Comments

@HackervvSKvasdlK
Copy link

Feature Request

Is your feature request related to a problem? Please describe:

Describe the feature you'd like:
add_months/months_between:
We now have calculation requirements for month addition and subtraction and monthly difference, and the result needs to be consistent with Oracle/Hive. May I ask whether these two functions can be implemented. Example:
add_months('2019-2-28',1)=2019-3-31
add_months('2020-2-28',1)=2019-3-28
add_months('2020-2-29',1)=2019-3-31
add_months('2020-2-28',-1)=2019-1-28
add_months('2020-2-29',-1)=2019-1-31
add_months('2020-3-31',-1)=2020-2-29
add_months('2020-3-30',-1)=2020-2-29
add_months('2020-3-29',-1)=2020-2-29
add_months('2019-2-28',-1)=2019-1-31
add_months('2019-3-31',-1)=2019-2-28

The implementation in Hive is:
months_between:
public Object evaluate(DeferredObject[] arguments) throws HiveException {
// the function should support both short date and full timestamp format
// time part of the timestamp should not be skipped
Date date1 = getTimestampValue(arguments, 0, tsConverters);
if (date1 == null) {
date1 = getDateValue(arguments, 0, dtInputTypes, dtConverters);
if (date1 == null) {
return null;
}
}

Date date2 = getTimestampValue(arguments, 1, tsConverters);
if (date2 == null) {
  date2 = getDateValue(arguments, 1, dtInputTypes, dtConverters);
  if (date2 == null) {
    return null;
  }
}

cal1.setTime(date1);
cal2.setTime(date2);

// skip day/time part if both dates are end of the month
// or the same day of the month
int monDiffInt = (cal1.get(YEAR) - cal2.get(YEAR)) * 12 + (cal1.get(MONTH) - cal2.get(MONTH));
if (cal1.get(DATE) == cal2.get(DATE)
    || (cal1.get(DATE) == cal1.getActualMaximum(DATE) && cal2.get(DATE) == cal2
        .getActualMaximum(DATE))) {
  output.set(monDiffInt);
  return output;
}

int sec1 = getDayPartInSec(cal1);
int sec2 = getDayPartInSec(cal2);

// 1 sec is 0.000000373 months (1/2678400). 1 month is 31 days.
// there should be no adjustments for leap seconds
double monBtwDbl = monDiffInt + (sec1 - sec2) / 2678400D;
// Round a double to 8 decimal places.
double result = BigDecimal.valueOf(monBtwDbl).setScale(8, ROUND_HALF_UP).doubleValue();
output.set(result);
return output;

}

add_months:
protected Calendar addMonth(Date d, int numMonths) {
calendar.setTime(d);

boolean lastDatOfMonth = isLastDayOfMonth(calendar);

calendar.add(Calendar.MONTH, numMonths);

if (lastDatOfMonth) {
  int maxDd = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
  calendar.set(Calendar.DAY_OF_MONTH, maxDd);
}
return calendar;

}

@HackervvSKvasdlK HackervvSKvasdlK added the type/feature-request This is a feature requests on the product label Aug 12, 2021
@github-actions github-actions bot added this to Need Triage in Feature Request Kanban Aug 12, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type/feature-request This is a feature requests on the product
Projects
Feature Request Kanban
  
Need Triage
Development

No branches or pull requests

1 participant