最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于Vue3實(shí)現(xiàn)一個(gè)日期計(jì)算器的操作方案

 更新時(shí)間:2026年01月27日 09:59:48   作者:滕青山  
該文章主要介紹了在線日期計(jì)算器工具的開(kāi)發(fā)過(guò)程,包括核心功能設(shè)計(jì)、實(shí)現(xiàn)細(xì)節(jié)、狀態(tài)管理和日期處理技巧,工具提供了日期間隔計(jì)算、日期加減計(jì)算、年齡計(jì)算和工作日計(jì)算等功能,需要的朋友可以參考下

在線工具網(wǎng)址:https://see-tool.com/date-calculator

工具截圖:

一、核心功能設(shè)計(jì)

日期計(jì)算器包含四個(gè)獨(dú)立模塊:

  1. 日期間隔計(jì)算: 計(jì)算兩個(gè)日期之間的天數(shù)、周數(shù)、月數(shù)、年數(shù)
  2. 日期加減計(jì)算: 在基準(zhǔn)日期上加減指定時(shí)間單位
  3. 年齡計(jì)算: 精確計(jì)算年齡(年/月/日)
  4. 工作日計(jì)算: 統(tǒng)計(jì)工作日、周末天數(shù)

二、日期間隔計(jì)算實(shí)現(xiàn)

2.1 核心計(jì)算邏輯

const dateDiff = computed(() => {
  if (!startDate.value || !endDate.value) {
    return { days: 0, weeks: 0, months: 0, years: 0 }
  }

  const start = new Date(startDate.value)
  const end = new Date(endDate.value)

  // 確保開(kāi)始日期小于結(jié)束日期(自動(dòng)排序)
  const [earlierDate, laterDate] = start <= end ? [start, end] : [end, start]

  let diffTime = laterDate.getTime() - earlierDate.getTime()

  // 如果包含結(jié)束日期,增加一天
  if (includeEndDate.value) {
    diffTime += 24 * 60 * 60 * 1000
  }

  const diffDays = Math.floor(diffTime / (1000 * 60 * 60 * 24))

  // 計(jì)算精確的月數(shù)差異
  let months = (laterDate.getFullYear() - earlierDate.getFullYear()) * 12
  months += laterDate.getMonth() - earlierDate.getMonth()

  // 如果日期不足一個(gè)月,減去一個(gè)月
  if (laterDate.getDate() < earlierDate.getDate()) {
    months--
  }

  // 計(jì)算年數(shù)
  const years = Math.floor(months / 12)

  return {
    days: diffDays,
    weeks: Math.floor(diffDays / 7),
    months: Math.max(0, months),
    years: Math.max(0, years)
  }
})

關(guān)鍵點(diǎn):

  1. 自動(dòng)排序: 無(wú)論用戶輸入順序,自動(dòng)識(shí)別較早和較晚的日期
  2. 包含結(jié)束日期: 可選項(xiàng),影響天數(shù)計(jì)算(+1天)
  3. 精確月數(shù): 考慮日期不足一個(gè)月的情況
  4. 負(fù)數(shù)保護(hù): 使用 Math.max(0, value) 防止負(fù)數(shù)

2.2 輔助工具函數(shù)

// 交換開(kāi)始和結(jié)束日期
const swapDates = () => {
  const temp = startDate.value
  startDate.value = endDate.value
  endDate.value = temp
}

// 設(shè)置結(jié)束日期為今天
const setToday = (type) => {
  if (!process.client) return
  const today = new Date().toISOString().split('T')[0]
  if (type === 'diff') {
    endDate.value = today
  }
}

三、日期加減計(jì)算實(shí)現(xiàn)

3.1 核心計(jì)算邏輯

