日期相关的小函数汇总

在写日历组件和旅行相关频道开发的过程中,很多需要地方需要和日期对象打交道。拿京东旅游首页来说, 左上角的搜索框就包含了许多日期相关的交互逻辑,它包含了机票,酒店,度假等,这些都含有出发日期,到达日期等。

里面还包含了一个日期组件,在用户选择完出发日期后,会自动把到达日期定位在出发日期的下一天。


又如机票低价日历


还有度假的这种特殊日历

 

以下是经常需要用到日期相关小函数


一、 判断闰年
这个函数在日历组件是必须要的,闰年的2月是29天,非闰年是28天

1
2
3
4
5
6
7
8
9
10
/*
 * 判断闰年
 * @param  {Number} 年
 * @return {Blooean}
 */
function isLeapYear(year) {
    return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)
}
isLeapYear(2015) // false
isLeapYear(2016) // true

  

二、补齐月,日数字位数

通过Date对下的getMonth,getDate返回的数字如果是10以下的需要在前面补齐一个0。这里需要注意的是getMonth返回的月份是从0开始的,即0代表1月份,1代表2月份,依次类推。

1
2
3
4
5
6
7
8
9
10
11
12
/*
 * 补齐月,日数字位数
 * @param {number|string} n 需要补齐的数字
 * @return {string} 补齐两位后的字符
 */
function getTwoBit(n) {
    return (n > 9 ? '' : '0') + n
}
getTwoBit(3)  // '03'
getTwoBit(9)  // '09'
getTwoBit(10) // '10'
getTwoBit(11) // '11'

  

三、Date对象转成日期格式字符串

有两种格式"2015-01-22" 和 "2015/01/23"

1
2
3
4
5
6
7
8
9
10
11
12
13
/*
 * 日期对象转成字符串
 * @param  {Date} new Date()
 * @split  {String} "-" 或 "/"
 * @return {String} "2014-12-31"
 */
function date2Str(date, split) {
    split = split || '-'
    var y = date.getFullYear()
    var m = getTwoBit(date.getMonth() + 1)
    var d = getTwoBit(date.getDate())
    return [y, m, d].join(split)   
}

 

四、日期格式字符串转成Date对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*
 * 日期字符串转成Date对象
 * @param {String} str
 *   "2014-12-31"
 *   "2014/12/31"
 * @return {Date}
 */
function str2Date(str) {
    var reDate = /^\d{4}\-\d{1,2}\-\d{1,2}/
    if (reDate.test(str)) {
        str = str.replace(/-/g, '/')
    }
    return new Date(str)
}

这里需要注意下,不能直接 new Date('2014-12-31'),横线间隔的日期格式字符串作为参数传给Date构造器不是所有浏览器都支持

 

五、根据数字返回特定的天

比如旅行频道出发日期一般是第二天(明天),返程日期是第三天(后天)

这个函数根据数字返回特定的日期字符串

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*
 * 返回日期格式字符串
 * @param {Number} 0返回今天的日期、1返回明天的日期,2返回后天得日期,依次类推
 * @return {string} '2014-12-31'
 */
function getSpecDay(i) {
    i = i || 0
    var date = new Date
    var diff = i * (1000 * 60 * 60 * 24)
    date = new Date(date.getTime() + diff)
    return date2Str(date)
}
getSpecDay(0) // 2014-12-31
getSpecDay(1) // 2015-01-01

  

六、根据Date对象获取星期

有的需求要显示的是 “周三”,有的则是 “星期三”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*
 * 根据Date对象获取周几
 * @param date {Date|String} 如 '2014-12-22'
 * @param isFormal {Boolean}
 * @return '周一' 或 '星期一'
 */
function getWeekByDate(date, isFormal) {
    var obj = null
    var weekArr1 = ['周日','周一','周二','周三','周四','周五','周六']
    var weekArr2 = ['星期日', '星期一','星期二','星期三','星期四','星期五','星期六']
    if (typeof date == 'string') {
        obj = str2Date(date)
    } else if (date instanceof Date) {
        obj = date
    }
    var num = obj.getDay()
    return isFormal ? weekArr2[num] : weekArr1[num]
}

 

七、根据年获取生肖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*
 * 根据年获取生肖
 *
 * **参数**
 *  year {number} 年
 *
 * **示例**
 *  getAnimal(1980) // "猴"
 *  getAnimal(1981) // "鸡"
 *  getAnimal(2013) // "蛇"
 */
function getAnimal(year) {
    var animals = ['鼠', '牛', '虎', '兔', '龙', '蛇', '马', '羊', '猴', '鸡', '狗', '猪'];
    var i = (year - 4) % 12;
    return animals[i];
}

 

八、根据年月返回该月的两个节气,一个公历月有两个节气

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/*
 * 根据年月返回该月的两个节气,一个公历月有两个节气
 *
 * **节气算法**
 *  http://ershisijieqi.baike.com/article-284624.html
 *  http://www.azg168.com/huangli/24sijieqi/28337.html
 *  http://blog.csdn.net/orbit/article/details/7910220
 *
 * **参数**
 *  year  {number} 年
 *  month {number} 月
 *
 * **返回**
 *  object
 *
 * **示例**
 *  getSolarTerm(2016, 4); // {day1: 4, term1: "清明", day2: 19, term2: "谷雨"}
 *
 */
function getSolarTerm(year, month) {
    var solarTerm = [
        "小寒", "大寒",
        "立春", "雨水",
        "惊蛰", "春分",
        "清明", "谷雨",
        "立夏", "小满",
        "芒种", "夏至",
        "小暑", "大暑",
        "立秋", "处暑",
        "白露", "秋分",
        "寒露", "霜降",
        "立冬", "小雪",
        "大雪", "冬至"
    ];
    var termInfo = [
        0, 21208, 42467, 63836, 85337, 107014,
        128867, 150921, 173149, 195551, 218072,
        240693, 263343, 285989, 308563, 331033,
        353350, 375494, 397447, 419210, 440795,
        462224, 483532, 504758
    ];
    // 返回某年的第n个节气为几日(从0小寒起算)
    function computeTermDay(y, n) {
        var d = new Date((31556925974.7 * (y - 1900) + termInfo[n] * 60000) + Date.UTC(1900, 0, 6, 2, 5));
        return d.getUTCDate();
    }
 
    // month 转为 [0-11] 范畴
    month = month - 1;
 
    // 计算节气
    var n1 = month * 2;
    var n2 = month * 2 + 1;
    // day1, day2 为当月的两个节气日
    var day1 = computeTermDay(year, n1);
    var day2 = computeTermDay(year, n2);
    // 当月的两个节气名称
    var term1 = solarTerm[n1];
    var term2 = solarTerm[n2];
 
    // 返回结果
    return {
        day1: day1,
        term1: term1,
        day2: day2,
        term2: term2
    };
}

 

九、获取Y年的清明节是哪一天

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
 * 获取Y年的清明节是哪一天
 
 * **参数**
 *  yare {number} 年
 *
 * **示例**
 *  getQingMing(2015); // 0405
 *  getQingMing(2016); // 0404
 */
function getQingMing(year) {
    // [Y*D+C]-L
    // Y=年数后2位,D=0.2422,L=闰年数,21世纪C=4.81,20世纪=5.59
    var d = 0.2422;
    var c = 4.81;
    var y = (year + '').substr(2);
    var day = parseInt(y*d+c) - parseInt(y/4);
    return day;
}

 

posted on   snandy  阅读(2369)  评论(3编辑  收藏  举报

编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示