package com.livingsocial.hive.udf;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import org.apache.hadoop.hive.ql.exec.Description;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.hive.serde2.io.TimestampWritable;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
/**
*
* UDFQuarter
*
* From https://issues.apache.org/jira/browse/HIVE-3404 until it's in the main hive build
*
*/
@Description(name = "quarter", value = "_FUNC_(date or timestamp) -" +
" Returns the quarter of the year corresponding to date or timestamp")
public class UDFQuarter extends UDF {
private final SimpleDateFormat formatter = new SimpleDateFormat(
"yyyy-MM-dd");
private final Calendar calendar = Calendar.getInstance();
private IntWritable result = new IntWritable();
public UDFQuarter() {
}
/**
* Get the quarter of the year from a date string.
*
* @param dateString
* the dateString in the format of "yyyy-MM-dd HH:mm:ss" or
* "yyyy-MM-dd".
* @return an IntWritable from 1 to 4. null if the dateString is not a valid date
* string.
*/
public IntWritable evaluate(Text dateString) {
if (dateString == null) {
return null;
}
try {
Date date = formatter.parse(dateString.toString());
calendar.setTime(date);
int month = calendar.get(Calendar.MONTH) + 1;
result = getQuarter(month);
} catch (ParseException e) {
return null;
}
return result;
}
/**
* Get the quarter of the year from a date Timestamp.
*
* @param dateTimeStamp
* the dateTimeStamp in the format of "yyyy-MM-dd HH:mm:ss" or
* "yyyy-MM-dd".
* @return an IntWritable from 1 to 4. null if the dateTimeStamp is not a valid date
* TimeStamp.
*/
public IntWritable evaluate(TimestampWritable dateTimeStamp) {
if (dateTimeStamp == null) {
return null;
}
calendar.setTime(dateTimeStamp.getTimestamp());
int month = calendar.get(Calendar.MONTH) + 1;
result = getQuarter(month);
return result;
}
/**
* getQuarter method calculates in which quarter the date falls
*
* @param monthOfYear
* @return quarter
*/
public IntWritable getQuarter(int monthOfYear) {
IntWritable quarter = new IntWritable();
if (monthOfYear >= 1 && monthOfYear <= 3) {
quarter.set(1);
} else if (monthOfYear >= 4 && monthOfYear <= 6) {
quarter.set(2);
} else if (monthOfYear >= 7 && monthOfYear <= 9) {
quarter.set(3);
} else if (monthOfYear >= 10 && monthOfYear <= 12) {
quarter.set(4);
}
return quarter;
}
}