最近工做工做遇到一個簽到功能,網上找了不少日曆插件,發現都不是很適合,或者說不能很好的實現產品的需求,結果仍是本身擼了一個,擼的過程也是對js Date 類型從新學習了一遍,對 Date 類型的方法也是有了一個全面的熟悉.css
每日簽到功能html
日曆補籤功能瀏覽器
特殊日特殊獎勵提醒(不能補籤)bash
簽到活躍度領取加上一個活躍進度條與禮包領取app
這裏只對日曆功能進行實現,若是有機會再寫一下分享一下進度條功能吧
框架
要建立一個日期對象, 使用 new 操做符和 Date 構造函數便可,以下所示函數
let now = new Date()
複製代碼
在調用 Date 構造函數而不傳遞參數的狀況下, 新建立的對象自動得到當前日期和時間. 若是想根據特定的日期和時間建立時間對象,必須傳入表示該日期的毫秒數( 即從 UTC 時間 1970 年 1 月 1 日我i也起至該日期止通過的毫秒數 ). 爲了簡化這一計算過程, ECMAScript 提供了兩個方法: Date.parse() 和 Dare.UTC()學習
其中, Date.parse() 方法接收一個表示日期的字符串參數,而後嘗試根據這個字符串返回的日期毫秒數, ECMA-262 沒有定義Date.parse() 應該支持哪一種日期格式,所以這個方法的行爲因實現地區而異.國內支持的日期格式爲flex
例如, 要爲 2019 年 3 月 8 號 建立一個日期對象,可使用下面的代碼:ui
let someDate = new Date(Date.parse("2019/3/8"))
複製代碼
若是傳入的 Date.parse() 方法的字符串不能表示日期,那麼它會返回 NaN , 實際上,若是直接將表示日期的字符串傳遞給 Date 構造函數,也會在後臺調用 Date.parse() 方法.也就是下面的代碼和上面的等價:
let someDate = new Date("2019/3/8")
複製代碼
Date.UTC() 方法一樣也返回表示日期的毫秒數,但它與 Date.parse() 在構建值時使用不一樣的信息. Date.UTC() 的參數分別是年份、基於0的月份(一月是 0 ,二月是 1 , 一次類推)、月中的哪一天( 1 到 31 )、小時數( 0 到 23 )、分鐘、秒以及毫秒數.在這些參數中,只有前兩個參數(年月)是必須的,若是沒有提供月中的天數,則假設天數爲1; 若是省略其餘參數,則通通設置爲 0 . 如下是例子:
// GMT 時間 2000 年 1 月 1 日 午夜零時,換算成中國標準時間就成了 2000 年 1 月 1 日 早晨 8 點整,中國時區爲 GMT+0800(東八區)
let yk1 = new Date(Date.UTC(2000, 0))
// GMT 時間 2005 年 5 月 5 日 下午 5:55:55 換成中國標準時間就是 6 號 凌晨一點了
let allFives = new Date(Date.UTC(2005, 4 , 5, 17, 55, 55))
複製代碼
如同模仿 Date.parse() 同樣, Date 構造函數也會模仿 Date.UTC() ,但有一點明顯不一樣: 日期和時間都是基於本地而非 GMT 來建立. 而 Date 構造函數接受的參數仍然與 Date.UTC() 相同.所以, 若是第一個參數是數值, Date 構造函數就會假設該數值是日期中的年份, 而第二個參數是月份,以此類推.據此,能夠將前面的例子重寫以下
// 本地時間 2000 年 1 月 1 日
let yk2 = new Date(2000, 0)
// 本地時間 2005 年 5 月 5 日 下午 5:55:55
let allFives1 = new Date(2005, 4 , 5, 17, 55, 55)
複製代碼
ECMAScript 5 添加了 Date.now() 方法,返回表示調用這個方法時的日期和時間的毫秒數,在不支持它的瀏覽器可使用 + 操做符獲取 Date 對象的時間戳,也能夠達到一樣的目的
Date 類型還有一些專門用於將日期格式化爲字符串的方法,這些方法以下:
這些方法的輸出字符串格式因瀏覽器而已
console.log(allFives1.toDateString()) // "Thu May 05 2005"
console.log(allFives1.toTimeString()) // "17:55:55 GMT+0800 (中國標準時間)"
console.log(allFives1.toLocaleDateString()) // "2005/5/5"
console.log(allFives1. toLocaleTimeString()) // "下午5:55:55"
複製代碼
Date 類型提供瞭如下方法能夠獲取Date 類型的詳細信息
如下方法能夠設置Date 類型的的信息
詳細API可查閱 MDN
當天年月信息
let date = new Date() //新建Date() 類型對象
let year = date.getFullYear() // 年
let month = date.getMonth() // 月
let day = date.getDate() // 日
複製代碼
上個月有多少天
有上面對 Date 類型的詳細介紹(2.1.2)應該知道若是 new Date(year, month, day)
若是年月信息是必須填入的,然後面的信息不填,則天數默認爲 1 號,那麼若是咱們填入 0 的話則爲上個月月末(~小技巧~) 那麼要知道本月末,則只須要設置月份的時候多加個 1 就行了,例如:
// 月份經過 UTC 方式設置須要減一
let newDate1 = new Date(2019, 12) // "2020/1/1"
//咱們須要獲得二月份天數的話
let newDate1 = new Date(2019, 3, 0) // "2019/2/28"
複製代碼
let MonthEndDate = new Date(year, month + 1, 0) // 本月末
let MonthEndDay = thisMonthEnd.getDate() // 月末號即這個月的天數
複製代碼
一號是周幾
date.setDate(1) // 重置時間對象爲本月一號
let week = date.getDay() // 這個月一號是周幾
複製代碼
這裏就用 Vue 框架來實現一個日曆功能
效果展現
<template>
<div id="app">
<div class="calendar">
<div class="header">
<p class="data-time">{{dataTime}}</p>
<p class="data-day">{{dataDay}}</p>
</div>
<div class="data-month">
<p>{{dataMonth}}</p>
</div>
<div class="calendar-content data-week">
<div class="content-item" v-for="(item,index) in week" :key="index">
<div class="content-item-value">{{item}}</div>
</div>
</div>
<div class="calendar-content">
<div class="content-item" v-for="(item,index) in day" :key="index">
<div class="content-item-value">{{item.day}}</div>
<div class="content-item-state">{{item.state}}</div>
</div>
</div>
</div>
</div>
</template>
複製代碼
<script>
export default {
name: "app",
data() {
return {
dataTime: "00:00:00",
dataDay: "2000年01月01日",
dataMonth: "2019年三月",
week: ["日", "一", "二", "三", "四", "五", "六"],
day: [],
timer: null
};
},
created() {
let date = new Date();
let year = date.getFullYear();
let month = date.getMonth();
let today = date.getDate();
let thisMonthEnd = new Date(year, month + 1, 0); // 本月末
let thisDay = thisMonthEnd.getDate(); // 月末號即這個月的天數
month = ++month < 10 ? "0" + month : month;
today = today < 10 ? "0" + today : today;
this.dataDay = year + "年" + month + "月" + today + "日";
this.dataMonth = year + "年" + month + "月";
this.setTimer();
this.timer = setInterval(this.setTimer, 1000);
date.setDate(1); // 重置時間對象爲本月一號
let week = date.getDay(); // 這個月一號是周幾
for (let i = 1; i <= 40; i++) {
if (i <= week) {
this.day.push({
day: ""
}); // 前幾天都是上個月,置空
} else {
let day = i - week;
this.day.push({
day: day, // 日曆號碼
state: day === 8 ? "婦女節" : ""
});
if (day === thisDay) {
break; // 若是填滿這個月天數就結束
}
}
}
},
methods: {
setTimer() {
let date = new Date();
let hours = date.getHours();
let mintus = date.getMinutes();
let seconds = date.getSeconds();
hours = hours < 10 ? "0" + hours : hours;
mintus = mintus < 10 ? "0" + mintus : mintus;
seconds = seconds < 10 ? "0" + seconds : seconds;
this.dataTime = hours + ":" + mintus + ":" + seconds;
}
},
beforeDestroy() {
clearInterval(this.timer);
}
};
</script>
複製代碼
<style lang="scss">
* {
margin: 0;
padding: 0;
}
html,
body,
#app {
height: 100%;
}
#app {
width: 455px;
height: 100%;
font-size: 16px;
margin: 0 auto;
color: #ffffff;
background: #39a54d;
}
.calendar {
.header {
padding: 20px;
border-bottom: 1px solid #ffffff;
.data-time {
font-size: 36px;
}
.data-day {
color: aqua;
}
}
.data-month {
padding: 20px;
}
.calendar-content {
display: flex;
flex-wrap: wrap;
width: 100%;
padding: 0 3%;
.content-item {
width: 13.4%;
height: 40px;
margin: 4px 0;
color: #fff;
text-align: center;
.content-item-state {
color: coral;
}
}
}
}
</style>
複製代碼