如何将Date对象格式化为字符串?
当前回答
该函数的灵感来自Java的SimpleDateFormat。它提供各种格式,例如:
dd-MMM-yyyy → 17-Jul-2018
yyyyMMdd'T'HHmmssXX → 20180717T120856+0900
yyyy-MM-dd'T'HH:mm:ssXXX → 2018-07-17T12:08:56+09:00
E, dd MMM yyyy HH:mm:ss Z → Tue, 17 Jul 2018 12:08:56 +0900
yyyy.MM.dd 'at' hh:mm:ss Z → 2018.07.17 at 12:08:56 +0900
EEE, MMM d, ''yy → Tue, Jul 17, '18
h:mm a → 12:08 PM
hh 'o''''clock' a, X → 12 o'clock PM, +09
代码示例:
函数formatWith(formatStr,date,opts){if(!date){date=新日期();}opts=opts||{};let _days=opts.days;如果(!_days){_days=[星期日、星期一、星期二、星期三、星期四、星期五、星期六];}let _months=opts.months;如果(!_months){_months=['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];}常量pad=(number,strDigits,isUnpad)=>{const strNum=number.toString();如果(!isUnpad&&strNum.length>strDigits.length){返回strNum;}其他{return('0000'+strNum).sslice(-strDigits.length);}};常量时区=(日期,字母)=>{常量块=[];const offset=-date.getTimezoneOffset();chunk.push(偏移量==0?“Z”:偏移量>0?“+”:“-”)//添加Z或+-如果(偏移量==0)返回块;chunk.push(pad(数学地板(偏移量/60),“00”))//小时if(letter==“X”)返回chunk.join(“”);if(letter=='XXX')chunk.push(':');chunk.push(pad((偏移量%60),'00'))//最小值return chunk.join(“”);};const ESCAPE_DELIM=“\0”;常量escapeStack=[];const escapedFmtStr=格式Str.替换(/'.*?'/g,m=>{escapeStack.push(m.replace(/'/g,''));return ESCAPE_DELIM+(escapeStack.length-1)+ESCAPE_DELIM;});常量格式化Str=转义FmtStr.replace(/y{4}| y{2}/g,m=>pad(date.getFullYear(),m,true)).replace(/M{3}/g,M=>_months[date.getMonth()]).replace(/M{1,2}/g,M=>pad(date.getMonth()+1,M)).replace(/M{1,2}/g,M=>pad(date.getMonth()+1,M)).replace(/d{1,2}/g,m=>pad(date.getDate(),m)).replace(/H{1,2}/g,m=>pad(date.getHours(),m)).替换(/h{1,2}/g,m=>{const hours=date.getHours();返回垫(小时==0?12:小时>12?小时-12:小时,m);}).replace(/a{1,2}/g,m=>date.getHours()>=12?'下午:上午).replace(/m{1,2}/g,m=>pad(date.getMinutes(),m)).replace(/s{1,2}/g,m=>pad(date.getSeconds(),m)).replace(/S{3}/g,m=>pad(date.getMilliseconds(),m)).replace(/[E]+/g,m=>_days[date.getDay()]).替换(/[Z]+/g,m=>时区(日期,m)).替换(/X{1,3}/g,m=>时区(日期,m));const unescapedStr=格式化Str.替换(/\0\d+\0/g,m=>{const unescaped=escapeStack.shift();返回unscaped.length>0?未转义:“\”;});返回unscapedStr;}//让我们用上面的函数格式化const dateStr='2018/07/17 12:08:56';const date=新日期(dateStr);常量模式=[“年-月-日”,“yyyyMMdd''HHmmssXX”,//ISO8601“yyyy-MM-dd''HH:MM:ssXXX”,//ISO8601EX“E,dd MMM yyyy HH:mm:ss Z”,//RFC1123(RFC822)类似电子邮件“yyyy.MM.dd'at'hh:MM:ss Z”,//hh显示1-12“EEE,MMM d,'yy”,“h:mm a”,“hh'o'''时钟'a,X”,];for(let模式){console.log(`${pattern}→ ${formatWith(pattern,date)}`);}
你可以把它当作图书馆
它也作为NPM模块发布。您可以在Node.js上使用它,也可以在浏览器的CDN中使用它。
节点.js
const {SimpleDateFormat} = require('@riversun/simple-date-format');
在浏览器中
<script src="https://cdn.jsdelivr.net/npm/@riversun/simple-date-format@1.0.2/dist/simple-date-format.js"></script>
按照以下步骤编写代码。
const date = new Date('2018/07/17 12:08:56');
const sdf = new SimpleDateFormat();
console.log(sdf.formatWith("yyyy-MM-dd'T'HH:mm:ssXXX", date));//to be "2018-07-17T12:08:56+09:00"
GitHub上的源代码:
https://github.com/riversun/simple-date-format
其他回答
也许这有助于那些自愿或意外地一个接一个地寻找多种日期格式的人。请查找代码:我在当前日期(今天是2020年6月29日)使用Moment.js格式函数:var startDate=Moment(new date()).format('MM/DD/YY');结果:20年6月28日
它只保留年份部分:20作为“06/28/20”,之后如果我运行语句new Date(startDate),结果是“Mon Jun 28 1920 00:00:00 GMT+0530(印度标准时间)”。
然后,当我在“06/28/20”上使用另一种格式时:startDate=moment(startDate).format('MM-DD-YYYY');结果:1920年6月28日,在谷歌Chrome和Firefox浏览器中,它给出了第二次尝试的正确日期:2020年6月28-日。
但在Internet Explorer中,它存在问题。由此,我理解我们可以在给定日期应用一种日期格式。如果我们想要第二个日期格式,它应该应用于新的日期,而不是第一个日期格式结果。并观察到,首次应用“MM-DD-YYYY”和下一个“MM-DD-YYYY”在Internet Explorer中工作。为了清楚理解,请在链接中找到我的问题:在Internet Explorer 11中使用Moment.js日期格式时,日期出错。
在JavaScript中格式化DateTime的一种有用且灵活的方法是Intl.DateTimeFormat:
var date = new Date();
var options = { year: 'numeric', month: 'short', day: '2-digit'};
var _resultDate = new Intl.DateTimeFormat('en-GB', options).format(date);
// The _resultDate is: "12 Oct 2017"
// Replace all spaces with - and then log it.
console.log(_resultDate.replace(/ /g,'-'));
结果是:“2017年10月12日”
可以使用options参数自定义日期和时间格式。
Intl.DateTimeFormat对象是启用语言敏感日期和时间格式的对象的构造函数。
语法
new Intl.DateTimeFormat([locales[, options]])
Intl.DateTimeFormat.call(this[, locales[, options]])
参数
区域设置
可选择的带有BCP 47语言标记的字符串或此类字符串的数组。有关locales参数的一般形式和解释,请参阅Intl页。允许使用以下Unicode扩展密钥:
nu
Numbering system. Possible values include: "arab", "arabext", "bali", "beng", "deva", "fullwide", "gujr", "guru", "hanidec", "khmr", "knda", "laoo", "latn", "limb", "mlym", "mong", "mymr", "orya", "tamldec", "telu", "thai", "tibt".
ca
Calendar. Possible values include: "buddhist", "chinese", "coptic", "ethioaa", "ethiopic", "gregory", "hebrew", "indian", "islamic", "islamicc", "iso8601", "japanese", "persian", "roc".
选项
可选择的具有以下部分或全部财产的对象:
本地匹配器
要使用的区域设置匹配算法。可能的值是“查找”和“最佳匹配”;默认值为“最佳拟合”。有关此选项的信息,请参阅Intl页面。
时区
要使用的时区。实现必须识别的唯一值是“UTC”;默认值是运行时的默认时区。实施还可以识别IANA时区数据库的时区名称,例如“亚洲/上海”、“亚洲/加尔各答”、“美国/纽约”。
小时12
是否使用12小时(而不是24小时)。可能的值为true和false;默认值取决于区域设置。
格式匹配器
要使用的格式匹配算法。可能的值是“基本”和“最适合”;默认值为“最佳拟合”。有关使用此属性的信息,请参见以下段落。
以下财产描述了格式化输出中使用的日期时间组件及其所需的表示。需要实现至少支持以下子集:
weekday, year, month, day, hour, minute, second
weekday, year, month, day
year, month, day
year, month
month, day
hour, minute, second
hour, minute
实现可能支持其他子集,并且将针对所有可用的子集表示组合来协商请求,以找到最佳匹配。有两种算法可用于此协商,并由formatMatcher属性选择:完全指定的“基本”算法和依赖于实现的“最佳匹配”算法。
周工作日
工作日的表示。可能的值有“窄”、“短”、“长”。
era
时代的代表。可能的值有“窄”、“短”、“长”。
year
年度的表示。可能的值为“数字”、“2位数”。
月
月份的表示。可能的值有“数字”、“2位数”、“窄”、“短”、“长”。
day
当天的表示。可能的值为“数字”、“2位数”。
hour
小时的表示。可能的值为“数字”、“2位数”。
分钟
会议记录的表示。可能的值为“数字”、“2位数”。
第二
第二个的表示。可能的值为“数字”、“2位数”。
时区名称
时区名称的表示形式。可能的值为“短”、“长”。每个日期时间组件属性的默认值未定义,但如果所有组件财产均未定义,则假定年、月和日为“数字”。
联机检查
更多详细信息
包装解决方案:Luxon或date fns
如果你想使用一个解决方案来适应所有人,我建议使用date fns或Luxon。
Luxon托管在Moment.js网站上,由Moment.jss开发人员开发,因为Momentjs具有开发人员想解决但无法解决的局限性。
要安装:
npm安装luxon或纱线添加luxon(其他安装方法请访问链接)
例子:
luxon.DateTime.fromISO('2010-08-10').toFormat('yyyy-LL-dd');
产量:
2010年8月10日
手动解决方案
使用与Moment.js、ClassDateTimeFormatter(Java)和ClassSimpleDateFormat(Java)类似的格式,我实现了一个全面的解决方案formatDate(date,patternStr),代码易于阅读和修改。您可以显示日期、时间、AM/PM等。有关更多示例,请参阅代码。
例子:
formatDate(new Date(),'EEEE,MMMM d,yyyy HH:mm:ss:S')
(formatDate在下面的代码段中实现)
产量:
2018年10月12日星期五18:11:23:445
单击“运行代码段”尝试代码
日期和时间模式
yy=2位年份;yyyy=全年
M=数字月;MM=2位月;MMM=短月份名称;MMMM=完整月份名称
EEEE=工作日全名;EEE=短工作日名称
d=数字日;dd=2位数字日
h=小时上午/下午;hh=上午/下午两位数小时;H=小时;HH=2位数小时
m=分钟;mm=2位数分钟;aaa=上午/下午
s=秒;ss=2位数秒
S=毫秒
var month名称=[“一月”,“二月”,“三月”,“四月”,“五月”,“六月”,“七月”,“八月”、“九月”、“十月”、“十一月”、“十二月”];var dayOfWeekNames=[“星期日”、“星期一”、“周二”,“周三”、“周四”、“周五”、“周六”];函数formatDate(日期,patternStr){if(!patternStr){patternStr='M/d/yyyy';}var day=date.getDate(),month=date.getMonth(),year=date.getFullYear(),hour=date.getHours(),minute=date.getMinutes(),second=date.getSeconds(),毫秒=date.getMilliseconds(),h=小时%12,hh=两位数广告(h),HH=两位数(小时),mm=两个DigitPad(分钟),ss=twoDigitPad(秒),aaa=小时<12?'上午:下午,EEEE=dayOfWeekNames[date.getDay()],EEE=EEEE.substr(0,3),dd=twoDigitPad(天),M=月+1,MM=两个DigitPad(M),MMMM=monthNames[月],MMM=MMMM.substr(0,3),yyyy=年+“”,yy=yyyy.substr(2,2);//检查是否将使用月份名称patternStr=patternStr.替换('h',hh).替换('h',h)替换('HH',HH)替换('H',小时).替换('m',mm).替换(m',分钟).替换('s',ss).替换(s'',second).replace('S',毫秒)替换('dd',dd)替换('d',day)替换('EEE',EEEE)替换('EE',EEE)替换('yyyy',yyyy).替换('yy',yy).替换('aaa',aaa);如果(patternStr.indexOf('MMM')>-1){patternStr=patternStr.替换('MMMM',MMMM).替换('MMM',MMM);}其他{patternStr=patternStr.替换('MM',MM).替换(M’,M);}返回模式Str;}函数twoDigitPad(num){返回num<10?“0”+num:num;}console.log(formatDate(newDate()));console.log(formatDate(new Date(),'dd MMM yyyy'))//OP的请求console.log(formatDate(new Date(),'EEEE,MMMM d,yyyy HH:mm:ss.S aaa'));console.log(formatDate(new Date(),'EEE,MMM d,yyyy HH:mm'));console.log(formatDate(new Date(),'yyyy-MM-dd HH:MM:ss.S'));console.log(formatDate(new Date(),'M/dd/yyyy h:mmaa'));
谢谢你@Gerry提起Luxon。
@Sébastien——可选的所有浏览器支持
new Date(parseInt(496407600)*1000).toLocaleDateString('de-DE', {
year: 'numeric',
month: '2-digit',
day: '2-digit'
}).replace(/\./g, '/');
文档:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleDateString
基于Date.toLocaleDateString的高阶标记模板文本示例:
const date = new Date(Date.UTC(2020, 4, 2, 3, 23, 16, 738));
const fmt = (dt, lc = "en-US") => (str, ...expr) =>
str.map((str, i) => str + (expr[i]?dt.toLocaleDateString(lc, expr[i]) :'')).join('')
console.log(fmt(date)`${{year: 'numeric'}}-${{month: '2-digit'}}-${{day: '2-digit'}}`);
// expected output: "2020-05-02"
在我的情况下,我已将日期表“2022年7月1日”格式化为“2022-07-01”
常量格式日期=日期=>{const d=新日期(日期)let month=(d.getMonth()+1).toString()let day=d.getDate().toString()const year=d.getFullYear()如果(月长度<2){月=“0”+月}如果(日长度<2){天=“0”+天}return[年,月,日]。join('-')}console.log(格式日期('01/07/2022'))