日历

import dayjs from 'dayjs';

export type DayItem = {
  weekDay: number;
  fullDate: string | null;
  dateDay: number | null;
};

export type flatCalendar = Array<DayItem>;
export type Calendar = Array<Array<DayItem>>;

export function getCalendar(dateYearMonth?: string): {
  flatCalendar: flatCalendar;
  calendar: Calendar;
  fullYearMonth: string;
  fullYearString: string;
  fullYear: number;
  month: number;
  monthString: string;
} {
  let curDate: any = null;
  if (dateYearMonth) {
    const [year, month] = dateYearMonth.split('-');
    curDate = new Date(Number(year), Number(month) - 1, 1);
  } else {
    dateYearMonth = getCurrentMonth();
    curDate = new Date();
  }
  const calendar: DayItem[][] = [];
  const curMonth = curDate.getMonth();
  const fullMonth = curMonth < 9 ? `0${curMonth + 1}` : `${curMonth + 1}`;
  const fullYear = curDate.getFullYear();
  const fullYearMonth = `${fullYear}-${fullMonth}`;
  // 设置每月1号;
  curDate.setDate(1);
  const firstMonthOfDayWeekDay = curDate.getDay();
  let colIndex = 0;
  if (firstMonthOfDayWeekDay !== 0) {
    // 输出1号前面空白的星期
    for (let i = 0; i < firstMonthOfDayWeekDay; i++) {
      if (!calendar[colIndex]) {
        calendar[colIndex] = [];
      }
      calendar[colIndex].push({
        weekDay: i,
        fullDate: null,
        dateDay: null,
      });
    }
  }

  while (curDate.getMonth() === curMonth) {
    const weekDay = curDate.getDay();
    const dateDay = curDate.getDate();

    if (weekDay === 0) {
      // 星期天时换行
      colIndex += 1;
    }
    if (!calendar[colIndex]) {
      calendar[colIndex] = [];
    }
    calendar[colIndex].push({
      weekDay,
      fullDate: `${dateYearMonth}-${dateDay < 10 ? '0' + dateDay : dateDay}`,
      dateDay,
    });

    curDate.setDate(dateDay + 1);
  }

  if (calendar[colIndex].length !== 7) {
    for (let j = curDate.getDay(); j <= 6; j++) {
      calendar[colIndex].push({
        weekDay: j,
        fullDate: null,
        dateDay: null,
      });
    }
  }

  return {
    flatCalendar: calendar.flat(),
    calendar,
    fullYearMonth,
    fullYear,
    fullYearString: fullYear.toString(),
    month: curMonth + 1,
    monthString: fullMonth,
  };
}

function getCurrentMonth() {
  return dayjs().format('YYYY-MM');
}

组件:

import {View, Text, StyleSheet} from 'react-native';
import React, {useEffect, useState} from 'react';
import type {flatCalendar} from '@/utils/calendar';
import {getCalendar} from '@/utils/calendar';

export default function Calendar() {
  const [calendar, setCalendar] = useState<flatCalendar>([]);

  useEffect(() => {
    const data = getCalendar();
    setCalendar(data.flatCalendar);
  }, []);

  return (
    <View>
      <View style={styles.container}>
        {calendar.map(item => (
          <View style={styles.item}>
            <Text style={styles.itemText} key={item.fullDate}>
              {item.dateDay}
            </Text>
          </View>
        ))}
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flexDirection: 'row',
    flexWrap: 'wrap',
    justifyContent: 'space-around',
    alignItems: 'center',
  },
  item: {
    width: '13.2%',
    margin: '0.5%',
  },
  itemText: {
    textAlign: 'center',
    backgroundColor: '#ccc',
  },
});
Contributors: masecho