diff --git a/index/timeframe.go b/index/timeframe.go index a73e28328..a6d9e5f6d 100644 --- a/index/timeframe.go +++ b/index/timeframe.go @@ -11,42 +11,155 @@ const ( YMDH ) -func PackTimeBits(t TimeQuantum, year uint, month uint, day uint, hour uint) uint64 { - v := uint64((uint(t) << 30) | (year << 24) | (month << 20) | (day << 15) | (hour << 10)) - v = v << 32 - return v +func GetTimeID(t TimeQuantum, year uint, month uint, day uint, hour uint, tile_id uint64) uint64 { + y := year - 2014 //config.startyear + time_stamp := uint64((uint(t) << 30) | (y << 24) | (month << 20) | (day << 15) | (hour << 10)) + time_stamp = time_stamp << 32 + return time_stamp | tile_id } -func getTimeIds(tile_id uint64, atime time.Time, min_quantum TimeQuantum, offset uint) []uint64 { +func getTimeIds(tile_id uint64, atime time.Time, min_quantum TimeQuantum) []uint64 { results := make([]uint64, 0, 4) - year := uint(atime.Year()) - offset + year := uint(atime.Year()) month := atime.Month() day := atime.Day() hour := atime.Hour() if min_quantum <= Y { - id := PackTimeBits(Y, year, 0, 0, 0) - id = id | tile_id + id := GetTimeID(Y, year, 0, 0, 0, tile_id) results = append(results, id) } if min_quantum <= YM { - id := PackTimeBits(YM, uint(year), uint(month), 0, 0) - id = id | tile_id + id := GetTimeID(YM, uint(year), uint(month), 0, 0, tile_id) results = append(results, id) } if min_quantum <= YMD { - id := PackTimeBits(YMD, year, uint(month), uint(day), 0) - id = id | tile_id + id := GetTimeID(YMD, year, uint(month), uint(day), 0, tile_id) results = append(results, id) } if min_quantum <= YMDH { - id := PackTimeBits(Y, year, uint(month), uint(day), uint(hour)) - id = id | tile_id + id := GetTimeID(Y, year, uint(month), uint(day), uint(hour), tile_id) results = append(results, id) } return results } + +func IncrementYear(t time.Time) time.Time { + return t.AddDate(1, 0, 0) +} +func IncrementMonth(t time.Time) time.Time { + return t.AddDate(0, 1, 0) +} +func IncrementDay(t time.Time) time.Time { + return t.AddDate(0, 0, 1) +} +func IncrementHour(t time.Time) time.Time { + return t.Add(time.Hour) +} + +func sameYear(t1, t2 time.Time) bool { + y1, _, _ := t1.Date() + y2, _, _ := t2.Date() + return (y1 == y2) +} + +func NextYear(start time.Time, end time.Time) bool { + nextYear := start.AddDate(1, 0, 0) + return sameYear(nextYear, end) || end.After(nextYear) +} + +func sameMonth(t1, t2 time.Time) bool { + y1, m1, _ := t1.Date() + y2, m2, _ := t2.Date() + return (y1 == y2) && (m1 == m2) +} + +func NextMonth(start time.Time, end time.Time) bool { + nextMonth := start.AddDate(0, 1, 0) + return sameMonth(nextMonth, end) || end.After(nextMonth) +} +func sameDay(t1, t2 time.Time) bool { + y1, m1, d1 := t1.Date() + y2, m2, d2 := t2.Date() + return (y1 == y2) && (m1 == m2) && (d1 == d2) +} +func NextDay(start time.Time, end time.Time) bool { + nextDay := start.AddDate(0, 0, 1) + return sameDay(nextDay, end) || end.After(nextDay) +} +func GetRange(start_time time.Time, end_time time.Time, tile_id uint64) []uint64 { + results, marker := upHill(start_time, end_time, tile_id) + r2 := downHill(marker, end_time, tile_id) + results = append(results, r2...) + return results +} + +func upHill(start_time time.Time, end_time time.Time, tile_id uint64) ([]uint64, time.Time) { + var results []uint64 + time_iterator := start_time + for time_iterator.Before(end_time) { + if NextDay(time_iterator, end_time) { + if time_iterator.Hour() == 0 { + if NextMonth(time_iterator, end_time) { + if time_iterator.Day() == 1 { + if NextYear(time_iterator, end_time) { + if time_iterator.Month() == 1 { + break + } else { + + month_id := GetTimeID(YM, uint(time_iterator.Year()), uint(time_iterator.Month()), 0, 0, tile_id) + results = append(results, month_id) + time_iterator = IncrementMonth(time_iterator) + } + } else { + break + } + } else { + day_id := GetTimeID(YMD, uint(time_iterator.Year()), uint(time_iterator.Month()), uint(time_iterator.Day()), 0, tile_id) + results = append(results, day_id) + time_iterator = IncrementDay(time_iterator) + } + } else { + break + } + } else { + hour_id := GetTimeID(YMDH, uint(time_iterator.Year()), uint(time_iterator.Month()), uint(time_iterator.Day()), uint(time_iterator.Hour()), tile_id) + results = append(results, hour_id) + time_iterator = IncrementHour(time_iterator) + } + } else { + break + } + } + return results, time_iterator + +} +func downHill(start_time time.Time, end_time time.Time, tile_id uint64) []uint64 { + + var results []uint64 + time_iterator := start_time + for time_iterator.Before(end_time) { + if NextYear(time_iterator, end_time) { + year_id := GetTimeID(Y, uint(time_iterator.Year()), 0, 0, 0, tile_id) + results = append(results, year_id) + time_iterator = IncrementYear(time_iterator) + } else if NextMonth(time_iterator, end_time) { + month_id := GetTimeID(YM, uint(time_iterator.Year()), uint(time_iterator.Month()), 0, 0, tile_id) + results = append(results, month_id) + time_iterator = IncrementMonth(time_iterator) + } else if NextDay(time_iterator, end_time) { + day_id := GetTimeID(YMD, uint(time_iterator.Year()), uint(time_iterator.Month()), uint(time_iterator.Day()), 0, tile_id) + results = append(results, day_id) + time_iterator = IncrementDay(time_iterator) + } else { + hour_id := GetTimeID(YMDH, uint(time_iterator.Year()), uint(time_iterator.Month()), uint(time_iterator.Day()), uint(time_iterator.Hour()), tile_id) + results = append(results, hour_id) + time_iterator = IncrementHour(time_iterator) + } + } + return results +} diff --git a/index/timeframe_test.go b/index/timeframe_test.go index 34bfceaee..37683a21d 100644 --- a/index/timeframe_test.go +++ b/index/timeframe_test.go @@ -16,9 +16,85 @@ func TestTimeFrame(t *testing.T) { x, _ := time.Parse(shortForm, "2014-01-01 10:03") fmt.Println(x) - m := getTimeIds(uint64(1), x, YMDH, 2014) + m := getTimeIds(uint64(1), x, YMDH) spew.Dump(m) So(1, ShouldEqual, 1) }) + Convey("Test 1H", t, func() { + const shortForm = "2006-01-02 15:04" + t1, _ := time.Parse(shortForm, "2014-01-02 10:03") + t2, _ := time.Parse(shortForm, "2014-01-02 11:03") + m := GetRange(t1, t2, uint64(1)) + So(len(m), ShouldEqual, 1) + }) + Convey("Test 2H", t, func() { + const shortForm = "2006-01-02 15:04" + t1, _ := time.Parse(shortForm, "2014-01-02 10:03") + t2, _ := time.Parse(shortForm, "2014-01-02 12:03") + m := GetRange(t1, t2, uint64(1)) + So(len(m), ShouldEqual, 2) + }) + + Convey("Test 24H", t, func() { + const shortForm = "2006-01-02 15:04" + t1, _ := time.Parse(shortForm, "2014-01-02 12:03") + t2, _ := time.Parse(shortForm, "2014-01-03 12:03") + m := GetRange(t1, t2, uint64(1)) + So(len(m), ShouldEqual, 24) + }) + Convey("Test 1D", t, func() { + const shortForm = "2006-01-02 15:04" + t1, _ := time.Parse(shortForm, "2014-01-02 00:00") + t2, _ := time.Parse(shortForm, "2014-01-03 00:00") + m := GetRange(t1, t2, uint64(1)) + So(len(m), ShouldEqual, 1) + }) + + Convey("Test 1D1H", t, func() { + const shortForm = "2006-01-02 15:04" + t1, _ := time.Parse(shortForm, "2014-01-02 00:00") + t2, _ := time.Parse(shortForm, "2014-01-03 01:00") + m := GetRange(t1, t2, uint64(1)) + So(len(m), ShouldEqual, 2) + }) + + Convey("Test 1H1D", t, func() { + const shortForm = "2006-01-02 15:04" + t1, _ := time.Parse(shortForm, "2014-01-02 23:00") + t2, _ := time.Parse(shortForm, "2014-01-04 00:00") + m := GetRange(t1, t2, uint64(1)) + So(len(m), ShouldEqual, 2) + }) + + Convey("Test 1H1D1H", t, func() { + const shortForm = "2006-01-02 15:04" + t1, _ := time.Parse(shortForm, "2014-01-02 23:00") + t2, _ := time.Parse(shortForm, "2014-01-04 01:00") + m := GetRange(t1, t2, uint64(1)) + So(len(m), ShouldEqual, 3) + }) + + Convey("Test 1Y", t, func() { + const shortForm = "2006-01-02 15:04" + t1, _ := time.Parse(shortForm, "2014-01-01 00:00") + t2, _ := time.Parse(shortForm, "2015-01-01 00:00") + m := GetRange(t1, t2, uint64(1)) + So(len(m), ShouldEqual, 1) + }) + Convey("Test 1H1D1M", t, func() { + const shortForm = "2006-01-02 15:04" + t1, _ := time.Parse(shortForm, "2014-01-30 23:00") + t2, _ := time.Parse(shortForm, "2014-03-01 00:00") + m := GetRange(t1, t2, uint64(1)) + So(len(m), ShouldEqual, 3) + }) + + Convey("Test 1H1D1MD1H1", t, func() { + const shortForm = "2006-01-02 15:04" + t1, _ := time.Parse(shortForm, "2014-01-30 23:00") + t2, _ := time.Parse(shortForm, "2014-03-02 01:00") + m := GetRange(t1, t2, uint64(1)) + So(len(m), ShouldEqual, 5) + }) }