• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

atinc / ngx-tethys / 68ef226c-f83e-44c1-b8ed-e420a83c5d84

28 May 2025 10:31AM UTC coverage: 10.352% (-80.0%) from 90.316%
68ef226c-f83e-44c1-b8ed-e420a83c5d84

Pull #3460

circleci

pubuzhixing8
chore: xxx
Pull Request #3460: refactor(icon): migrate signal input #TINFR-1476

132 of 6823 branches covered (1.93%)

Branch coverage included in aggregate %.

10 of 14 new or added lines in 1 file covered. (71.43%)

11648 existing lines in 344 files now uncovered.

2078 of 14525 relevant lines covered (14.31%)

6.69 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/date-picker/picker.util.ts
1
import { Signal } from '@angular/core';
2
import { ThyI18nLocale, ThyLocaleType } from 'ngx-tethys/i18n';
3
import { SafeAny } from 'ngx-tethys/types';
UNCOV
4
import { coerceArray, helpers, TinyDate } from 'ngx-tethys/util';
×
UNCOV
5
import { CompatibleValue, RangeAdvancedValue } from './inner-types';
×
6
import { CompatibleDate, DateEntry, ThyDateGranularity, ThyDateRangeEntry, ThyPanelMode, ThyShortcutValue } from './standard-types';
7

UNCOV
8
export function transformDateValue(value: CompatibleDate | CompatibleValue | number | DateEntry | ThyDateRangeEntry | RangeAdvancedValue): {
×
UNCOV
9
    value: CompatibleDate;
×
10
    withTime?: boolean;
UNCOV
11
    flexibleDateGranularity?: ThyDateGranularity;
×
UNCOV
12
} {
×
UNCOV
13
    if (!value) {
×
14
        return { value: null };
15
    }
UNCOV
16
    let withTime, flexibleDateGranularity: ThyDateGranularity;
×
UNCOV
17
    if (value && typeof value === 'number') {
×
18
        value = convertDate(value);
19
    }
UNCOV
20
    if (value && instanceOfCompatibleValue(value as CompatibleValue)) {
×
UNCOV
21
        if (value instanceof TinyDate) {
×
UNCOV
22
            value = convertDate(value.nativeDate);
×
UNCOV
23
        } else {
×
24
            value[0] = convertDate(value[0].nativeDate);
UNCOV
25
            value[1] = convertDate(value[1].nativeDate);
×
UNCOV
26
        }
×
UNCOV
27
    }
×
UNCOV
28
    if (value && instanceOfDateEntry(value as DateEntry)) {
×
UNCOV
29
        const { date, with_time } = value as DateEntry;
×
UNCOV
30
        value = date ? convertDate(date) : null;
×
31
        withTime = !!with_time;
UNCOV
32
    }
×
UNCOV
33
    if (value && instanceOfRangeEntry(value as ThyDateRangeEntry)) {
×
34
        const rangeValue = value as ThyDateRangeEntry;
35
        value = [];
UNCOV
36
        if (rangeValue.begin && rangeValue.end) {
×
UNCOV
37
            value[0] = convertDate(rangeValue.begin);
×
UNCOV
38
            value[1] = convertDate(rangeValue.end);
×
UNCOV
39
        }
×
40
        if (rangeValue.granularity) {
UNCOV
41
            flexibleDateGranularity = rangeValue.granularity;
×
UNCOV
42
        }
×
UNCOV
43
    }
×
UNCOV
44

×
45
    if (value && instanceOfRangeAdvancedValue(value as RangeAdvancedValue)) {
46
        const rangeValue = value as RangeAdvancedValue;
UNCOV
47
        if (rangeValue.dateGranularity) {
×
48
            flexibleDateGranularity = rangeValue.dateGranularity;
49
        }
UNCOV
50
        value = [];
×
UNCOV
51
        if (rangeValue.begin && rangeValue.end) {
×
UNCOV
52
            value[0] = convertDate(rangeValue.begin.nativeDate);
×
53
            value[1] = convertDate(rangeValue.end.nativeDate);
UNCOV
54
        }
×
55
    }
UNCOV
56
    return { value: value as CompatibleDate, withTime, flexibleDateGranularity };
×
UNCOV
57
}
×
UNCOV
58

