日期格式处理在前端的日常任务中非常常见,但是为此引入monent.js这样的类库又会显得有点臃肿,毕竟我们一个特定的项目中,并不需要monent.js那么全的涵盖范围。另外,如果现在公司让你自己手写一个日历组件(月历、周历),日历组件中需要耦合我们的其他业务需求,如果有一个任务列表,当11月22号的待进行任务,我需要在日历上有一个绿色圆点,表示当天有待办事项。下面介绍一些常规的函数,希望对大家有用。

  • 月历效果图

月历.png
函数目录
  • getFormatDateStr 获得指定日期格式的字符串;
  • getDayPrevAfter 获得n天前/后的日期;
  • formatDateWithTimeZone 格式化日期带时区,ISO 8601;
  • countDownBySecond 倒计时;
  • monthSize 获得指定日期所在月的天数;
  • getCalendarMonth 获得指定日期所在月的第一周到第四/五周的数据组合;
  • getOneDateWeekIndex 获得指定的某天所在该月的第几周,下标从0开始;
下面是详细的说明:
  • getFormatDateStr
/**
* [zeroPadding 小于10的数字补0,必填]
* @param {[Int]} value [description]
* @return {[String]} [description]
*/
export function zeroPadding(value){
return value < 10 ? `0${value}` : value;
} /**
* [_isDateStrSeparatorCh 判断日期格式字符串的分隔符是否是中文]
* @param {[String]} str [必填]
* @return {[String]} [分隔符]
*/
function _getDateStrSeparator(str, startIndex, endIndex) {
startIndex = startIndex ? startIndex : 4;
endIndex = endIndex ? endIndex : 5;
let separator = str.slice(startIndex, endIndex);
if (separator === '年' || separator === '月' ) {
separator = 'Ch';
}
return separator;
} /**
* [_isDateStrSeparatorCh 判断日期格式字符串的分隔符是否是中文]
* @param {[String]} str [必填]
* @return {[String]} [分隔符]
*/
function _isDateStrSeparatorCh(str) {
if ( str.indexOf('年')!=-1 || str.indexOf('月')!=-1 ) {
return true;
}
return false;
} /**
* [getFormatDateStr 获得指定日期格式的字符串]
* @param {[String or Date]} date [要转换的日期,必填]
* @param {[String]} dateFormatStr [要转化的目标格式,必填,2016-11-22之间的分隔符可任意,可选项:
* 'yyyy-mm-dd hh:mm:ss','yyyy/mm/dd hh:mm:ss','yyyy.mm.dd hh:mm:ss','yyyy年mm月dd hh:mm:ss',
* 'yyyy-mm-dd hh:mm',
* 'mm-dd hh:mm',
* 'yyyy-mm-dd',
* 'mm-dd',
* 'hh:mm:ss',
* 'hh:mm'
* ]
* @return {[String]} [时间格式字符串]
*/
export function getFormatDateStr(date, dateFormatStr) { if ( !(date instanceof Date) ) {
if ( date.indexOf('-') != -1 ) {
date.replace(/\-/g,'/');
}
date = new Date(date);
} dateFormatStr = dateFormatStr.toLowerCase();
if (!dateFormatStr){
return false;
} let returnStr = '',
separator = _getDateStrSeparator(dateFormatStr),
year = date.getFullYear(),
month = date.getMonth() + 1,
day = date.getDate(),
hour = date.getHours(),
minute = date.getMinutes(),
second = date.getSeconds(); if ( /^yyyy(.{1})mm(.{1})dd hh:mm:ss$/.test(dateFormatStr) ) {
if (_isDateStrSeparatorCh(dateFormatStr)) {
returnStr = `${year}年${zeroPadding(month)}月${zeroPadding(day)}日`;
} else {
separator =
returnStr = `${year}${separator}${zeroPadding(month)}${separator}${zeroPadding(day)}`;
}
returnStr += ` ${zeroPadding(hour)}:${zeroPadding(minute)}:${zeroPadding(second)}`;
} else if ( /^yyyy(.{1})mm(.{1})dd hh:mm$/.test(dateFormatStr) ) {
if (_isDateStrSeparatorCh(dateFormatStr)) {
returnStr = `${year}年${zeroPadding(month)}月${zeroPadding(day)}日`;
} else {
returnStr = `${year}${separator}${zeroPadding(month)}${separator}${zeroPadding(day)}`;
}
returnStr += ` ${zeroPadding(hour)}:${zeroPadding(minute)}`;
} else if ( /^mm(.{1})dd hh:mm$/.test(dateFormatStr) ) {
if (_isDateStrSeparatorCh(dateFormatStr)) {
returnStr = `${zeroPadding(month)}月${zeroPadding(day)}日`;
} else {
separator = _getDateStrSeparator(dateFormatStr, 2, 3);
returnStr = `${zeroPadding(month)}${separator}${zeroPadding(day)}`;
}
returnStr += ` ${zeroPadding(hour)}:${zeroPadding(minute)}`;
} else if ( /^yyyy(.{1})mm(.{1})dd$/.test(dateFormatStr) ) {
if (_isDateStrSeparatorCh(dateFormatStr)) {
returnStr = `${year}年${zeroPadding(month)}月${zeroPadding(day)}日`;
} else {
returnStr = `${year}${separator}${zeroPadding(month)}${separator}${zeroPadding(day)}`;
}
} else if ( /^mm(.{1})dd$/.test(dateFormatStr) ) {
if (_isDateStrSeparatorCh(dateFormatStr)) {
returnStr = `${zeroPadding(month)}月${zeroPadding(day)}日`;
} else {
separator = _getDateStrSeparator(dateFormatStr, 2, 3);
returnStr = `${zeroPadding(month)}${separator}${zeroPadding(day)}`;
}
} else if ( /^hh:mm:ss$/.test(dateFormatStr) ) {
returnStr = `${zeroPadding(hour)}:${zeroPadding(minute)}:${zeroPadding(second)}`;
} else if ( /^hh:mm$/.test(dateFormatStr) ) {
returnStr = `${zeroPadding(hour)}:${zeroPadding(minute)}`;
} return returnStr; }
  • getDayPrevAfter
