PHP 提供了很多日期时间函数,可以很方便的操作日期时间。JavaScript 也提供了 Date 对象来操作日期时间,但相比 PHP 来说,还是要麻烦一些,很多功能只能自己编写实现。

下面是我项目中用过的一些操作日期时间的代码片段,这里把它封装成函数,方便我查阅和调用。

获取当前的 UNIX 时间戳

这里的时间戳只精确到秒:

function timestamp() {
  return Math.round(new Date().getTime() / 1000);
}

可以使用 timestamp() 调用,也可以直接把函数中的一行代码拷贝出来使用,返回 Number 类型的时间戳。

如果要获取精确到毫秒的时间戳可以直接使用 new Date().getTime() 获取。

获取本月第一天 00:00 的时间戳

在查询数据库的时候可能会遇到需要查询本月的数据的情况,下面是获取本月第一天00:00 的函数:

function monthFirstDayTimestamp() {
  return Math.round(new Date(
    new Date().getFullYear(),
    new Date().getMonth(),
    1
  ).getTime() / 1000);
}

可以使用 monthFirstDayTimestamp() 调用,返回 Number 类型的时间戳,这里的时间戳也是精确到秒。

获取指定月份第一天 00:00 和 最后一天 23:59:59 的时间戳

数据库如果要查询某个月的数据,就可能会需要用到 第一天 00:00 和最后一天 23:59:59 的时间戳,下面编写一个函数,传入指定的年和月,返回第一天和最后一天 23:59:59 的时间戳:

function monthTimestamp(year, month) {
  const date = new Date();
  date.setFullYear(year);
  date.setMonth(month - 1);
  date.setDate(1);
  date.setHours(0);
  date.setMinutes(0);
  date.setSeconds(0);
  date.setMilliseconds(0);
  const firstDay = date / 1000;
  date.setMonth(month);
  return {firstDay: firstDay, lastDay: date / 1000 - 1};
}

上面的 monthTimestamp 函数的第一个参数是 Number 类型的年,第二个参数是 Number 类型的月,返回一个对象,对象包含 firstDay 第一天 00:00:00 的时间戳和 lastDay 最后一天 23:59:59 的时间戳。

下面在控制台调用输出:

console.log(monthTimestamp(2022, 1));  // 输出 { firstDay: 1640966400, lastDay: 1643644799 }
console.log(monthTimestamp(2022, 2));  // 输出 { firstDay: 1643644800, lastDay: 1646063999 }
console.log(monthTimestamp(2022, 4));  // 输出 { firstDay: 1648742400, lastDay: 1651334399 }
console.log(monthTimestamp(2020, 2));  // 输出 { firstDay: 1580486400, lastDay: 1582991999 }

获取今天 00:00 的时间戳

获取今天 00:00 的时间戳,精确到秒:

function todayTimestamp() {
  const day = new Date();
  day.setHours(0);
  day.setMinutes(0);
  day.setSeconds(0);
  day.setMilliseconds(0);
  return day / 1000;
}

使用 todayTimestamp() 调用,返回 Number 类型的时间戳。

获取今年第一天 00:00 的时间戳

下面获取今年 1 月 1日 00:00 的时间戳:

function thisYearFirstDayTimestamp() {
  const day = new Date();
  day.setMonth(0);
  day.setDate(1);
  day.setHours(0);
  day.setMinutes(0);
  day.setSeconds(0);
  day.setMilliseconds(0);
  return day / 1000;
}

使用 todayTimestamp() 调用,返回 Number 类型的时间戳。

获取指定年份第一天 00:00 和最后一天 23:59:59 的时间戳

下面是获取指定年份第一天 00:00:00 和最后一天 23:59:59 的时间戳的函数,这个函数和上面的月份第一天和最后一天是差不多的:

function yearTimestamp(year) {
  const date = new Date();
  date.setFullYear(year);
  date.setMonth(0);
  date.setDate(1);
  date.setHours(0);
  date.setMinutes(0);
  date.setSeconds(0);
  date.setMilliseconds(0);
  const firstDay = date / 1000;
  date.setFullYear(year + 1);
  return {firstDay: firstDay, lastDay: date / 1000 - 1};
}

