Files
qb/mqe/helpers.go
2026-06-19 07:25:46 +03:00

159 lines
4.7 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package mqe
import (
"fmt"
)
func getPeriodDateTime(groupBy GroupBy, lastDayOfMonth int, firstHourOfDay int) (dt string, err error) {
//fmt.Printf("getPeriodDateTime: %s, lastDay: %d, firstHour: %d\n", groupBy, lastDayOfMonth, firstHourOfDay)
// Если FirstHourOfDay и LastDayOfMonth равны 0 - модифицировать дату не нужно
dt = `FROM_UNIXTIME(tm)`
switch groupBy {
case ByDay:
if firstHourOfDay > 0 {
dt = fmt.Sprintf(`
IF (HOUR(FROM_UNIXTIME(tm)) >= %d,
FROM_UNIXTIME(tm),
DATE_SUB(FROM_UNIXTIME(tm), INTERVAL 1 DAY)
)`,
firstHourOfDay)
}
case ByMonth:
if lastDayOfMonth > 0 {
if lastDayOfMonth > 28 {
// На всякий случай добавляем защиту от дурака, ибо модификация даты
// в запросе (+1 месяц) для 29, 30 и 31 чисел сделает запрос неверным.
err = fmt.Errorf("LastDayOfMonth: %d, max allowed value is 28", lastDayOfMonth)
return
}
if firstHourOfDay > 0 {
// В псевдокоде модификация времени показания по корректный период
// выглядит так:
//
// if hour >= FirstHourOfDay {
// if day <= LastDayOfMonth {
// return tm
// } else {
// return tm + 1 month
// }
// } else {
// if (day - 1) <= LastDayOfMonth {
// return tm - 1 day
// } else {
// return tm - 1 day + 1 month
// }
// }
dt = fmt.Sprintf(`
IF (HOUR(FROM_UNIXTIME(tm)) >= %d,
IF (DAYOFMONTH(FROM_UNIXTIME(tm)) <= %d,
FROM_UNIXTIME(tm),
DATE_ADD(FROM_UNIXTIME(tm), INTERVAL 1 MONTH)
),
IF (DAYOFMONTH(DATE_SUB(FROM_UNIXTIME(tm), INTERVAL 1 DAY)) <= %d,
DATE_SUB(FROM_UNIXTIME(tm), INTERVAL 1 DAY),
DATE_ADD(DATE_SUB(FROM_UNIXTIME(tm), INTERVAL 1 DAY), INTERVAL 1 MONTH)
)
)`,
firstHourOfDay, lastDayOfMonth, lastDayOfMonth)
} else {
dt = fmt.Sprintf(`
IF (DAYOFMONTH(FROM_UNIXTIME(tm)) <= %d,
FROM_UNIXTIME(tm),
DATE_ADD(FROM_UNIXTIME(tm), INTERVAL 1 MONTH)
)`,
lastDayOfMonth)
}
} else {
if firstHourOfDay > 0 {
dt = fmt.Sprintf(`
IF (HOUR(FROM_UNIXTIME(tm)) >= %d,
FROM_UNIXTIME(tm),
DATE_SUB(FROM_UNIXTIME(tm), INTERVAL 1 DAY)
)`,
firstHourOfDay)
}
}
}
return
}
func getDateTimeFacingFHD(firstHourOfDay int) (dt string, err error) {
if firstHourOfDay > 0 {
dt = fmt.Sprintf(`
IF (HOUR(FROM_UNIXTIME(tm)) >= %d,
FROM_UNIXTIME(tm),
DATE_SUB(FROM_UNIXTIME(tm), INTERVAL 1 DAY)
)`,
firstHourOfDay)
} else {
// Если FirstHourOfDay = 0 - модифицировать дату не нужно
dt = "FROM_UNIXTIME(tm)"
}
return
}
func getDateTimeFacingFHDAndLDM(firstHourOfDay int, lastDayOfMonth int) (dt string, err error) {
// Если FirstHourOfDay и LastDayOfMonth равны 0 - модифицировать дату не нужно
dt = "FROM_UNIXTIME(tm)"
if lastDayOfMonth > 0 {
if lastDayOfMonth > 28 {
// На всякий случай добавляем защиту от дурака, ибо модификация даты
// в запросе (+1 месяц) для 29, 30 и 31 чисел сделает запрос неверным.
err = fmt.Errorf("LastDayOfMonth: %d, max allowed value is 28", lastDayOfMonth)
return
}
if firstHourOfDay > 0 {
// В псевдокоде модификация времени показания по корректный период
// выглядит так:
//
// if hour >= FirstHourOfDay {
// if day <= LastDayOfMonth {
// return tm
// } else {
// return tm + 1 month
// }
// } else {
// if (day - 1) <= LastDayOfMonth {
// return tm - 1 day
// } else {
// return tm - 1 day + 1 month
// }
// }
dt = fmt.Sprintf(`
IF (HOUR(FROM_UNIXTIME(tm)) >= %d,
IF (DAYOFMONTH(FROM_UNIXTIME(tm)) <= %d,
FROM_UNIXTIME(tm),
DATE_ADD(FROM_UNIXTIME(tm), INTERVAL 1 MONTH)
),
IF (DAYOFMONTH(DATE_SUB(FROM_UNIXTIME(tm), INTERVAL 1 DAY)) <= %d,
DATE_SUB(FROM_UNIXTIME(tm), INTERVAL 1 DAY),
DATE_ADD(DATE_SUB(FROM_UNIXTIME(tm), INTERVAL 1 DAY), INTERVAL 1 MONTH)
)
)`,
firstHourOfDay, lastDayOfMonth, lastDayOfMonth)
} else {
dt = fmt.Sprintf(`
IF (DAYOFMONTH(FROM_UNIXTIME(tm)) <= %d,
FROM_UNIXTIME(tm),
DATE_ADD(FROM_UNIXTIME(tm), INTERVAL 1 MONTH)
)`,
lastDayOfMonth)
}
} else {
if firstHourOfDay > 0 {
dt = fmt.Sprintf(`
IF (HOUR(FROM_UNIXTIME(tm)) >= %d,
FROM_UNIXTIME(tm),
DATE_SUB(FROM_UNIXTIME(tm), INTERVAL 1 DAY)
)`,
firstHourOfDay)
}
}
return
}