1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/hanchuanchuan-goInception

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Это зеркальный репозиторий, синхронизируется ежедневно с исходного репозитория.
Клонировать/Скачать
time_test.go 30 КБ
Копировать Редактировать Исходные данные Просмотреть построчно История
hanchuanchuan Отправлено 6 лет назад 27f3c5a
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047
// Copyright 2015 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.
package types_test
import (
"math"
"time"
"github.com/hanchuanchuan/goInception/mysql"
"github.com/hanchuanchuan/goInception/sessionctx/stmtctx"
"github.com/hanchuanchuan/goInception/types"
"github.com/hanchuanchuan/goInception/util/mock"
"github.com/hanchuanchuan/goInception/util/testleak"
. "github.com/pingcap/check"
)
var _ = Suite(&testTimeSuite{})
type testTimeSuite struct {
}
func (s *testTimeSuite) TestDateTime(c *C) {
sc := mock.NewContext().GetSessionVars().StmtCtx
sc.IgnoreZeroInDate = true
defer testleak.AfterTest(c)()
table := []struct {
Input string
Expect string
}{
{"2012-12-31 11:30:45", "2012-12-31 11:30:45"},
{"0000-00-00 00:00:00", "0000-00-00 00:00:00"},
{"0001-01-01 00:00:00", "0001-01-01 00:00:00"},
{"00-12-31 11:30:45", "2000-12-31 11:30:45"},
{"12-12-31 11:30:45", "2012-12-31 11:30:45"},
{"2012-12-31", "2012-12-31 00:00:00"},
{"20121231", "2012-12-31 00:00:00"},
{"121231", "2012-12-31 00:00:00"},
{"2012^12^31 11+30+45", "2012-12-31 11:30:45"},
{"2012^12^31T11+30+45", "2012-12-31 11:30:45"},
{"2012-2-1 11:30:45", "2012-02-01 11:30:45"},
{"12-2-1 11:30:45", "2012-02-01 11:30:45"},
{"20121231113045", "2012-12-31 11:30:45"},
{"121231113045", "2012-12-31 11:30:45"},
{"2012-02-29", "2012-02-29 00:00:00"},
{"00-00-00", "0000-00-00 00:00:00"},
{"00-00-00 00:00:00.123", "2000-00-00 00:00:00.123"},
{"11111111111", "2011-11-11 11:11:01"},
{"1701020301.", "2017-01-02 03:01:00"},
{"1701020304.1", "2017-01-02 03:04:01.0"},
{"1701020302.11", "2017-01-02 03:02:11.00"},
{"170102036", "2017-01-02 03:06:00"},
{"170102039.", "2017-01-02 03:09:00"},
{"170102037.11", "2017-01-02 03:07:11.00"},
}
for _, test := range table {
t, err := types.ParseDatetime(sc, test.Input)
c.Assert(err, IsNil)
c.Assert(t.String(), Equals, test.Expect)
}
fspTbl := []struct {
Input string
Fsp int
Expect string
}{
{"20170118.123", 6, "2017-01-18 12:03:00.000000"},
{"121231113045.123345", 6, "2012-12-31 11:30:45.123345"},
{"20121231113045.123345", 6, "2012-12-31 11:30:45.123345"},
{"121231113045.9999999", 6, "2012-12-31 11:30:46.000000"},
{"170105084059.575601", 0, "2017-01-05 08:41:00"},
{"2017-01-05 23:59:59.575601", 0, "2017-01-06 00:00:00"},
{"2017-01-31 23:59:59.575601", 0, "2017-02-01 00:00:00"},
{"2017-00-05 23:59:58.575601", 3, "2017-00-05 23:59:58.576"},
}
for _, test := range fspTbl {
t, err := types.ParseTime(sc, test.Input, mysql.TypeDatetime, test.Fsp)
c.Assert(err, IsNil)
c.Assert(t.String(), Equals, test.Expect)
}
t, _ := types.ParseTime(sc, "121231113045.9999999", mysql.TypeDatetime, 6)
c.Assert(t.Time.Second(), Equals, 46)
c.Assert(t.Time.Microsecond(), Equals, 0)
// test error
errTable := []string{
"1000-01-01 00:00:70",
"1000-13-00 00:00:00",
"10000-01-01 00:00:00",
"1000-09-31 00:00:00",
"1001-02-29 00:00:00",
"20170118.999",
}
for _, test := range errTable {
_, err := types.ParseDatetime(sc, test)
c.Assert(err, NotNil)
}
}
func (s *testTimeSuite) TestTimestamp(c *C) {
defer testleak.AfterTest(c)()
table := []struct {
Input string
Expect string
}{
{"2012-12-31 11:30:45", "2012-12-31 11:30:45"},
}
for _, test := range table {
t, err := types.ParseTimestamp(&stmtctx.StatementContext{TimeZone: time.UTC}, test.Input)
c.Assert(err, IsNil)
c.Assert(t.String(), Equals, test.Expect)
}
errTable := []string{
"2048-12-31 11:30:45",
"1969-12-31 11:30:45",
}
for _, test := range errTable {
_, err := types.ParseTimestamp(&stmtctx.StatementContext{TimeZone: time.UTC}, test)
c.Assert(err, NotNil)
}
}
func (s *testTimeSuite) TestDate(c *C) {
sc := mock.NewContext().GetSessionVars().StmtCtx
sc.IgnoreZeroInDate = true
defer testleak.AfterTest(c)()
table := []struct {
Input string
Expect string
}{
{"2012-12-31", "2012-12-31"},
{"00-12-31", "2000-12-31"},
{"20121231", "2012-12-31"},
{"121231", "2012-12-31"},
{"2015-06-01 12:12:12", "2015-06-01"},
{"0001-01-01 00:00:00", "0001-01-01"},
{"0001-01-01", "0001-01-01"},
}
for _, test := range table {
t, err := types.ParseDate(sc, test.Input)
c.Assert(err, IsNil)
c.Assert(t.String(), Equals, test.Expect)
}
errTable := []string{
"0121231",
}
for _, test := range errTable {
_, err := types.ParseDate(sc, test)
c.Assert(err, NotNil)
}
}
func (s *testTimeSuite) TestTime(c *C) {
sc := mock.NewContext().GetSessionVars().StmtCtx
sc.IgnoreZeroInDate = true
defer testleak.AfterTest(c)()
table := []struct {
Input string
Expect string
}{
{"10:11:12", "10:11:12"},
{"101112", "10:11:12"},
{"020005", "02:00:05"},
{"112", "00:01:12"},
{"10:11", "10:11:00"},
{"101112.123456", "10:11:12"},
{"1112", "00:11:12"},
{"1", "00:00:01"},
{"12", "00:00:12"},
{"1 12", "36:00:00"},
{"1 10:11:12", "34:11:12"},
{"1 10:11:12.123456", "34:11:12"},
{"10:11:12.123456", "10:11:12"},
{"1 10:11", "34:11:00"},
{"1 10", "34:00:00"},
{"24 10", "586:00:00"},
{"-24 10", "-586:00:00"},
{"0 10", "10:00:00"},
{"-10:10:10", "-10:10:10"},
{"-838:59:59", "-838:59:59"},
{"838:59:59", "838:59:59"},
{"2011-11-11 00:00:01", "00:00:01"},
{"2011-11-11", "00:00:00"},
}
for _, test := range table {
t, err := types.ParseDuration(sc, test.Input, types.MinFsp)
c.Assert(err, IsNil)
c.Assert(t.String(), Equals, test.Expect)
}
table = []struct {
Input string
Expect string
}{
{"101112.123456", "10:11:12.123456"},
{"1 10:11:12.123456", "34:11:12.123456"},
{"10:11:12.123456", "10:11:12.123456"},
}
for _, test := range table {
t, err := types.ParseDuration(sc, test.Input, types.MaxFsp)
c.Assert(err, IsNil)
c.Assert(t.String(), Equals, test.Expect)
}
errTable := []string{
"232 10",
"-232 10",
}
for _, test := range errTable {
_, err := types.ParseDuration(sc, test, types.DefaultFsp)
c.Assert(err, NotNil)
}
// test time compare
cmpTable := []struct {
lhs int64
rhs int64
ret int
}{
{1, 0, 1},
{0, 1, -1},
{0, 0, 0},
}
for _, t := range cmpTable {
t1 := types.Duration{
Duration: time.Duration(t.lhs),
Fsp: types.DefaultFsp,
}
t2 := types.Duration{
Duration: time.Duration(t.rhs),
Fsp: types.DefaultFsp,
}
ret := t1.Compare(t2)
c.Assert(ret, Equals, t.ret)
}
}
func (s *testTimeSuite) TestDurationAdd(c *C) {
defer testleak.AfterTest(c)()
table := []struct {
Input string
Fsp int
InputAdd string
FspAdd int
Expect string
}{
{"00:00:00.1", 1, "00:00:00.1", 1, "00:00:00.2"},
{"00:00:00", 0, "00:00:00.1", 1, "00:00:00.1"},
{"00:00:00.09", 2, "00:00:00.01", 2, "00:00:00.10"},
{"00:00:00.099", 3, "00:00:00.001", 3, "00:00:00.100"},
}
for _, test := range table {
t, err := types.ParseDuration(nil, test.Input, test.Fsp)
c.Assert(err, IsNil)
ta, err := types.ParseDuration(nil, test.InputAdd, test.FspAdd)
c.Assert(err, IsNil)
result, err := t.Add(ta)
c.Assert(err, IsNil)
c.Assert(result.String(), Equals, test.Expect)
}
t, err := types.ParseDuration(nil, "00:00:00", 0)
c.Assert(err, IsNil)
ta := new(types.Duration)
result, err := t.Add(*ta)
c.Assert(err, IsNil)
c.Assert(result.String(), Equals, "00:00:00")
t = types.Duration{Duration: math.MaxInt64, Fsp: 0}
tatmp, err := types.ParseDuration(nil, "00:01:00", 0)
c.Assert(err, IsNil)
_, err = t.Add(tatmp)
c.Assert(err, NotNil)
}
func (s *testTimeSuite) TestDurationSub(c *C) {
sc := mock.NewContext().GetSessionVars().StmtCtx
sc.IgnoreZeroInDate = true
defer testleak.AfterTest(c)()
table := []struct {
Input string
Fsp int
InputAdd string
FspAdd int
Expect string
}{
{"00:00:00.1", 1, "00:00:00.1", 1, "00:00:00.0"},
{"00:00:00", 0, "00:00:00.1", 1, "-00:00:00.1"},
}
for _, test := range table {
t, err := types.ParseDuration(sc, test.Input, test.Fsp)
c.Assert(err, IsNil)
ta, err := types.ParseDuration(sc, test.InputAdd, test.FspAdd)
c.Assert(err, IsNil)
result, err := t.Sub(ta)
c.Assert(err, IsNil)
c.Assert(result.String(), Equals, test.Expect)
}
}
func (s *testTimeSuite) TestTimeFsp(c *C) {
sc := mock.NewContext().GetSessionVars().StmtCtx
sc.IgnoreZeroInDate = true
defer testleak.AfterTest(c)()
table := []struct {
Input string
Fsp int
Expect string
}{
{"00:00:00.1", 0, "00:00:00"},
{"00:00:00.1", 1, "00:00:00.1"},
{"00:00:00.777777", 2, "00:00:00.78"},
{"00:00:00.777777", 6, "00:00:00.777777"},
// fsp -1 use default 0
{"00:00:00.777777", -1, "00:00:01"},
{"00:00:00.001", 3, "00:00:00.001"},
// fsp round overflow 60 seconds
{"08:29:59.537368", 0, "08:30:00"},
{"08:59:59.537368", 0, "09:00:00"},
}
for _, test := range table {
t, err := types.ParseDuration(sc, test.Input, test.Fsp)
c.Assert(err, IsNil)
c.Assert(t.String(), Equals, test.Expect)
}
errTable := []struct {
Input string
Fsp int
}{
{"00:00:00.1", -2},
{"00:00:00.1", 7},
}
for _, test := range errTable {
_, err := types.ParseDuration(sc, test.Input, test.Fsp)
c.Assert(err, NotNil)
}
}
func (s *testTimeSuite) TestYear(c *C) {
defer testleak.AfterTest(c)()
table := []struct {
Input string
Expect int16
}{
{"1990", 1990},
{"10", 2010},
{"0", 2000},
{"99", 1999},
}
for _, test := range table {
t, err := types.ParseYear(test.Input)
c.Assert(err, IsNil)
c.Assert(t, Equals, test.Expect)
}
valids := []struct {
Year int64
Expect bool
}{
{2000, true},
{20000, false},
{0, true},
{-1, false},
}
for _, test := range valids {
_, err := types.AdjustYear(test.Year)
if test.Expect {
c.Assert(err, IsNil)
} else {
c.Assert(err, NotNil)
}
}
}
func (s *testTimeSuite) getLocation(c *C) *time.Location {
locations := []string{"Asia/Shanghai", "Europe/Berlin"}
timeFormat := "Jan 2, 2006 at 3:04pm (MST)"
z, err := time.LoadLocation(locations[0])
c.Assert(err, IsNil)
t1, err := time.ParseInLocation(timeFormat, "Jul 9, 2012 at 5:02am (CEST)", z)
c.Assert(err, IsNil)
t2, err := time.Parse(timeFormat, "Jul 9, 2012 at 5:02am (CEST)")
c.Assert(err, IsNil)
if t1.Equal(t2) {
z, err = time.LoadLocation(locations[1])
c.Assert(err, IsNil)
}
return z
}
func (s *testTimeSuite) TestCodec(c *C) {
defer testleak.AfterTest(c)()
sc := &stmtctx.StatementContext{TimeZone: time.UTC}
// MySQL timestamp value doesn't allow month=0 or day=0.
t, err := types.ParseTimestamp(sc, "2016-12-00 00:00:00")
c.Assert(err, NotNil)
t, err = types.ParseTimestamp(sc, "2010-10-10 10:11:11")
c.Assert(err, IsNil)
packed, err := t.ToPackedUint()
c.Assert(err, IsNil)
var t1 types.Time
t1.Type = mysql.TypeTimestamp
t1.Time = types.FromGoTime(time.Now())
packed, err = t1.ToPackedUint()
c.Assert(err, IsNil)
var t2 types.Time
t2.Type = mysql.TypeTimestamp
err = t2.FromPackedUint(packed)
c.Assert(err, IsNil)
c.Assert(t1.String(), Equals, t2.String())
packed, _ = types.ZeroDatetime.ToPackedUint()
var t3 types.Time
t3.Type = mysql.TypeDatetime
err = t3.FromPackedUint(packed)
c.Assert(err, IsNil)
c.Assert(t3.String(), Equals, types.ZeroDatetime.String())
t, err = types.ParseDatetime(nil, "0001-01-01 00:00:00")
c.Assert(err, IsNil)
packed, _ = t.ToPackedUint()
var t4 types.Time
t4.Type = mysql.TypeDatetime
err = t4.FromPackedUint(packed)
c.Assert(err, IsNil)
c.Assert(t.String(), Equals, t4.String())
tbl := []string{
"2000-01-01 00:00:00.000000",
"2000-01-01 00:00:00.123456",
"0001-01-01 00:00:00.123456",
"2000-06-01 00:00:00.999999",
}
for _, test := range tbl {
t, err := types.ParseTime(nil, test, mysql.TypeDatetime, types.MaxFsp)
c.Assert(err, IsNil)
packed, _ = t.ToPackedUint()
var dest types.Time
dest.Type = mysql.TypeDatetime
dest.Fsp = types.MaxFsp
err = dest.FromPackedUint(packed)
c.Assert(err, IsNil)
c.Assert(dest.String(), Equals, test)
}
}
func (s *testTimeSuite) TestParseTimeFromNum(c *C) {
defer testleak.AfterTest(c)()
table := []struct {
Input int64
ExpectDateTimeError bool
ExpectDateTimeValue string
ExpectTimeStampError bool
ExpectTimeStampValue string
ExpectDateError bool
ExpectDateValue string
}{
{20101010111111, false, "2010-10-10 11:11:11", false, "2010-10-10 11:11:11", false, "2010-10-10"},
{2010101011111, false, "0201-01-01 01:11:11", true, types.ZeroDatetimeStr, false, "0201-01-01"},
{201010101111, false, "2020-10-10 10:11:11", false, "2020-10-10 10:11:11", false, "2020-10-10"},
{20101010111, false, "2002-01-01 01:01:11", false, "2002-01-01 01:01:11", false, "2002-01-01"},
{2010101011, true, types.ZeroDatetimeStr, true, types.ZeroDatetimeStr, true, types.ZeroDateStr},
{201010101, false, "2000-02-01 01:01:01", false, "2000-02-01 01:01:01", false, "2000-02-01"},
{20101010, false, "2010-10-10 00:00:00", false, "2010-10-10 00:00:00", false, "2010-10-10"},
{2010101, true, types.ZeroDatetimeStr, true, types.ZeroDatetimeStr, true, types.ZeroDateStr},
{201010, false, "2020-10-10 00:00:00", false, "2020-10-10 00:00:00", false, "2020-10-10"},
{20101, false, "2002-01-01 00:00:00", false, "2002-01-01 00:00:00", false, "2002-01-01"},
{2010, true, types.ZeroDatetimeStr, true, types.ZeroDatetimeStr, true, types.ZeroDateStr},
{201, false, "2000-02-01 00:00:00", false, "2000-02-01 00:00:00", false, "2000-02-01"},
{20, true, types.ZeroDatetimeStr, true, types.ZeroDatetimeStr, true, types.ZeroDateStr},
{2, true, types.ZeroDatetimeStr, true, types.ZeroDatetimeStr, true, types.ZeroDateStr},
{0, false, types.ZeroDatetimeStr, false, types.ZeroDatetimeStr, false, types.ZeroDateStr},
{-1, true, types.ZeroDatetimeStr, true, types.ZeroDatetimeStr, true, types.ZeroDateStr},
{99999999999999, true, types.ZeroDatetimeStr, true, types.ZeroDatetimeStr, true, types.ZeroDateStr},
{100000000000000, true, types.ZeroDatetimeStr, true, types.ZeroDatetimeStr, true, types.ZeroDateStr},
{10000102000000, false, "1000-01-02 00:00:00", true, types.ZeroDatetimeStr, false, "1000-01-02"},
{19690101000000, false, "1969-01-01 00:00:00", true, types.ZeroDatetimeStr, false, "1969-01-01"},
{991231235959, false, "1999-12-31 23:59:59", false, "1999-12-31 23:59:59", false, "1999-12-31"},
{691231235959, false, "2069-12-31 23:59:59", true, types.ZeroDatetimeStr, false, "2069-12-31"},
{370119031407, false, "2037-01-19 03:14:07", false, "2037-01-19 03:14:07", false, "2037-01-19"},
{380120031407, false, "2038-01-20 03:14:07", true, types.ZeroDatetimeStr, false, "2038-01-20"},
{11111111111, false, "2001-11-11 11:11:11", false, "2001-11-11 11:11:11", false, "2001-11-11"},
}
for ith, test := range table {
// testtypes.ParseDatetimeFromNum
t, err := types.ParseDatetimeFromNum(nil, test.Input)
if test.ExpectDateTimeError {
c.Assert(err, NotNil, Commentf("%d", ith))
} else {
c.Assert(err, IsNil)
c.Assert(t.Type, Equals, mysql.TypeDatetime)
}
c.Assert(t.String(), Equals, test.ExpectDateTimeValue)
// testtypes.ParseTimestampFromNum
t, err = types.ParseTimestampFromNum(&stmtctx.StatementContext{
TimeZone: time.UTC,
}, test.Input)
if test.ExpectTimeStampError {
c.Assert(err, NotNil)
} else {
c.Assert(err, IsNil, Commentf("%d", ith))
c.Assert(t.Type, Equals, mysql.TypeTimestamp)
}
c.Assert(t.String(), Equals, test.ExpectTimeStampValue)
// testtypes.ParseDateFromNum
t, err = types.ParseDateFromNum(nil, test.Input)
if test.ExpectDateTimeError {
c.Assert(err, NotNil)
} else {
c.Assert(err, IsNil)
c.Assert(t.Type, Equals, mysql.TypeDate)
}
c.Assert(t.String(), Equals, test.ExpectDateValue)
}
}
func (s *testTimeSuite) TestToNumber(c *C) {
sc := mock.NewContext().GetSessionVars().StmtCtx
sc.IgnoreZeroInDate = true
defer testleak.AfterTest(c)()
tblDateTime := []struct {
Input string
Fsp int
Expect string
}{
{"12-12-31 11:30:45", 0, "20121231113045"},
{"12-12-31 11:30:45", 6, "20121231113045.000000"},
{"12-12-31 11:30:45.123", 6, "20121231113045.123000"},
{"12-12-31 11:30:45.123345", 0, "20121231113045"},
{"12-12-31 11:30:45.123345", 3, "20121231113045.123"},
{"12-12-31 11:30:45.123345", 5, "20121231113045.12335"},
{"12-12-31 11:30:45.123345", 6, "20121231113045.123345"},
{"12-12-31 11:30:45.1233457", 6, "20121231113045.123346"},
{"12-12-31 11:30:45.823345", 0, "20121231113046"},
}
for _, test := range tblDateTime {
t, err := types.ParseTime(nil, test.Input, mysql.TypeDatetime, test.Fsp)
c.Assert(err, IsNil)
c.Assert(t.ToNumber().String(), Equals, test.Expect)
}
// Fix issue #1046
tblDate := []struct {
Input string
Fsp int
Expect string
}{
{"12-12-31 11:30:45", 0, "20121231"},
{"12-12-31 11:30:45", 6, "20121231"},
{"12-12-31 11:30:45.123", 6, "20121231"},
{"12-12-31 11:30:45.123345", 0, "20121231"},
{"12-12-31 11:30:45.123345", 3, "20121231"},
{"12-12-31 11:30:45.123345", 5, "20121231"},
{"12-12-31 11:30:45.123345", 6, "20121231"},
{"12-12-31 11:30:45.1233457", 6, "20121231"},
{"12-12-31 11:30:45.823345", 0, "20121231"},
}
for _, test := range tblDate {
t, err := types.ParseTime(nil, test.Input, mysql.TypeDate, 0)
c.Assert(err, IsNil)
c.Assert(t.ToNumber().String(), Equals, test.Expect)
}
tblDuration := []struct {
Input string
Fsp int
Expect string
}{
{"11:30:45", 0, "113045"},
{"11:30:45", 6, "113045.000000"},
{"11:30:45.123", 6, "113045.123000"},
{"11:30:45.123345", 0, "113045"},
{"11:30:45.123345", 3, "113045.123"},
{"11:30:45.123345", 5, "113045.12335"},
{"11:30:45.123345", 6, "113045.123345"},
{"11:30:45.1233456", 6, "113045.123346"},
{"11:30:45.9233456", 0, "113046"},
{"-11:30:45.9233456", 0, "-113046"},
}
for _, test := range tblDuration {
t, err := types.ParseDuration(sc, test.Input, test.Fsp)
c.Assert(err, IsNil)
// now we can only changetypes.Duration's Fsp to check ToNumber with different Fsp
c.Assert(t.ToNumber().String(), Equals, test.Expect)
}
}
func (s *testTimeSuite) TestParseFrac(c *C) {
defer testleak.AfterTest(c)()
tbl := []struct {
S string
Fsp int
Ret int
Overflow bool
}{
// Round when fsp < string length.
{"1234567", 0, 0, false},
{"1234567", 1, 100000, false},
{"0000567", 5, 60, false},
{"1234567", 5, 123460, false},
{"1234567", 6, 123457, false},
// Fill 0 when fsp > string length.
{"123", 4, 123000, false},
{"123", 5, 123000, false},
{"123", 6, 123000, false},
{"11", 6, 110000, false},
{"01", 3, 10000, false},
{"012", 4, 12000, false},
{"0123", 5, 12300, false},
// Overflow
{"9999999", 6, 0, true},
{"999999", 5, 0, true},
{"999", 2, 0, true},
{"999", 3, 999000, false},
}
for _, t := range tbl {
v, overflow, err := types.ParseFrac(t.S, t.Fsp)
c.Assert(err, IsNil)
c.Assert(v, Equals, t.Ret)
c.Assert(overflow, Equals, t.Overflow)
}
}
func (s *testTimeSuite) TestRoundFrac(c *C) {
sc := mock.NewContext().GetSessionVars().StmtCtx
sc.IgnoreZeroInDate = true
sc.TimeZone = time.UTC
defer testleak.AfterTest(c)()
tbl := []struct {
Input string
Fsp int
Except string
}{
{"2012-12-31 11:30:45.123456", 4, "2012-12-31 11:30:45.1235"},
{"2012-12-31 11:30:45.123456", 6, "2012-12-31 11:30:45.123456"},
{"2012-12-31 11:30:45.123456", 0, "2012-12-31 11:30:45"},
{"2012-12-31 11:30:45.123456", 1, "2012-12-31 11:30:45.1"},
{"2012-12-31 11:30:45.999999", 4, "2012-12-31 11:30:46.0000"},
{"2012-12-31 11:30:45.999999", 0, "2012-12-31 11:30:46"},
{"2012-00-00 11:30:45.999999", 3, "2012-00-00 11:30:46.000"},
// TODO: MySQL can handle this case, but we can't.
// {"2012-01-00 23:59:59.999999", 3, "2012-01-01 00:00:00.000"},
}
for _, t := range tbl {
v, err := types.ParseTime(sc, t.Input, mysql.TypeDatetime, types.MaxFsp)
c.Assert(err, IsNil)
nv, err := v.RoundFrac(sc, t.Fsp)
c.Assert(err, IsNil)
c.Assert(nv.String(), Equals, t.Except)
}
tbl = []struct {
Input string
Fsp int
Except string
}{
{"11:30:45.123456", 4, "11:30:45.1235"},
{"11:30:45.123456", 6, "11:30:45.123456"},
{"11:30:45.123456", 0, "11:30:45"},
{"1 11:30:45.123456", 1, "35:30:45.1"},
{"1 11:30:45.999999", 4, "35:30:46.0000"},
{"-1 11:30:45.999999", 0, "-35:30:46"},
}
for _, t := range tbl {
v, err := types.ParseDuration(sc, t.Input, types.MaxFsp)
c.Assert(err, IsNil)
nv, err := v.RoundFrac(t.Fsp)
c.Assert(err, IsNil)
c.Assert(nv.String(), Equals, t.Except)
}
}
func (s *testTimeSuite) TestConvert(c *C) {
defer testleak.AfterTest(c)()
tbl := []struct {
Input string
Fsp int
Except string
}{
{"2012-12-31 11:30:45.123456", 4, "11:30:45.1235"},
{"2012-12-31 11:30:45.123456", 6, "11:30:45.123456"},
{"2012-12-31 11:30:45.123456", 0, "11:30:45"},
{"2012-12-31 11:30:45.999999", 0, "11:30:46"},
{"2017-01-05 08:40:59.575601", 0, "08:41:00"},
{"2017-01-05 23:59:59.575601", 0, "00:00:00"},
{"0000-00-00 00:00:00", 6, "00:00:00"},
}
for _, t := range tbl {
v, err := types.ParseTime(nil, t.Input, mysql.TypeDatetime, t.Fsp)
c.Assert(err, IsNil)
nv, err := v.ConvertToDuration()
c.Assert(err, IsNil)
c.Assert(nv.String(), Equals, t.Except)
}
tblDuration := []struct {
Input string
Fsp int
}{
{"11:30:45.123456", 4},
{"11:30:45.123456", 6},
{"11:30:45.123456", 0},
{"1 11:30:45.999999", 0},
}
sc := mock.NewContext().GetSessionVars().StmtCtx
sc.TimeZone = time.UTC
for _, t := range tblDuration {
v, err := types.ParseDuration(sc, t.Input, t.Fsp)
c.Assert(err, IsNil)
year, month, day := time.Now().In(time.UTC).Date()
n := time.Date(year, month, day, 0, 0, 0, 0, time.UTC)
t, err := v.ConvertToTime(sc, mysql.TypeDatetime)
c.Assert(err, IsNil)
// TODO: Consider time_zone variable.
t1, _ := t.Time.GoTime(time.UTC)
c.Assert(t1.Sub(n), Equals, v.Duration)
}
}
func (s *testTimeSuite) TestCompare(c *C) {
defer testleak.AfterTest(c)()
tbl := []struct {
Arg1 string
Arg2 string
Ret int
}{
{"2011-10-10 11:11:11", "2011-10-10 11:11:11", 0},
{"2011-10-10 11:11:11.123456", "2011-10-10 11:11:11.1", 1},
{"2011-10-10 11:11:11", "2011-10-10 11:11:11.123", -1},
{"0000-00-00 00:00:00", "2011-10-10 11:11:11", -1},
{"0000-00-00 00:00:00", "0000-00-00 00:00:00", 0},
}
for _, t := range tbl {
v1, err := types.ParseTime(nil, t.Arg1, mysql.TypeDatetime, types.MaxFsp)
c.Assert(err, IsNil)
ret, err := v1.CompareString(nil, t.Arg2)
c.Assert(err, IsNil)
c.Assert(ret, Equals, t.Ret)
}
tbl = []struct {
Arg1 string
Arg2 string
Ret int
}{
{"11:11:11", "11:11:11", 0},
{"11:11:11.123456", "11:11:11.1", 1},
{"11:11:11", "11:11:11.123", -1},
}
for _, t := range tbl {
v1, err := types.ParseDuration(nil, t.Arg1, types.MaxFsp)
c.Assert(err, IsNil)
ret, err := v1.CompareString(nil, t.Arg2)
c.Assert(err, IsNil)
c.Assert(ret, Equals, t.Ret)
}
}
func (s *testTimeSuite) TestDurationClock(c *C) {
defer testleak.AfterTest(c)()
// test hour, minute, second and micro second
tbl := []struct {
Input string
Hour int
Minute int
Second int
MicroSecond int
}{
{"11:11:11.11", 11, 11, 11, 110000},
{"1 11:11:11.000011", 35, 11, 11, 11},
{"2010-10-10 11:11:11.000011", 11, 11, 11, 11},
}
for _, t := range tbl {
d, err := types.ParseDuration(nil, t.Input, types.MaxFsp)
c.Assert(err, IsNil)
c.Assert(d.Hour(), Equals, t.Hour)
c.Assert(d.Minute(), Equals, t.Minute)
c.Assert(d.Second(), Equals, t.Second)
c.Assert(d.MicroSecond(), Equals, t.MicroSecond)
}
}
func (s *testTimeSuite) TestParseDateFormat(c *C) {
defer testleak.AfterTest(c)()
tbl := []struct {
Input string
Result []string
}{
{"2011-11-11 10:10:10.123456", []string{"2011", "11", "11", "10", "10", "10", "123456"}},
{" 2011-11-11 10:10:10.123456 ", []string{"2011", "11", "11", "10", "10", "10", "123456"}},
{"2011-11-11 10", []string{"2011", "11", "11", "10"}},
{"2011-11-11T10:10:10.123456", []string{"2011", "11", "11", "10", "10", "10", "123456"}},
{"2011:11:11T10:10:10.123456", []string{"2011", "11", "11", "10", "10", "10", "123456"}},
{"xx2011-11-11 10:10:10", nil},
{"T10:10:10", nil},
{"2011-11-11x", nil},
{"2011-11-11 10:10:10", nil},
{"xxx 10:10:10", nil},
}
for _, t := range tbl {
r := types.ParseDateFormat(t.Input)
c.Assert(r, DeepEquals, t.Result)
}
}
func (s *testTimeSuite) TestTamestampDiff(c *C) {
tests := []struct {
unit string
t1 types.MysqlTime
t2 types.MysqlTime
expect int64
}{
{"MONTH", types.FromDate(2002, 5, 30, 0, 0, 0, 0), types.FromDate(2001, 1, 1, 0, 0, 0, 0), -16},
{"YEAR", types.FromDate(2002, 5, 1, 0, 0, 0, 0), types.FromDate(2001, 1, 1, 0, 0, 0, 0), -1},
{"MINUTE", types.FromDate(2003, 2, 1, 0, 0, 0, 0), types.FromDate(2003, 5, 1, 12, 5, 55, 0), 128885},
{"MICROSECOND", types.FromDate(2002, 5, 30, 0, 0, 0, 0), types.FromDate(2002, 5, 30, 0, 13, 25, 0), 805000000},
{"MICROSECOND", types.FromDate(2000, 1, 1, 0, 0, 0, 12345), types.FromDate(2000, 1, 1, 0, 0, 45, 32), 44987687},
{"QUARTER", types.FromDate(2000, 1, 12, 0, 0, 0, 0), types.FromDate(2016, 1, 1, 0, 0, 0, 0), 63},
{"QUARTER", types.FromDate(2016, 1, 1, 0, 0, 0, 0), types.FromDate(2000, 1, 12, 0, 0, 0, 0), -63},
}
for _, test := range tests {
t1 := types.Time{
Time: test.t1,
Type: mysql.TypeDatetime,
Fsp: 6,
}
t2 := types.Time{
Time: test.t2,
Type: mysql.TypeDatetime,
Fsp: 6,
}
c.Assert(types.TimestampDiff(test.unit, t1, t2), Equals, test.expect)
}
}
func (s *testTimeSuite) TestDateFSP(c *C) {
tests := []struct {
date string
expect int
}{
{"2004-01-01 12:00:00.111", 3},
{"2004-01-01 12:00:00.11", 2},
{"2004-01-01 12:00:00.111111", 6},
{"2004-01-01 12:00:00", 0},
}
for _, test := range tests {
c.Assert(types.DateFSP(test.date), Equals, test.expect)
}
}
func (s *testTimeSuite) TestConvertTimeZone(c *C) {
loc, _ := time.LoadLocation("Asia/Shanghai")
tests := []struct {
input types.MysqlTime
from *time.Location
to *time.Location
expect types.MysqlTime
}{
{types.FromDate(2017, 1, 1, 0, 0, 0, 0), time.UTC, loc, types.FromDate(2017, 1, 1, 8, 0, 0, 0)},
{types.FromDate(2017, 1, 1, 8, 0, 0, 0), loc, time.UTC, types.FromDate(2017, 1, 1, 0, 0, 0, 0)},
{types.FromDate(0, 0, 0, 0, 0, 0, 0), loc, time.UTC, types.FromDate(0, 0, 0, 0, 0, 0, 0)},
}
for _, test := range tests {
var t types.Time
t.Time = test.input
t.ConvertTimeZone(test.from, test.to)
c.Assert(t.Compare(types.Time{Time: test.expect}), Equals, 0)
}
}
func (s *testTimeSuite) TestTimeAdd(c *C) {
tbl := []struct {
Arg1 string
Arg2 string
Ret string
}{
{"2017-01-18", "12:30:59", "2017-01-18 12:30:59"},
{"2017-01-18 01:01:01", "12:30:59", "2017-01-18 13:32:00"},
{"2017-01-18 01:01:01.123457", "12:30:59", "2017-01-18 13:32:0.123457"},
{"2017-01-18 01:01:01", "838:59:59", "2017-02-22 00:01:00"},
{"2017-08-21 15:34:42", "-838:59:59", "2017-07-17 16:34:43"},
{"2017-08-21", "01:01:01.001", "2017-08-21 01:01:01.001"},
}
sc := &stmtctx.StatementContext{
TimeZone: time.UTC,
}
for _, t := range tbl {
v1, err := types.ParseTime(nil, t.Arg1, mysql.TypeDatetime, types.MaxFsp)
c.Assert(err, IsNil)
dur, err := types.ParseDuration(sc, t.Arg2, types.MaxFsp)
c.Assert(err, IsNil)
result, err := types.ParseTime(nil, t.Ret, mysql.TypeDatetime, types.MaxFsp)
c.Assert(err, IsNil)
v2, err := v1.Add(sc, dur)
c.Assert(err, IsNil)
c.Assert(v2.Compare(result), Equals, 0, Commentf("%v %v", v2.Time, result.Time))
}
}
func (s *testTimeSuite) TestTruncateOverflowMySQLTime(c *C) {
t := types.MaxTime + 1
res, err := types.TruncateOverflowMySQLTime(t)
c.Assert(types.ErrTruncatedWrongVal.Equal(err), IsTrue)
c.Assert(res, Equals, types.MaxTime)
t = types.MinTime - 1
res, err = types.TruncateOverflowMySQLTime(t)
c.Assert(types.ErrTruncatedWrongVal.Equal(err), IsTrue)
c.Assert(res, Equals, types.MinTime)
t = types.MaxTime
res, err = types.TruncateOverflowMySQLTime(t)
c.Assert(err, IsNil)
c.Assert(res, Equals, types.MaxTime)
t = types.MinTime
res, err = types.TruncateOverflowMySQLTime(t)
c.Assert(err, IsNil)
c.Assert(res, Equals, types.MinTime)
t = types.MaxTime - 1
res, err = types.TruncateOverflowMySQLTime(t)
c.Assert(err, IsNil)
c.Assert(res, Equals, types.MaxTime-1)
t = types.MinTime + 1
res, err = types.TruncateOverflowMySQLTime(t)
c.Assert(err, IsNil)
c.Assert(res, Equals, types.MinTime+1)
}
func (s *testTimeSuite) TestCheckTimestamp(c *C) {
shanghaiTz, _ := time.LoadLocation("Asia/Shanghai")
tests := []struct {
tz *time.Location
input types.MysqlTime
expectRetError bool
}{{
tz: shanghaiTz,
input: types.FromDate(2038, 1, 19, 11, 14, 7, 0),
expectRetError: false,
}, {
tz: shanghaiTz,
input: types.FromDate(1970, 1, 1, 8, 1, 1, 0),
expectRetError: false,
}, {
tz: shanghaiTz,
input: types.FromDate(2038, 1, 19, 12, 14, 7, 0),
expectRetError: true,
}, {
tz: shanghaiTz,
input: types.FromDate(1970, 1, 1, 7, 1, 1, 0),
expectRetError: true,
}, {
tz: time.UTC,
input: types.FromDate(2038, 1, 19, 3, 14, 7, 0),
expectRetError: false,
}, {
tz: time.UTC,
input: types.FromDate(1970, 1, 1, 0, 1, 1, 0),
expectRetError: false,
}, {
tz: time.UTC,
input: types.FromDate(2038, 1, 19, 4, 14, 7, 0),
expectRetError: true,
}, {
tz: time.UTC,
input: types.FromDate(1969, 1, 1, 0, 0, 0, 0),
expectRetError: true,
},
}
for _, t := range tests {
validTimestamp := types.CheckTimestampTypeForTest(&stmtctx.StatementContext{TimeZone: t.tz}, t.input)
if t.expectRetError {
c.Assert(validTimestamp, NotNil, Commentf("For %s", t.input))
} else {
c.Assert(validTimestamp, IsNil, Commentf("For %s", t.input))
}
}
}

Комментарий ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://gitlife.ru/oschina-mirror/hanchuanchuan-goInception.git
git@gitlife.ru:oschina-mirror/hanchuanchuan-goInception.git
oschina-mirror
hanchuanchuan-goInception
hanchuanchuan-goInception
v1.2.3