一文秒懂js如何快速处理日期以及手写Day.js
作者:码农白衣
一、Day.js介绍
1.Day.js的概念
Day.js 是一个轻量级的 JavaScript 日期库,用于解析、操作和格式化日期和时间。它的设计灵感来自于 Moment.js,但相比于 Moment.js,Day.js 更小巧、性能更好,并且提供了更现代化的 API。
2.Day.js的特点及功能
日期解析和格式化:
- Day.js 提供了
parse
方法用于解析字符串形式的日期,并将其转换为 Day.js 的日期对象。 - 使用
format
方法可以将日期对象格式化为特定的日期字符串,支持自定义格式化模板。
- Day.js 提供了
日期操作:
- Day.js 提供了一系列方法用于增减年、月、日、小时、分钟、秒等时间单位,如
add
、subtract
等方法。 - 还提供了诸如
startOf
、endOf
等方法,用于将日期设置为指定时间单位的起始或结束。
- Day.js 提供了一系列方法用于增减年、月、日、小时、分钟、秒等时间单位,如
日期比较:
- Day.js 提供了
isBefore
、isSame
、isAfter
等方法,用于比较两个日期的先后顺序或是否相同。
- Day.js 提供了
链式操作:
- Day.js 支持链式调用方法,可以在同一个语句中连续调用多个方法,从而实现更复杂的日期操作。
国际化支持:
- Day.js 支持国际化,可以根据不同的语言和地区,格式化日期字符串和输出本地化的日期表示。
插件系统:
- Day.js 提供了简单的插件系统,允许开发者扩展其功能或添加新的特性,以满足项目的特定需求。
不可变性:
- Day.js 的日期对象是不可变的,一旦创建了日期对象,就无法直接修改它,这有助于避免副作用带来的潜在问题。
格式化:
- Day.js 具有丰富的格式化选项,可以根据需求输出日期和时间的各种格式,如年、月、日、小时、分钟、秒等。
时区和夏令时:
- Day.js 可以处理时区和夏令时的问题,使得在跨时区和跨国界的应用中更加可靠和灵活。
二、Day.js的使用
首先可以到Day.js中文网查看官方文档,了解使用说明
1.获取使用
要在您的 Node.js 项目中使用 Day.js,只需使用 npm (opens new window) 安装,或 cnpm (opens new window) 安装,或 yarn (opens new window) 安装,或 pnpm (opens new window) 安装
npm install dayjs cnpm install dayjs -S yarn add dayjs pnpm add dayjs
然后在项目代码中引入即可:
var dayjs = require('dayjs') // import dayjs from 'dayjs' // ES 2015 dayjs().format()
2.本地使用
本地存储dayjs库进行使用
!function (t, n) { "object" == typeof exports && "undefined" != typeof module ? module.exports = n() : "function" == typeof define && define.amd ? define(n) : t.dayjs = n() }(this, function () { "use strict"; var t = "millisecond", n = "second", e = "minute", r = "hour", i = "day", s = "week", u = "month", o = "quarter", a = "year", h = /^(\d{4})-?(\d{1,2})-?(\d{0,2})[^0-9]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?.?(\d{1,3})?$/, f = /\[([^\]]+)]|Y{2,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g, c = function (t, n, e) { var r = String(t); return !r || r.length >= n ? t : "" + Array(n + 1 - r.length).join(e) + t }, d = { s: c, z: function (t) { var n = -t.utcOffset(), e = Math.abs(n), r = Math.floor(e / 60), i = e % 60; return (n <= 0 ? "+" : "-") + c(r, 2, "0") + ":" + c(i, 2, "0") }, m: function (t, n) { var e = 12 * (n.year() - t.year()) + (n.month() - t.month()), r = t.clone().add(e, u), i = n - r < 0, s = t.clone().add(e + (i ? -1 : 1), u); return Number(-(e + (n - r) / (i ? r - s : s - r)) || 0) }, a: function (t) { return t < 0 ? Math.ceil(t) || 0 : Math.floor(t) }, p: function (h) { return { M: u, y: a, w: s, d: i, D: "date", h: r, m: e, s: n, ms: t, Q: o }[h] || String(h || "").toLowerCase().replace(/s$/, "") }, u: function (t) { return void 0 === t } }, $ = { name: "en", weekdays: "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"), months: "January_February_March_April_May_June_July_August_September_October_November_December".split("_") }, l = "en", m = {}; m[l] = $; var y = function (t) { return t instanceof v }, M = function (t, n, e) { var r; if (!t) return l; if ("string" == typeof t) m[t] && (r = t), n && (m[t] = n, r = t); else { var i = t.name; m[i] = t, r = i } return e || (l = r), r }, g = function (t, n, e) { if (y(t)) return t.clone(); var r = n ? "string" == typeof n ? { format: n, pl: e } : n : {}; return r.date = t, new v(r) }, D = d; D.l = M, D.i = y, D.w = function (t, n) { return g(t, { locale: n.$L, utc: n.$u, $offset: n.$offset }) }; var v = function () { function c(t) { this.$L = this.$L || M(t.locale, null, !0), this.parse(t) } var d = c.prototype; return d.parse = function (t) { this.$d = function (t) { var n = t.date, e = t.utc; if (null === n) return new Date(NaN); if (D.u(n)) return new Date; if (n instanceof Date) return new Date(n); if ("string" == typeof n && !/Z$/i.test(n)) { var r = n.match(h); if (r) return e ? new Date(Date.UTC(r[1], r[2] - 1, r[3] || 1, r[4] || 0, r[5] || 0, r[6] || 0, r[7] || 0)) : new Date(r[1], r[2] - 1, r[3] || 1, r[4] || 0, r[5] || 0, r[6] || 0, r[7] || 0) } return new Date(n) }(t), this.init() }, d.init = function () { var t = this.$d; this.$y = t.getFullYear(), this.$M = t.getMonth(), this.$D = t.getDate(), this.$W = t.getDay(), this.$H = t.getHours(), this.$m = t.getMinutes(), this.$s = t.getSeconds(), this.$ms = t.getMilliseconds() }, d.$utils = function () { return D }, d.isValid = function () { return !("Invalid Date" === this.$d.toString()) }, d.isSame = function (t, n) { var e = g(t); return this.startOf(n) <= e && e <= this.endOf(n) }, d.isAfter = function (t, n) { return g(t) < this.startOf(n) }, d.isBefore = function (t, n) { return this.endOf(n) < g(t) }, d.$g = function (t, n, e) { return D.u(t) ? this[n] : this.set(e, t) }, d.year = function (t) { return this.$g(t, "$y", a) }, d.month = function (t) { return this.$g(t, "$M", u) }, d.day = function (t) { return this.$g(t, "$W", i) }, d.date = function (t) { return this.$g(t, "$D", "date") }, d.hour = function (t) { return this.$g(t, "$H", r) }, d.minute = function (t) { return this.$g(t, "$m", e) }, d.second = function (t) { return this.$g(t, "$s", n) }, d.millisecond = function (n) { return this.$g(n, "$ms", t) }, d.unix = function () { return Math.floor(this.valueOf() / 1e3) }, d.valueOf = function () { return this.$d.getTime() }, d.startOf = function (t, o) { var h = this, f = !!D.u(o) || o, c = D.p(t), d = function (t, n) { var e = D.w(h.$u ? Date.UTC(h.$y, n, t) : new Date(h.$y, n, t), h); return f ? e : e.endOf(i) }, $ = function (t, n) { return D.w(h.toDate()[t].apply(h.toDate(), (f ? [0, 0, 0, 0] : [23, 59, 59, 999]).slice(n)), h) }, l = this.$W, m = this.$M, y = this.$D, M = "set" + (this.$u ? "UTC" : ""); switch (c) { case a: return f ? d(1, 0) : d(31, 11); case u: return f ? d(1, m) : d(0, m + 1); case s: var g = this.$locale().weekStart || 0, v = (l < g ? l + 7 : l) - g; return d(f ? y - v : y + (6 - v), m); case i: case "date": return $(M + "Hours", 0); case r: return $(M + "Minutes", 1); case e: return $(M + "Seconds", 2); case n: return $(M + "Milliseconds", 3); default: return this.clone() } }, d.endOf = function (t) { return this.startOf(t, !1) }, d.$set = function (s, o) { var h, f = D.p(s), c = "set" + (this.$u ? "UTC" : ""), d = (h = {}, h[i] = c + "Date", h.date = c + "Date", h[u] = c + "Month", h[a] = c + "FullYear", h[r] = c + "Hours", h[e] = c + "Minutes", h[n] = c + "Seconds", h[t] = c + "Milliseconds", h)[f], $ = f === i ? this.$D + (o - this.$W) : o; if (f === u || f === a) { var l = this.clone().set("date", 1); l.$d[d]($), l.init(), this.$d = l.set("date", Math.min(this.$D, l.daysInMonth())).toDate() } else d && this.$d[d]($); return this.init(), this }, d.set = function (t, n) { return this.clone().$set(t, n) }, d.get = function (t) { return this[D.p(t)]() }, d.add = function (t, o) { var h, f = this; t = Number(t); var c = D.p(o), d = function (n) { var e = g(f); return D.w(e.date(e.date() + Math.round(n * t)), f) }; if (c === u) return this.set(u, this.$M + t); if (c === a) return this.set(a, this.$y + t); if (c === i) return d(1); if (c === s) return d(7); var $ = (h = {}, h[e] = 6e4, h[r] = 36e5, h[n] = 1e3, h)[c] || 1, l = this.$d.getTime() + t * $; return D.w(l, this) }, d.subtract = function (t, n) { return this.add(-1 * t, n) }, d.format = function (t) { var n = this; if (!this.isValid()) return "Invalid Date"; var e = t || "YYYY-MM-DDTHH:mm:ssZ", r = D.z(this), i = this.$locale(), s = this.$H, u = this.$m, o = this.$M, a = i.weekdays, h = i.months, c = function (t, r, i, s) { return t && (t[r] || t(n, e)) || i[r].substr(0, s) }, d = function (t) { return D.s(s % 12 || 12, t, "0") }, $ = i.meridiem || function (t, n, e) { var r = t < 12 ? "AM" : "PM"; return e ? r.toLowerCase() : r }, l = { YY: String(this.$y).slice(-2), YYYY: this.$y, M: o + 1, MM: D.s(o + 1, 2, "0"), MMM: c(i.monthsShort, o, h, 3), MMMM: h[o] || h(this, e), D: this.$D, DD: D.s(this.$D, 2, "0"), d: String(this.$W), dd: c(i.weekdaysMin, this.$W, a, 2), ddd: c(i.weekdaysShort, this.$W, a, 3), dddd: a[this.$W], H: String(s), HH: D.s(s, 2, "0"), h: d(1), hh: d(2), a: $(s, u, !0), A: $(s, u, !1), m: String(u), mm: D.s(u, 2, "0"), s: String(this.$s), ss: D.s(this.$s, 2, "0"), SSS: D.s(this.$ms, 3, "0"), Z: r }; return e.replace(f, function (t, n) { return n || l[t] || r.replace(":", "") }) }, d.utcOffset = function () { return 15 * -Math.round(this.$d.getTimezoneOffset() / 15) }, d.diff = function (t, h, f) { var c, d = D.p(h), $ = g(t), l = 6e4 * ($.utcOffset() - this.utcOffset()), m = this - $, y = D.m(this, $); return y = (c = {}, c[a] = y / 12, c[u] = y, c[o] = y / 3, c[s] = (m - l) / 6048e5, c[i] = (m - l) / 864e5, c[r] = m / 36e5, c[e] = m / 6e4, c[n] = m / 1e3, c)[d] || m, f ? y : D.a(y) }, d.daysInMonth = function () { return this.endOf(u).$D }, d.$locale = function () { return m[this.$L] }, d.locale = function (t, n) { if (!t) return this.$L; var e = this.clone(), r = M(t, n, !0); return r && (e.$L = r), e }, d.clone = function () { return D.w(this.$d, this) }, d.toDate = function () { return new Date(this.valueOf()) }, d.toJSON = function () { return this.isValid() ? this.toISOString() : null }, d.toISOString = function () { return this.$d.toISOString() }, d.toString = function () { return this.$d.toUTCString() }, c }(); return g.prototype = v.prototype, g.extend = function (t, n) { return t(n, v, g), g }, g.locale = M, g.isDayjs = y, g.unix = function (t) { return g(1e3 * t) }, g.en = m[l], g.Ls = m, g });
会在Dayjs的原型上添加: formNow
!function (r, e) { "object" == typeof exports && "undefined" != typeof module ? module.exports = e() : "function" == typeof define && define.amd ? define(e) : (r = "undefined" != typeof globalThis ? globalThis : r || self).dayjs_plugin_relativeTime = e() }(this, (function () { "use strict"; return function (r, e, t) { r = r || {}; var n = e.prototype, o = { future: "in %s", past: "%s ago", s: "a few seconds", m: "a minute", mm: "%d minutes", h: "an hour", hh: "%d hours", d: "a day", dd: "%d days", M: "a month", MM: "%d months", y: "a year", yy: "%d years" }; function i(r, e, t, o) { return n.fromToBase(r, e, t, o) } t.en.relativeTime = o, n.fromToBase = function (e, n, i, d, u) { for (var f, a, s, l = i.$locale().relativeTime || o, h = r.thresholds || [{ l: "s", r: 44, d: "second" }, { l: "m", r: 89 }, { l: "mm", r: 44, d: "minute" }, { l: "h", r: 89 }, { l: "hh", r: 21, d: "hour" }, { l: "d", r: 35 }, { l: "dd", r: 25, d: "day" }, { l: "M", r: 45 }, { l: "MM", r: 10, d: "month" }, { l: "y", r: 17 }, { l: "yy", d: "year" }], m = h.length, c = 0; c < m; c += 1) { var y = h[c]; y.d && (f = d ? t(e).diff(i, y.d, !0) : i.diff(e, y.d, !0)); var p = (r.rounding || Math.round)(Math.abs(f)); if (s = f > 0, p <= y.r || !y.r) { p <= 1 && c > 0 && (y = h[c - 1]); var v = l[y.l]; u && (p = u("" + p)), a = "string" == typeof v ? v.replace("%d", p) : v(p, n, y.l, s); break } } if (n) return a; var M = s ? l.future : l.past; return "function" == typeof M ? M(a) : M.replace("%s", a) }, n.to = function (r, e) { return i(r, e, this, !0) }, n.from = function (r, e) { return i(r, e, this) }; var d = function (r) { return r.$u ? t.utc() : t() }; n.toNow = function (r) { return this.to(d(this), r) }, n.fromNow = function (r) { return this.from(d(this), r) } } }));
给dayjs的全局变量Ls添加一个中文支持
!function(e,_){"object"==typeof exports&&"undefined"!=typeof module?module.exports=_(require("dayjs")):"function"==typeof define&&define.amd?define(["dayjs"],_):(e="undefined"!=typeof globalThis?globalThis:e||self).dayjs_locale_zh_cn=_(e.dayjs)}(this,(function(e){"use strict";function _(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var t=_(e),d={name:"zh-cn",weekdays:"星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"),weekdaysShort:"周日_周一_周二_周三_周四_周五_周六".split("_"),weekdaysMin:"日_一_二_三_四_五_六".split("_"),months:"一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月".split("_"),monthsShort:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),ordinal:function(e,_){return"W"===_?e+"周":e+"日"},weekStart:1,yearStart:4,formats:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY/MM/DD",LL:"YYYY年M月D日",LLL:"YYYY年M月D日Ah点mm分",LLLL:"YYYY年M月D日ddddAh点mm分",l:"YYYY/M/D",ll:"YYYY年M月D日",lll:"YYYY年M月D日 HH:mm",llll:"YYYY年M月D日dddd HH:mm"},relativeTime:{future:"%s内",past:"%s前",s:"几秒",m:"1 分钟",mm:"%d 分钟",h:"1 小时",hh:"%d 小时",d:"1 天",dd:"%d 天",M:"1 个月",MM:"%d 个月",y:"1 年",yy:"%d 年"},meridiem:function(e,_){var t=100*e+_;return t<600?"凌晨":t<900?"早上":t<1100?"上午":t<1300?"中午":t<1800?"下午":"晚上"}};return t.default.locale(d,null,!0),d}));
插件使用
<script src="./libs/day.js"></script> // 会在Dayjs的原型上添加: formNow <script src="./libs/dayjs.relative-time.js"></script> //给dayjs的全局变量Ls添加一个中文支持 <script src="./libs/dayjs.zh-cn.js"></script> // 1.安装插件 dayjs.extend(dayjs_plugin_relativeTime) dayjs.locale('zh-cn') //1. 1个小时 5分钟 2天前 var day = dayjs(1656206934331) console.log(day.fromNow())
3.通过Dayjs获取和控制时间
<script src="./libs/day.js"></script> //基础写法 // 1.拿到Dayjs的效果 var day = dayjs() // 获取时间 console.log(day.year(),(day.month()+1),day.date(),day.hour(),day.minute(),day.second()) //高阶写法 var day = dayjs() .year(2021) .month(5) .date(1) console.log(day.year(),(day.month()+1),day.date(),day.hour(),day.minute(),day.second())
4.时间操作
<script src="./libs/day.js"></script> //增加一天 var day = dayjs() .add(1, 'day') .startOf('year') .startOf('month'); console.log(day.format("YYYY-MM-DD HH:mm:ss"));
5.时间解析
<script src="./libs/day.js"></script> // 1. 解析一个字符串类型的时间 // YYYY-MM-DD HH:mm:ss // YYYY-MM-DD // YYYY/MM/DD var day1 = dayjs('2021-2-2 12:00:10'); // 2.解析时间戳(毫秒) var day2 = dayjs(1656206934331); // 3.解析时间戳(秒) var day3 = dayjs.unix(1656206934); // 4.解析data对象 var day4 = dayjs(new Date('2022-10-1')); // 时间的格式化 console.log(day1.format("YYYY-MM-DD HH:mm:ss")); // 格式化输出日期时间
6.手写Day.js
JS封装函数
;(function(g){ //browser -> window ; //node -> global //globalThis -> ES11 g = typeof globalThis !== 'undefined' ? globalThis : g || self //构造函数 function Dayjs(){ var date = new Date() this.$Y = date.getFullYear() this.$M = date.getMonth() this.$D = date.getDate() } Dayjs.prototype.format = function(){ return `${this.$Y}-${(this.$M+1)}-${this.$D}` } // ....原型的方法 // ....原型的方法 // ....原型的方法 // ....原型的方法 // ....原型的方法 // ....原型的方法 // ....原型的方法 //工厂函数 function dayjs(){ return new Dayjs() } dayjs.prototype = Dayjs.prototype //统一导出 g.dayjs = dayjs })(this)
HTML结构
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script src="./utils/JYDayjs.js"></script> <script> console.log("%O", dayjs) console.log("%O", dayjs())// 创建dayjs对象 console.log(dayjs().format()) //拿到当前的时间 </script> </body> </html>
三、Day.js的应用
Day.js 是一个非常方便的日期和时间处理库,可以在各种 Web 开发项目中使用。以下是一些 Day.js 的常见应用场景:
日期显示和格式化: Day.js 可以帮助你将日期和时间格式化为特定的格式,以便在用户界面中显示。比如,你可以将日期格式化为 "YYYY-MM-DD"、"YYYY-MM-DD HH:mm:ss" 等等,以满足项目的需求。
日期计算和操作: Day.js 提供了丰富的日期计算和操作方法,如增加/减少天数、月份、年份,获取某个日期的起始时间或结束时间等。这些功能对于实现各种日期逻辑非常有用,比如计算两个日期之间的差值、判断某个日期是否在指定范围内等。
日期解析和转换: Day.js 可以解析各种格式的日期字符串、时间戳和 Date 对象,并将它们转换为 Day.js 对象,便于后续的操作和处理。这对于从用户输入或后端接口中获取日期数据非常有用。
相对时间和持续时间: Day.js 提供了一些方法来处理相对时间,比如获取当前时间相对于另一个时间的差值(如 "3 天前"、"1 小时前" 等),以及计算持续时间(如 "2 小时 30 分钟")。
本地化和时区处理: Day.js 支持本地化和时区处理,可以根据用户的地理位置和偏好显示本地化的日期和时间格式,并且可以在不同的时区之间进行转换和处理。
事件日历和计划安排: Day.js 可以帮助你实现事件日历和计划安排功能,比如显示日历、添加/编辑事件、设置提醒等。你可以利用 Day.js 的日期计算和格式化功能来实现这些功能,并且可以根据用户的需求进行定制化开发。
表单验证和日期选择器: Day.js 可以用于表单验证和日期选择器,帮助用户输入正确格式的日期,并且可以根据用户的输入实时验证日期的有效性。你可以结合其他前端框架或组件库(如 React、Vue、Bootstrap 等)来实现这些功能。
四、最终手写Day.js封装
(function(g){ g = typeof globalThis !== 'undefined' ? globalThis : g || self; // 构造函数 function Dayjs(dateString) { if (dateString) { var parsedDate = new Date(dateString); if (isNaN(parsedDate.getTime())) { throw new Error('Invalid date format'); } this.$Y = parsedDate.getFullYear(); this.$M = parsedDate.getMonth(); this.$D = parsedDate.getDate(); } else { var currentDate = new Date(); this.$Y = currentDate.getFullYear(); this.$M = currentDate.getMonth(); this.$D = currentDate.getDate(); } } // 格式化日期 Dayjs.prototype.format = function(formatString = 'YYYY-MM-DD') { const year = this.$Y; const month = (this.$M + 1).toString().padStart(2, '0'); const day = this.$D.toString().padStart(2, '0'); return formatString.replace(/YYYY/g, year) .replace(/MM/g, month) .replace(/DD/g, day); } // 工厂函数 function dayjs(dateString) { return new Dayjs(dateString); } // 原型链处理 dayjs.prototype = Object.create(Dayjs.prototype); dayjs.prototype.constructor = dayjs; // 导出 g.dayjs = dayjs; })(this);
总结
到此这篇关于js如何快速处理日期以及手写Day.js的文章就介绍到这了,更多相关JS中Day.js使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!