传入 Number 类型的年份,返回一个对象,对象包含 firstDay 第一天和 lastDay 最后一天 23:59:59 的时间戳,下面在控制台调用输出:

console.log(yearTimestamp(2020));  // 输出 { firstDay: 1577808000, lastDay: 1609430399 }

UNIX 时间戳格式化

UNIX 时间戳是从 1970 年 1 月 1 日 00:00:00 开始所经过的秒数,数据库一般会把时间存储为数值类型的时间戳,但是页面显示的时候不能直接显示为数字,需要先格式化。

下面是时间戳格式化的函数:

function timestampFormat(format, timestamp) {
  const date = new Date(timestamp * 1000);
  format = format.replace('y', date.getFullYear());
  format = format.replace('m', date.getMonth() + 1);
  format = format.replace('d', date.getDate());
  format = format.replace('h', date.getHours());
  let minute = date.getMinutes();
  if (minute < 10) minute = '0' + minute;
  format = format.replace('i', minute);
  let second = date.getSeconds();
  if (second < 10) second = '0' + second;
  format = format.replace('s', second);
  return format;
}

第一个参数 format 是时间格式,第二个参数 timestamp 是 Number 类型的时间戳,时间戳只需要精确到秒,返回 String 类型的日期时间。

下面调用 timestampFormat 函数格式化时间戳:

// 在控制台输出各种格式的日期时间
console.log(timestampFormat('y-m-d h:i:s', 1662293251));  // 输出 2022-9-4 20:07:31
console.log(timestampFormat('y年m月d日 h:i:s', 1662293251));  // 输出 2022年9月4日 20:07:31
console.log(timestampFormat('y/m/d h:i', 1662293251));  // 输出 2022/9/4 20:07
console.log(timestampFormat('y年m月d日', 1662293251));  // 输出 2022年9月4日
console.log(timestampFormat('h:i:s', 1662293251));  // 输出 20:07:31

如果需要传入精确到毫秒的时间戳,可以把函数里的 * 1000 删除。

日期时间格式转时间戳

一般表单提交的日期都是标准的 String 类型的日期格式,数据库在存储之前就需要把 String 类型的日期转为 Number 类型的时间戳。

下面是日期格式转时间戳函数:

function strDateToTimestamp(strDate) {
  return Date.parse(strDate) / 1000;
}

传入 String 类型的日期,返回 Number 类型的时间戳。

调用和参数格式如下:

// 在控制台输出时间戳
console.log(strDateToTimestamp('2022-9-6 17:30:00'));  // 输出 1662456600
console.log(strDateToTimestamp('2022/9/6 17:30:00'));  // 输出 1662456600
console.log(strDateToTimestamp('2022/9/6'));  // 输出 1662393600
console.log(strDateToTimestamp('2022-9'));  // 输出 1661961600

UNIX 时间戳转日期时间,通过对象返回 Number 类型的年 月 日 时 分 秒

下面把时间戳转换为日期时间,通过对象返回 年 月 日 时 分 秒:

function timestampToDate(timestamp) {
  const date = timestamp !== undefined?new Date(timestamp * 1000):new Date();
  return {
    year: date.getFullYear(),
    month: date.getMonth() + 1,
    date: date.getDate(),
    day: date.getDay(),
    hour: date.getHours(),
    minute: date.getMinutes(),
    second: date.getSeconds()
  }
}

上面的 timestampToDate 函数需要传入一个 Number 类型的时间戳,返回时间戳的日期时间对象,如果省略参数会返回当前时间的日期时间对象。

返回的对象包括 year 年、month 月、date 日、day 星期、hour 小时、minute 分钟、second 秒,下面在控制台调用输出:

console.log(timestampToDate(1663386506));

控制台输出:

{
  year: 2022,
  month: 9,
  date: 17,
  day: 6,
  hour: 11,
  minute: 48,
  second: 26
}

获取指定日期的星期

下面是获取指定日期的星期的函数:

function getDay(strDate) {
  const date = strDate !== undefined?new Date(Date.parse(strDate)):new Date();
  return date.getDay();
}