const calculatedDate = computed(() => {
  if (!baseDate.value) {
    return ''
  }

  if (!amount.value || amount.value === 0) {
    return baseDate.value
  }

  const base = new Date(baseDate.value)
  // 根據(jù)操作類型確定正負(fù)
  const value = operation.value === 'add' ? parseInt(amount.value) : -parseInt(amount.value)

  switch (unit.value) {
    case 'days':
      base.setDate(base.getDate() + value)
      break
    case 'weeks':
      base.setDate(base.getDate() + (value * 7))
      break
    case 'months':
      base.setMonth(base.getMonth() + value)
      break
    case 'years':
      base.setFullYear(base.getFullYear() + value)
      break
  }

  return base.toISOString().split('T')[0]
})

關(guān)鍵點(diǎn):

  1. 操作符處理: 減法通過(guò)負(fù)數(shù)實(shí)現(xiàn),統(tǒng)一使用加法邏輯
  2. 原生 Date API: 利用 setDate/setMonth/setFullYear 自動(dòng)處理溢出
  3. 格式化輸出: toISOString().split('T')[0] 獲取 YYYY-MM-DD 格式

3.2 獲取星期幾

const getWeekday = (dateStr) => {
  if (!dateStr) return ''
  const weekdays = tm('dateCalculator.weekdays')
  if (!weekdays || !Array.isArray(weekdays)) return ''
  const date = new Date(dateStr)
  return weekdays[date.getDay()] || ''
}

說(shuō)明:

  • getDay() 返回 0-6,其中 0 代表周日
  • 從國(guó)際化配置中讀取星期名稱數(shù)組

四、年齡計(jì)算實(shí)現(xiàn)

4.1 精確年齡計(jì)算

const age = computed(() => {
  if (!birthDate.value || !ageCalculateDate.value) {
    return { years: 0, months: 0, days: 0, totalDays: 0 }
  }

  const birth = new Date(birthDate.value)
  const calculate = new Date(ageCalculateDate.value)

  // 如果出生日期晚于計(jì)算日期,返回0
  if (birth > calculate) {
    return { years: 0, months: 0, days: 0, totalDays: 0 }
  }

  // 計(jì)算精確年齡
  let years = calculate.getFullYear() - birth.getFullYear()
  let months = calculate.getMonth() - birth.getMonth()
  let days = calculate.getDate() - birth.getDate()

  // 調(diào)整天數(shù)
  if (days < 0) {
    months--
    // 獲取上個(gè)月的天數(shù)
    const lastMonth = new Date(calculate.getFullYear(), calculate.getMonth(), 0)
    days += lastMonth.getDate()
  }

  // 調(diào)整月數(shù)
  if (months < 0) {
    years--
    months += 12
  }

  // 計(jì)算總天數(shù)
  const totalDays = Math.floor((calculate.getTime() - birth.getTime()) / (1000 * 60 * 60 * 24))

  return {
    years: Math.max(0, years),
    months: Math.max(0, months),
    days: Math.max(0, days),
    totalDays: Math.max(0, totalDays)
  }
})

關(guān)鍵點(diǎn):

  1. 逐級(jí)調(diào)整: 先調(diào)整天數(shù),再調(diào)整月數(shù),最后得到年數(shù)
  2. 借位邏輯: 天數(shù)不足時(shí)從月份借位,月份不足時(shí)從年份借位
  3. 上月天數(shù): 使用 new Date(year, month, 0) 獲取上月最后一天
  4. 總天數(shù): 單獨(dú)計(jì)算,用于顯示"已活xx天"

4.2 派生數(shù)據(jù)計(jì)算

// 模板中使用
Math.floor(age.totalDays / 30.44)  // 總月數(shù)(平均每月30.44天)
Math.floor(age.totalDays / 7)      // 總周數(shù)
age.totalDays                      // 總天數(shù)

五、工作日計(jì)算實(shí)現(xiàn)

5.1 核心計(jì)算邏輯