/**
* [getDayPrevAfter 获得n天前/后的日期]
* @param {[String]} date [日期,非必填参数,表示调用时的时间]
* @param {[String]} type [前一天还是后一天,非必填参数,默认后一天]
* @param {[Int]} daysNum [天数,非必填参数,默认一天]
* @return {[Date]} [description]
*/
export function getDayPrevAfter(date, type, daysNum) { date = date ? date : new Date();
type = type ? type : 'after';
daysNum = daysNum ? daysNum : 1; if ( !(date instanceof Date) ) {
if ( date.indexOf('-') != -1 ) {
date.replace(/\-/g,'/');
}
date = new Date(date);
} let returnDate = date;
if (type === 'prev') {
returnDate = new Date(date.getTime() - (daysNum * 24 * 60 * 60 * 1000));
} else if (type === 'after') {
returnDate = new Date(date.getTime() + (daysNum * 24 * 60 * 60 * 1000));
}
return returnDate; }
  • formatDateWithTimeZone
/**
* [formatDateWithTimeZone 格式化日期带时区,ISO 8601]
* @param {[Date]} date [日期,非必填参数,表示调用时的时间]
* @return {[String]} [ISO 8601格式的日期,example: 2016-11-21T14:09:15+08:00]
*/
export function formatDateWithTimeZone(date) { date = date ? date : new Date();
if ( !(date instanceof Date) ) {
if ( date.indexOf('-') != -1 ) {
date.replace(/\-/g,'/');
}
date = new Date(date);
} let tzo = -date.getTimezoneOffset(),
dif = tzo >= 0 ? '+' : '-',
pad = function (num) {
let norm = Math.abs(Math.floor(num));
return zeroPadding(norm);
};
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}T${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}${dif}${pad(tzo / 60)}:${pad(tzo % 60)}`; }
  • countDownBySecond
/**
* [countDownBySecond 倒计时]
* @param {[Int]} restSeconds [剩余秒数,必填]
* @param {[Int]} timeInterval [时间间隔,非必填,默认1000ms]
* @param {[Function]} func [每倒计时一次,就需要执行一次的回调函数名,非必填]
* @param {[Function]} endFun [倒计时结束需要执行的函数名,非必填]
* @return {[null]} [无返回值]
*/
export function countDownBySecond(restSeconds, timeInterval, func, endCallback) {
let timer = null;
let total = restSeconds;
timeInterval = timeInterval ? timeInterval : 1000;
timer = setInterval(function() {
--total;
if (total <= 0) {
clearInterval(timer);
endCallback && endCallback();
}
func && func(total);
}, timeInterval);
}
  • monthSize
/**
* [monthSize 获得指定日期所在月的天数]
* @param {[Date]} oDate [指定的日期,非必填,默认为当天]
* @return {[Int]} [总天数]
*/
function monthSize(oDate) {
oDate = oDate ? oDate : new Date();
let year = oDate.getFullYear(),
month = oDate.getMonth(),
_oDate = new Date();
_oDate.setFullYear(year);
_oDate.setMonth(month + 1, 0);
return _oDate.getDate();
}
  • getCalendarMonth
/**
* [getCalendarMonth 获得指定日期所在月的第一周到第四/五周的数据组合,形如:
* [{
"date": "2016/10/30", //日期字符串
"dateNum": 30, //日
"isCurMonth": false, //是否当前月
"weekIndex": 0 //是本月的第几周,下标从0开始
},{
"date": "2016/10/31",
"dateNum": 31,
"isCurMonth": false,
"weekIndex": 0
},{
"date": "2016/11/1",
"dateNum": 1,
"day": 2,
"isCurMonth": true,
"isToday": false,
"weekIndex": 0
}]
]
* @param {[Date]} param [指定的日期,非必填,默认为当天]
* @return {[Array]} [获得指定日期所在月的第一周到第四/五周的数据组合]
*/
export function getCalendarMonth(date) {
date = date ? date : new Date();
let y = date.getFullYear();
let m = date.getMonth();
let _m;
let firstDay = new Date(y, m, 1).getDay(); //当月第一天 周期
let days = monthSize(date);//当月天数
let prevMonthDays = monthSize(new Date(y, m - 1));//上月天数
let initPrevDay = prevMonthDays - firstDay;
let lines = Math.ceil((firstDay + days) / 7);
_m = new Array(lines * 7);
let nextMonthDay = 0; for (let i = 0; i < _m.length; i++) {
let weekIndex = parseInt(i / 7);
if (i < firstDay) {
let date = ++initPrevDay;
if (m === 0 && date > 7) {
_m[i] = {
isCurMonth: false,
dateNum: date,
weekIndex,
date: `${y - 1}/${12}/${date}`
};
} else {
_m[i] = {
isCurMonth: false,
dateNum: date,
weekIndex,
date: `${y}/${m}/${date}`
};
}
} else if (i >= (firstDay + days)) {
let date = ++nextMonthDay; if (m === 11 && date <= 7) {
_m[i] = {
isCurMonth: false,
dateNum: date,
weekIndex,
date: `${y + 1}/${1}/${date}`
};
} else {
_m[i] = {
isCurMonth: false,
dateNum: date,
weekIndex,
date: `${y}/${m + 2}/${date}`
};
}
} else {
let _date = i - firstDay + 1;
let today = new Date();
let today_y = today.getFullYear();
let today_m = today.getMonth();
let today_d = today.getDate();
let isToday = today_y === y && today_m === m && today_d === _date ? true : false;
_m[i] = {
dateNum: _date, //日期
day: i % 7, //周期
weekIndex,
isCurMonth: true,
isToday,
date: `${y}/${m + 1}/${_date}`
};
}
}
return _m;
}
  • getOneDateWeekIndex
/**
* [getOneDateWeekIndex 获得指定的某天所在该月的第几周,下标从0开始]
* @param {[Date]} date [指定的日期,非必填,默认为当天]
* @return {[Int]} [在该月的第几周]
*/
export function getOneDateWeekIndex(date) {
date = date ? date : new Date();
let monthDays = getCalendarMonth(date);
let dateString = getFormatDateStr(date, '/', true, false, false);
let returnDate = monthDays.filter(item => {
return item.date === dateString;
});
let weekIndex = returnDate[0].weekIndex;
return weekIndex ? weekIndex : 0;
}
用上面的函数就能够实现日期格式转换,倒计时,自定义月历等常规的需要,希望对您有用~

 
文/webCoder(简书作者)
原文链接:http://www.jianshu.com/p/5f07f26b0716
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

js常规日期格式处理、月历渲染、倒计时函数的更多相关文章

  1. 字符串转换成js的日期格式

    js字符串转日期格式 ,JavaScript字符串转日期格式 大家都知道JS是根据结果来确定数据类型的. 当然我们也是可以转化的,下面我就介绍两种关于JS字符串类型转换成日期类型的方法, 我个人比较喜 ...

  2. JS关于日期格式转换的问题

    写Js时,有个地方用到日期,要求是yyyy--MM--dd的格式,于是想到了format函数,下面介绍了时间函数的定义,和调用前引入函数和如何格式化自己想要的日期格式. //当前时间 var Time ...

  3. js中日期格式与时间戳格式互换

    2014-04-23 18:55:49:123    日期格式 1398250549123        时间戳格式 前台显示日期格式,则 function tsToTime(ts) { var da ...

  4. js json日期格式转换日期方法

      接收json数据,日期格式为:"\/Date(1414078309687)\/" var value = "/Date(1414078309687)/"; ...

  5. js设置日期格式

    取数据时后台返回的日期数据是一串数字,前台显示时需要将时间格式化,通过以下代码转换. var format = function(time, format){    var t = new Date( ...

  6. js将日期格式转换为YYYY-MM-DD HH:MM:SS

    <script language="javascript" type="text/javascript"> //页面加载 jQuery(docume ...

  7. 使用日期插件用js处理日期格式

    function compareDate(checkStartDate, checkEndDate) {    var arys1= new Array();    var arys2= new Ar ...

  8. JS转换日期格式

    // 对Date的扩展,将 Date 转化为指定格式的String // 月(M).日(d).小时(h).分(m).秒(s).季度(q) 可以用 1-2 个占位符, // 年(y)可以用 1-4 个占 ...

  9. js判断日期格式(YYYYMM)

    function datepanduan(obj){ var date = document.getElementById(obj.id).value; var reg = /^\b[1-3]\d{3 ...

随机推荐

  1. form 上传 html 代码

    $("#fm").form('submit',{ url: url, onSubmit: function(){ //进行表单验证 $scope.editor.sync(); va ...

  2. WordPress主机

  3. 遇到的check the manual that corresponds to your MySQL server version for the right syntax错误

    遇到的check the manual that corresponds to your MySQL server version for the right syntax错误. 结果发现是SQL关键 ...

  4. mormot orm rest注意事项

    mORMot创建ORM RestFul,当CreateMissingTables的时候报错,搜了n多资料没搞定,后来胡乱建了个表测试了一通搞定了. ORM对应的每个数据表都需要一个ID字段并设置主键, ...

  5. javascript学习第一课

    1.基本知识: 1.1 词法结构 1.1.1 字符集 javascript程序是用Unicode字符集编写的. 1.1.2 区分大小写 javascript是区分大小写的语言.也即是关键字.变量.函数 ...

  6. java中final,finally和finalize的区别

    final,finally和finalize的区别: final:最终的意思,可以修饰类,成员变量,成员方法 修饰类,类不能被继承 修饰变量,变量是常量 修饰方法,方法不能被重写 finally:是异 ...

  7. [原]iOS自带社会化分享框架——Social.framework

    http://m.blog.csdn.net/blog/u012189584/43236379 Social.framework支持的分享平台(打开手机上的“设置”即可看到)(如Twitter.fac ...

  8. SQL分页查询结果不一致

    今天遇到了SQL分页查询结果不一致的情况,一看代码,原来是没加排序查询!!分页查询最好加排序,且以唯一性高的字段进行排序,如ID,时间等,以保持每页查询结果的准确! PS:又帮别人擦屁股!!

  9. 新建MMS草稿保存后,再进入草稿修改收件人,退出到会话界面,会显示两条草稿

    分析原因:新建彩信草稿,保存后,再打开草稿,修改收件人,再保存会产生新的threadId, 而之前保存的草稿theadId还存在,导致此问题. (必现. 解决方法:将原来的Thread_id和新的收件 ...

  10. jsp 和jspf

    http://www.cnblogs.com/liaojie970/p/5035077.html