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資料庫日期格式轉換操作Oracle資料庫
- java工具類之編碼轉換工具類Java
- 型別轉換工具類型別
- LocalDateTime工具類(常用轉換)LDA
- 日期與字串的互相轉換SQL語句字串SQL
- Linq 日期轉換
- LocalDateTime日期轉換LDA
- 轉換日期(C)
- js時間戳與日期格式的相互轉換JS時間戳
- 直播電商平臺開發,日期與時間戳轉換封裝工具類時間戳封裝
- 進位制轉換的工具類
- JS實現線上CSV轉換PHP、Mysql、Ruby等工具 -toolfk程式設計師工具網JSPHPMySql程式設計師
- 用於日期轉換的訊息轉換器
- Java常用時間格式轉換工具類Java
- JAVA-java日期工具類Java
- js 轉換時間戳的寫法ScriptJS時間戳
- JavaScript 時間日期格式轉換JavaScript
- SimpleDateFormat日期格式轉換的使用ORM
- SQL SERVER 日期格式化、日期和字串轉換SQLServer字串
- 萬能java字串編碼轉換工具類Java字串編碼
- Oracle轉換PostgresOracle
- JavaScript 時間日期轉換成中文JavaScript
- python字串轉換為日期時間Python字串
- oracle partition by 語法Oracle
- js轉換/Date(........)/JS
- js基礎01--js的簡介、使用、語法、輸出、註釋、變數、型別轉換、表JS變數型別
- sqlserver資料庫日期如何格式化-日期轉換字串SQLServer資料庫字串
- Oracle 查詢轉換Oracle
- php日期時間如何轉換為字串PHP字串
- golang日期字串與時間戳轉換Golang字串時間戳
- js顯式轉換和隱式轉換JS
- js圖片 轉換JS
- js型別轉換JS型別
- MSSQL-從字串轉換日期和/或時間時,轉換失敗SQL字串
- Oracle實驗(02):轉換 & 轉譯Oracle
- 一個日期處理類庫moment.jsJS
- 漢語言處理工具pyhanlp的簡繁轉換HanLP
- pl/sql to_dateSQL