nodejs向前台send數據時Date類型數據格式問題


1.現象

前端向nodejs服務器請求數據時,發現得到的返回數據中日期字段(json格式)值有時差

從mysql中讀出的時間格式 > publishtime:Sat Aug 19 2017 15:46:01 GMT+0800 (中國標准時間) 

前端收到的時間格式 > "publishtime":"2017-07-16T14:46:01.000Z"

“Sat Aug 19 2017 15:46:01 GMT+0800”這個可以用new date 得到和設置的時間一致,但是用json序列化過的時間重新new 后得到的時間和設置的時間相差8個小時。
原因是時間對象在轉化成json字符串時會被轉換成國際標准時間(ISO),而不是當前國家區域的時間,而用new Date轉成時間對象返回的是當前國家所在時區的時間,東八區就加上了8個小時。
2.解決
nodejs發送前數據轉化在response.js中,

res.send = function send(body) {
  var chunk = body;
  var encoding;
  var len;
  var req = this.req;
  var type;

  // settings
  var app = this.app;

  // allow status / body
  if (arguments.length === 2) {
    // res.send(body, status) backwards compat
    if (typeof arguments[0] !== 'number' && typeof arguments[1] === 'number') {
      deprecate('res.send(body, status): Use res.status(status).send(body) instead');
      this.statusCode = arguments[1];
    } else {
      deprecate('res.send(status, body): Use res.status(status).send(body) instead');
      this.statusCode = arguments[0];
      chunk = arguments[1];
    }
  }

  // disambiguate res.send(status) and res.send(status, num)
  if (typeof chunk === 'number' && arguments.length === 1) {
    // res.send(status) will set status message as text string
    if (!this.get('Content-Type')) {
      this.type('txt');
    }

    deprecate('res.send(status): Use res.sendStatus(status) instead');
    this.statusCode = chunk;
    chunk = statuses[chunk]
  }

  switch (typeof chunk) {
    // string defaulting to html
    case 'string':
      if (!this.get('Content-Type')) {
        this.type('html');
      }
      break;
    case 'boolean':
    case 'number':
    case 'object':
      if (chunk === null) {
        chunk = '';
      } else if (Buffer.isBuffer(chunk)) {
        if (!this.get('Content-Type')) {
          this.type('bin');
        }
      } else {
        return this.json(chunk);
      }
      break;
  }
...............此處省略.................

如果發送的數據是對象的話,會轉換成json字符串格式后在發送,下面是json轉換

res.json = function json(obj) {
  var val = obj;

  // allow status / body
  if (arguments.length === 2) {
    // res.json(body, status) backwards compat
    if (typeof arguments[1] === 'number') {
      deprecate('res.json(obj, status): Use res.status(status).json(obj) instead');
      this.statusCode = arguments[1];
    } else {
      deprecate('res.json(status, obj): Use res.status(status).json(obj) instead');
      this.statusCode = arguments[0];
      val = arguments[1];
    }
  }

  // settings
  var app = this.app;
  var replacer = app.get('json replacer');
  var spaces = app.get('json spaces');
  var body = stringify(val, replacer, spaces);

  // content-type
  if (!this.get('Content-Type')) {
    this.set('Content-Type', 'application/json');
  }

  return this.send(body);
};

繼續跟蹤發現 xx\plugins\JavaScriptLanguage\lib\JavaScriptLanguage.jar!\com\intellij\lang\javascript\index\predefined\EcmaScript5.js 這里有這兩句

Date.now = function() {};
/**
@return {string}
*/
Date.prototype.toJSON = function() {};

發現原來日期類型有專門的轉化處理方式的。所以我的解決方式是 覆蓋這個方法,返回time長整型,方便處理,也不容易有時區轉化問題。

Date.prototype.toJSON = function () {
    return this.getTime();
}

當然如果只是展示成一般格式的話可以用這個,直接網上拷貝一個,可以看這個博客http://www.cnblogs.com/vipstone/p/4953110.html

function dateFormat(date, fmt) {
    if (null == date || undefined == date) return '';
    var o = {
        "M+": date.getMonth() + 1, //月份
        "d+": date.getDate(), //
        "h+": date.getHours(), //小時
        "m+": date.getMinutes(), //
        "s+": date.getSeconds(), //
        "S": date.getMilliseconds() //毫秒
    };
    if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
    for (var k in o)
        if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
    return fmt;
}

 




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM