带周数和日期范围的日期选择框 级联选择

  /**

   * @Description 带周数和日期范围的日期选择框

   * @Author 彤先森

   */

  import { CascadePicker } from "antd-mobile"

  import { useEffect, useState } from "react";

  import moment from 'moment';

  export default (props: {

    visible?: boolean;

    onClose?: () => void;

    onCancel?: () => void;

    onConfirmed?: (startWeek:string, endWeek:string) => void;

  }) => {

  const { visible, onClose, onCancel, onConfirmed } = props;

  const [options, setOptions] = useState<any>([

    {

      label: moment().subtract(10, 'years').format('YYYY'),

      value: moment().subtract(10, 'years').format('YYYY'),

      children: [],

    },

    {

      label: moment().subtract(9, 'years').format('YYYY'),

      value: moment().subtract(9, 'years').format('YYYY'),

      children: [],

    },

    {

      label: moment().subtract(8, 'years').format('YYYY'),

      value: moment().subtract(8, 'years').format('YYYY'),

      children: [],

    },

    {

      label: moment().subtract(7, 'years').format('YYYY'),

      value: moment().subtract(7, 'years').format('YYYY'),

      children: [],

    },

    {

      label: moment().subtract(6, 'years').format('YYYY'),

      value: moment().subtract(6, 'years').format('YYYY'),

      children: [],

    },

    {

      label: moment().subtract(5, 'years').format('YYYY'),

      value: moment().subtract(5, 'years').format('YYYY'),

      children: [],

    },

    {

      label: moment().subtract(4, 'years').format('YYYY'),

      value: moment().subtract(4, 'years').format('YYYY'),

      children: [],

    },

    {

      label: moment().subtract(3, 'years').format('YYYY'),

      value: moment().subtract(3, 'years').format('YYYY'),

      children: [],

    },

    {

      label: moment().subtract(2, 'years').format('YYYY'),

      value: moment().subtract(2, 'years').format('YYYY'),

      children: [],

    },

    {

      label: moment().subtract(1, 'years').format('YYYY'),

      value: moment().subtract(1, 'years').format('YYYY'),

      children: [],

    },

    {

      label: moment().format('YYYY'),

      value: moment().format('YYYY'),

      children: [],

    },

  ])

  useEffect(() => {

    if(visible) {

      getWeek(options[10].value)

    }

  }, [visible])

  // 传入年份,获取周数和日期范围

  const getWeek = (year:any) => {

    let index:any = ''

    options.map((item:any, key:any) => {

      if(item.value == year) {

        index = key

      }

    })

    // 当前选中年份的周数

    let weekNum:any = 0

    if(index === 10) {

      // 当前选中的年份是本年

      weekNum = getNowWeek().weekNum

    } else {

      weekNum = getNumOfWeeks(year);

    }

    // 当前选中年份的第一个星期日

    let firstSunday = new Date(year, 0, 1);

    let n = 6 - (firstSunday.getDay() + 6) % 7;

    firstSunday.setDate(firstSunday.getDate() + n);

    // 根据年份获取周数及日期范围

    const weekArr:any = []

    for (let i = 1; i <= weekNum; i++) {

      if (i == 1) {

        //计算当前选中年份第一个周一的日期

        let firstMonday = new Date(firstSunday.setDate(firstSunday.getDate() - 6));

        firstSunday.setDate(firstSunday.getDate() + 6);

        let weekStr = '第' + i + '周(' + getNowFormatDate(firstMonday) + '~' + getNowFormatDate(firstSunday) + ')'

        let obj:any = {}

        obj.label = weekStr

        obj.value = weekStr

        weekArr.push(obj)

      } else {

        let weekStr = '第' + i + '周' + getDateRange(firstSunday)

        let obj:any = {}

        obj.label = weekStr

        obj.value = weekStr

        weekArr.push(obj)

      }

    }

    // 设置周数及日期范围

    setOptions((options:any) =>

      options.map((option:any) => {

        if (option.value === year) {

          return {

            ...option,

            children: weekArr

          }

        }

        return option

      })

    )

  }

  // 获取今天所属周数及范围

  const getNowWeek = () => {

    // 获取今天日期

    let date:any = moment().format('YYYY-MM-DD')

    date = new Date(date);

    var date2 = new Date(date.getFullYear(), 0, 1);

    var day1 = date.getDay();

    if (day1 == 0) day1 = 7;

    var day2 = date2.getDay();

    if (day2 == 0) day2 = 7;

    let d = Math.round((date.getTime() - date2.getTime() + (day2 - day1) * (24 * 60 * 60 * 1000)) / 86400000);

   

    // 本年周数:是否第一周

    let weekNum:any = ''

    if((Math.ceil(d / 7) + 1)>52){

      // 当周数大于52则为下一年的第一周

      weekNum = 1

    } else {

      weekNum = (Math.ceil(d / 7) + 1)

    }

    // 本年年份

    let year:any = moment().format('YYYY')

    // 本年的第一个星期日

    let firstSunday = new Date(year, 0, 1);

    let n = 6 - (firstSunday.getDay() + 6) % 7;

    firstSunday.setDate(firstSunday.getDate() + n);

    // 本年周数对应的日期范围

    let weekStr:any = ''

    for (let i = 1; i <= weekNum; i++) {

      if (i == 1) {

        //计算这年第一个周一的日期

        let firstMonday = new Date(firstSunday.setDate(firstSunday.getDate() - 6));

        firstSunday.setDate(firstSunday.getDate() + 6);

        weekStr = '第' + i + '周(' + getNowFormatDate(firstMonday) + '~' + getNowFormatDate(firstSunday) + ')'

      } else {

        weekStr = '第' + i + '周' + getDateRange(firstSunday)

      }

    }

    return {weekNum, weekStr}

  }

  // 根据年份计算总周数

  const getNumOfWeeks = (year:any) => {

    //设置为这一年开始日期

    let startDateOfYear = new Date(year, 0, 1);

    //计算这一年有多少天

    let daysOfYear = ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) ? 366 : 365;

    //366(365)/7=52.2(52.1),所以一般一年有52周余1天或者2天,当这一年有366天时且第一天是周日,那么他的最后一天则是周一,这一年就有54周。

    let weekNum = 53;

    //当年份是闰年且第一天是周日时有54周

    if (startDateOfYear.getDay() == 0 && daysOfYear == 366) {

        weekNum = 54;

    }

    return weekNum;

  }

  // 根据上周日获取这周日的日期范围

  const getDateRange = (lastSunday:any) => {

    if (lastSunday == null || lastSunday == '') {

        return "";

    }

    let beginDate = new Date(lastSunday.setDate(lastSunday.getDate() + 1));

    let endDate = new Date(lastSunday.setDate(lastSunday.getDate() + 6));

    return '(' + getNowFormatDate(beginDate) + '~' + getNowFormatDate(endDate) + ')';

  }

  // 时间转换成字符串

  const getNowFormatDate = (date: any) => {

    let Month = 0;

    let Day = 0;

    let CurrentStr = "";

    // 初始化时间

    Month = date.getMonth() + 1;

    Day = date.getDate();

    if (Month >= 10) {

        CurrentStr += Month + '-'

    } else {

        CurrentStr += "0" + Month + '-'

    }

    if (Day >= 10) {

        CurrentStr += Day

    } else {

        CurrentStr += "0" + Day

    }

    return CurrentStr;

  }

  return (

    <CascadePicker

      title='周'

      options={options}

      visible={visible}

      defaultValue={[moment().format('YYYY'), getNowWeek().weekStr]}

      onClose={() => {

        onClose && onClose()

      }}

      onCancel={() => {

        onCancel && onCancel()

      }}

      onConfirm={val => {

        let startWeek:string = ''

        let endWeek:string = ''

        if(val && val[0] && val[1]) {

          startWeek= val[0] + '-' + val[1].split('(')[1].slice(0,5)

          endWeek = val[0] + '-' + val[1].split('(')[1].slice(6,11)

        }

        onConfirmed && onConfirmed(startWeek, endWeek)

      }}

      onSelect={(val) => {

        val && val[0] && getWeek(val[0])

      }}

    />

  )

  }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值