support calendar display type (Gregorian and Buddhist)

This commit is contained in:
MaysWind
2025-08-28 00:31:59 +08:00
parent c099443783
commit 411130db4e
47 changed files with 769 additions and 788 deletions
+2 -12
View File
@@ -1,10 +1,9 @@
import { ref, computed } from 'vue';
import { type TimeRangeAndDateType, type PresetDateRange, type UnixTimeRange, type WeekDayValue, DateRange } from '@/core/datetime.ts';
import { arrangeArrayWithNewStartIndex } from '@/lib/common.ts';
import {
getCurrentUnixTime,
getAllowedYearRange,
getLocalDatetimeFromUnixTime,
getUnixTimeFromLocalDatetime,
getTodayFirstUnixTime,
@@ -46,21 +45,16 @@ function getDateRangeFromProps(props: CommonDateRangeSelectionProps): { minDate:
}
export function useDateRangeSelectionBase(props: CommonDateRangeSelectionProps) {
const { tt, getAllMinWeekdayNames, formatUnixTimeToLongDateTime, isLongDateMonthAfterYear, isLongTime24HourFormat } = useI18n();
const { tt, formatUnixTimeToLongDateTime } = useI18n();
const userStore = useUserStore();
const { minDate, maxDate } = getDateRangeFromProps(props);
const yearRange = ref<number[]>(getAllowedYearRange());
const dateRange = ref<Date[]>([
getLocalDatetimeFromUnixTime(getDummyUnixTimeForLocalUsage(minDate, getTimezoneOffsetMinutes(), getBrowserTimezoneOffsetMinutes())),
getLocalDatetimeFromUnixTime(getDummyUnixTimeForLocalUsage(maxDate, getTimezoneOffsetMinutes(), getBrowserTimezoneOffsetMinutes()))
]);
const firstDayOfWeek = computed<WeekDayValue>(() => userStore.currentUserFirstDayOfWeek);
const dayNames = computed<string[]>(() => arrangeArrayWithNewStartIndex(getAllMinWeekdayNames(), firstDayOfWeek.value));
const isYearFirst = computed<boolean>(() => isLongDateMonthAfterYear());
const is24Hour = computed<boolean>(() => isLongTime24HourFormat());
const beginDateTime = computed<string>(() => {
const actualBeginUnixTime = getActualUnixTimeForStore(getUnixTimeFromLocalDatetime(dateRange.value[0]), getTimezoneOffsetMinutes(), getBrowserTimezoneOffsetMinutes());
return formatUnixTimeToLongDateTime(actualBeginUnixTime);
@@ -123,12 +117,8 @@ export function useDateRangeSelectionBase(props: CommonDateRangeSelectionProps)
return {
// states
yearRange,
dateRange,
// computed states
dayNames,
isYearFirst,
is24Hour,
beginDateTime,
endDateTime,
presetRanges,
@@ -2,12 +2,7 @@ import { ref, computed } from 'vue';
import { useI18n } from '@/locales/helpers.ts';
import { useUserStore } from '@/stores/user.ts';
import { type NameValue } from '@/core/base.ts';
import { type WeekDayValue } from '@/core/datetime.ts';
import { arrangeArrayWithNewStartIndex } from '@/lib/common.ts';
import { getAllowedYearRange } from '@/lib/datetime.ts';
export interface TimePickerValue {
value: string;
@@ -16,9 +11,7 @@ export interface TimePickerValue {
export function useDateTimeSelectionBase() {
const {
getAllMinWeekdayNames,
getAllMeridiemIndicators,
isLongDateMonthAfterYear,
isLongTime24HourFormat,
isLongTimeMeridiemIndicatorFirst,
isLongTimeHourTwoDigits,
@@ -26,22 +19,14 @@ export function useDateTimeSelectionBase() {
isLongTimeSecondTwoDigits
} = useI18n();
const userStore = useUserStore();
const is24Hour = ref<boolean>(isLongTime24HourFormat());
const isHourTwoDigits = ref<boolean>(isLongTimeHourTwoDigits());
const isMinuteTwoDigits = ref<boolean>(isLongTimeMinuteTwoDigits());
const isSecondTwoDigits = ref<boolean>(isLongTimeSecondTwoDigits());
const isMeridiemIndicatorFirst = ref<boolean>(isLongTimeMeridiemIndicatorFirst() || false);
const yearRange = ref<number[]>(getAllowedYearRange());
const meridiemItems = computed<NameValue[]>(() => getAllMeridiemIndicators());
const firstDayOfWeek = computed<WeekDayValue>(() => userStore.currentUserFirstDayOfWeek);
const dayNames = computed<string[]>(() => arrangeArrayWithNewStartIndex(getAllMinWeekdayNames(), firstDayOfWeek.value));
const isYearFirst = computed<boolean>(() => isLongDateMonthAfterYear());
function getDisplayTimeValue(value: number, forceTwoDigits: boolean): string {
if (forceTwoDigits && value < 10) {
return `0${value}`;
@@ -96,12 +81,8 @@ export function useDateTimeSelectionBase() {
isMinuteTwoDigits,
isSecondTwoDigits,
isMeridiemIndicatorFirst,
yearRange,
// computed
meridiemItems,
firstDayOfWeek,
dayNames,
isYearFirst,
// functions
getDisplayTimeValue,
generateAllHours,
@@ -2,11 +2,9 @@ import { ref, computed } from 'vue';
import { useI18n } from '@/locales/helpers.ts';
import { useUserStore } from '@/stores/user.ts';
import { type WeekDayValue } from '@/core/datetime.ts';
import type { MonthDay } from '@/core/datetime.ts';
import { FiscalYearStart } from '@/core/fiscalyear.ts';
import { arrangeArrayWithNewStartIndex } from '@/lib/common.ts';
import {
getLocalDatetimeFromUnixTime,
getThisYearFirstUnixTime,
@@ -39,12 +37,7 @@ function getFiscalYearStartFromProps(props: CommonFiscalYearStartSelectionProps)
}
export function useFiscalYearStartSelectionBase(props: CommonFiscalYearStartSelectionProps) {
const {
getAllMinWeekdayNames,
formatGregorianCalendarMonthDashDayToLongMonthDay
} = useI18n();
const userStore = useUserStore();
const { formatGregorianCalendarMonthDashDayToLongMonthDay } = useI18n();
const disabledDates = (date: Date) => {
// Disable February 29 (leap day)
@@ -53,18 +46,15 @@ export function useFiscalYearStartSelectionBase(props: CommonFiscalYearStartSele
const selectedFiscalYearStart = ref<number>(getFiscalYearStartFromProps(props));
const selectedFiscalYearStartValue = computed<string>({
const selectedFiscalYearStartValue = computed<Date>({
get: () => {
const fiscalYearStart = FiscalYearStart.valueOf(selectedFiscalYearStart.value);
const monthDay: MonthDay = fiscalYearStart?.toMonthDay() ?? FiscalYearStart.Default.toMonthDay();
if (fiscalYearStart) {
return fiscalYearStart.toMonthDashDayString();
} else {
return FiscalYearStart.Default.toMonthDashDayString();
}
return new Date(new Date().getFullYear(), monthDay.month - 1, monthDay.day);
},
set: (value: string) => {
const fiscalYearStart = FiscalYearStart.parse(value);
set: (value: Date) => {
const fiscalYearStart = FiscalYearStart.of(value.getMonth() + 1, value.getDate());
if (fiscalYearStart) {
selectedFiscalYearStart.value = fiscalYearStart.value;
@@ -87,9 +77,6 @@ export function useFiscalYearStartSelectionBase(props: CommonFiscalYearStartSele
const allowedMinDate = computed<Date>(() => getLocalDatetimeFromUnixTime(getThisYearFirstUnixTime()));
const allowedMaxDate = computed<Date>(() => getLocalDatetimeFromUnixTime(getThisYearLastUnixTime()));
const firstDayOfWeek = computed<WeekDayValue>(() => userStore.currentUserFirstDayOfWeek);
const dayNames = computed<string[]>(() => arrangeArrayWithNewStartIndex(getAllMinWeekdayNames(), firstDayOfWeek.value));
return {
// constants
disabledDates,
@@ -99,8 +86,6 @@ export function useFiscalYearStartSelectionBase(props: CommonFiscalYearStartSele
selectedFiscalYearStartValue,
displayFiscalYearStartDate,
allowedMinDate,
allowedMaxDate,
firstDayOfWeek,
dayNames
allowedMaxDate
};
}
+10 -52
View File
@@ -7,7 +7,6 @@ import {
getYear0BasedMonthObjectFromString,
getYearMonthStringFromYear0BasedMonthObject,
getCurrentUnixTime,
getAllowedYearRange,
getThisYearFirstUnixTime,
getYearMonthFirstUnixTime,
getYearMonthLastUnixTime
@@ -15,11 +14,6 @@ import {
import { useI18n } from '@/locales/helpers.ts';
export interface MonthSelectionValue {
year: number;
month: number; // 0-based month (0 = January, 11 = December)
}
export interface CommonMonthRangeSelectionProps {
minTime?: TextualYearMonth;
maxTime?: TextualYearMonth;
@@ -28,7 +22,7 @@ export interface CommonMonthRangeSelectionProps {
show: boolean;
}
function getMonthRangeFromProps(props: CommonMonthRangeSelectionProps): { minDate: MonthSelectionValue; maxDate: MonthSelectionValue } {
function getMonthRangeFromProps(props: CommonMonthRangeSelectionProps): { minDate: Year0BasedMonth; maxDate: Year0BasedMonth } {
let minDate: Year0BasedMonth = getYear0BasedMonthObjectFromUnixTime(getThisYearFirstUnixTime());
let maxDate: Year0BasedMonth = getYear0BasedMonthObjectFromUnixTime(getCurrentUnixTime());
@@ -49,67 +43,34 @@ function getMonthRangeFromProps(props: CommonMonthRangeSelectionProps): { minDat
}
return {
minDate: {
year: minDate.year,
month: minDate.month0base
},
maxDate: {
year: maxDate.year,
month: maxDate.month0base
}
minDate: minDate,
maxDate: maxDate
};
}
export function useMonthRangeSelectionBase(props: CommonMonthRangeSelectionProps) {
const { formatUnixTimeToLongYearMonth, isLongDateMonthAfterYear } = useI18n();
const { formatUnixTimeToLongYearMonth } = useI18n();
const { minDate, maxDate } = getMonthRangeFromProps(props);
const yearRange = ref<number[]>(getAllowedYearRange());
const dateRange = ref<MonthSelectionValue[]>([
const dateRange = ref<Year0BasedMonth[]>([
minDate,
maxDate
]);
const isYearFirst = computed<boolean>(() => isLongDateMonthAfterYear());
const beginDateTime = computed<string>(() => formatUnixTimeToLongYearMonth(getYearMonthFirstUnixTime({
year: dateRange.value[0].year,
month0base: dateRange.value[0].month
})));
const endDateTime = computed<string>(() => formatUnixTimeToLongYearMonth(getYearMonthLastUnixTime({
year: dateRange.value[1].year,
month0base: dateRange.value[1].month
})));
function getMonthSelectionValue(yearMonth: TextualYearMonth): MonthSelectionValue | null {
const yearMonthObj = getYear0BasedMonthObjectFromString(yearMonth);
if (!yearMonthObj) {
return null;
}
return {
year: yearMonthObj.year,
month: yearMonthObj.month0base
};
}
const beginDateTime = computed<string>(() => formatUnixTimeToLongYearMonth(getYearMonthFirstUnixTime(dateRange.value[0])));
const endDateTime = computed<string>(() => formatUnixTimeToLongYearMonth(getYearMonthLastUnixTime(dateRange.value[1])));
function getFinalMonthRange(): { minYearMonth: TextualYearMonth | '', maxYearMonth: TextualYearMonth | '' } | null {
if (!dateRange.value[0] || !dateRange.value[1]) {
return null;
}
if (dateRange.value[0].year <= 0 || dateRange.value[0].month < 0 || dateRange.value[1].year <= 0 || dateRange.value[1].month < 0) {
if (dateRange.value[0].year <= 0 || dateRange.value[0].month0base < 0 || dateRange.value[1].year <= 0 || dateRange.value[1].month0base < 0) {
throw new Error('Date is too early');
}
const minYearMonth = getYearMonthStringFromYear0BasedMonthObject({
year: dateRange.value[0].year,
month0base: dateRange.value[0].month
});
const maxYearMonth = getYearMonthStringFromYear0BasedMonthObject({
year: dateRange.value[1].year,
month0base: dateRange.value[1].month
});
const minYearMonth = getYearMonthStringFromYear0BasedMonthObject(dateRange.value[0]);
const maxYearMonth = getYearMonthStringFromYear0BasedMonthObject(dateRange.value[1]);
return {
minYearMonth,
@@ -119,14 +80,11 @@ export function useMonthRangeSelectionBase(props: CommonMonthRangeSelectionProps
return {
// states
yearRange,
dateRange,
// computed states
isYearFirst,
beginDateTime,
endDateTime,
// functions
getMonthSelectionValue,
getFinalMonthRange
};
}
-82
View File
@@ -1,82 +0,0 @@
import { ref, computed } from 'vue';
import type { Year0BasedMonth } from '@/core/datetime.ts';
import {
getYear0BasedMonthObjectFromUnixTime,
getAllowedYearRange,
getThisMonthFirstUnixTime
} from '@/lib/datetime.ts';
import { useI18n } from '@/locales/helpers.ts';
export interface MonthSelectionValue {
year: number;
month: number; // 0-based month (0 = January, 11 = December)
}
export interface CommonMonthSelectionProps {
modelValue?: Year0BasedMonth;
title?: string;
hint?: string;
show: boolean;
}
function getYearMonthValueFromProps(props: CommonMonthSelectionProps): MonthSelectionValue {
let value: Year0BasedMonth = getYear0BasedMonthObjectFromUnixTime(getThisMonthFirstUnixTime());
if (props.modelValue) {
value = props.modelValue;
}
return {
year: value.year,
month: value.month0base
};
}
export function useMonthSelectionBase(props: CommonMonthSelectionProps) {
const { isLongDateMonthAfterYear } = useI18n();
const yearRange = ref<number[]>(getAllowedYearRange());
const monthValue = ref<MonthSelectionValue>(getYearMonthValueFromProps(props));
const isYearFirst = computed<boolean>(() => isLongDateMonthAfterYear());
function getMonthSelectionValue(yearMonth: Year0BasedMonth): MonthSelectionValue | null {
if (!yearMonth) {
return null;
}
return {
year: yearMonth.year,
month: yearMonth.month0base
};
}
function getYear0BasedMonth(): Year0BasedMonth | null {
if (!monthValue.value) {
return null;
}
if (monthValue.value.year <= 0 || monthValue.value.month < 0) {
throw new Error('Date is too early');
}
return {
year: monthValue.value.year,
month0base: monthValue.value.month
};
}
return {
// states
yearRange,
monthValue,
// computed states
isYearFirst,
// functions
getMonthSelectionValue,
getYear0BasedMonth
};
}