我注意到JavaScript的新Date()函数在接受多种格式的日期方面非常聪明。

Xmas95 = new Date("25 Dec, 1995 23:15:00")
Xmas95 = new Date("2009 06 12,12:52:39")
Xmas95 = new Date("20 09 2006,12:52:39")

调用new Date()函数时,我在任何地方都找不到显示所有有效字符串格式的文档。

这用于将字符串转换为日期。如果我们从相反的方面来看,即将日期对象转换为字符串,直到现在,我的印象是JavaScript没有将日期对象格式化为字符串的内置API。

编者按:以下方法是询问者在特定浏览器上的尝试,但通常不起作用;请参阅本页上的答案以了解一些实际解决方案。

今天,我在date对象上使用了toString()方法,令人惊讶的是,它可以将日期格式化为字符串。

var d1 = new Date();
d1.toString('yyyy-MM-dd');       //Returns "2009-06-29" in Internet Explorer, but not Firefox or Chrome
d1.toString('dddd, MMMM ,yyyy')  //Returns "Monday, June 29,2009" in Internet Explorer, but not Firefox or Chrome

在这里,我也找不到任何关于将日期对象格式化为字符串的方法的文档。

列出Date()对象支持的格式说明符的文档在哪里?


当前回答

懒惰的解决方案是使用带有正确区域代码的Date.toLocaleString

要获取可以运行的匹配区域列表

#!/bin/bash

[ -f bcp47.json ] || \
wget https://raw.githubusercontent.com/pculture/bcp47-json/master/bcp47.json

grep 'tag" : ' bcp47.json | cut -d'"' -f4 >codes.txt

js=$(cat <<'EOF'
const fs = require('fs');
const d = new Date(2020, 11, 12, 20, 00, 00);
fs.readFileSync('codes.txt', 'utf8')
.split('\n')
.forEach(code => {
  try {
    console.log(code+' '+d.toLocaleString(code))
  }
  catch (e) { console.log(code+' '+e.message) }
});
EOF
)

# print THE LIST of civilized countries
echo "$js" | node - | grep '2020-12-12 20:00:00'

这里是。。。。列表

af ce eo gv ha ku kw ky lt mg rw se sn sv xh zu 
ksh mgo sah wae AF KW KY LT MG RW SE SN SV

样品用途:

(new Date()).toLocaleString('af')

// -> '2020-12-21 11:50:15'

: )

(注意,这可能不是便携式的。)

其他回答

确保在JavaScript中处理日期时签出Datejs。正如您在toString函数的例子中看到的那样,它非常令人印象深刻,并且有很好的文档记录。

编辑:Tyler Forsyth指出,datejs已经过时了。我在当前的项目中使用了它,并没有遇到任何问题,但您应该意识到这一点,并考虑其他选择。

懒惰的解决方案是使用带有正确区域代码的Date.toLocaleString

要获取可以运行的匹配区域列表

#!/bin/bash

[ -f bcp47.json ] || \
wget https://raw.githubusercontent.com/pculture/bcp47-json/master/bcp47.json

grep 'tag" : ' bcp47.json | cut -d'"' -f4 >codes.txt

js=$(cat <<'EOF'
const fs = require('fs');
const d = new Date(2020, 11, 12, 20, 00, 00);
fs.readFileSync('codes.txt', 'utf8')
.split('\n')
.forEach(code => {
  try {
    console.log(code+' '+d.toLocaleString(code))
  }
  catch (e) { console.log(code+' '+e.message) }
});
EOF
)

# print THE LIST of civilized countries
echo "$js" | node - | grep '2020-12-12 20:00:00'

这里是。。。。列表

af ce eo gv ha ku kw ky lt mg rw se sn sv xh zu 
ksh mgo sah wae AF KW KY LT MG RW SE SN SV

样品用途:

(new Date()).toLocaleString('af')

// -> '2020-12-21 11:50:15'

: )

(注意,这可能不是便携式的。)

如果您不需要Moment.js这样的库提供的所有功能,那么可以使用我的strftime端口。它是轻量级的(与Moment.js 2.15.0相比,减少了1.35 KB和57.9 KB),并提供了strftime()的大部分功能。

/* Port of strftime(). Compatibility notes:
 *
 * %c - formatted string is slightly different
 * %D - not implemented (use "%m/%d/%y" or "%d/%m/%y")
 * %e - space is not added
 * %E - not implemented
 * %h - not implemented (use "%b")
 * %k - space is not added
 * %n - not implemented (use "\n")
 * %O - not implemented
 * %r - not implemented (use "%I:%M:%S %p")
 * %R - not implemented (use "%H:%M")
 * %t - not implemented (use "\t")
 * %T - not implemented (use "%H:%M:%S")
 * %U - not implemented
 * %W - not implemented
 * %+ - not implemented
 * %% - not implemented (use "%")
 *
 * strftime() reference:
 * http://man7.org/linux/man-pages/man3/strftime.3.html
 *
 * Day of year (%j) code based on Joe Orost's answer:
 * http://stackoverflow.com/questions/8619879/javascript-calculate-the-day-of-the-year-1-366
 *
 * Week number (%V) code based on Taco van den Broek's prototype:
 * http://techblog.procurios.nl/k/news/view/33796/14863/calculate-iso-8601-week-and-year-in-javascript.html
 */