×
59
export function getFlexibleAdvancedReadableValue(
60
    tinyDates: TinyDate[],
61
    flexibleDateGranularity: ThyDateGranularity,
×
62
    separator: string,
UNCOV
63
    locale: Signal<ThyI18nLocale>
×
64
) {
UNCOV
65
    let value = '';
×
UNCOV
66
    if (!tinyDates[0] || !tinyDates[1]) {
×
UNCOV
67
        return value;
×
68
    }
69
    switch (flexibleDateGranularity) {
70
        case 'year':
×
71
            const yearFormatStr = locale()?.id === ThyLocaleType.zhHans ? `yyyy年` : `yyyy`;
UNCOV
72
            if (tinyDates[0].isSameYear(tinyDates[1])) {
×
73
                value = `${tinyDates[0].format(yearFormatStr)}`;
UNCOV
74
            } else {
×
UNCOV
75
                value = `${tinyDates[0].format(yearFormatStr)}${separator}${tinyDates[1].format(yearFormatStr)}`;
×
UNCOV
76
            }
×
77
            break;
78
        case 'quarter':
UNCOV
79
            const quarterFormatStr = locale()?.id === ThyLocaleType.zhHans ? `yyyy年 qqq` : `yyyy-qqq`;
×
80
            if (tinyDates[0].isSameQuarter(tinyDates[1])) {
UNCOV
81
                value = `${tinyDates[0].format(quarterFormatStr)}`;
×
82
            } else {
UNCOV
83
                value = `${tinyDates[0].format(quarterFormatStr)}${separator}${tinyDates[1].format(quarterFormatStr)}`;
×
84
            }
85
            break;
UNCOV
86
        case 'month':
×
UNCOV
87
            const monthFormatStr = locale()?.id === ThyLocaleType.zhHans ? `yyyy年 MM月` : `yyyy-MM`;
×
UNCOV
88
            if (tinyDates[0].isSameMonth(tinyDates[1])) {
×
89
                value = `${tinyDates[0].format(monthFormatStr)}`;
90
            } else {
UNCOV
91
                value = `${tinyDates[0].format(monthFormatStr)}${separator}${tinyDates[1].format(monthFormatStr)}`;
×
92
            }
93
            break;
UNCOV
94
    }
×
95
    return value;
×
96
}
97

UNCOV
98
export function convertDate(date: Date | number | TinyDate): Date {
×
99
    if (typeof date === 'number') {
100
        if (date.toString().length < 13) {
101
            return TinyDate.fromUnixTime(date)?.nativeDate;
UNCOV
102
        } else {
×
103
            return new TinyDate(date)?.nativeDate;
×
104
        }
105
    } else if (date instanceof TinyDate) {
UNCOV
106
        return date?.nativeDate;
×
107
    } else {
108
        return new TinyDate(date)?.nativeDate;
109
    }
×
UNCOV
110
}
×
UNCOV
111

×
112
export function hasValue(value: CompatibleValue): boolean {
113
    if (Array.isArray(value)) {
UNCOV
114
        return !!value[0] && !!value[1];
×
115
    } else {
116
        return !!value;
117
    }
118
}
UNCOV
119

×
120
export function makeValue(value: CompatibleDate | null, isRange: boolean = false, timeZone?: string): CompatibleValue {
UNCOV
121
    if (isRange) {
×
UNCOV
122
        return Array.isArray(value) ? (value as Date[]).map(val => new TinyDate(val, timeZone)) : [];
×
123
    } else {
UNCOV
124
        return value ? new TinyDate(value as Date, timeZone) : null;
×
UNCOV
125
    }
×
126
}
UNCOV
127

×
UNCOV
128
export function dateAddAmount(value: TinyDate, amount: number, mode: ThyPanelMode): TinyDate {
×
129
    let date: TinyDate;
UNCOV
130
    switch (mode) {
×
UNCOV
131
        case 'decade':
×
132
            date = value.addYears(amount * 10);
UNCOV
133
            break;
×
134
        case 'year':
135
            date = value.addYears(amount);
136
            break;
UNCOV
137
        case 'month':
×
UNCOV
138
            date = value.addMonths(amount);
×
UNCOV
139
            break;
×
140
        default:
×
141
            date = value.addMonths(amount);
UNCOV
142
            break;
×
UNCOV
143
    }
×
144
    return date;
145
}
UNCOV
146

×
147
// rightDate 超过 leftDate 一个月
148
export function isAfterMoreThanOneMonth(rightDate: TinyDate, leftDate: TinyDate) {
149
    rightDate = rightDate ? rightDate : leftDate ? leftDate : new TinyDate();
UNCOV
150
    leftDate = leftDate ? leftDate : rightDate;
×
UNCOV
151
    if (rightDate.getYear() < leftDate.getYear()) {
×
UNCOV
152
        return false;
×
UNCOV
153
    }
×
154

155
    if (rightDate.getYear() === leftDate.getYear() && leftDate.getMonth() + 1 >= rightDate.getMonth()) {
UNCOV
156
        return false;
×
157
    }
158

159
    // 处理rightDate(2020,1,1) 为leftDate(2020,12,1)后一年1月,同时leftDate日期为12月的特殊情况
UNCOV
160
    return !(rightDate.getYear() - leftDate.getYear() === 1 && rightDate.getMonth() === 0 && leftDate.getMonth() === 11);
×
UNCOV
161
}
×
UNCOV
162

×
UNCOV
163
// rightDate 超过 leftDate 不到一年
×
164
export function isAfterMoreThanLessOneYear(rightDate: TinyDate, leftDate: TinyDate) {
165
    rightDate = rightDate ? rightDate : leftDate ? leftDate : new TinyDate();
UNCOV
166
    leftDate = leftDate ? leftDate : rightDate;
×
167
    if (rightDate.getYear() <= leftDate.getYear()) {
168
        return false;
169
    }
UNCOV
170
    // 处理rightDate(2021,1,1)日期比leftDate(2020,12,1)日期大1年,同时rightDate日期月份小于leftDate日期月份的情况
×
UNCOV
171
    return !(rightDate.getYear() - leftDate.getYear() === 1 && rightDate.getMonth() <= leftDate.getMonth());
×
UNCOV
172
}
×
173

