js日期轉換工具類(仿oracle to_char,to_date等語法)
摘要
js字串轉日期,js日期轉字串。
更新日誌
2018/08/21
- 在字串轉日期中,修改“日”的預設值為1.
- 可以識別單數字的“日”,”月“。比如 1-9-2018可以直接這樣轉換
NayiUtil.to_date("1-9-2015", "dd-mm-yyyy")
2018/12/04
- 新增add_days、add_months、add_years三個函式
2019/02/01
- 修復to_date方法中的bug,例
NayiUtil.to_date('20190131 12:13:14', 'yyyymmdd hh24:mi:ss');
或NayiUtil.to_date('20190131 2:13:14', 'yyyymmdd hh24:mi:ss');
在之前會返回錯誤結果 - 新增add_months_plus方法,轉換原則為
If date is the last day of the month or if the resulting month has fewer days than the day component of date, then the result is the last day of the resulting month. Otherwise, the result has the same day component as date.
2019/04/04
- 繼續修復hh12與hh24的bug。。。
- 新增last_day方法(傳入日期型別,獲取當月的最後一天)例:
document.write(NayiUtil.last_day(new Date()));
- 新增last_month_day方法(傳入日期型別,獲取當月最後一天的日期字串,兩位的,比如31,28,31)例:
document.write(NayiUtil.last_month_day(new Date()));
- 新增months_between方法(三個引數,前兩個為需要比較的日期型別,後一個為標識,1時不考慮dd,只做月份加減,永遠返回整數;0或者預設時,安下述規則計算)例
document.write(NayiUtil.months_between(NayiUtil.to_date("20190228", "yyyymmdd"), NayiUtil.to_date("20190127", "yyyymmdd"), 0));
If date1 and date2 are either the same days of the month or both last days of months, then the result is always an integer. Otherwise Oracle Database calculates the fractional portion of the result based on a 31-day month and considers the difference in time components date1 and date2.
背景
一般來說,應該是要儘量避免在js中做時間操作的,它可能會導致很奇葩的bug產生。但是有時候又確實需要這麼做。這個時候就會被蹩腳的語法噁心一臉。為了避免再次發生這種情況,我寫了一個時間操作的工具類,在此分享。
我個人比較喜歡oracle中的to_char與to_date函式,所以具體的使用方法與在oracle中是一樣的。雖然只實現了最基本的用法,不過熟悉oracle的朋友可以直接把文章最後的程式碼粘過來用。不熟悉的往下看用法。
用法
to_char
用法示例
NayiUtil.to_char(new Date(2018,0,31,12,30,40), "yyyymmdd");
返回20180130
;
NayiUtil.to_char(new Date(2018,0,31,12,30,40), "yyyy-mm-dd");
返回2018-01-30
;
NayiUtil.to_char(new Date(2018,0,31,12,30,40), "y,yyy-yyyy-yyy-yy-y-mm-dd hh12:hh24:mi:ss**sssss***q 季度:qcn 星期d__dc_day");
返回 2,018-2018-018-18-8-01-31 00:12:30:40**45040***1 季度:第一季度 星期3__3_星期三
;
NayiUtil.to_char(new Date(2018,0,31,12,30,40), "Aa(YyYy)yyyy");
返回aaYyYy2018
;
NayiUtil.to_char(new Date(2018,0,31,12,30,40), "Aa\\(YyYy\\)yyyy\\\\");
返回aa(2018)2018\
;
NayiUtil.to_char(new Date(2018,0,31,12,30,40), "fmmm");
返回1
;
基本憑感覺用就對了,我只解釋幾點
- 格式化引數會自動轉為小寫,除非寫在圓括號中。
- 圓括號中的字元會直接原樣輸出,其他沒有匹配上的字元會小寫格式輸出。
\
是轉義符號。只有兩個作用,輸出圓括號和他自己。- 優先最長匹配規則。比如
ddd
會解析為dd+d,而不會是d+dd或d+d+d。 - fm,去除多餘的前導零。
####to_date
未進行匹配的部分會預設為當前時間
可以匹配的字元(很少用到的沒寫)
yyyy mm dd hh24 hh mi ss
用法示例
NayiUtil.to_char(NayiUtil.to_date("01-2015-15", "mm-yyyy-dd"), 'yyyy-mm-dd hh24:mi:ss')
返回2015-01-15 19:36:03
NayiUtil.to_char(NayiUtil.to_date("01-aaaaaa2015", "mm-nayinayyyy"), 'yyyy-mm-dd hh24:mi:ss')
返回2015-01-29 19:37:58
解釋
不需要匹配的部分可以用任意無關字元佔位。
完整程式碼
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript">
var NayiUtil = function(){
var fill_zreo = function(str, length){
str = str.toString();
var l = str.length;
if (str.length >= length) {return str;}
for(var i = 0; i < length - l; i++){
str = "0" + str;
}
return str;
}
var to_char = function(dateObj, fmtSrc) {
if(!(dateObj instanceof Date)){
return "now, only Datetype is supported";
}
if(!dateObj || !fmtSrc){
return dateObj || "null";
}
var fmtModel = "";
var result = "";
var init = function(){
var res = "";
var inner_flag = false;
for(var i = 0; i < fmtSrc.length; i++){
if(fmtSrc.charAt(i) == "\\"){
res += fmtSrc.charAt(i) + fmtSrc.charAt(i + 1);
i += 1;
continue;
}
if(fmtSrc.charAt(i) == "("){
inner_flag = true;
}
res += inner_flag ? fmtSrc.charAt(i) : fmtSrc.charAt(i).toLowerCase();
if(fmtSrc.charAt(i) == ")"){
inner_flag = false;
}
}
fmtSrc = res;
fmtModel = fmtSrc.match(/fm/g);
fmtSrc = fmtSrc.replace(/fm/g, "");
}
init();
var validFmt = {
"yyyy": function() {
if(fmtModel == "fm"){
return dateObj.getFullYear();
}else {
return fill_zreo(dateObj.getFullYear(), 4);
}
},
"mm": function() {
if(fmtModel == "fm"){
return dateObj.getMonth() + 1;
}else {
return fill_zreo(dateObj.getMonth() + 1, 2);
}
},
"dd": function(){
if(fmtModel == "fm"){
return dateObj.getDate();
}else {
return fill_zreo(dateObj.getDate(), 2);
}
},
"yyy": function(){
if(fmtModel == "fm"){
return dateObj.getFullYear().toString().substr(-3);
}else {
return fill_zreo(dateObj.getFullYear().toString().substr(-3), 3);
}
},
"yy": function(){
if(fmtModel == "fm"){
return dateObj.getFullYear().toString().substr(-2);
}else {
return fill_zreo(dateObj.getFullYear().toString().substr(-2), 1);
}
},
"y": function(){
if(fmtModel == "fm"){
return dateObj.getFullYear().toString().substr(-1);
}else {
return fill_zreo(dateObj.getFullYear().toString().substr(-1), 1);
}
},
"y,yyy": function(){
var temp = fill_zreo(dateObj.getFullYear(), 4);
var yResult = temp.substr(0, 1) + "," + temp.substr(1, 3);
return yResult;
},
"hh": function(){
if(fmtModel == "fm"){
return (dateObj.getHours()) % 12;
}else {
return fill_zreo((dateObj.getHours()) % 12, 2);
}
},
"hh12": function(){
if(fmtModel == "fm"){
return (dateObj.getHours()) % 12;
}else {
return fill_zreo((dateObj.getHours()) % 12, 2);
}
},
"hh24": function(){
if(fmtModel == "fm"){
return dateObj.getHours();
}else {
return fill_zreo(dateObj.getHours(), 2);
}
},
"mi": function(){
if(fmtModel == "fm"){
return dateObj.getMinutes();
}else {
return fill_zreo(dateObj.getMinutes(), 2);
}
},
"ss": function(){
if(fmtModel == "fm"){
return dateObj.getSeconds();
}else {
return fill_zreo(dateObj.getSeconds(), 2);
}
},
"sssss": function(){
return dateObj.getSeconds() + dateObj.getHours() * 3600 + dateObj.getMinutes() * 60;
},
"ff": function(){
return dateObj.getMilliseconds();
},
"d": function(){
return fill_zreo(dateObj.getDay(), 1);
},
"ddd": function(){
var dateArr = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
var date = new Date();
var day = date.getDate();
var month = date.getMonth(); //getMonth()是從0開始
var year = date.getFullYear();
var result = 0;
for ( var i = 0; i < month; i++) {
result += dateArr[i];
}
result += day;
if (month > 1 && (year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
result += 1;
}
return result;
},
"dc": function(){
return fill_zreo(dateObj.getDay() == 0 ? 7 : dateObj.getDay(), 1); //中文星期數字(js是0-6,0是星期日)
},
"day": function(){
var arr = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"];
return arr[dateObj.getDay()];
},
"q": function(){
var arr = ["1", "1", "1", "1",
"2", "2", "2", "2",
"3", "3", "3", "3",
"4", "4", "4", "4"]
return arr[dateObj.getMonth()];
},
"qcn": function(){
var arr = ["第一季度", "第一季度", "第一季度", "第一季度",
"第二季度", "第二季度", "第二季度", "第二季度",
"第三季度", "第三季度", "第三季度", "第三季度",
"第四季度", "第四季度", "第四季度", "第四季度"];
return arr[dateObj.getMonth()];
}
}
var temp = "";
var bracket_num = 0;
for(var i = 0; i < fmtSrc.length; ){
if(fmtSrc.charAt(i) == "("){
bracket_num++;
i++;
continue;
}
if(fmtSrc.charAt(i) == ")" && bracket_num > 0){
bracket_num--;
i++;
continue;
}
if(fmtSrc.charAt(i) == "\\"){
result += fmtSrc.charAt(i + 1);
i += 2;
continue;
}
if(bracket_num > 0){
result += fmtSrc.charAt(i);
i++;
continue;
}
var maxLength = 0;
var j = i + 1;
for(; j <= fmtSrc.length; j++){
if(validFmt[fmtSrc.substr(i, j - i)]){
maxLength = j - i;
}
}
if(maxLength){
result += validFmt[fmtSrc.substr(i, maxLength)]();
}else {
result += fmtSrc.charAt(i);
}
i += maxLength || 1;
}
return result;
}
var to_date = function(dateStr, fmt){
var dateStr_bk = dateStr;
var init = function(){
fmt = fmt.toLowerCase();
}()
var default_date = new Date();
var year = default_date.getFullYear();
var month = default_date.getMonth();
//var day = default_date.getDate();
var day = 1;
var hour = default_date.getHours();
var minute = default_date.getMinutes();
var second = default_date.getSeconds();;
var validFmt = {
"yyyy": function(str, s_index, length){
var temp = str.substr(s_index, length);
year = temp.match(/^[0-9]+/g)[0];
return temp.length - year.length;
},
"mm": function(str, s_index, length){
var temp = str.substr(s_index, length);
month = temp.match(/^[0-9]+/g)[0] - 1;
return temp.length - temp.match(/^[0-9]+/g)[0].length;
},
"dd": function(str, s_index, length){
var temp = str.substr(s_index, length);
day = temp.match(/^[0-9]+/g)[0];
return temp.length - day.length;
},
"hh12": function(str, s_index, length){
//hour = str.substr(s_index, length);
var temp = str.substr(s_index, length);
hour = temp.match(/^[0-9]+/g)[0] ;
hour = hour.substr(0, 2);
var returnLength = temp.length - hour.length;
hour = parseInt(hour) % 12;
return returnLength;
},
"hh24": function(str, s_index, length){
//hour = str.substr(s_index, length);
var temp = str.substr(s_index, length);
hour = temp.match(/^[0-9]+/g)[0];
hour = hour.substr(0, 2);
return temp.length - hour.length;
},
"hh": function(str, s_index, length){
//hour = str.substr(s_index, length);
var temp = str.substr(s_index, length);
hour = temp.match(/^[0-9]+/g)[0];
return temp.length - hour.length;
},
"mi": function(str, s_index, length){
//minute = str.substr(s_index, length);
var temp = str.substr(s_index, length);
minute = temp.match(/^[0-9]+/g)[0];
return temp.length - minute.length;
},
"ss": function(str, s_index, length){
//second = str.substr(s_index, length);
var temp = str.substr(s_index, length);
second = temp.match(/^[0-9]+/g)[0];
return temp.length - second.length;
}
}
var temp = "";
var bracket_num = 0;
var axis = 0; //主要為處理2018-8-21這種特殊情況(2018-08-21為正常情況)
for(var i = 0; i < fmt.length; ){
var maxLength = 0;
var j = i + 1;
for(; j <= fmt.length; j++){
if(validFmt[fmt.substr(i, j - i)]){
maxLength = j - i;
}
}
if(maxLength){
axis += validFmt[fmt.substr(i, maxLength)](dateStr, i - axis, maxLength) || 0;
}else {
}
i += maxLength || 1;
}
//alert(year+"_"+ month+"_"+ day+"_"+ hour+"_"+ minute+"_"+ second);
var resultDate = new Date(year, month, day, hour, minute, second);
return resultDate;
}
var add_days = function(oldDate, addDays){
return new Date(oldDate.setDate(oldDate.getDate() + addDays));
}
var add_months = function(oldDate, addMonths){
return new Date(oldDate.setMonth(oldDate.getMonth() + addMonths));
}
var add_years = function(oldDate, addYesrs){
return new Date(oldDate.setFullYear(oldDate.getFullYear() + addYesrs));
}
var add_months_plus = function(oldDate, addMonths){
var dateArr = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
var oldYear = fill_zreo(oldDate.getFullYear(), 4);
var oldMonth = fill_zreo(oldDate.getMonth(), 2);
var oldDay = fill_zreo(oldDate.getDate(), 2);
var newYear = parseInt(oldYear) + Math.floor((parseInt(oldMonth) + 1 + parseInt(addMonths)) / 12);
var newMonth = (parseInt(oldMonth) + 1 + parseInt(addMonths)) % 12;
var newDay;
var currentLastDay;
if((oldMonth == 1) && (oldYear % 400 == 0 || (oldYear % 4 == 0 && oldYear % 100 != 0))){
currentLastDay = 29;
}else {
currentLastDay = dateArr[oldMonth];
}
if(oldDay == currentLastDay){
newDay = dateArr[newMonth];
}else if(oldDay > dateArr[(newMonth - 1) % 12]){
if(newMonth == 2 && (oldYear % 400 == 0 || (oldYear % 4 == 0 && oldYear % 100 != 0))){
newDay = 29;
}else {
newDay = dateArr[(newMonth - 1) % 12];
}
}else{
newDay = oldDay;
}
//alert(to_date("2019-04-30 14:34", 'yyyy-mm-dd hh24:mi'));
//alert("old : " + oldDay + "__"+newYear+"-"+newMonth+"-"+newDay);
//alert(""+newYear+"-"+newMonth+"-"+newDay+to_char(oldDate, '-hh24-mi-ss'));
return to_date(""+newYear+"-"+newMonth+"-"+newDay+" "+to_char(oldDate, 'hh24:mi:ss'), 'yyyy-mm-dd hh24:mi:ss');
}
return {
to_char: to_char,
to_date: to_date,
add_days: add_days,
add_months: add_months,
add_years: add_years,
add_months_plus: add_months_plus
};
}();
;
//"2018","0","31","1","31","13"
//var test = NayiUtil.to_char(new Date(), "yyyy(年)mm月dd(Ri) \\(yyyy-mm-dd\\) dd-mm-yyyy hh24:mi:ss:ff d dc dcn qcn q ddd sssss y,yyy ---");
//alert(test);
//var ttt = NayiUtil.to_char(new Date(2018,0,31,12,30,40), "fmmm");
//alert(ttt);
//document.write(ttt);
//document.write(NayiUtil.to_char(NayiUtil.to_date("01-2015-15", "mm-yyyy-dd"), 'yyyy-mm-dd hh24:mi:ss'));
//document.write("\r\n ");
document.write(NayiUtil.to_char(NayiUtil.to_date("1-9-2015", "dd-mm-yyyy"), 'yyyy-mm-dd hh24:mi:ss'));
</script>
</head>
<body>
</body>
</html>
相關文章
- Oracle 中的 TO_DATE 和 TO_CHAR 函式 日期處理Oracle函式
- oracle 日期to_char轉換24小時制12小時制Oracle
- 字串與日期型別轉換的工具類字串型別
- Oracle中的時間函式用法(to_date、to_char) (總結)Oracle函式
- Oracle 中文日期轉換Oracle
- jsp語法轉換為thyemleafJS
- js日期轉換函式JS函式
- 【Tip】使用TO_DATE和TO_CHAR函式讓Oracle自己去數數函式Oracle
- oracle日期轉換成星期Oracle
- 使用Oracle to_date方法【轉】Oracle
- ORACLE TO_CHAR()函式中日期格式的使用Oracle函式
- JS日期格式化轉換方法JS
- Date轉換工具類
- java工具類之編碼轉換工具類Java
- js日期格式簡單轉換程式碼JS
- 型別轉換工具類型別
- to_char函式格式轉換參考函式
- js將時間日期物件轉換為時間日期字元JS物件字元
- Oracle資料庫日期格式轉換操作Oracle資料庫
- 直播電商平臺開發,日期與時間戳轉換封裝工具類時間戳封裝
- 日期與字串的互相轉換SQL語句字串SQL
- js將時間日期字串轉換為時間日期Date物件JS字串物件
- oracle to_date格式Oracle
- to_date、to_char及格式化大小寫 nvl nvl2 nullifNull
- LocalDateTime工具類(常用轉換)LDA
- 轉換日期(C)
- 日期實用工具類
- JSP語法格式 (轉)JS
- 將任意格式轉換為JSON資料格式的工具類JSON
- JS的語句及語法(轉)JS
- js時間戳與日期格式的相互轉換JS時間戳
- JS實現線上CSV轉換PHP、Mysql、Ruby等工具 -toolfk程式設計師工具網JSPHPMySql程式設計師
- 自寫Json轉換工具JSON
- 進位制轉換的工具類
- Linq 日期轉換
- mysql 日期轉換字串MySql字串
- 日期格式的轉換
- sql 日期格式轉換SQL