简单模拟 - Day of Week

该博客介绍了如何通过编程实现基姆拉尔森计算公式,来确定给定日期所对应的星期。文章提供了C语言的代码示例,解释了如何处理不同月份的日期,并利用公式计算星期几。这种方法适用于1582年10月15日之后的日期。

逻辑很简单就是,输入下面这种格式的日期字符串,输出星期几
样例输入

21 December 2012
5 January 2013

样例输出

Friday
Saturday

两种方法:

  1. 与其他的日期比较
  2. 用伟大的数学家推导的公式

第一种方法就不说了,这里说公式
这是两个公式的百科 蔡勒公式基姆拉尔森计算公式
这个博文说的很清楚 [https://www.cnblogs.com/tgycoder/p/4960487.html]
(https://www.cnblogs.com/tgycoder/p/4960487.html)

因为蔡勒公式只适用于1582年(中国明朝万历十年)10月15日之后的情形,所以我们用基姆拉尔森计算公式

#include <stdio.h>
#include <string.h>

int main(int argc, char const *argv[])
{
    char monthStr[12][10] = {
        "January", "February", "March", "April",
        "May", "June", "July", "August",
        "September", "October", "November", "December"
    };
    char weekStr[7][10] = {
        "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"
    };
    int day, year;
    char month[10];
    int i;
    int w, y, m, d;

    while (scanf("%d%s%d", &day, month, &year) != EOF)
    {
        y = year;
        for (i = 0; i < 12; i++)
        {
            if (strcmp(monthStr[i], month) == 0)
            {
                // 1月按上一年的13月来算
                if (i == 0)
                {
                    m = 13;
                    y--;
                }
                // 2月按上一年的14月来算
                else if (i == 1)
                {
                    m = 14;
                    y--;
                }
                else
                {
                    m = i + 1;
                }
                break;
            }
        }
        d = day;

        // 公式计算
        w = (d + 2 * m + 3 * (m + 1) / 5 + y + y / 4 - y /100 + y / 400) % 7;
        printf("%s\n", weekStr[w]);
    }

    return 0;
}

<template> <view class="calendar-container" style="margin: 20rpx 0; margin-bottom: 0"> <!-- 头部显示 --> <!-- <view class="header"> <text class="year-month">{{ displayYearMonth }}</text> --> <!-- <img class="person-img" style="width: 120rpx" :src="IMG_URL + 'schedulePerson.png'" /> --> <!-- <img width="100%;" style="border-top-left-radius: 32rpx; border-top-right-radius: 32rpx" :src="IMG_URL + 'date-header.png'" /> --> <view class="fr jb ac" style="margin: 0 40rpx"> <view class="fr jb ac"> <!-- 向左箭头上一周 --> <image class="arrow-left" v-if="isShowArrowLeft" style="width: 30rpx; height: 30rpx; margin-right: 10rpx; transform: rotate(180deg)" :src="IMG_URL + 'before_icon.png'" @click="handleArrowLeft" /> <image class="arrow-left" v-if="!isShowArrowLeft" style="width: 30rpx; height: 30rpx; margin-right: 10rpx" :src="IMG_URL + 'after_icon.png'" @click="handleArrowLeft" /> <!-- 中间显示日期 --> <view class="date-change-btn">{{ formattedDate }}</view> <!-- 向右箭头下一周 --> <image class="arrow-right" v-if="isShowArrowRight" style="width: 30rpx; height: 30rpx; margin-left: 10rpx" :src="IMG_URL + 'before_icon.png'" @click="handleArrowRight" /> <image class="arrow-right" v-if="!isShowArrowRight" style="width: 30rpx; height: 30rpx; margin-left: 10rpx; transform: rotate(180deg)" :src="IMG_URL + 'after_icon.png'" @click="handleArrowRight" /> </view> <!-- <view class="fr jb ac" v-if="props.isShow != false"> <view class="date-change-btn"> <image style="width: 40rpx; height: 40rpx; margin-right: 20rpx" :src="IMG_URL + 'filtration.png'" /> </view> </view> --> </view> <!-- 滑动容器 --> <!-- <swiper :current-item-id="currentItemId" @change="onSwiperChange" class="swiper-container" :duration="300"> --> <swiper :current-item-id="currentItemId" @change="throttledSwiperChange" class="swiper-container" :duration="300" :circular="false"> <swiper-item v-for="item in weekArray" :key="item" :item-id="item.toString()" class="swiper-item"> <view class="week-container"> <view v-for="day in weekDateObject.obj[item]" :key="day.date" class="day-item" @tap="selectDay(day)"> <text class="weekday">{{ day.weekday }}</text> <text class="day-number" :class="{ today: day.isToday, current: currentSelected === formatDate1(day.date) }">{{ day.day }}</text> <!-- <view v-if="dataArray?.includes(formatDate1(day.date))" style="background-color: #ffbd27; width: 6rpx; height: 6rpx; border-radius: 999rpx; margin-top: 4rpx"> </view> --> <image v-if="dataArray.includes(formatDate1(day.date))" style="width: 10rpx; height: 10rpx; margin-top: 4rpx" :src="IMG_URL + 'star_a.png'" /> </view> </view> </swiper-item> </swiper> </view> </template> <script setup> import { IMG_URL } from '@/config/base' import { getCalendarStatistics } from '@/request/api/org/course.js' import { addWeeks, eachDayOfInterval, endOfWeek, format, isSameDay, isToday, startOfWeek, subWeeks } from 'date-fns' import { zhCN } from 'date-fns/locale' import { throttle } from 'lodash-es' import { computed, ref, watch } from 'vue' const emit = defineEmits(['date-change']) // 当前基准日期(中间位置) const baseDate = ref(new Date()) const currentItemId = ref('0') const isInitialized = ref(false) // 添加初始化标志 const props = defineProps({ courseId: { type: String, default: '' }, // 兼容c端约课组件 type: { type: Number, default: 1 }, function: { type: Function, default: null }, // 兼容c端约课组件 courseMode: { type: Number, default: null }, //插班补课是否显示筛选 isShow: { type: Boolean, default: true } }) // 预渲染的周数据(前一周/当前周/下一周) const formatDate1 = dateString => { const date = new Date(dateString) const year = date.getFullYear() const month = String(date.getMonth() + 1).padStart(2, '0') const day = String(date.getDate()).padStart(2, '0') return `${year}-${month}-${day}` } const userInfo = uni.getStorageSync('USERINFO') const orgId = computed(() => uni.getStorageSync('orgInfo').orgId || {}) // const weekArray = ref([-4, -3, -2, -1, 0, 1, 2, 3, 4]) const weekArray = ref([-1, 0, 1]) // 只保留前一周/当前周/下一周 const dataArray = ref([]) const weekDateObject = computed(() => { const finallyArray = weekArray.value.map(week => { let curDate if (week < 0) { curDate = subWeeks(baseDate.value, Math.abs(week)) } else if (week == 0) { curDate = baseDate.value } else { curDate = addWeeks(baseDate.value, week) } const start = startOfWeek(curDate, { weekStartsOn: 1 }) const end = endOfWeek(curDate, { weekStartsOn: 1 }) return { [week]: eachDayOfInterval({ start, end }).map(day => ({ date: day, day: format(day, 'd'), // 使用自定义函数截取第二个字符(去掉"周"字) weekday: format(day, 'EEE', { locale: zhCN }).substring(1), isToday: isToday(day), isCurrent: isSameDay(day, new Date()) })) } }) console.log('finallyArray', finallyArray) const obj = {} finallyArray.forEach(item => { obj[Object.keys(item)[0]] = Object.values(item)[0] }) const returnObj = { obj, startTime: formatDate1(obj[weekArray.value[0]][0].date), endTime: formatDate1(obj[weekArray.value[weekArray.value.length - 1]][6].date) } console.log(obj, 'obj') return returnObj }) const getScheduleData = () => { if (!weekDateObject.value) { return } const params = { beginTime: `${weekDateObject.value.startTime} 00:00:00`, endTime: `${weekDateObject.value.endTime} 23:59:59`, orgId: orgId.value, userId: userInfo.userId } if (props.courseId) { params.courseId = props.courseId } // 兼容c端约课组件 if (props.courseMode) { params.courseMode = props.courseMode } let port = getCalendarStatistics // 兼容c端约课组件 if (props.type == 1) { port = getCalendarStatistics } else { port = props.function } console.log(port, 'port') port(params).then(res => { dataArray.value = res.data?.map(v => v.scheduleDate) // console.log(dataArray.value, "dataArray"); }) } watch( () => [weekDateObject.value, props.courseId], () => { getScheduleData() }, { immediate: true, deep: true } ) // 判断上一周是否有课表 const isShowArrowLeft = computed(() => { const prevWeekMonday = format(startOfWeek(subWeeks(baseDate.value, 1), { weekStartsOn: 1 }), 'yyyy-MM-dd') return dataArray.value.includes(prevWeekMonday) }) // 判断下一周是否有课表 const isShowArrowRight = computed(() => { const nextWeekMonday = format(startOfWeek(addWeeks(baseDate.value, 1), { weekStartsOn: 1 }), 'yyyy-MM-dd') return dataArray.value.includes(nextWeekMonday) }) const handleArrowLeft = () => { const { start, end } = getLastWeek() baseDate.value = subWeeks(baseDate.value, 1) emit('date-search', start, end) } const handleArrowRight = () => { const { start, end } = getNextWeek() baseDate.value = addWeeks(baseDate.value, 1) emit('date-search', start, end) } // 新增辅助方法获取日期范围 const getDateRange = date => { const start = format(startOfWeek(date, { weekStartsOn: 1 }), 'yyyy-MM-dd') const end = format(endOfWeek(date, { weekStartsOn: 1 }), 'yyyy-MM-dd') return [start, end] } // 重构 onSwiperChange 方法 // const onSwiperChange = e => { // const curId = Number(e.detail.currentItemId) // currentItemId.value = curId.toString() // // 向左滑动加载前一周 // if (curId === weekArray.value[0]) { // baseDate.value = subWeeks(baseDate.value, 1) // emit('date-search', ...getDateRange(baseDate.value)) // } // // 向右滑动加载下一周 // if (curId === weekArray.value[weekArray.value.length - 1]) { // baseDate.value = addWeeks(baseDate.value, 1) // emit('date-search', ...getDateRange(baseDate.value)) // } // } const onSwiperChange = e => { const curId = Number(e.detail.currentItemId) currentItemId.value = curId.toString() // 如果是初始化阶段,不触发date-search if (!isInitialized.value) { isInitialized.value = true return } // 向左滑动加载前一周 if (curId === weekArray.value[0]) { weekArray.value.unshift(curId - 1) // 限制最大数量(可选) if (weekArray.value.length > 10) weekArray.value.pop() } // 向右滑动加载下一周 else if (curId === weekArray.value[weekArray.value.length - 1]) { weekArray.value.push(curId + 1) // 限制最大数量(可选) if (weekArray.value.length > 10) weekArray.value.shift() } // 触发数据更新 const curDate = addWeeks(baseDate.value, curId) emit('date-search', ...getDateRange(curDate)) } // 创建节流版本 const throttledSwiperChange = throttle(onSwiperChange, 300, { leading: true, trailing: false }) // 向左箭头查询上一周课表列表数据 // 获取上一周的开始和结束时间 const getLastWeek = () => { //时间格式化为YYYY-MM-DD const lastWeek = subWeeks(baseDate.value, 1) const start = format(startOfWeek(lastWeek, { weekStartsOn: 1 }), 'yyyy-MM-dd') const end = format(endOfWeek(lastWeek, { weekStartsOn: 1 }), 'yyyy-MM-dd') return { start, end } } //获取下一周的开始和结束时间 const getNextWeek = () => { const nextWeek = addWeeks(baseDate.value, 1) const start = format(startOfWeek(nextWeek, { weekStartsOn: 1 }), 'yyyy-MM-dd') const end = format(endOfWeek(nextWeek, { weekStartsOn: 1 }), 'yyyy-MM-dd') return { start, end } } // const handleArrowLeft = () => { // // 先获取时间范围(只调用一次) // const newId = Math.min(...weekArray.value) - 1 // weekArray.value.unshift(newId) // currentItemId.value = newId.toString() // // 发送单个请求 // getCalendarStatistics({ // beginTime: `${start} 00:00:00`, // endTime: `${end} 23:59:59`, // orgId: orgId.value, // userId: userInfo.userId // }).then(res => { // formattedDate.value = `${start} - ${end}` // }) // // 触发父组件更新(只需要触发一次) // emit('date-search', start, end) // } // 向右箭头下一周 // const handleArrowRight = () => { // // 先获取时间范围(只调用一次) // const { start, end } = getNextWeek() // //下一周 // baseDate.value = addWeeks(baseDate.value, 1) // // 触发父组件更新(只需要触发一次) // //发送单个请求 // getCalendarStatistics({ // beginTime: `${start} 00:00:00`, // endTime: `${end} 23:59:59`, // orgId: orgId.value, // userId: userInfo.userId // }).then(res => { // formattedDate.value = `${start} - ${end}` // }) // // 触发父组件更新(只需要触发一次) // emit('date-search', start, end) // } const currentSelected = ref(formatDate1(new Date())) // 初始化为字符串格式 // 选择日期 // 修改后的selectDay方法 const selectDay = day => { currentSelected.value = formatDate1(day.date) // 确保存储字符串格式 emit('date-change', currentSelected.value) // 调试日志 console.log('当前选中:', currentSelected.value) console.log('点击日期:', formatDate1(day.date)) } // 格式化日期取当前日期的一周的开始和结束 const formattedDate = computed(() => { const currentWeekIndex = currentItemId.value const currentWeek = weekDateObject.value.obj[currentWeekIndex] if (!currentWeek) return '' const monday = currentWeek[0].date const sunday = currentWeek[6].date // 格式化日期为 "YYYY年MM月DD日" 格式 const formatDate = date => { const year = date.getFullYear() const month = String(date.getMonth() + 1).padStart(2, '0') const day = String(date.getDate()).padStart(2, '0') return `${year}年${month}月${day}日` } // 格式化结束日期为 "MM月DD日" 格式 const formatEndDate = date => { const month = String(date.getMonth() + 1).padStart(2, '0') const day = String(date.getDate()).padStart(2, '0') return `${month}月${day}日` } return `${formatDate(monday)} - ${formatEndDate(sunday)}` }) const formatDate = dateString => { const date = new Date(dateString) return `${date.getFullYear()}年${date.getMonth() + 1}月${date.getDate()}日` // 格式化为 YYYY年MM月 // return `${date.getFullYear()}年${date.getMonth() + 1}月${date.getDate()}日`; // 格式化为 YYYY年MM月DD日 } </script> <style scoped> .calendar-container { position: relative; background: #fff; border-radius: 32rpx; /* box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1); */ } .header { padding: 24rpx; border-bottom: 1rpx solid #eee; } .year-month { font-size: 32rpx; color: #333; font-weight: bold; } .swiper-container { /* padding-top: 90rpx; */ height: 180rpx; } .swiper-item { height: 100%; } .week-container { display: flex; justify-content: space-around; align-items: center; padding: 0 20rpx; gap: 5rpx; height: 100%; } .day-item { display: flex; flex-direction: column; align-items: center; flex: 1; /* 关键修改:等分容器宽度 */ height: 120rpx; border-radius: 16rpx; transition: all 0.2s; font-weight: 500; color: #4a4a4a; } .weekday { font-size: 20rpx; color: #4a4a4a; margin-bottom: 8rpx; } .day-number { font-size: 28rpx; color: #333; padding: 0 10rpx; border-radius: 12rpx; margin-bottom: 10rpx; } /* .current { background: #5e94ff !important; color: #fff !important; border: 1rpx solid #3a6ccc !important; } */ .today { background: #83c3ff; color: #333; } .today { /* background: #83c3ff; */ /* border: 1rpx solid #5e94ff; */ } /* .today .day-number { color: #328add; font-weight: bold; } */ .current { background: #5e94ff !important; color: #fff !important; } .current .weekday, .current .day-number { color: #fff !important; } .date-change-btn { /* position: absolute; top: 10rpx; left: 24rpx; */ /* padding: 0 20rpx; */ font-weight: bold; font-size: 26rpx; color: #000000; line-height: 70rpx; height: 70rpx; /* margin-left: 40rpx; */ /* background: #edf6ff; */ border-radius: 20rpx 20rpx 20rpx 20rpx; } .person-img { position: absolute; right: 60rpx; top: -128rpx; width: 200rpx; } </style>能不能根据已上代码重新写这个组件,样式布局不变,props的条件不变,就是把滑动日历的功能和点击上一周和下一周这两个共嗯那个每一次改变保持同步可以更改const weekArray = ref([-1, 0, 1]) 的初始值,只要滑动和切换保持一致就可以,
最新发布
07-06
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值