174
// rightDate 超过 leftDate 一年
UNCOV
175
export function isAfterMoreThanOneYear(rightDate: TinyDate, leftDate: TinyDate) {
×
176
    rightDate = rightDate ? rightDate : leftDate ? leftDate : new TinyDate();
177
    leftDate = leftDate ? leftDate : rightDate;
UNCOV
178
    if (leftDate.getYear() + 1 >= rightDate.getYear()) {
×
179
        return false;
180
    } else {
UNCOV
181
        return true;
×
182
    }
183
}
UNCOV
184

×
185
export function isAfterMoreThanOneDecade(rightDate: TinyDate, leftDate: TinyDate) {
186
    rightDate = rightDate ? rightDate : leftDate ? leftDate : new TinyDate();
UNCOV
187
    leftDate = leftDate ? leftDate : rightDate;
×
188
    return rightDate.getYear() - leftDate.getYear() >= 20;
189
}
UNCOV
190

×
191
export function instanceOfDateEntry(object: DateEntry): object is DateEntry {
192
    return isSupportDateType(object, 'date') && typeof object.with_time === 'number';
UNCOV
193
}
×
UNCOV
194

×
195
export function instanceOfRangeEntry(object: ThyDateRangeEntry): object is ThyDateRangeEntry {
196
    return isSupportDateType(object, 'begin') && isSupportDateType(object, 'end');
UNCOV
197
}
×
198

199
export function instanceOfCompatibleValue(object: CompatibleValue): object is CompatibleValue {
200
    return object instanceof TinyDate || object[0] instanceof TinyDate;
201
}
UNCOV
202

×
UNCOV
203
export function instanceOfRangeAdvancedValue(object: RangeAdvancedValue): object is RangeAdvancedValue {
×
UNCOV
204
    return object['begin'] instanceof TinyDate && object['end'] instanceof TinyDate;
×
205
}
206

UNCOV
207
export function isSupportDateType(object: DateEntry | ThyDateRangeEntry, key: string) {
×
UNCOV
208
    return typeof object[key] === 'number' || object[key] === null || object[key] instanceof Date;
×
UNCOV
209
}
×
UNCOV
210

×
211
export function getShortcutValue(value: ThyShortcutValue): number | Date {
UNCOV
212
    return helpers.isFunction(value) ? value() : value;
×
213
}
214

UNCOV
215
export function isValidStringDate(dateStr: string, timeZone?: string): boolean {
×
UNCOV
216
    const parseDate = parseStringDate(dateStr, timeZone).nativeDate.getTime();
×
UNCOV
217
    return !(parseDate < 0 || isNaN(parseDate));
×
218
}
UNCOV
219

×
UNCOV
220
export function parseStringDate(dateStr: string, timeZone?: string): TinyDate {
×
UNCOV
221
    return hasTimeInStringDate(dateStr, timeZone)
×
222
        ? new TinyDate(fixStringDate(dateStr, timeZone), timeZone)
223
        : new TinyDate(fixStringDate(dateStr, timeZone), timeZone).startOfDay();
224
}
UNCOV
225

×
UNCOV
226
export function hasTimeInStringDate(dateStr: string, timeZone?: string): boolean {
×
227
    const formatDate = fixStringDate(dateStr, timeZone);
228
    const timeRegex = /(\d{1,2}:\d{1,2}(:\d{1,2})?)|(^\d{1,2}时\d{1,2}分(\d{1,2}秒)?)$/;
229
    return timeRegex.test(formatDate);
230
}
231

232
function fixStringDate(dateStr: string, timeZone?: string) {
233
    let replacedStr = dateStr.replace(/[^0-9\s.,:]/g, '-').replace('- ', ' ');
234
    const hasYear = /\d{4}/.test(replacedStr);
235
    if (!hasYear || replacedStr.length < 'yyyy.M.d'.length) {
236
        replacedStr = `${new TinyDate(undefined, timeZone).getYear()}-${replacedStr}`;
237
    }
238
    return replacedStr;
239
}
240

241
export function setValueByTimestampPrecision(
242
    date: CompatibleDate | number | Date | DateEntry | ThyDateRangeEntry | SafeAny,
243
    isRange: boolean,
244
    timestampPrecision: 'seconds' | 'milliseconds',
245
    timeZone?: string
246
): number | number[] {
247
    const { value } = transformDateValue(date);
248
    if (!value || (helpers.isArray(value) && !value?.length)) {
249
        return helpers.isArray(value) ? [null, null] : null;
250
    }
251
    if (timestampPrecision === 'milliseconds') {
252
        return isRange
253
            ? coerceArray(value).map(val => new TinyDate(val, timeZone).getTime())
254
            : new TinyDate(value as Date, timeZone).getTime();
255
    } else {
256
        return isRange
257
            ? coerceArray(value).map(val => new TinyDate(val, timeZone).getUnixTime())
258
            : new TinyDate(value as Date, timeZone)?.getUnixTime();
259
    }
260
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc