-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutils.go
More file actions
98 lines (77 loc) · 2.79 KB
/
utils.go
File metadata and controls
98 lines (77 loc) · 2.79 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
95
96
97
98
package lotime
import (
"fmt"
"time"
)
// GetWeekOfMonth returns the week number as int in month by date
func GetWeekOfMonth(dt time.Time, isFirstDayMon bool) int {
// Get the first day of the month
firstDayOfMonth := time.Date(dt.Year(), dt.Month(), 1, 0, 0, 0, 0, dt.Location())
// Get offset for first weekday
adjustedWeekday := 0
if isFirstDayMon {
adjustedWeekday = (int(firstDayOfMonth.Weekday()) + 6) % 7
}
// Day of month
dayOfMonth := dt.Day()
// Calculate adjusted day
adjustedDay := dayOfMonth + adjustedWeekday - 1
// Calculate week number
return (adjustedDay / 7) + 1
}
// GetDayOfYear return day of year by date
func GetDayOfYear(year int, month int, day int) int {
monthName := time.Month(month)
date := time.Date(year, monthName, day, 0, 0, 0, 0, time.UTC)
return date.YearDay()
}
// DateIsPassedInCurrentYear Проверяем, прошла ли дата в текущем году
func DateIsPassedInCurrentYear(dt time.Time) bool {
now := time.Now().Local()
date := time.Date(now.Year(), dt.Month(), dt.Day(), 0, 0, 0, 0, time.Local)
if now.After(date) {
return true
}
return false
}
// DateYearsSince Amount of years since the given date
func DateYearsSince(dt time.Time) int {
now := time.Now()
years := now.Year() - dt.Year()
// If current date is before dt by day or month, then year is not complete
if now.Month() < dt.Month() || (now.Month() == dt.Month() && now.Day() < dt.Day()) {
years--
}
return years
}
// NthOrLastWeekdayOfMonth Calculate the nth or last weekday of a given month and year.
func NthOrLastWeekdayOfMonth(year int, month time.Month, userWeekday int, weekNum int, isFirstDayMon bool) (time.Time, error) {
if userWeekday < 1 || userWeekday > 7 {
return time.Time{}, fmt.Errorf("invalid weekday: %d", userWeekday)
}
if weekNum < 0 || weekNum > 5 {
return time.Time{}, fmt.Errorf("invalid week number: %d", weekNum)
}
targetWeekday := time.Weekday(0)
if isFirstDayMon {
targetWeekday = time.Weekday(userWeekday % 7) // Sunday=0 ... Saturday=6
}
if weekNum == 0 {
// Search for the last weekday of the month
firstOfNextMonth := time.Date(year, month+1, 1, 0, 0, 0, 0, time.UTC)
lastDayOfMonth := firstOfNextMonth.AddDate(0, 0, -1)
for lastDayOfMonth.Weekday() != targetWeekday {
lastDayOfMonth = lastDayOfMonth.AddDate(0, 0, -1)
}
return lastDayOfMonth, nil
}
// Search for the nth weekday of the month
firstOfMonth := time.Date(year, month, 1, 0, 0, 0, 0, time.UTC)
offset := (int(targetWeekday) - int(firstOfMonth.Weekday()) + 7) % 7
day := 1 + offset + (weekNum-1)*7
// Check if the date is valid
if day > 31 || time.Date(year, month, day, 0, 0, 0, 0, time.UTC).Month() != month {
return time.Time{}, fmt.Errorf("no such weekday occurrence in this month")
}
return time.Date(year, month, day, 0, 0, 0, 0, time.UTC), nil
}