react day.js使用及经典场景

发布于:2025-06-23 ⋅ 阅读:(15) ⋅ 点赞:(0)

简介

Day.js 是一个轻量级的 JavaScript 日期库,它提供了简单易用的 API 来处理日期和时间。以及更加轻量级,并且具有更快的性能。

安装

npm install dayjs

使用

import dayjs from "dayjs";

dayjs().format("YYYY-MM-DD HH:mm:ss");

经典场景

1. 获取当前时间

dayjs().format("YYYY-MM-DD HH:mm:ss");

2. 格式化时间

dayjs("2021-01-01").format("YYYY-MM-DD HH:mm:ss");

3. 解析时间

dayjs("2021-01-01 12:00:00", "YYYY-MM-DD HH:mm:ss");

4. 时间加减

dayjs().add(1, "day").format("YYYY-MM-DD HH:mm:ss");
dayjs().subtract(1, "day").format("YYYY-MM-DD HH:mm:ss");

5. 时间比较

dayjs("2021-01-01").isBefore("2021-01-02");
dayjs("2021-01-01").isAfter("2021-01-02");
dayjs("2021-01-01").isSame("2021-01-01");

6. 获取时间差

dayjs("2021-01-01").diff("2021-01-02", "day");
类型 说明
year
quarter 季度
month
week
day
hour 小时
minute 分钟
second
millisecond 毫秒

diff 默认返回是整数,如果需要返回小数,可以传入第三个参数:true|false。

7. 快速获取常用日期

# 前一天
dayjs().subtract(1, "day").format("YYYY-MM-DD HH:mm:ss");
# 后一天
dayjs().add(1, "day").format("YYYY-MM-DD HH:mm:ss");
# 前一周
dayjs().subtract(1, "week").format("YYYY-MM-DD HH:mm:ss");
# 后一周
dayjs().add(1, "week").format("YYYY-MM-DD HH:mm:ss");
# 前一月
dayjs().subtract(1, "month").format("YYYY-MM-DD HH:mm:ss");
# 后一月
dayjs().add(1, "month").format("YYYY-MM-DD HH:mm:ss");
# 前一季
dayjs().subtract(1, "quarter").format("YYYY-MM-DD HH:mm:ss");
# 后一季
dayjs().add(1, "quarter").format("YYYY-MM-DD HH:mm:ss");
# 前一年
dayjs().subtract(1, "year").format("YYYY-MM-DD HH:mm:ss");
# 后一年
dayjs().add(1, "year").format("YYYY-MM-DD HH:mm:ss");

8. 日期范围

import dayjs from "dayjs";
import isBetween from "dayjs/plugin/isBetween";

dayjs.extend(isBetween);

// 是否属于某个范围
dayjs("2021-01-01").isBetween("2021-01-01", "2021-01-02");
// 是否属于某个范围(包含边界)
// [ 包含开始日期,包含结束日期 ]
// ( 不包含开始日期,不包含结束日期 )
dayjs("2021-01-01").isBetween("2021-01-01", "2021-01-02", "day", "[)");

9. 倒计时实现

import { useState, useEffect, useCallback, useRef } from "react";
import dayjs from "dayjs";
import duration from "dayjs/plugin/duration";

dayjs.extend(duration);

/**
 * 倒计时 Hook
 * @param {number} targetTime - 目标时间戳(毫秒)
 * @param {number} interval - 更新间隔(毫秒),默认 1000ms
 * @returns {Object} 倒计时状态
 * @returns {number} remainingTime - 剩余时间(毫秒)
 * @returns {boolean} isFinished - 是否结束
 * @returns {Object} formattedTime - 格式化后的时间对象
 * @returns {Function} reset - 重置倒计时
 */
export default function useCountdown(targetTime, interval = 1000) {
  const [remainingTime, setRemainingTime] = useState(0);
  const [isFinished, setIsFinished] = useState(false);
  const targetTimeRef = useRef(targetTime);

  // 计算剩余时间
  const calculateRemainingTime = useCallback(() => {
    const now = dayjs();
    const target = dayjs(targetTimeRef.current);
    const diff = target.diff(now);

    if (diff <= 0) {
      setRemainingTime(0);
      setIsFinished(true);
      return;
    }

    setRemainingTime(diff);
    setIsFinished(false);
  }, []);

  // 格式化时间
  const formatTime = useCallback((time) => {
    const duration = dayjs.duration(time);
    return {
      days: Math.floor(duration.asDays()),
      hours: duration.hours(),
      minutes: duration.minutes(),
      seconds: duration.seconds(),
      milliseconds: duration.milliseconds(),
    };
  }, []);

  // 重置倒计时
  const reset = useCallback(() => {
    // 更新目标时间引用
    targetTimeRef.current = dayjs().add(24, "hour").valueOf();
    setIsFinished(false);
    calculateRemainingTime();
  }, [calculateRemainingTime]);

  useEffect(() => {
    // 初始化目标时间
    targetTimeRef.current = targetTime;

    // 初始化
    calculateRemainingTime();

    // 设置定时器
    const timer = setInterval(() => {
      calculateRemainingTime();
    }, interval);

    // 清理定时器
    return () => clearInterval(timer);
  }, [calculateRemainingTime, interval, targetTime]);

  return {
    remainingTime,
    isFinished,
    formattedTime: formatTime(remainingTime),
    reset,
  };
}