上面的 getDay 函数需要传入 String 类型的日期格式,返回一个 Number 类型的星期,如果省略参数会返回当天的星期。

在控制台调用输出:

console.log(getDay());  // 调用日期 2022-9-17 输出 6
console.log(getDay('2022-9-1'));  // 输出 4

计算当前时间和未来某个时间的间隔

在某个重要日期到来之前,很多相关的网站为了预热,都会显示一个实时更新的倒计时。下面是卡塔尔世界杯的官网倒计时:

卡塔尔世界杯官网倒计时

倒计时包含天数、小时、分钟。

下面编写一个函数,传入一个未来的时间,返回当前时间和未来时间的间隔,包含天数、小时、分钟、秒:

function futureTimeInterval(futureTime) {
  // 把传入的时间转为时间戳
  futureTime = Date.parse(futureTime) / 1000;
  // 获取当前时间的时间戳
  const currentTime = Math.round(new Date().getTime() / 1000);
  // 如果未来时间小于当前时间就返回 0
  if (futureTime <= currentTime) {
    return {day: 0, hour: 0, minute: 0, second: 0};
  }
  // 计算出剩余天数
  const day = Math.floor((futureTime - currentTime) / 86400);
  // 计算完天数后剩余的秒数
  let timeLeft = (futureTime - currentTime) % 86400;
  // 计算出小时
  const hour = Math.floor(timeLeft / 3600);
  // 计算完小时后剩余的秒数
  timeLeft = timeLeft % 3600;
  // 计算出分钟
  const minute = Math.floor(timeLeft / 60);
  // 计算出秒数
  const second = timeLeft % 60;
  return {day: day, hour: hour, minute: minute, second: second};
}

传入一个 String 类型的日期格式,返回一个对象,对象包含 day 天数、hour 小时、minute 分钟、second 秒。

时间间隔返回的对象如下:

{ 
  day: 23,
  hour: 6,
  minute: 40,
  second: 40
}

下面在控制台输出当前时间和 2022 年 10 月 1 日的时间间隔:

const interval = futureTimeInterval('2022-10-1 00:00:00');
console.log(`距离国庆假期到来还有 ${interval.day} 天 ${interval.hour} 小时 ${interval.minute} 分 ${interval.second} 秒`);

控制台输出:距离国庆假期到来还有 23 天 6 小时 30 分 12 秒

放到定时器里就能实现实时更新。

计算过去的某个时间和当前时间的间隔

在有的网站下方,你可能会看到 本站已运行 xx天xx小时xx分xx秒 的网站运行时间,我的博客也会显示网站运行时间,不过我的只精确到天。

修改一下上面的获取当前时间和未来时间间隔的函数,让它返回过去某个时间和当前时间的间隔:

function pastTimeInterval(pastTime) {
  // 把传入的时间转为时间戳
  pastTime = Date.parse(pastTime) / 1000;
  // 获取当前时间的时间戳
  const currentTime = Math.round(new Date().getTime() / 1000);
  // 如果过去时间大于当前时间就返回 0
  if (pastTime >= currentTime) {
    return {day: 0, hour: 0, minute: 0, second: 0};
  }
  // 计算出剩余天数
  const day = Math.floor((currentTime - pastTime) / 86400);
  // 计算完天数后剩余的秒数
  let timeLeft = (currentTime - pastTime) % 86400;
  // 计算出小时
  const hour = Math.floor(timeLeft / 3600);
  // 计算完小时后剩余的秒数
  timeLeft = timeLeft % 3600;
  // 计算出分钟
  const minute = Math.floor(timeLeft / 60);
  // 计算出秒数
  const second = timeLeft % 60;
  return {day: day, hour: hour, minute: minute, second: second};
}

还是一样的传入一个过去的时间,返回过去时间和当前时间的间隔:

const interval = pastTimeInterval('2017-12-7');
console.log(`本站已运行 ${interval.day} 天 ${interval.hour} 小时 ${interval.minute} 分 ${interval.second} 秒`);

调用时间为 2022 年 9 月 16 日 19:01 ,控制台输出 本站已运行 1744 天 19 小时 2 分 10 秒