const workDays = computed(() => {
  if (!workStartDate.value || !workEndDate.value) {
    return { total: 0, weekdays: 0, weekends: 0 }
  }

  const start = new Date(workStartDate.value)
  const end = new Date(workEndDate.value)

  // 確保開(kāi)始日期不大于結(jié)束日期
  if (start > end) {
    return { total: 0, weekdays: 0, weekends: 0 }
  }

  let weekdays = 0
  let weekends = 0
  const current = new Date(start)

  // 包含開(kāi)始和結(jié)束日期
  while (current <= end) {
    const dayOfWeek = current.getDay()
    if (dayOfWeek === 0 || dayOfWeek === 6) { // 周日=0, 周六=6
      weekends++
    } else {
      weekdays++
    }
    current.setDate(current.getDate() + 1)
  }

  return {
    total: weekdays + weekends,
    weekdays: excludeWeekends.value ? weekdays : weekdays + weekends,
    weekends
  }
})

關(guān)鍵點(diǎn):

  1. 逐日遍歷: 從開(kāi)始日期循環(huán)到結(jié)束日期,逐日判斷
  2. 星期判斷: getDay() 返回 0(周日) 或 6(周六) 為周末
  3. 可選排除: 根據(jù) excludeWeekends 決定是否排除周末
  4. 包含邊界: 包含開(kāi)始和結(jié)束日期

六、狀態(tài)管理

6.1 響應(yīng)式狀態(tài)定義

// Tab 切換
const activeTab = ref('difference')

// 日期間隔計(jì)算
const startDate = ref('')
const endDate = ref('')
const includeEndDate = ref(false)

// 日期加減計(jì)算
const baseDate = ref('')
const operation = ref('add')      // 'add' | 'subtract'
const amount = ref(0)
const unit = ref('days')          // 'days' | 'weeks' | 'months' | 'years'

// 工作日計(jì)算
const workStartDate = ref('')
const workEndDate = ref('')
const excludeWeekends = ref(true)

// 年齡計(jì)算
const birthDate = ref('')
const ageCalculateDate = ref('')

6.2 初始化默認(rèn)值

onMounted(() => {
  if (!process.client) return
  const today = new Date().toISOString().split('T')[0]
  startDate.value = today
  endDate.value = today
  baseDate.value = today
  workStartDate.value = today
  workEndDate.value = today
  birthDate.value = ''  // 不設(shè)置默認(rèn)出生日期
  ageCalculateDate.value = today
})

說(shuō)明:

  • 使用 process.client 判斷避免 SSR 問(wèn)題
  • 出生日期不設(shè)默認(rèn)值,避免誤導(dǎo)用戶

七、日期處理技巧

7.1 Date 對(duì)象的自動(dòng)溢出處理

// JavaScript 的 Date 會(huì)自動(dòng)處理溢出
const date = new Date('2024-01-31')
date.setMonth(date.getMonth() + 1)  // 自動(dòng)變?yōu)?2024-03-02(2月沒(méi)有31日)

7.2 獲取上月最后一天

// 將日期設(shè)為0,會(huì)自動(dòng)回退到上月最后一天
const lastDayOfLastMonth = new Date(year, month, 0)

7.3 日期格式化

// ISO 格式轉(zhuǎn) YYYY-MM-DD
const dateStr = new Date().toISOString().split('T')[0]

八、核心算法總結(jié)

日期間隔計(jì)算:
  時(shí)間戳相減 → 轉(zhuǎn)換為天數(shù)
  年月日逐級(jí)計(jì)算 → 處理借位

日期加減計(jì)算:
  原生 Date API → 自動(dòng)處理溢出

年齡計(jì)算:
  年月日分別相減 → 逐級(jí)調(diào)整借位

工作日計(jì)算:
  逐日遍歷 → 判斷星期幾 → 統(tǒng)計(jì)分類

核心原則:

  1. 利用原生 API: Date 對(duì)象的自動(dòng)溢出處理
  2. 邊界處理: 防止負(fù)數(shù)、空值、非法日期
  3. 精確計(jì)算: 考慮月份天數(shù)差異、閏年等特殊情況
  4. 用戶友好: 自動(dòng)排序、可選配置、實(shí)時(shí)計(jì)算

