hive 函数

weekofyear()

用法

select weekofyear('2022-01-01') 或 select weekofyear('2022-01-01 12:00:00')

返回值

1

函数含义

给定一个日期返回再当年的第几周

源码地址

org.apache.hadoop.hive.ql.udf.UDFWeekOfYear

源代码

@Description(name = "yearweek",
    value = "_FUNC_(date) - Returns the week of the year of the given date. A week "
    + "is considered to start on a Monday and week 1 is the first week with >3 days.",
    extended = "Examples:\n"
    + "  > SELECT _FUNC_('2008-02-20') FROM src LIMIT 1;\n"
    + "  8\n"
    + "  > SELECT _FUNC_('1980-12-31 12:59:59') FROM src LIMIT 1;\n" + "  1")
@VectorizedExpressions({VectorUDFWeekOfYearDate.class, VectorUDFWeekOfYearString.class, VectorUDFWeekOfYearTimestamp.class})
@NDV(maxNdv = 52)
// 因为一年当中最大为52周,所以返回值最大就为52
public class UDFWeekOfYear extends UDF {
	// 结果值返回值,使用Hadoop的IntWritable 数据类型
  private final IntWritable result = new IntWritable();
	// 使用 java Calendar 获取日期再一年中的第几个周
	// 默认使用 utc 时区
  private final Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));

	
  public UDFWeekOfYear() {
  		// 设置一周的第一天是什么;例如,美国的SUNDAY ,法国的MONDAY 。
    calendar.setFirstDayOfWeek(Calendar.MONDAY);
	   // 设置一年中第一周所需的最少天数;例如,如果将第一周定义为包含一年第一个月的第一天的一周,则使用值 1 调用此方法。如果必须是整周,则使用值 4。
    calendar.setMinimalDaysInFirstWeek(4);
  }

  /**
   * Get the week 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 int from 1 to 53. null if the dateString is not a valid date
   *         string.
   */
  public IntWritable evaluate(Text dateString) {
  		// 非空判断
    if (dateString == null) {
      return null;
    }
    try {
	    // 对输出的字符串转换成Date类型
      Date date = Date.valueOf(dateString.toString());
				// 转换成秒
      calendar.setTimeInMillis(date.toEpochMilli());
	     // 获取第几周
      result.set(calendar.get(Calendar.WEEK_OF_YEAR));
      return result;
    } catch (IllegalArgumentException e) {
      return null;
    }
  }
	// 只是传入的参数类型为hive自定义的 DateWritableV2 其他的都一样
  public IntWritable evaluate(DateWritableV2 d) {
    if (d == null) {
      return null;
    }
    Date date = d.get();
    calendar.setTimeInMillis(date.toEpochMilli());
    result.set(calendar.get(Calendar.WEEK_OF_YEAR));
    return result;
  }
	// 只是传入的参数类型为hive自定义的 TimestampWritableV2 其他的都产不多
  public IntWritable evaluate(TimestampWritableV2 t) {
    if (t == null) {
      return null;
    }

    Timestamp ts = t.getTimestamp();
    calendar.setTimeInMillis(ts.toEpochMilli());
    result.set(calendar.get(Calendar.WEEK_OF_YEAR));
    return result;
  }

}

总结

  1. 整体上这个函数,比较简单,做了一些简单的值域判断,加上使用java calendar 类型加工。