fix: 日历月份切换在UTC+8时区跳两个月

toISOString() 使用UTC时间,在UTC+8时区下 new Date(y,m-2,1) 会回退到前一天导致月份-1。
改用本地时间格式化函数 fmtMonth/fmtDate 替代所有 toISOString().slice() 调用。
This commit is contained in:
selfrelease
2026-08-01 14:33:54 +08:00
parent 8faf0d4365
commit e8690d4fbb
+13 -8
View File
@@ -44,15 +44,20 @@ const PRIORITY_DOT: Record<string, string> = {
const WEEKDAYS = ['日', '一', '二', '三', '四', '五', '六']
/** 本地日期格式化为 YYYY-MM-DD,避免 toISOString() 的 UTC 时区偏移 */
const fmtDate = (d: Date) => `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`
/** 本地月份格式化为 YYYY-MM */
const fmtMonth = (d: Date) => `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}`
export default function Calendar() {
const queryClient = useQueryClient()
const [calendarMonth, setCalendarMonth] = useState(new Date().toISOString().slice(0, 7))
const [calendarMonth, setCalendarMonth] = useState(`${new Date().getFullYear()}-${String(new Date().getMonth() + 1).padStart(2, '0')}`)
const [showEventForm, setShowEventForm] = useState(false)
const [selectedDate, setSelectedDate] = useState<string | null>(null)
const [typeFilter, setTypeFilter] = useState<string | null>(null)
const [eventForm, setEventForm] = useState({
title: '',
date: new Date().toISOString().slice(0, 10),
date: `${new Date().getFullYear()}-${String(new Date().getMonth() + 1).padStart(2, '0')}-${String(new Date().getDate()).padStart(2, '0')}`,
type: 'CUSTOM',
priority: 'medium',
location: '',
@@ -81,7 +86,7 @@ export default function Calendar() {
queryClient.invalidateQueries({ queryKey: ['custom-events'] })
queryClient.invalidateQueries({ queryKey: ['calendar'] })
setShowEventForm(false)
setEventForm({ title: '', date: selectedDate || new Date().toISOString().slice(0, 10), type: 'CUSTOM', priority: 'medium', location: '', description: '' })
setEventForm({ title: '', date: selectedDate || fmtDate(new Date()), type: 'CUSTOM', priority: 'medium', location: '', description: '' })
toast.success('事件已创建')
},
onError: () => toast.error('创建事件失败'),
@@ -102,7 +107,7 @@ export default function Calendar() {
const lastDay = new Date(year, mon, 0)
const startWeekday = firstDay.getDay()
const daysInMonth = lastDay.getDate()
const todayStr = new Date().toISOString().slice(0, 10)
const todayStr = fmtDate(new Date())
const cells: Array<{ day: number | null; date: string | null; events: any[]; isToday: boolean }> = []
for (let i = 0; i < startWeekday; i++) cells.push({ day: null, date: null, events: [], isToday: false })
for (let d = 1; d <= daysInMonth; d++) {
@@ -131,14 +136,14 @@ export default function Calendar() {
const prevMonth = () => {
const [y, m] = calendarMonth.split('-').map(Number)
const d = new Date(y, m - 2, 1)
setCalendarMonth(d.toISOString().slice(0, 7))
setCalendarMonth(fmtMonth(d))
}
const nextMonth = () => {
const [y, m] = calendarMonth.split('-').map(Number)
const d = new Date(y, m, 1)
setCalendarMonth(d.toISOString().slice(0, 7))
setCalendarMonth(fmtMonth(d))
}
const goToday = () => setCalendarMonth(new Date().toISOString().slice(0, 7))
const goToday = () => setCalendarMonth(fmtMonth(new Date()))
const handleDayClick = (date: string | null) => {
if (!date) return
@@ -183,7 +188,7 @@ export default function Calendar() {
<ChevronRight className="w-4 h-4" />
</Button>
<Button variant="secondary" size="sm" onClick={goToday}></Button>
<Button size="sm" onClick={() => { setEventForm({ ...eventForm, date: new Date().toISOString().slice(0, 10) }); setShowEventForm(true) }}>
<Button size="sm" onClick={() => { setEventForm({ ...eventForm, date: fmtDate(new Date()) }); setShowEventForm(true) }}>
<Plus className="w-4 h-4 mr-1" />
</Button>
</div>