js中進行數字,超大金額(千位符)格式化處理

前言

最近遇到一個需求,對於社區裏討論的帖子展現一個訪問量的計數顯示問題,當超過多少頁面訪問量時,就讓其顯示xxx萬,xx億css

對於後臺返回該字段的數據類型是number,須要進行格式化數字的輸出前端

這個應用場景在前端開發中其實很廣泛,例如:音樂app裏面音樂歌曲播放數量,微博裏的點贊數,評論留言條數,頁面的訪問量,超大金額(千位符格式)處理,甚至時間格式轉換等處理git

下面就一塊兒來看看怎麼處理的github

數字超大時-末尾添加相應的單位

需求:當後臺接口返回一個較大的數字時,例如:1000,26742238,1234787325,低於6位數時,讓數字徹底顯示,若高於4位,低於8位,給數字加相對應的單位,那麼須要在前臺作轉換爲2674.22萬,12.34億面試

示例代碼以下所示:本身封裝一個格式化函數正則表達式

function tranNumber(num, point){
   // 將數字轉換爲字符串,而後經過split方法用.分隔,取到第0個
   let numStr = num.toString().split('.')[0]
   if(numStr.length<6) { // 判斷數字有多長,若是小於6,,表示10萬之內的數字,讓其直接顯示
       console.log(numStr);
       return numStr;
     }else if(numStr.length>=6 && numStr.length<=8){ // 若是數字大於6位,小於8位,讓其數字後面加單位萬
        let decimal = numStr.substring(numStr.length-4, numStr.length-4+point)
        console.log(decimal);
        // 由千位,百位組成的一個數字
        return parseFloat(parseInt(num / 10000)+'.'+decimal)+'萬'  
   }else if(numStr.length >8){ // 若是數字大於8位,讓其數字後面加單位億
        let decimal = numStr.substring(numStr.length-8, numStr.length-8+point);
        console.log(decimal);
        return parseFloat(parseInt(num/100000000)+'.'+decimal)+'億'
   }
}

console.log(tranNumber(1000,2)) // 1000
console.log(tranNumber(26742238,2)) // 2674.22萬
console.log(tranNumber(1234787325,2)) // 12.34億
複製代碼

示例效果以下所示 數據庫

格式化數字.png
固然對於小數點後面留幾位,本身能夠自定義的,若是那種計量頁面瀏覽量,視頻播放次數,以及點贊數,評論數,省略後面的數,其實沒有什麼

可是要注意的是:若是涉及到金額轉帳之類,那可不能隨意舍掉的,否則的話,老闆會找你問話的npm

數字千位符格式化

需求:所謂的數字千分位形式,是從個位數起,每三位之間加一個逗號,例如:1450068,通過處理以後:1,450,068小程序

這在前端是一個很是常見的問題,後臺返回一金額數字,前臺拿到以後,要進行格式化處理,而後顯示到頁面上微信小程序

方法一:利用字符串提供的toLocaleString()方法處理,此方法最簡單

var num = 1450068;
console.log(num.toLocaleString()) // 1,450,068
複製代碼

方法二:截取末尾三個字符的功能能夠經過字符串類型的slice、substr或substring方法作到

/*
   slice() 方法可從已有的數組中返回選定的元素,截取數組的一個方法
*/
function toThousandsNum(num) {
       var num = (num || 0).toString(),
             result = '';

        while (num.length > 3) {
            //此處用數組的slice方法,若是是負數,那麼它規定從數組尾部開始算起的位置
            result = ',' + num.slice(-3) + result;
            num = num.slice(0, num.length - 3);
        }
        // 若是數字的開頭爲0,不須要逗號
        if (num){
          result = num + result
        }
        return result;
    }

    console.log(toThousandsNum(000123456789123)) // 123,456,789,123
複製代碼

方法三:把數字經過toString,轉換成字符串後,打散爲數組,再從末尾開始,逐個把數組中的元素插入到新數組(result)的開頭,每插入一個元素,counter就計一次數(加1),當counter爲3的倍數時,利用取餘的方式,就插入一個逗號,可是要注意開頭(i爲0時)不須要逗號。最後經過調用新數組的join方法得出結果

