Repository navigation
Expand file tree
/
Copy pathperiods.ts
More file actions
94 lines (83 loc) · 2.6 KB
/
Copy pathperiods.ts
File metadata and controls
94 lines (83 loc) · 2.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
/**
* Indian ITR advance-tax periods for a financial year.
*
* The ITR portal asks capital gains to be split across five periods that mirror
* the advance-tax instalment cut-off dates:
*
* Period 1: Up to 15th June
* Period 2: 16th June to 15th September
* Period 3: 16th September to 15th December
* Period 4: 16th December to 15th March
* Period 5: 16th March to 31st March
*
* Everything is derived from a single input: the financial-year start year `Y`
* (an Indian FY runs 1 April `Y` to 31 March `Y+1`). Nothing is hard-coded to a
* specific year. This mirrors `src/tax_utils/periods.py`.
*/
/** A calendar day as a UTC-safe date (time components ignored). */
export type Day = Date;
export interface Period {
index: number;
start: Day;
end: Day;
}
const MONTHS = [
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec",
];
/** Build a date at UTC midnight so comparisons are timezone-independent. */
export function makeDay(year: number, month1: number, day: number): Day {
return new Date(Date.UTC(year, month1 - 1, day));
}
export function periodLabel(period: Period): string {
return `Period ${period.index}`;
}
function fmtDay(d: Day): string {
const day = String(d.getUTCDate()).padStart(2, "0");
return `${day} ${MONTHS[d.getUTCMonth()]} ${d.getUTCFullYear()}`;
}
export function periodRangeLabel(period: Period): string {
return `${fmtDay(period.start)} - ${fmtDay(period.end)}`;
}
function contains(period: Period, day: Day): boolean {
return (
period.start.getTime() <= day.getTime() &&
day.getTime() <= period.end.getTime()
);
}
/** Return the five ITR periods for the FY starting on 1 April `fyStartYear`. */
export function buildPeriods(fyStartYear: number): Period[] {
const y = fyStartYear;
const n = y + 1;
const boundaries: [Day, Day][] = [
[makeDay(y, 4, 1), makeDay(y, 6, 15)],
[makeDay(y, 6, 16), makeDay(y, 9, 15)],
[makeDay(y, 9, 16), makeDay(y, 12, 15)],
[makeDay(y, 12, 16), makeDay(n, 3, 15)],
[makeDay(n, 3, 16), makeDay(n, 3, 31)],
];
return boundaries.map(([start, end], i) => ({ index: i + 1, start, end }));
}
/** Return the FY start year that a given date falls into (Apr-Mar year). */
export function fyStartYearFor(day: Day): number {
return day.getUTCMonth() + 1 >= 4
? day.getUTCFullYear()
: day.getUTCFullYear() - 1;
}
/** Return the period a date belongs to, or `null` if outside the FY. */
export function periodFor(day: Day, periods: Period[]): Period | null {
for (const period of periods) {
if (contains(period, day)) return period;
}
return null;
}