// hook使用
const { formattedTime, isFinished, reset } = useCountdown(targetTime);

10. 日历组件实现

import { useState, useMemo } from "react";
import dayjs from "dayjs";
import weekOfYear from "dayjs/plugin/weekOfYear";
import isoWeek from "dayjs/plugin/isoWeek";

dayjs.extend(weekOfYear);
dayjs.extend(isoWeek);

export default function Calendar() {
  const [currentDate, setCurrentDate] = useState(dayjs());
  const [selectedDate, setSelectedDate] = useState(dayjs());

  // 生成日历数据
  const calendarData = useMemo(() => {
    const firstDayOfMonth = currentDate.startOf("month");
    const lastDayOfMonth = currentDate.endOf("month");
    const firstDayOfWeek = firstDayOfMonth.day();
    const daysInMonth = lastDayOfMonth.date();
    const daysInPrevMonth = firstDayOfMonth.subtract(1, "month").daysInMonth();

    const days = [];
    // 上个月的天数
    for (let i = firstDayOfWeek - 1; i >= 0; i--) {
      days.push({
        date: firstDayOfMonth.subtract(i + 1, "day"),
        isCurrentMonth: false,
      });
    }
    // 当前月的天数
    for (let i = 1; i <= daysInMonth; i++) {
      days.push({
        date: currentDate.date(i),
        isCurrentMonth: true,
      });
    }
    // 下个月的天数
    const remainingDays = 42 - days.length; // 6行7列
    for (let i = 1; i <= remainingDays; i++) {
      days.push({
        date: lastDayOfMonth.add(i, "day"),
        isCurrentMonth: false,
      });
    }

    return days;
  }, [currentDate]);

  // 切换月份
  const changeMonth = (delta) => {
    setCurrentDate(currentDate.add(delta, "month"));
  };

  // 切换年份
  const changeYear = (delta) => {
    setCurrentDate(currentDate.add(delta, "year"));
  };

  // 判断是否是今天
  const isToday = (date) => {
    return date.isSame(dayjs(), "day");
  };

  // 判断是否是选中日期
  const isSelected = (date) => {
    return date.isSame(selectedDate, "day");
  };

  return (
    <div className="w-full max-w-md mx-auto bg-white rounded-lg shadow-lg p-4">
      {/* 日历头部 */}
      <div className="flex items-center justify-between mb-4">
        <div className="flex items-center space-x-2">
          <button
            onClick={() => changeYear(-1)}
            className="p-2 hover:bg-blue-50 rounded-full transition-colors"
          >
            {"<<"}
          </button>
          <button
            onClick={() => changeMonth(-1)}
            className="p-2 hover:bg-blue-50 rounded-full transition-colors"
          >
            {"<"}
          </button>
        </div>
        <div className="text-lg font-semibold text-blue-600">
          {currentDate.format("YYYY年 MM月")}
        </div>
        <div className="flex items-center space-x-2">
          <button
            onClick={() => changeMonth(1)}
            className="p-2 hover:bg-blue-50 rounded-full transition-colors"
          >
            {">"}
          </button>
          <button
            onClick={() => changeYear(1)}
            className="p-2 hover:bg-blue-50 rounded-full transition-colors"
          >
            {">>"}
          </button>
        </div>
      </div>
      {/* 星期标题 */}
      <div className="grid grid-cols-7 gap-1 mb-2">
        {["日", "一", "二", "三", "四", "五", "六"].map((day) => (
          <div
            key={day}
            className="text-center text-sm font-medium text-blue-600 py-2"
          >
            {day}
          </div>
        ))}
      </div>
      {/* 日历主体 */}
      <div className="grid grid-cols-7 gap-1">
        {calendarData.map(({ date, isCurrentMonth }, index) => (
          <button
            key={index}
            onClick={() => setSelectedDate(date)}
            className={`
              aspect-square p-1 text-sm rounded-lg transition-colors
              ${
                isCurrentMonth
                  ? "hover:bg-blue-50"
                  : "text-gray-400 hover:bg-gray-50"
              }
              ${isToday(date) ? "bg-blue-100" : ""}
              ${
                isSelected(date)
                  ? "bg-blue-500 text-white hover:bg-blue-600"
                  : ""
              }
            `}
          >
            {date.date()}
          </button>
        ))}
      </div>
    </div>
  );
}

11.国际化

import dayjs from "dayjs";
import "dayjs/locale/zh-cn";

dayjs.locale("zh-cn");
dayjs().format("YYYY-MM-DD HH:mm:ss");

 更多用法


网站公告

今日签到

点亮在社区的每一天
去签到