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 }