以下代碼所示

function toThousands(num) {
    var result = [],
    counter = 0;
    num = (num || 0).toString().split('');
    for (var i = num.length - 1; i >= 0; i--) {
        counter++;
        result.unshift(num[i]);
        if (!(counter % 3) && i != 0) {
           result.unshift(',');
        }
    }
    return result.join('');
}
console.log(toThousands(236471283572983412)); // 236,471,283,572,983,420
複製代碼

方法四:不把字符串打散爲數組,始終對字符串操做,下面的這種操做字符串的方式是對上面的改良

function toThousands(num) {
    var result = '',
    counter = 0;
    num = (num || 0).toString();
    for (var i = num.length - 1; i >= 0; i--) {
        counter++;
        result = num.charAt(i) + result;
        if (!(counter % 3) && i != 0) {
          result = ',' + result;
            
        }
    }
    return result;
}
console.log(toThousands(42371582378423))  // 42,371,582,378,423
複製代碼

方法五:正則表達式,此方法我的以爲比較難以理解,網上大牛寫的

function toThousands(num) {
   var numStr = (num || 0).toString();
    return numStr.replace(/(\d)(?=(?:\d{3})+$)/g, '$1,');
}
複製代碼

綜上所述:數字千位符格式化的方式有不少種方式,固然我的以爲最簡單粗暴的方法就是toLocalString()方法,即便數字開始是0,這個方法也自動幫咱們處理了的,實際開發中,強烈建議用第一種方式最好,後面的方法僅次

有時候,每每在面試時會被問到,除了最簡單的一種方式,還有沒有別的方式,其餘方法是有些燒腦袋的

結合第三方庫的使用

當你以爲本身編寫這種格式化方法比較繁瑣的時候,總有好用的工具已經幫咱們實現了的

  • Numeral.js

  • 官網及文檔:numeraljs.com/

  • GitHub:github.com/adamwdraper… 它是一個用於格式化和操做數字的JavaScript庫

  • 下載具體的文件:bootcdn下載或者github下載均可以 根據官方文檔使用案例:直接使用便可

  • 它也支持npm,在React,Vue等前端框架,甚至微信小程序裏一樣可使用

<script src="https://cdn.bootcss.com/numeral.js/2.0.6/numeral.min.js"></script>

var string = numeral(1634600).format('0,0');
console.log(string); // 1,634,600
複製代碼

具體詳細使用,可參照官方手冊文檔 這個庫在githu上的star有七千多的,說明使用的人仍是挺多的

若是僅僅是一個小小的功能數字的轉換,引入一個庫進去,未免有些大才小用了,這個庫不只僅格式化數字,格式化成時間,貨幣,百分比,幾位小數,以及千分位.

時間戳轉換爲指定的日期時間格式

在前端UI界面顯示中,後臺每每返回了一個時間戳格式,多是一串數字或者一些非正常的顯示格式,這時,在前臺處理時,每每須要進行時間格式化的處理

例如:前臺獲得這樣的一時間格式:1572728572986或者2019-10-11T05:04:02.506Z等格式

這裏以微信小程序雲開發爲例,經過前臺往數據庫裏插入一個時間createTime字段,最終要以指定的格式顯示到頁面上
前臺拿到該createTime時間字段,但時間格式須要作處理
最終須要轉換爲 2019年-11月-03日 05時:02分:52秒或者 2019-11-03 05:02:52或者 2019/11/03 05:02:52,2019-10-11 13:04:02等指定的格式的

方式一:使用toLocalString()方法

此方法可將本地時間Date對象轉換爲字符串,並返回結果,若是new Date()沒有接收任何參數,它會返回當下時刻的時間

/*
* 使用toLocaleString()方法
* 可根據本地時間把 Date 對象轉換爲字符串,並返回結果
*
*/
var d = new Date(1572728572986);
console.log(d.toLocaleString()) // 2019/11/3 上午5:02:52
複製代碼