function strftime(sFormat, date) {
  if (!(date instanceof Date)) date = new Date();
  var nDay = date.getDay(),
    nDate = date.getDate(),
    nMonth = date.getMonth(),
    nYear = date.getFullYear(),
    nHour = date.getHours(),
    aDays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
    aMonths = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
    aDayCount = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334],
    isLeapYear = function() {
      if (nYear&3!==0) return false;
      return nYear%100!==0 || year%400===0;
    },
    getThursday = function() {
      var target = new Date(date);
      target.setDate(nDate - ((nDay+6)%7) + 3);
      return target;
    },
    zeroPad = function(nNum, nPad) {
      return ('' + (Math.pow(10, nPad) + nNum)).slice(1);
    };
  return sFormat.replace(/%[a-z]/gi, function(sMatch) {
    return {
      '%a': aDays[nDay].slice(0,3),
      '%A': aDays[nDay],
      '%b': aMonths[nMonth].slice(0,3),
      '%B': aMonths[nMonth],
      '%c': date.toUTCString(),
      '%C': Math.floor(nYear/100),
      '%d': zeroPad(nDate, 2),
      '%e': nDate,
      '%F': date.toISOString().slice(0,10),
      '%G': getThursday().getFullYear(),
      '%g': ('' + getThursday().getFullYear()).slice(2),
      '%H': zeroPad(nHour, 2),
      '%I': zeroPad((nHour+11)%12 + 1, 2),
      '%j': zeroPad(aDayCount[nMonth] + nDate + ((nMonth>1 && isLeapYear()) ? 1 : 0), 3),
      '%k': '' + nHour,
      '%l': (nHour+11)%12 + 1,
      '%m': zeroPad(nMonth + 1, 2),
      '%M': zeroPad(date.getMinutes(), 2),
      '%p': (nHour<12) ? 'AM' : 'PM',
      '%P': (nHour<12) ? 'am' : 'pm',
      '%s': Math.round(date.getTime()/1000),
      '%S': zeroPad(date.getSeconds(), 2),
      '%u': nDay || 7,
      '%V': (function() {
              var target = getThursday(),
                n1stThu = target.valueOf();
              target.setMonth(0, 1);
              var nJan1 = target.getDay();
              if (nJan1!==4) target.setMonth(0, 1 + ((4-nJan1)+7)%7);
              return zeroPad(1 + Math.ceil((n1stThu-target)/604800000), 2);
            })(),
      '%w': '' + nDay,
      '%x': date.toLocaleDateString(),
      '%X': date.toLocaleTimeString(),
      '%y': ('' + nYear).slice(2),
      '%Y': nYear,
      '%z': date.toTimeString().replace(/.+GMT([+-]\d+).+/, '$1'),
      '%Z': date.toTimeString().replace(/.+\((.+?)\)$/, '$1')
    }[sMatch] || sMatch;
  });
}

示例用法:

strftime('%F'); // Returns "2016-09-15"
strftime('%A, %B %e, %Y'); // Returns "Thursday, September 15, 2016"

// You can optionally pass it a Date object...

strftime('%x %X', new Date('1/1/2016')); // Returns "1/1/2016 12:00:00 AM"

此处提供最新代码:https://github.com/thdoan/strftime

您可能会发现日期对象的这种修改很有用,它比任何库都小,并且可以轻松扩展以支持不同的格式:

注:

它使用Object.keys(),这在旧浏览器中是未定义的,所以您可能需要从给定的链接实现polyfill。

CODE

Date.prototype.format = function(format) {
    // set default format if function argument not provided
    format = format || 'YYYY-MM-DD hh:mm';

    var zeropad = function(number, length) {
            number = number.toString();
            length = length || 2;
            while(number.length < length)
                number = '0' + number;
            return number;
        },
        // here you can define your formats
        formats = {
            YYYY: this.getFullYear(),
            MM: zeropad(this.getMonth() + 1),
            DD: zeropad(this.getDate()),
            hh: zeropad(this.getHours()),
            mm: zeropad(this.getMinutes())
        },
        pattern = '(' + Object.keys(formats).join(')|(') + ')';

    return format.replace(new RegExp(pattern, 'g'), function(match) {
        return formats[match];
    });
};

USE

var now = new Date;
console.log(now.format());
// outputs: 2015-02-09 11:47
var yesterday = new Date('2015-02-08');
console.log(yesterday.format('hh:mm YYYY/MM/DD'));
// outputs: 00:00 2015/02/08

只是为了继续龚志涛的坚定回答-这处理上午/下午

 Date.prototype.format = function (format) //author: meizz
{
    var hours = this.getHours();
    var ttime = "AM";
    if(format.indexOf("t") > -1 && hours > 12)
    {
        hours = hours - 12;
        ttime = "PM";
     }

var o = {
    "M+": this.getMonth() + 1, //month
    "d+": this.getDate(),    //day
    "h+": hours,   //hour
    "m+": this.getMinutes(), //minute
    "s+": this.getSeconds(), //second
    "q+": Math.floor((this.getMonth() + 3) / 3),  //quarter
    "S": this.getMilliseconds(), //millisecond,
    "t+": ttime
}

if (/(y+)/.test(format)) format = format.replace(RegExp.$1,
  (this.getFullYear() + "").substr(4 - RegExp.$1.length));
for (var k in o) if (new RegExp("(" + k + ")").test(format))
    format = format.replace(RegExp.$1,
      RegExp.$1.length == 1 ? o[k] :
        ("00" + o[k]).substr(("" + o[k]).length));
return format;
}