Skip to content

표시 타임존 (Display Timezone)

ScheduleCalendar는 기본적으로 브라우저의 시스템 타임존 기준으로 날짜/시간을 표시합니다. displayTimezone prop을 지정하면 브라우저 로컬 타임존과 무관하게 특정 IANA 타임존 기준으로 Month/Week/Day/List 뷰를 렌더링할 수 있습니다 — 예를 들어 서울에 있는 관리자가 뉴욕 지사 팀의 일정을 뉴욕 시각 기준으로 확인하는 시나리오입니다.

zero-dependency 유지

luxon/date-fns-tz 같은 외부 라이브러리 없이 브라우저·Node에 내장된 Intl.DateTimeFormat만으로 구현했습니다.

v1 범위

항목v1비고
데이터 모델Schedule은 그대로 UTC 인스턴트(Date) — 신규 필드 없음일정별 원본 타임존(Schedule.timezone)은 이후 검토
방향읽기/렌더링만 (날짜 배치·시간 위치·"오늘" 판정)일정 생성(드래그 슬롯 선택)·드래그 이동/리사이즈는 계속 브라우저 로컬 기준
적용 뷰Month / Week / Day / List@vuepkg/calendar/timeline(Timeline 가이드)은 별도 서브패스라 범위 밖

v1에서 아직 안 되는 것: displayTimezone을 지정한 상태에서 시간 슬롯을 드래그해 새 일정을 만들거나 기존 일정을 드래그로 이동/리사이즈하면, 생성/이동되는 시각은 여전히 브라우저 로컬 타임존 기준으로 계산됩니다. 화면에 보이는 날짜/시간 배치(읽기)와 실제로 새로 만들어지는 일정의 시각(쓰기)이 다를 수 있다는 뜻입니다 — 이 갭은 v1.1에서 다룰 예정입니다.

기본 사용

vue
<script setup lang="ts">
import { ref } from 'vue'
import { ScheduleCalendar, useScheduleCalendarHost } from '@vuepkg/calendar'
import type { Schedule } from '@vuepkg/calendar'

const schedules = ref<Schedule[]>([
  {
    id: '1',
    title: 'New York 팀 스탠드업',
    type: 'team_schedule',
    // UTC 인스턴트 — displayTimezone 지정 시 그 타임존 기준 벽시계 시각으로 표시됩니다.
    start: new Date('2026-05-20T13:00:00Z'),
    end: new Date('2026-05-20T13:30:00Z'),
  },
])

const { view, date, calendarListeners } = useScheduleCalendarHost({
  initialDate: new Date(2026, 4, 20),
})
</script>

<template>
  <ScheduleCalendar
    v-model:view="view"
    v-model:date="date"
    :schedules="schedules"
    display-timezone="America/New_York"
    v-on="calendarListeners"
  />
</template>

display-timezone="America/New_York"을 지정하면 위 일정은 (UTC 13:00 → EDT 09:00) 아침 9시 일정으로 표시됩니다. prop을 생략하면 브라우저 시스템 타임존을 그대로 사용하는 기존 동작과 100% 동일합니다.

잘못된 타임존 이름

Intl.DateTimeFormat이 인식하지 못하는 값(예: 오타)을 넘기면 개발 모드 콘솔에 경고를 출력하고 브라우저 로컬 타임존으로 자동 폴백합니다 — 프로덕션 빌드에서 화면이 깨지지 않습니다.

ts
displayTimezone: 'Aisa/Seoul' // 오타
// → [ScheduleCalendar] displayTimezone "Aisa/Seoul"은(는) 유효한 IANA 타임존 이름이 아닙니다. 브라우저 로컬 타임존으로 대체합니다.

SSR과의 관계

SSR/Nuxt 검증(examples/nuxt-demo) 과정에서 확인된 것처럼, 서버와 클라이언트의 시스템 타임존이 다르면 new Date() 기준 "오늘" 판정이 hydration mismatch를 일으킬 수 있습니다. displayTimezone을 명시하면 서버·클라이언트가 항상 같은 타임존으로 날짜를 계산하므로 이 문제가 실질적으로 해소됩니다 — Nuxt 등 SSR 환경에서 캘린더를 쓴다면 displayTimezone을 명시적으로 지정하는 걸 권장합니다.

Headless 사용

useCalendar도 동일한 displayTimezone 옵션을 받습니다:

ts
import { useCalendar } from '@vuepkg/calendar/headless'

const calendar = useCalendar({
  schedules,
  displayTimezone: 'America/New_York',
})

Released under the MIT License.