固然你如今看到的與咱們指定想要的結果不一致,例如:輸出這樣的格式的 2019年11月03日 05點02分52秒,代碼以下所示:若是你想要輸出格式如上文中同樣的,只須要把拼接的連字符替換掉成你本身想要的格式就能夠了的

*
* 這種方法是直接改變Date的原型下面的方法,這樣也是能夠的
* getFullYear,getMonth,getDate,getMinutes,getHours,getMinutes,getSeconds方法,獲取年,月,日,時,分,秒
* 利用字符串+加號拼接起來,若是你以爲+號拼接字符串很不舒服,也能夠用Es6中的模板字符串方法的`${變量}`
*
*
*/
var d = new Date(1572728572986);
Date.prototype.toLocaleString = function() {
  return this.getFullYear() + "年" + (this.getMonth() + 1<10?'0'+this.getMonth()+1:this.getMonth()+1) + "月" + (this.getDate()<10?'0'+this.getDate():this.getDate()) + "日 " + (this.getHours()<10?'0'+this.getHours():this.getHours()) + "點" + (this.getMinutes()<10?'0'+this.getMinutes():this.getMinutes()) + "分" + (this.getSeconds()<10?'0'+this.getSeconds():this.getSeconds()) + "秒";
};
console.log(d.toLocaleString()); // 2019年11月03日 05點02分52秒
複製代碼

固然在new Date()下面還有其餘的一些方法,例如你只想要得到年,月,日可使用toLocalDateString方法的

該方法是把本地時間把 Date 對象的日期部分轉換爲字符串,並返回結果

/*
*
* 使用時間對象下面的toLocaleDateString方法,可是此法只能獲取到年,月,日,並不能獲得時,分,秒

*/
var d = new Date(1572728572986);
console.log(d.toLocaleDateString()) // 2019/11/3
複製代碼

可是若是想要獲取時,分,秒,可使用toLocaleTimeString這個方法的,至於更多的一些API方法,你們能夠在控制檯下進行測試,也能夠查看MDN文檔的,以下gif所示的,若是有不清楚,順便百度,谷歌的

方式二:利用new Date()方法,getFullYear(),getMonth(),getDate(),getHours(),getMinutes(),getSeconds()

/*
* new Date(時間戳)
* 獲取年:new Date(時間戳).getFullYear()
* 獲取月:new Date(時間戳).getMonth()+1
* 獲取日:new Date(時間戳).getDate()
* 獲取小時:new Date(時間戳).getHours()
* 獲取分鐘:new Date(時間戳).getMinutes()
* 獲取秒:new Date(時間戳).getSeconds()
*
* 下面使用的是Es6中的模板字符串,反引號,裏面直接能夠寫變量,避免了使用+加號作字符串的拼接,同時當日,月,小時,分鐘,秒小於10時,作了一個補零的操做
*/

var date = new Date(1572728572986);
var Year = `${date.getFullYear()}-`;
var Month = `${ date.getMonth()+1<10? `0${date.getMonth()+1}`: date.getMonth()+1}-`;
var Day = `${date.getDate()<10? `0${date.getDate()}`:date.getDate()}`;
var hour = `${date.getHours()<10? `0${date.getHours()}`:date.Hours()}:`;
var min = `${date.getMinutes()<10?`0${date.getMinutes()}`:date.getMinutes()}:`;
var sec = `${date.getSeconds()<10? `0${date.getSeconds()}`:date.getSeconds()}`;
var formateDate = `${Year}${Month}${Day} ${hour}${min}${sec}`
console.log(formateDate); // 2019-11-03 05:02:52
複製代碼

若是你想要2019/11/03 05:02:52,這種格式,你只須要改變拼接後面的鏈接符-替換成斜槓就能夠了

這種方法是最直接也是沒有什麼邏輯可言的,使用系統內置的Date函數就能夠實現的,可是複用性不好

方式三:一樣也是使用new Date(),可是若是把它封裝成一個函數,那麼就能夠隨意調用了

