util_test.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603
  1. package util
  2. import (
  3. "fmt"
  4. "sort"
  5. "strconv"
  6. "strings"
  7. "testing"
  8. "time"
  9. "github.com/stretchr/testify/assert"
  10. )
  11. func TestConvertParseLocalUnix(t *testing.T) {
  12. type args struct {
  13. unix int64
  14. }
  15. tests := []struct {
  16. Name string
  17. Args args
  18. }{
  19. {
  20. Name: "08:00:00",
  21. Args: args{
  22. unix: 1727049600,
  23. },
  24. },
  25. {
  26. Name: "09:00:00",
  27. Args: args{
  28. unix: 1727053200,
  29. },
  30. },
  31. }
  32. for _, tt := range tests {
  33. t.Run(tt.Name, func(t *testing.T) {
  34. got, err := ConvertParseLocalUnix(tt.Name)
  35. assert.Nil(t, err)
  36. assert.Equal(t, tt.Args.unix, got)
  37. })
  38. }
  39. }
  40. func TestGetLastDayOfMonth(t *testing.T) {
  41. tests := []struct {
  42. month string
  43. got string
  44. }{
  45. {
  46. month: "2022-02",
  47. got: "2022-02-28",
  48. },
  49. {
  50. month: "2023-02",
  51. got: "2023-02-28",
  52. },
  53. {
  54. month: "2024-02",
  55. got: "2024-02-29",
  56. },
  57. {
  58. month: "2024-10",
  59. got: "2024-10-31",
  60. }, {
  61. month: "2024-09",
  62. got: "2024-09-30",
  63. },
  64. }
  65. for _, tt := range tests {
  66. t.Run(tt.month, func(t *testing.T) {
  67. got, err := GetLastDayOfMonth(tt.month)
  68. assert.Nil(t, err)
  69. assert.Equal(t, tt.got, got)
  70. })
  71. }
  72. }
  73. func TestGetMonthsInRange(t *testing.T) {
  74. tests := []struct {
  75. startMonth string
  76. endMonth string
  77. got []string
  78. }{
  79. {
  80. startMonth: "2023-01",
  81. endMonth: "2023-03",
  82. got: []string{
  83. "2023-01",
  84. "2023-02",
  85. "2023-03",
  86. },
  87. },
  88. {
  89. startMonth: "2023-01",
  90. endMonth: "2023-12",
  91. got: []string{
  92. "2023-01",
  93. "2023-02",
  94. "2023-03",
  95. "2023-04",
  96. "2023-05",
  97. "2023-06",
  98. "2023-07",
  99. "2023-08",
  100. "2023-09",
  101. "2023-10",
  102. "2023-11",
  103. "2023-12",
  104. },
  105. },
  106. {
  107. startMonth: "2023-01",
  108. endMonth: "2023-01",
  109. got: []string{
  110. "2023-01",
  111. },
  112. },
  113. {
  114. startMonth: "2023-01",
  115. endMonth: "2023-01",
  116. got: []string{
  117. "2023-01",
  118. },
  119. },
  120. }
  121. for _, tt := range tests {
  122. t.Run(tt.startMonth, func(t *testing.T) {
  123. got, err := GetMonthsInRange(tt.startMonth, tt.endMonth)
  124. assert.Nil(t, err)
  125. assert.Equal(t, tt.got, got)
  126. })
  127. }
  128. }
  129. func TestRoundToTwoDecimals(t *testing.T) {
  130. tests := []struct {
  131. exp float64
  132. got float64
  133. }{
  134. {
  135. exp: 123.456,
  136. got: 123.46,
  137. },
  138. {
  139. exp: 123.455,
  140. got: 123.46,
  141. },
  142. {
  143. exp: 123.444,
  144. got: 123.44,
  145. },
  146. {
  147. exp: 123.4551,
  148. got: 123.46,
  149. },
  150. {
  151. exp: 123.4449,
  152. got: 123.44,
  153. },
  154. {
  155. exp: 0,
  156. got: 0,
  157. },
  158. {
  159. exp: 0.2,
  160. got: 0.2,
  161. },
  162. }
  163. for _, tt := range tests {
  164. t.Run("TestRoundToTwoDecimals", func(t *testing.T) {
  165. got := RoundToTwoDecimals(tt.exp)
  166. assert.Equal(t, tt.got, got)
  167. })
  168. }
  169. }
  170. func TestGet21DayPeriods(t *testing.T) {
  171. tests := []struct {
  172. startDay string
  173. endDay string
  174. got struct {
  175. DateRange [][]string
  176. Day int32
  177. MiddleDayString []string
  178. }
  179. }{
  180. {
  181. startDay: "2023-01-01",
  182. endDay: "2023-01-02",
  183. got: struct {
  184. DateRange [][]string
  185. Day int32
  186. MiddleDayString []string
  187. }{
  188. DateRange: [][]string{
  189. {"2022-12-13", "2023-01-02"},
  190. },
  191. Day: 11,
  192. MiddleDayString: []string{"2022-12-23"},
  193. },
  194. },
  195. {
  196. startDay: "2024-10-23",
  197. endDay: "2024-10-24",
  198. got: struct {
  199. DateRange [][]string
  200. Day int32
  201. MiddleDayString []string
  202. }{
  203. DateRange: [][]string{
  204. {"2024-10-04", "2024-10-24"},
  205. },
  206. Day: 11,
  207. MiddleDayString: []string{"2024-10-14"},
  208. },
  209. },
  210. {
  211. startDay: "2024-06-22",
  212. endDay: "2024-10-24",
  213. got: struct {
  214. DateRange [][]string
  215. Day int32
  216. MiddleDayString []string
  217. }{
  218. DateRange: [][]string{
  219. {"2024-06-21", "2024-07-11"},
  220. {"2024-07-12", "2024-08-01"},
  221. {"2024-08-02", "2024-08-22"},
  222. {"2024-08-23", "2024-09-12"},
  223. {"2024-09-13", "2024-10-03"},
  224. {"2024-10-04", "2024-10-24"},
  225. }, Day: 11,
  226. MiddleDayString: []string{"2024-07-01", "2024-07-22", "2024-08-12", "2024-09-02", "2024-09-23", "2024-10-14"},
  227. },
  228. },
  229. }
  230. for _, tt := range tests {
  231. t.Run(tt.startDay, func(t *testing.T) {
  232. got, err := Get21DayPeriods(tt.startDay, tt.endDay)
  233. assert.Nil(t, err)
  234. assert.Equal(t, tt.got.DateRange, got)
  235. for i, v := range tt.got.DateRange {
  236. middleDate, err := GetRangeDayMiddleDay(v, tt.got.Day)
  237. assert.Nil(t, err)
  238. assert.Equal(t, tt.got.MiddleDayString[i], middleDate)
  239. }
  240. })
  241. }
  242. }
  243. func TestGetRangeDayByDays(t *testing.T) {
  244. tests := []struct {
  245. startDay string
  246. endDay string
  247. days int32
  248. got [][]string
  249. }{
  250. {
  251. startDay: "2024-10-23",
  252. endDay: "2024-10-24",
  253. days: 5,
  254. got: [][]string{
  255. {"2024-10-23", "2024-10-24"},
  256. },
  257. },
  258. {
  259. startDay: "2024-10-23",
  260. endDay: "2024-10-24",
  261. days: 1,
  262. got: [][]string{
  263. {"2024-10-23", "2024-10-23"},
  264. {"2024-10-24", "2024-10-24"},
  265. },
  266. },
  267. {
  268. startDay: "2024-10-01",
  269. endDay: "2024-10-31",
  270. days: 7,
  271. got: [][]string{
  272. {"2024-10-01", "2024-10-07"},
  273. {"2024-10-08", "2024-10-14"},
  274. {"2024-10-15", "2024-10-21"},
  275. {"2024-10-22", "2024-10-28"},
  276. {"2024-10-29", "2024-10-31"},
  277. },
  278. },
  279. {
  280. startDay: "2024-10-01",
  281. endDay: "2024-10-31",
  282. days: 5,
  283. got: [][]string{
  284. {"2024-10-01", "2024-10-05"},
  285. {"2024-10-06", "2024-10-10"},
  286. {"2024-10-11", "2024-10-15"},
  287. {"2024-10-16", "2024-10-20"},
  288. {"2024-10-21", "2024-10-25"},
  289. {"2024-10-26", "2024-10-30"},
  290. {"2024-10-31", "2024-10-31"},
  291. },
  292. },
  293. }
  294. for _, tt := range tests {
  295. t.Run(tt.startDay, func(t *testing.T) {
  296. got, err := GetRangeDayByDays(tt.startDay, tt.endDay, tt.days)
  297. assert.Nil(t, err)
  298. assert.Equal(t, tt.got, got)
  299. })
  300. }
  301. }
  302. func TestConfidenceInterval2(t *testing.T) {
  303. tests := []struct {
  304. p float64
  305. total float64
  306. min float64
  307. max float64
  308. }{
  309. {
  310. p: 0.38,
  311. total: 114,
  312. min: 29,
  313. max: 47,
  314. },
  315. {
  316. p: 0.49,
  317. total: 142,
  318. min: 40,
  319. max: 58,
  320. },
  321. {
  322. p: 0.41,
  323. total: 125,
  324. min: 32,
  325. max: 50,
  326. },
  327. {
  328. p: 0,
  329. total: 0,
  330. min: 0,
  331. max: 0,
  332. },
  333. }
  334. for _, tt := range tests {
  335. min, max := ConfidenceInterval2(tt.p, tt.total)
  336. assert.Equal(t, tt.min, min)
  337. assert.Equal(t, tt.max, max)
  338. }
  339. }
  340. func TestRemoveDuplicates(t *testing.T) {
  341. tests := []struct {
  342. actual []string
  343. got []string
  344. }{
  345. {
  346. actual: []string{
  347. "1", "1",
  348. },
  349. got: []string{
  350. "1",
  351. },
  352. },
  353. {
  354. actual: []string{
  355. "1", "1", "2",
  356. },
  357. got: []string{
  358. "1", "2",
  359. },
  360. },
  361. {
  362. actual: []string{
  363. "1",
  364. },
  365. got: []string{
  366. "1",
  367. },
  368. },
  369. {
  370. actual: []string{},
  371. got: []string{},
  372. },
  373. }
  374. for _, tt := range tests {
  375. got := RemoveDuplicates(tt.actual)
  376. assert.Equal(t, tt.got, got)
  377. }
  378. }
  379. func TestDaysBetween(t *testing.T) {
  380. tests := []struct {
  381. actual []int64
  382. got int64
  383. }{
  384. {
  385. actual: []int64{
  386. 1730736000, // 2024-11-05 00:00:00
  387. 1730772000, // 2024-11-05 10:00:00
  388. },
  389. got: 0,
  390. },
  391. {
  392. actual: []int64{
  393. 1730772000, // 2024-11-05 10:00:00
  394. 1730908800, // 2024-11-07 00:00:00
  395. },
  396. got: 2,
  397. },
  398. {
  399. actual: []int64{
  400. 1730908800, // 2024-11-07 00:00:00
  401. 1730772000, // 2024-11-05 10:00:00
  402. },
  403. got: -2,
  404. },
  405. }
  406. for _, v := range tests {
  407. got := DaysBetween(v.actual[0], v.actual[1])
  408. assert.Equal(t, got, v.got)
  409. }
  410. }
  411. func TestGetNeckRingActiveTimer(t *testing.T) {
  412. nowTime := time.Now().Local().Format(Layout)
  413. tests := struct {
  414. frameId []int32
  415. dateTime []string
  416. hours []int32
  417. }{
  418. frameId: []int32{
  419. 1, 2, 3, 4, 5, 6,
  420. 11, 12, 13, 14, 15, 16,
  421. 21, 22, 23, 24, 25, 26,
  422. 31, 32, 33, 34, 35, 36,
  423. 41, 42, 43, 44, 45, 46,
  424. 51, 52, 53, 54, 55, 56,
  425. 61, 62, 63, 64, 65, 66,
  426. 71, 72, 73, 74, 75, 76,
  427. 81, 82, 83, 84, 85, 86,
  428. 91, 92, 93, 94, 95, 96,
  429. 101, 102, 103, 104, 105, 106,
  430. 111, 112, 113, 114, 115, 116,
  431. 8, 18, 28, 38, 48, 58, 68, 78, 88, 98, 108, 118,
  432. },
  433. hours: []int32{
  434. 0, 0, 1, 1, 1, 2,
  435. 2, 2, 3, 3, 3, 4,
  436. 4, 4, 5, 5, 5, 6,
  437. 6, 6, 7, 7, 7, 8,
  438. 8, 8, 9, 9, 9, 10,
  439. 10, 10, 11, 11, 11, 12,
  440. 12, 12, 13, 13, 13, 14,
  441. 14, 14, 15, 15, 15, 16,
  442. 16, 16, 17, 17, 17, 18,
  443. 18, 18, 19, 19, 19, 20,
  444. 20, 20, 21, 21, 21, 22,
  445. 22, 22, 23, 23, 23, 24,
  446. 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 0,
  447. },
  448. dateTime: []string{
  449. fmt.Sprintf("%s 00:20:00", nowTime), fmt.Sprintf("%s 00:40:00", nowTime), fmt.Sprintf("%s 01:00:00", nowTime),
  450. fmt.Sprintf("%s 01:20:00", nowTime), fmt.Sprintf("%s 01:40:00", nowTime), fmt.Sprintf("%s 02:00:00", nowTime),
  451. fmt.Sprintf("%s 02:20:00", nowTime), fmt.Sprintf("%s 02:40:00", nowTime), fmt.Sprintf("%s 03:00:00", nowTime),
  452. fmt.Sprintf("%s 03:20:00", nowTime), fmt.Sprintf("%s 03:40:00", nowTime), fmt.Sprintf("%s 04:00:00", nowTime),
  453. fmt.Sprintf("%s 04:20:00", nowTime), fmt.Sprintf("%s 04:40:00", nowTime), fmt.Sprintf("%s 05:00:00", nowTime),
  454. fmt.Sprintf("%s 05:20:00", nowTime), fmt.Sprintf("%s 05:40:00", nowTime), fmt.Sprintf("%s 06:00:00", nowTime),
  455. fmt.Sprintf("%s 06:20:00", nowTime), fmt.Sprintf("%s 06:40:00", nowTime), fmt.Sprintf("%s 07:00:00", nowTime),
  456. fmt.Sprintf("%s 07:20:00", nowTime), fmt.Sprintf("%s 07:40:00", nowTime), fmt.Sprintf("%s 08:00:00", nowTime),
  457. fmt.Sprintf("%s 08:20:00", nowTime), fmt.Sprintf("%s 08:40:00", nowTime), fmt.Sprintf("%s 09:00:00", nowTime),
  458. fmt.Sprintf("%s 09:20:00", nowTime), fmt.Sprintf("%s 09:40:00", nowTime), fmt.Sprintf("%s 10:00:00", nowTime),
  459. fmt.Sprintf("%s 10:20:00", nowTime), fmt.Sprintf("%s 10:40:00", nowTime), fmt.Sprintf("%s 11:00:00", nowTime),
  460. fmt.Sprintf("%s 11:20:00", nowTime), fmt.Sprintf("%s 11:40:00", nowTime), fmt.Sprintf("%s 12:00:00", nowTime),
  461. fmt.Sprintf("%s 12:20:00", nowTime), fmt.Sprintf("%s 12:40:00", nowTime), fmt.Sprintf("%s 13:00:00", nowTime),
  462. fmt.Sprintf("%s 13:20:00", nowTime), fmt.Sprintf("%s 13:40:00", nowTime), fmt.Sprintf("%s 14:00:00", nowTime),
  463. fmt.Sprintf("%s 14:20:00", nowTime), fmt.Sprintf("%s 14:40:00", nowTime), fmt.Sprintf("%s 15:00:00", nowTime),
  464. fmt.Sprintf("%s 15:20:00", nowTime), fmt.Sprintf("%s 15:40:00", nowTime), fmt.Sprintf("%s 16:00:00", nowTime),
  465. fmt.Sprintf("%s 16:20:00", nowTime), fmt.Sprintf("%s 16:40:00", nowTime), fmt.Sprintf("%s 17:00:00", nowTime),
  466. fmt.Sprintf("%s 17:20:00", nowTime), fmt.Sprintf("%s 17:40:00", nowTime), fmt.Sprintf("%s 18:00:00", nowTime),
  467. fmt.Sprintf("%s 18:20:00", nowTime), fmt.Sprintf("%s 18:40:00", nowTime), fmt.Sprintf("%s 19:00:00", nowTime),
  468. fmt.Sprintf("%s 19:20:00", nowTime), fmt.Sprintf("%s 19:40:00", nowTime), fmt.Sprintf("%s 20:00:00", nowTime),
  469. fmt.Sprintf("%s 20:20:00", nowTime), fmt.Sprintf("%s 20:40:00", nowTime), fmt.Sprintf("%s 21:00:00", nowTime),
  470. fmt.Sprintf("%s 21:20:00", nowTime), fmt.Sprintf("%s 21:40:00", nowTime), fmt.Sprintf("%s 22:00:00", nowTime),
  471. fmt.Sprintf("%s 22:20:00", nowTime), fmt.Sprintf("%s 22:40:00", nowTime), fmt.Sprintf("%s 23:00:00", nowTime),
  472. fmt.Sprintf("%s 23:20:00", nowTime), fmt.Sprintf("%s 23:40:00", nowTime), fmt.Sprintf("%s 24:00:00", nowTime),
  473. fmt.Sprintf("%s 02:00:00", nowTime), fmt.Sprintf("%s 04:00:00", nowTime), fmt.Sprintf("%s 06:00:00", nowTime),
  474. fmt.Sprintf("%s 08:00:00", nowTime), fmt.Sprintf("%s 10:00:00", nowTime), fmt.Sprintf("%s 12:00:00", nowTime),
  475. fmt.Sprintf("%s 14:00:00", nowTime), fmt.Sprintf("%s 16:00:00", nowTime), fmt.Sprintf("%s 18:00:00", nowTime),
  476. fmt.Sprintf("%s 20:00:00", nowTime), fmt.Sprintf("%s 22:00:00", nowTime), fmt.Sprintf("%s 00:00:00", nowTime),
  477. },
  478. }
  479. for i, frameId := range tests.frameId {
  480. got, hours := GetNeckRingActiveTimer(frameId)
  481. t.Logf("frameId: %d, test-hours: %d,hours:%d got :%s", frameId, tests.hours[i], hours, got)
  482. //assert.Equal(t, got, tests.dateTime[i])
  483. assert.Equal(t, int32(hours), tests.hours[i])
  484. }
  485. }
  486. func TestSubstr(t *testing.T) {
  487. nowTime := time.Now().Local().Format(Layout)
  488. text := `102053 0 0 53 12.2 4.7 101415 101538 0.4 0 0 0 ???????? 000000 0.0 0.0 0.0 0.0 0`
  489. fmt.Println()
  490. detachTime := fmt.Sprintf("%s %s:%s:%s", nowTime, Substr(text, 0, 2), Substr(text, 2, 2), Substr(text, 4, 2))
  491. varCowCode := fmt.Sprintf("%s", Substr(text, 7, 6))
  492. detacherAddress := fmt.Sprintf("%s", Substr(text, 20, 2))
  493. milkWeight := fmt.Sprintf("%s", strings.TrimSpace(Substr(text, 25, 4)))
  494. s1 := strings.TrimSpace(Substr(text, 0, 6))
  495. s2 := strings.TrimSpace(Substr(text, 25, 4))
  496. fmt.Println("detachTime", detachTime, varCowCode, detacherAddress, milkWeight, s1, s2)
  497. fmt.Println("milkWeight:", milkWeight, strings.TrimSpace(Substr(text, 25, 4)))
  498. milkWeight1, err := strconv.ParseInt(strings.TrimSpace(Substr(text, 25, 4)), 10, 64)
  499. fmt.Println("milkWeight1:", milkWeight1, err)
  500. }
  501. type WeeklyActiveModel struct {
  502. CowId int64 `json:"cow_id"`
  503. HeatDate string `json:"heat_date"`
  504. Nb int32 `json:"nb"`
  505. High int32 `json:"high"`
  506. }
  507. func Test_demo(t *testing.T) {
  508. weeklyActiveModelList := make([]*WeeklyActiveModel, 0)
  509. weeklyActiveModelList = append(weeklyActiveModelList, &WeeklyActiveModel{
  510. CowId: 8859,
  511. HeatDate: "2025-04-08",
  512. Nb: 12,
  513. High: 1633,
  514. }, &WeeklyActiveModel{
  515. CowId: 8859,
  516. HeatDate: "2025-04-09",
  517. Nb: 12,
  518. High: 1697,
  519. }, &WeeklyActiveModel{
  520. CowId: 8859,
  521. HeatDate: "2025-04-10",
  522. Nb: 12,
  523. High: 1588,
  524. }, &WeeklyActiveModel{
  525. CowId: 8859,
  526. HeatDate: "2025-04-11",
  527. Nb: 12,
  528. High: 1789,
  529. }, &WeeklyActiveModel{
  530. CowId: 8859,
  531. HeatDate: "2025-04-12",
  532. Nb: 12,
  533. High: 1822,
  534. }, &WeeklyActiveModel{
  535. CowId: 8859,
  536. HeatDate: "2025-04-13",
  537. Nb: 12,
  538. High: 1672,
  539. }, &WeeklyActiveModel{
  540. CowId: 8859,
  541. HeatDate: "2025-04-14",
  542. Nb: 12,
  543. High: 1817,
  544. })
  545. // 1. 先按High值排序
  546. sort.Slice(weeklyActiveModelList, func(i, j int) bool {
  547. return weeklyActiveModelList[i].High < weeklyActiveModelList[j].High
  548. })
  549. countHigh := len(weeklyActiveModelList)
  550. sumHigh := int32(0)
  551. minHigh := weeklyActiveModelList[0].High
  552. maxHigh := weeklyActiveModelList[len(weeklyActiveModelList)-1].High
  553. for _, v := range weeklyActiveModelList {
  554. sumHigh += v.High
  555. }
  556. diff := 2
  557. x := int32(0)
  558. if countHigh > 3 {
  559. diff = 3
  560. x = weeklyActiveModelList[1].High
  561. }
  562. fmt.Println("sumHigh", sumHigh)
  563. fmt.Println("minHigh", minHigh)
  564. fmt.Println("maxHigh", maxHigh)
  565. fmt.Println("x", x)
  566. fmt.Println("diff", diff, "countHigh", countHigh)
  567. avgHigh := float64(sumHigh-minHigh-maxHigh-x) / float64(countHigh-diff)
  568. fmt.Println(int32(avgHigh))
  569. }