JavaScript 编写Date 格式化方法『Python风格ヾ(•ω•`)o』
Posted XianZhe_
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript 编写Date 格式化方法『Python风格ヾ(•ω•`)o』相关的知识,希望对你有一定的参考价值。
javascript 编写Date日期格式化方法『Python风格ヾ(•ω•`)o』
文章目录
一、Python 与 JavaScript 日期格式化对比🥯
在学习编写JS脚本的时候,一直觉得JS中的Date对象对于日期格式化方法很不友善,完全没有Python那么方便,我就在想能不能自己编写一个类似 Python风格的日期格式化方法,于是这篇笔记就此诞生
先来看看,在输出一样的时间格式的情况下,Python和JS的写法各是怎么样的
以显示 「年/月/日 时:分:秒」格式为例
-
Python 中输出指定格式日期
可以看到,Python 对日期格式化处理是真的简洁且不失简单
import time date = time.strftime(r"%Y/%m/%d %H:%M:%S", time.localtime()) print(date)
2021/06/01 23:41:03
甚至还能够简写
time.strftime(r"%Y/%m/%d %H:%M:%S")
-
JS 中输出指定格式日期
最能直接发现的是,相对于 Python 来说,JavaScript 对日期格式化处理就显得些许复杂且麻烦
在制作成期望的日期格式时,需要预先将所需日期数据获取或计算,最后再进行拼接,才能实现日期格式化var nowDate = new Date(); var year = nowDate.getFullYear(); // 获取年份 var month = nowDate.getMonth() + 1; // 获取月份 var day = nowDate.getDate(); // 获取当前月内的天数 var hour = nowDate.getHours(); // 获取小时 24小时制 var minute = nowDate.getMinutes(); // 获取分钟 var second = nowDate.getSeconds(); // 获取秒数 console.log(`${year}/${month}/${day} ${hour}:${minute}:${second}`);
二、使用JavaScript Moment 库
Moment.js1 在处理时间方面上是一个常用的轻量级 JavaScript 日期时间库,在 JavaScript 中解析,验证,操作和显示日期和时间,提供了比 JavaScript Date 对象 更强大的日期格式化功能,支持多种语言,可以任意新增一种新的语言包。
类型 | Moment 格式 | 对应 | Moment 格式 | 对应 |
---|---|---|---|---|
月份 | M | 1 2 … 11 12 | Mo | 1st 2nd … 11th 12th |
月份 | MM | 01 02 … 11 12 | MMM | Jan Feb … Nov Dec |
MMMM | January February … November December | |||
季度 | Q | 1 2 3 4 | Qo | 1st 2nd 3rd 4th |
月份的日期 | D | 1 2 … 30 31 | Do | 1st 2nd … 30th 31st |
DD | 01 02 … 30 31 | |||
年份的日期 | DDD | 1 2 … 364 365 | DDDo | 1st 2nd … 364th 365th |
DDDD | 001 002 … 364 365 | |||
星期几 | d | 0 1 … 5 6 | do | 0th 1st … 5th 6th |
dd | Su Mo … Fr Sa | ddd | Sun Mon … Fri Sat | |
dddd | Sunday Monday … Friday Saturday | |||
星期几(语言环境) | e | 0 1 … 5 6 | ||
星期几(ISO) | E | 1 2 … 6 7 | ||
年份的星期 | w | 1 2 … 52 53 | wo | 1st 2nd … 52nd 53rd |
ww | 01 02 … 52 53 | |||
年份的星期(ISO) | W | 1 2 … 52 53 | Wo | 1st 2nd … 52nd 53rd |
WW | 01 02 … 52 53 | |||
年份 | YY | 70 71 … 29 30 | YYYY | 1970 1971 … 2029 2030 |
Y | 1970 1971 … 9999 10000 10001 | |||
周年 | gg | 70 71 … 29 30 | gggg | 1970 1971 … 2029 2030 |
周年(ISO) | GG | 70 71 … 29 30 | GGGG | 1970 1971 … 2029 2030 |
子午线 | A | AM PM | a | am pm |
小时 | H | 0 1 … 22 23 | HH | 00 01 … 22 23 |
h | 1 2 … 11 12 | hh | 01 02 … 11 12 | |
k | 1 2 … 23 24 | kk | 01 02 … 23 24 | |
分钟 | m | 0 1 … 58 59 | mm | 00 01 … 58 59 |
秒数 | s | 0 1 … 58 59 | ss | 00 01 … 58 59 |
小数秒钟 | S | 0 1 … 8 9 | SS | 00 01 … 98 99 |
SSS | 000 001 … 998 999 | SSSS … SSSSSSSSS | 000[0…] 001[0…] … 998[0…] 999[0…] | |
时区 | Z | -07:00 -06:00 … +06:00 +07:00 | ZZ | -0700 -0600 … +0600 +0700 |
Unix 时间戳 | X | 1360013296 | ||
Unix 毫秒时间戳 | x | 1360013296123 |
先在 Moment1 官网上下载并且导入 Moment.js 库
<script type="text/javascript" src="js/moment-with-locales.js"></script>
还是以显示 「年/月/日 时:分:秒」 格式为例
moment.locale("zh-cn");
var now = moment().format("YYYY/M/DD HH:mm:ss");
console.log(now);
三、编写函数实现格式化
虽然前面提到了 有 Moment.js 这个库已经实现了 日期格式化功能,但我们也可以自己去编写一个属于自己的日期格式化函数,对于简单的日期格式化类型,这并非什么难事
1)、思路:🤔
其实思路很简单,无非就是将获取需要日期格式的过程封装到函数里,并间格式化后的结果返回即可
function getFormatTime(date) {
/* 获取需要的时间格式 */
var year = date.getFullYear(); // 获取年份
var month = date.getMonth() + 1; // 获取月份
var day = date.getDate(); // 获取当前月内的天数
var hour = date.getHours(); // 获取小时 24小时制
var minute = date.getMinutes(); // 获取分钟
var second = date.getSeconds(); // 获取秒数
/* 返回指定格式日期 */
return `${year}/${month}/${day} ${hour}:${minute}:${second}`;
}
var now = new Date();
console.log(getFormatTime(now));
2)、优缺点:
- 很明显的缺点是,每次函数所返回的日期格式是固定的,如果需要另外的日期格式,则需要再写多一个函数,或是修改函数内部代码
- 优点还是有的,一定程度上增加了代码复用,相较 「一、Python 与 JavaScript 日期格式化对比🥯」 中的 JS 示例减少了部分冗余,但还不如正统的日期格式化来的直接方便
- 但对于固定单一的时间显示要求,此方法写法简单也是可以的
四、为JavaScript Date对象添加格式化方法👺
终于来到本文的重点,为JavaScript Date对象添加格式化方法
1)、思路:🤔
日期格式化的格式内容,无非就是一堆字符串,只需要提取这个字符串中符合格式要求的内容,并将其替换成对应的日期时间数据即可。
可以使用正则去匹配格式是否存在,再将匹配的格式内容进行替换操作,从而实现基本的日期格式化功能,剩下的只是支持什么样的日期格式化,以及程序的扩展性。
与标题一致,我将使用Python风格的日期匹配格式进行编写
2)、分钟和秒数 两位数标准化
因为在 Date 对象获取 分钟和秒数 的时候返回的内容在 0 - 9 之间时,前面并不带一个0,比如 05分,那就需要对其进行一个两位数的标准化,将其标准化的过程十分简单
/* 两位数标准化函数 */
function getNormal(time) {
// 使用正则判断是否为一位数数字
if (/^\\d$/.test(time)) {
return `0${time}`
} else {
return time
}
}
/* 分钟、秒钟 */
var now = new Date();
var second = now.getSeconds();
var minute = now.getMinutes();
console.log(getNormal(second));
console.log(getNormal(minute));
3)、如何去使用正则匹配替换:
还是以 「一、Python 与 JavaScript 日期格式化对比🥯」 中的日期格式为准,「年/月/日 时:分:秒」
Date.prototype.toFormat = function (text) {
function getNormal(time) {
// 使用正则判断是否为一位数数字
if (/^\\d$/.test(time)) {
return `0${time}`
} else {
return time
}
}
var format = {
"%Y": String(this.getFullYear()),
"%m": String(this.getMonth() + 1),
"%d": String(this.getDate()),
"%H": String(this.getHours()),
"%I": String(this.getHours() % 12),
"%M": getNormal(this.getMinutes()),
"%S": getNormal(this.getSeconds()),
"%%": "%"
}
for (var i in format) {
if (RegExp(`(${i})`).test(text)) {
text = text.replace(RegExp.$1, format[i]);
}
}
return text
}
var now = new Date();
console.log(now.toFormat("%Y/%m/%d %H:%M:%S"))
你以为就这样结束了?那还是太年轻,当使用多次相同的日期格式,那就会发现一个BUG,同一种日期格式只能被匹配从左往右的第一个
var now = new Date();
console.log(now.toFormat("%Y/%m/%d %Y-%Y-%m %H:%M:%S"))
标准的日期格式化,都是全局匹配的,不可能单单只匹配一个这么简单,那么要怎么才能实现全局匹配呢?还得使用到正则
Date.prototype.toFormat = function (text) {
function getNormal(time) {
// 使用正则判断是否为一位数数字
if (/^\\d$/.test(time)) {
return `0${time}`
} else {
return time
}
}
var format = {
"%Y": String(this.getFullYear()),
"%m": String(this.getMonth() + 1),
"%d": String(this.getDate()),
"%H": String(this.getHours()),
"%I": String(this.getHours() % 12),
"%M": getNormal(this.getMinutes()),
"%S": getNormal(this.getSeconds()),
"%%": "%"
}
for (var i in format) {
if (RegExp(`(${i})`).test(text)) {
// 使用全局替换模式
var target = new RegExp(RegExp.$1, "g");
text = text.replace(target, format[i]);
}
}
return text
}
再使用多次相同的日期格式时,就能够被成功匹配了
var now = new Date();
console.log(now.toFormat("%Y/%m/%d %Y-%Y-%m %H:%M:%S"))
4)、JS Date对象能够获取什么日期数据
需要注意的是,在一些方法返回的内容需要进行处理才能使用,比如说获取月份的 getMonth()
返回的范围是 0~11,这就意味如果放到网页中显示的话,就需要我们对返回内容进行 +1 操作
Data 对象方法 | 对应 |
---|---|
getFullYear() | 以四位数字返回年份 |
getMonth() | 返回月份 (0 ~ 11) |
getDate() | 返回一个月中的某一天 (1 ~ 31) |
getDay() | 返回一周中的某一天 (0 ~ 6) |
getHours() | 返回小时 (0 ~ 23) |
getMinutes() | 返回分钟 (0 ~ 59) |
getSeconds() | 返回秒数 (0 ~ 59) |
getMilliseconds() | 返回毫秒(0 ~ 999) |
getTime() | 返回 1970 年 1 月 1 日至今的毫秒数 |
getUTCFullYear() | 根据世界时间 以四位数的年份返回年份 |
getUTCMonth() | 根据世界时间 返回月份 (0 ~ 11) |
getUTCDate() | 根据世界时间 返回一个月中的某一天 (1 ~ 31) |
getUTCDay() | 根据世界时间 返回一周中的某一天 (0 ~ 6) |
getUTCHours() | 根据世界时间 返回小时 (0 ~ 23) |
getUTCMinutes() | 根据世界时间 返回分钟 (0 ~ 59) |
getUTCSeconds() | 根据世界时间 返回秒数 (0 ~ 59) |
getUTCMilliseconds() | 根据世界时间 返回毫秒(0 ~ 999) |
5)、如何实现多种日期格式
在开始这个步骤前,可以打开Python time标准库官方手册或相关博客教程,去对照一下Python 都支持哪些日期格式化的格式
这里展示部分使用到的 Python 日期格式支持
Python 格式 | 对应 | Python 格式 | 对应 |
---|---|---|---|
%y | 两位数的年份表示 | %Y | 四位数的年份表示 |
%m | 月份 | %d | 天数 |
%H | 24小时制小时数 | %I | 12小时制小时数 |
%M | 分钟数 | %S | 秒数 |
%A | 本地完整星期名 | %B | 本地完整月份名 |
%w | 星期(数值为0-6,星期天每为星期的开始) | %% | %号本身 |
完整代码
Date.prototype.toFormat = function (text) {
var weekdays = {
0: "Sunday",
1: "Monday",
2: "Tuesday",
3: "Wednesday",
4: "Thursday",
5: "Friday",
6: "Saturday"
};
var weekdaysShort = {
0: "Sun",
1: "Mon",
2: "Tue",
3: "Wed",
4: "Thu",
5: "Fri",
6: "Sat"
};
var months = {
0: "January",
1: "February",
2: "March",
3: "April",
4: "May",
5: "June",
6: "July",
7: "August",
8: "September",
9: "October",
10: "November",
11: "December"
};
var monthsShort = {
0: "Jan",
1: "Feb",
2: "Mar",
3: "Apr",
4: "May",
5: "Jun",
6: "Jul",
7: "Aug",
8: "Sep",
9: "Oct",
10: "Nov",
11: "Dec"
};
function getNormal(Time) {
if (/^\\d$/.test(Time)) {
return `0${Time}`
} else {
return Time
}
}
var format = {
"%y": this.getFullYear().toString().substr(2),
"%Y": String(this.getFullYear()),
"%m": String(this.getMonth() + 1),
"%d": String(this.getDate()),
"%w": String(this.getDay()),
"%H": String(this.getHours()),
"%I": String(this.getHours() % 12),
"%M": getNormal(this.getMinutes()),
"%S": getNormal(this.getSeconds()),
"%a": weekdaysShort[this.getDay()],
"%A": weekdays[this.getDay()],
"%b": monthsShort[this.getMonth()],
"%B": months[this.getMonth()],
"%%": "%"
}
for (var i in format) {
if (RegExp(`(${i})`).test(text)) {
// 使用全局替换模式
var target = new RegExp以上是关于JavaScript 编写Date 格式化方法『Python风格ヾ(•ω•`)o』的主要内容,如果未能解决你的问题,请参考以下文章
javascript中的Date和java语言中的Date能互相转换么,能的话该怎么转?谢谢
javascript Date format(js日期格式化)
javascript Date format(js日期格式化) (转)