/*
* 封裝成一個時間格式化函數,formatDateTime函數的第一個形參time表明的是時間戳,第二個參數format是表明是格式化成什麼樣子:好比2019年-11月-03日 05時:02分:52秒這種形式等
*
*
*
*/
function formatDateTime (time, format){

     var t = new Date(time);
     var tf = function(i){ // 補零操做
         return (i < 10 ? '0' : '') + i
     };

 return format.replace(/yyyy|MM|dd|HH|mm|ss/g, function(a){
  switch(a){
    case 'yyyy':
      return tf(t.getFullYear()); // 獲取年
      break;
    case 'MM':
      return tf(t.getMonth() + 1); // 獲取月
      break;
    case 'dd':
      return tf(t.getDate()); // 獲取日
      break;
    case 'HH':
       return tf(t.getHours()); // 獲取小時
       break;
    case 'mm':
      return tf(t.getMinutes()); // 獲取分鐘
      break;
   case 'ss':
      return tf(t.getSeconds()); // 獲取秒
      break;
   }
 })
}
console.log(formatDateTime(1572728572986,"yyyy年-MM月-dd日 HH時:mm分:ss秒")); // 2019年-11月-03日 05時:02分:52秒
複製代碼

上面封裝了一個formateDateTime函數,使用了一個switch語句,進行了格式化時間操做,第一個參數表明的是時間戳,第二個參數表明的是想要格式化什麼樣的形式

方式四:獨立封裝一個函數,放到utils工具函數裏面去的,若是在一些框架中使用的話,能夠經過export暴露出去,而在要使用的時間格式化的文件內上方經過import導入的

/*
* 封裝時間格式化函數formatDateTime,date表示時間戳
*
*/
function formatDateTime(date){
  let fmt = 'yyyy-MM-dd hh:mm:ss' // 這裏是指定的時間格式,你能夠在後面加上年,月,日,時分,秒的,例如:yyyy年-MM月-dd日 hh時:mm分:ss秒
  const o = {
    'M+': date.getMonth() + 1, // 月份
    'd+': date.getDate(), // 日
    'h+': date.getHours(), // 小時
    'm+': date.getMinutes(), // 分鐘
    's+': date.getSeconds(), // 秒
  }

  if (/(y+)/.test(fmt)) { // 對指定的格式進行校驗
    fmt = fmt.replace(RegExp.$1, date.getFullYear()) // 替換操做
  }
  for (let k in o) { // 遍歷對象,補零操做,若是長度等於1的話,則數字前面補個零
    if (new RegExp('(' + k + ')').test(fmt)) {
      fmt = fmt.replace(RegExp.$1, o[k].toString().length == 1 ? '0' + o[k] : o[k])
    }
  }
  // console.log(fmt)
  return fmt
}

console.log(formatDateTime(new Date(1572728572986))) // 2019-11-03 05:02:52
console.log(formatDateTime(new Date("2019-10-11T05:04:02.506Z"))) // 2019-10-11 13:04:02
console.log(formatDateTime(new Date("Fri Oct 11 2019 13:04:02 GMT+0800"))) // 這個是東八區時間格式,2019-10-11 13:04:02
export default formatDateTime;
複製代碼

概括:上面的方法三與方法四,經過獨立封裝函數的方法,都是能夠經過模塊化導入導出進行使用的,這幾種方式任意選擇一種均可以,底層原理都是同樣的,只不過實現的方式不同而已

對於這種經常使用的工具類方法,在前端開發需求中的使用是很頻繁的,一旦遇到了,本身寫一個也沒有什麼問題,也能夠百度,谷歌一下的,但發現有的一些例子是並不完整的,存在一些問題,有時也知足不了業務的需求 方法五:使用jutils第三方庫進行格式化的 該庫封裝了一些常見的工具類函數,它也支持npm包,經過模塊化的在一些框架中使用

具體使用可見:github.com/dong-sir/ju…

/*
*
* 直接去cdn下載jutils-src文件或者github上克隆到本地均可以
   
*/
<script src="https://cdn.jsdelivr.net/npm/jutils-src"></script>
      <script>
        var date = jutils.formatDate(new Date("2019-10-11T05:04:02.506Z"),"YYYY-MM-DD HH:ii:ss");
            console.log(date); // 獲取年,月,日,時,分秒 2019-10-11 13:04:02
        // 獲取時間戳,結束時間要大於起止時間
        var timeStamp = jutils.getTimeInterval(1567562605000, 1567649014000);
        console.log(timeStamp); // 1天0小時0分鐘9秒
      </script>