以上就是基于Vue3實(shí)現(xiàn)一個(gè)日期計(jì)算器的操作方案的詳細(xì)內(nèi)容,更多關(guān)于Vue3日期計(jì)算器的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • vue如何使用cookie、localStorage和sessionStorage進(jìn)行儲(chǔ)存數(shù)據(jù)

    vue如何使用cookie、localStorage和sessionStorage進(jìn)行儲(chǔ)存數(shù)據(jù)

    這篇文章主要介紹了vue如何使用cookie、localStorage和sessionStorage進(jìn)行儲(chǔ)存數(shù)據(jù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • vue中的循環(huán)遍歷對(duì)象、數(shù)組和字符串

    vue中的循環(huán)遍歷對(duì)象、數(shù)組和字符串

    這篇文章主要介紹了vue中的循環(huán)遍歷對(duì)象、數(shù)組和字符串,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • 在Vue3中實(shí)現(xiàn)拖拽文件上傳功能的過(guò)程詳解

    在Vue3中實(shí)現(xiàn)拖拽文件上傳功能的過(guò)程詳解

    文件上傳是我們?cè)陂_(kāi)發(fā)Web應(yīng)用時(shí)經(jīng)常遇到的功能之一,為了提升用戶體驗(yàn),我們可以利用HTML5的拖放API來(lái)實(shí)現(xiàn)拖拽文件上傳的功能,本文將介紹如何在Vue3中實(shí)現(xiàn)這一功能,文中有詳細(xì)的代碼示例供大家參考,需要的朋友可以參考下
    2023-12-12
  • vue項(xiàng)目運(yùn)行時(shí)出現(xiàn)It works的問(wèn)題解決

    vue項(xiàng)目運(yùn)行時(shí)出現(xiàn)It works的問(wèn)題解決

    本文主要介紹了vue項(xiàng)目運(yùn)行時(shí)出現(xiàn)It works的問(wèn)題解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • vue使用反向代理解決跨域問(wèn)題方案

    vue使用反向代理解決跨域問(wèn)題方案

    這篇文章主要為大家介紹了vue使用反向代理解決跨域問(wèn)題方案詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • VUE自動(dòng)化部署全過(guò)程

    VUE自動(dòng)化部署全過(guò)程

    本文介紹了使用scp2庫(kù)將構(gòu)建后的文件上傳到生產(chǎn)或測(cè)試環(huán)境的方案,包括安裝scp2、編寫環(huán)境腳本、忽略腳本、添加npm腳本命令及執(zhí)行步驟,該方法簡(jiǎn)便但不夠安全,適合快速部署
    2025-11-11
  • Vue中ref和$refs的介紹以及使用方法示例

    Vue中ref和$refs的介紹以及使用方法示例

    這篇文章主要給大家介紹了關(guān)于Vue中ref和$refs使用方法的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • vue如何通過(guò)src引用assets中的圖片

    vue如何通過(guò)src引用assets中的圖片

    這篇文章主要介紹了vue如何通過(guò)src引用assets中的圖片,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • ElementUI中el-table表格組件如何自定義表頭

    ElementUI中el-table表格組件如何自定義表頭

    最近需要做一個(gè)el-table的表格,表頭需要顯示提示信息,本文主要介紹了ElementUI中el-table表格組件如何自定義表頭,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-09-09
  • vue3標(biāo)簽中的ref屬性詳解及如何使用$refs獲取元素

    vue3標(biāo)簽中的ref屬性詳解及如何使用$refs獲取元素

    這篇文章主要給大家介紹了關(guān)于vue3標(biāo)簽中的ref屬性詳解及如何使用$refs獲取元素的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2024-11-11

最新評(píng)論

兴山县| 全州县| 隆林| 扎鲁特旗| 德兴市| 开鲁县| 镇巴县| 淮北市| 呼玛县| 边坝县| 北碚区| 黄骅市| 象州县| 习水县| 托克逊县| 奎屯市| 无棣县| 思茅市| 资兴市| 南京市| 莫力| 汝南县| 桑植县| 施甸县| 桃园县| 东乡| 遂川县| 喀喇沁旗| 浑源县| 旬阳县| 昌宁县| 大悟县| 雷州市| 汉沽区| 陇川县| 乌鲁木齐县| 屯留县| 大埔县| 定襄县| 桂林市| 西盟|