1. 為什么要寫時間變量
項目中經(jīng)常會用到寫時間變量的情況丁眼,特別是調(diào)度系統(tǒng)中锨亏,運維的同學(xué)應(yīng)該深有體會炕泳。如定時調(diào)度的sql纵诞,周期生成的文件等等,其中時間都只能是變量培遵,執(zhí)行時替換為數(shù)據(jù)日期浙芙。而時間變量不可能只是簡單yyyyMMdd就能表示,比如sql的篩選條件是每月倒數(shù)第5天的數(shù)據(jù)籽腕,比如月文件數(shù)據(jù)日期為上月日期等等嗡呼。而此時就需要一個靈活簡便的方式,不但能做變量的替換皇耗,還需要按照規(guī)則對時間進行加減運算等等操作南窗。
例如:抽取每月1號到倒數(shù)第二天的數(shù)據(jù),此時sql的時間函數(shù)一般都能解決,但寫函數(shù)的麻煩程度可想而知万伤,而用時間變量就可以很好表示窒悔。
select * ?from bassint.int_10086_$OT_yyyyMM$ where op_time = '$OT_yyyyMMdd(^2d)$';
2. 規(guī)則:
1. 定義時間變量前綴、后綴壕翩,用以標(biāo)識前后綴之間的為時間變量蛉迹。如:
?前綴"$OT_"和后綴"$",代表前后綴之間的時間變量為數(shù)據(jù)時間放妈。而"$CT_"和"$"代表前后綴之間的時間變量為當(dāng)前時間
?$OT_yyyyMMdd$ $CT_yyyyMMdd HH:MM:ss$
2. 定義時間規(guī)則前綴北救、后綴,如前綴"("和后綴")"芜抒,代表前后綴之間的字符串為時間運算規(guī)則
?$OT_yyyyMMdd(-1d)$ 數(shù)據(jù)時間的前一天
?$OT_yyyyMMdd HH(+1h)$ 數(shù)據(jù)時間的后一小時
?$OT_yyyyMM(-1m)dd(^1d)$ 數(shù)據(jù)時間上一月的最后一天
3. 運算規(guī)則
?時間規(guī)則珍策,y(年),m(月)宅倒,d(天)攘宙,h(小時24),i(分鐘)拐迁,s(秒)
?運算符+ - ^
?+ 在原時間上加
?- 在原時間上減
?^ 當(dāng)前時間最后前多少時間蹭劈,即倒數(shù)如
? ?^5i 表示當(dāng)前小時最后前5分鐘 ?55分
? ?^1h 表示當(dāng)前天最后前1小時 23時
? ?^3m 表示當(dāng)前年最后前3月 10月
3. 實現(xiàn)代碼
由于篇幅有限,這里只提供主要屬性和方法聲明线召,具體代碼可自行實現(xiàn)铺韧。
private String optimePrefix="$OT_";
private String optimeSuffix="$";
private String currTimePrefix="$CT_";
private String currTimeSuffix="$";
private String timeRulePrefix="(";
private String timeRuleSuffix=")";
private static booleanignoreNotFound=false;
/**
*替換字符按串入口方法,獲取前后綴之間字符串集合缓淹,遍歷集合哈打,提取每個時間變量中的時間規(guī)則,并進行計算讯壶,最后得出計算后的時間
*@param timeStr需要替換的字符串
*@param timeMillis時間
*@param prefix前綴
*@param suffix后綴
*@return
*@throwsException
*/
public String replaceTimeString(String timeStr, longtimeMillis,String prefix,String suffix){...}
/**
*讀取字符串中固定前后綴之間的子串
*@param value原字符串
*@param prefix前綴
*@param suffix后綴
*@return提取出的子串Set集合
*/
public Set getStringVars(String value,String prefix,String suffix){...}
/**
*獲取單個時間變量料仗,以及其時間規(guī)則
*如yyyy(+1y)MM(-1m)dd HH:mm(+30i):ss提取的結(jié)果為鍵值對:("yyyyMMdd HH:mm:ss","+1y,-1m,+30i")
*@param value 時間變量
*@param prefix前綴
*@param suffix后綴
*@returnPair(K, V)即("yyyyMMdd HH:mm:ss","+1y,-1m,+30i")
*@throwsException
*/
public Pair getStringRule(String value,String prefix,String suffix) {...}
/**
*使用paramMap,替換value中對應(yīng)的K
*@param value需要替換的字符串
*@param prefix替換子串前綴
*@param suffix替換子串后綴
*@param paramMap替換子串的對應(yīng)關(guān)系
*@param ignoreNotFound當(dāng)paramMap中找到不到對應(yīng)子串的key時伏蚊,
* ? ? ? ? ? ? ? ? ? ? ? ? ?true:忽略錯誤立轧,返回未替換的字符串
* ? ? ? ? ? ? ? ? ? ? ? ? ?false:拋出異常
*@param notFoundValue當(dāng)ignoreNotFound為true時,將paramMap中找到不到對應(yīng)key的子串替換為notFoundValue
* ? ? ? ? ? ? ? ? ? ? ?notFoundValue為null時不做替換
*@return替換后的字符串
*/
public String replaceString(String value,String prefix,String suffix,Map paramMap,
booleanignoreNotFound,String notFoundValue) {...}
/**
*根據(jù)時間格式和時間規(guī)則躏吊,得到運算后的時間肺孵。
*@param format時間的格式,如yyyyMMdd
*@param timeRule時間規(guī)則
*@param timeMillis時間
*@return
*@throwsException
*/
public String parseTime(String format,String timeRule, longtimeMillis) {...}
/**
*返回按照時間規(guī)則運算后的時間
*@param cal輸入時間
*@param ruleItem時間規(guī)則颜阐,y(年)平窘,m(月),d(天)凳怨,h(小時24)瑰艘,i(分鐘)是鬼,s(秒)
*支持+ - ^運算
* ? ? ? ? ? ? ? ? ?+在原時間上加
* ? ? ? ? ? ? ? ? ?-在原時間上減
* ? ? ? ? ? ? ? ? ?^當(dāng)前時間最后前多少時間,如
* ? ? ? ? ? ? ? ? ? ? ?^5i表示當(dāng)前小時最后前5分鐘55分
* ? ? ? ? ? ? ? ? ? ? ?^1h表示當(dāng)前天最后前1小時23時
* ? ? ? ? ? ? ? ? ? ? ?^3m表示當(dāng)前年最后前3月10月
*
*@throwsException
*/
private Calendar calculateTimeByRuleItem(Calendar cal,String ruleItem) {...}