複製代碼

方法六:使用monentjs,第三方庫進行格式化的

monentjs是一個 JavaScript 日期處理類庫,用於解析、檢驗、操做、以及顯示日期,支持npm,也支持經過script標籤的方式在瀏覽器中引入 詳細各個使用,可參考http://momentjs.cn/,官方手冊,這在企業應用開發裏,也是一個很經常使用的日期格式類庫的

<script src="https://cdn.bootcss.com/moment.js/2.24.0/moment.js"></script>
<script>
    var dayTime0 = moment(1572728572986).format("YYYY-MM-DD HH:mm:ss");
    var dayTime1 = moment("2019-10-11T05:04:02.506Z").format("YYYY-MM-DD HH:mm:ss");
    var dayTime2 = moment("Fri Oct 11 2019 13:04:02 GMT+0800").format("YYYY-MM-DD HH:mm:ss");
    var dayTime3 = moment("Fri Oct 11 2019 13:04:02 GMT+0800").valueOf();
    console.log(dayTime0); // 2019-11-03 05:02:52
    console.log(dayTime1); // 2019-10-11 13:04:02
    console.log(dayTime2); // 2019-10-11 13:04:02
    console.log(dayTime3); // 1570770242000
</script>
複製代碼

拓展:

上面介紹的一些方法都是將數字類型,非正常日期格式轉化爲指定的日期格式,但要是反過來?例如:一些日期控件,查詢某些條件時,須要選擇起始時間和截止時間,獲取時間戳,根據時間戳去查詢相應的結果的

也就是:相似2019-10-11T05:04:02.506Z,Fri Oct 11 2019 13:04:02 GMT+0800或者2019-11-03 05:02:52,這樣的時間格式,轉換爲數字

/*
* getTime(),valueOf()這兩種方式獲取的時間會精確到毫秒
* 而Date.parse的方法只能精確到秒,毫秒將用0來代替
*
*/
var date = new Date('2019-11-03 05:02:52');
var time1 = date.getTime();
var time2 = date.valueOf();
var time3 = Date.parse('2019-11-03 05:02:52');
console.log(time1,time2,time3); // 1572728572000 1572728572000 1572728572000

var date = new Date('2019-10-11T05:04:02.506Z');
var time1 = date.getTime();
var time2 = date.valueOf();
var time3 = Date.parse('2019-10-11T05:04:02.506Z');
console.log(time1,time2,time3);// 1570770242506 1570770242506 1570770242506

var date = new Date('Fri Oct 11 2019 13:04:02 GMT+0800');
var time1 = date.getTime();
var time2 = date.valueOf();
var time3 = Date.parse('Fri Oct 11 2019 13:04:02 GMT+0800');
console.log(time1,time2,time3);// 1570770242000 1570770242000 1570770242000
複製代碼
  • getTime(),valueOf()這兩種方式獲取的時間會精確到毫秒

  • Date.parse的方法只能精確到秒,毫秒將用0來代替

當獲取到時間戳以後,若是想要把數字轉換爲指定的時間格式,又可使用上面的的任意一種方法了

須要注意的是:若是是獲取到的是unix的時間戳,須要將獲得的時間戳除以1000,便獲得秒數

上面介紹的時間戳格式化的方法:都是能夠的,這裏我我的推薦方法三,四,五,六的,若是你不想轉換,那就借用第三方庫的.

結語

本文主要記錄了一下使用js進行超大數字,金額顯示處理,以及日期時間格式化處理的問題,對於這種經常使用工具類函數,能夠自行收集起來的

遇到同類型的需求,要麼本身手擼一個,要麼就拿現有的輪子進行使用.一些經常使用的開發需求,基本上都有大牛提供了一些好用的第三方庫,能夠拿來主義,先實現當下需求,而後在研究其原理.固然手寫理解其原理也很重要了

相關文章
相關標籤/搜索