该函数使用的是 SimpleDateFormat
来格式化日期,但该类解析日期的时候,依赖 Locale
但是集群机器的 Locale
似乎并不全是一致的。
所以会出现这样的现象:
SELECT from_unixtime(unix_timestamp('Sun Jun 17 14:27:22 CST 2012', 'EEE MMM dd hh:mm:ss \'CST\' yyyy'))
该 sql 返回有时候为 null,有时候又是正常。
解决办法:
ADD JAR hdfs://nameservice/user/hadoop/udf/UDFUnixTimeStamp.jar;
CREATE TEMPORARY FUNCTION unixtimestamp AS 'com.hive.udf.UDFUnixTimeStamp';
SELECT from_unixtime(unixtimestamp('Sun Jun 17 14:27:22 CST 2012', 'EEE MMM dd hh:mm:ss \'CST\' yyyy'))
该自定义函数指定了 Locale 为 en
,所以日期格式如果是中文的,是不可已使用的。
附加 UDF 代码:
@UDFType(deterministic = false)
@Description(name = "unix_timestamp",
value = "_FUNC_([date[, pattern]]) - Returns the UNIX timestamp",
extended = "Converts the current or specified time to number of seconds "
+ "since 1970-01-01.")
public class UDFUnixTimeStamp extends GenericUDFToUnixTimeStamp {
static {
Locale locale = Locale.ENGLISH;
Locale.setDefault(locale);
System.setProperty("user.language", "en");
}
@Override
protected void initializeInput(ObjectInspector[] arguments) throws UDFArgumentException {
if (arguments.length > 0) {
super.initializeInput(arguments);
}
}
@Override
protected String getName() {
return "unix_timestamp";
}
@Override
public Object evaluate(DeferredObject[] arguments) throws HiveException {
if (arguments.length == 0) {
retValue.set(System.currentTimeMillis() / 1000);
return retValue;
}
return super.evaluate(arguments);
}
}