Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

util/types: re-implement check time related #2233

Merged
merged 20 commits into from
Dec 14, 2016
Merged

Conversation

tiancaiamao
Copy link
Contributor

provide the check method for Time, and functions
checkTimestampType
checkDatetimeType
checkDateType

FromDate doesn't check time now, newTime is removed.

In one word, rewrite the check time related.

"121231113045.9999999" should parse to
"2012-12-31 11:30:46.000000"
but we get
"2012-12-31 11:30:45.100000"
use Format to implement String(), so 00 month and day can be display
Conflicts:
	util/types/fsp.go
	util/types/time.go
	util/types/time_test.go
Conflicts:
	util/types/format_test.go
	util/types/fsp.go
	util/types/mytime.go
	util/types/time.go
	util/types/time_test.go
tm := gotime.Date(t.Year(), gotime.Month(t.Month()), t.Day(), t.Hour(), t.Minute(), t.Second(), t.Microsecond()*1000, gotime.Local)
return tm, errors.Trace(err)
year, month, day := tm.Date()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add comment for the following logic.

@@ -406,7 +406,7 @@ func (s *testTimeSuite) TestParseTimeFromNum(c *C) {
ExpectDateValue string
}{
{20101010111111, false, "2010-10-10 11:11:11", false, "2010-10-10 11:11:11", false, "2010-10-10"},
{2010101011111, true, zeroDatetimeStr, true, zeroDatetimeStr, true, zeroDateStr},
{2010101011111, false, "0201-01-01 01:11:11", true, zeroDatetimeStr, false, "0201-01-01"},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why use 0201-01-01 01:11:11 instead of zeroDatetimeStr ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I check MySQL's behavior, its result is "0201-01-01 01:11:11"...
There is a document say datetime range is '1000-01-01 00:00:00' to '9999-12-31 23:59:59', but it seems the implement doesn't obey it.

microsec != t.Microsecond() {
err = ErrInvalidTimeFormat
}
return tm, err
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add err trace.

@@ -1047,7 +1041,11 @@ func ParseTime(str string, tp byte, fsp int) (Time, error) {
return Time{Time: ZeroTime, Type: tp}, errors.Trace(err)
}

return t.Convert(tp)
t.Type = tp
if err = t.check(); err != nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use t.Convert?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Convert is now just a wrap around t.check() ....
set t.Type, check it's valid, that's all what Convert does.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Convert's semantic is not best fit for here.
Convert means I already have something, wants convert it to another,
but here I just want to new something, and check it's valid.

@hanfei1991

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

convert = new + check
here we already new, just need check

t.Fsp = fsp
return t.Convert(tp)
if err := t.check(); err != nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

@@ -274,34 +263,38 @@ func (t Time) ConvertToDuration() (Duration, error) {
// Compare returns an integer comparing the time instant t to o.
// If t is after o, return 1, equal o, return 0, before o, return -1.
func (t Time) Compare(o Time) int {
return compareTime(t.Time, o.Time)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why change this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Somewhere else need to compare TimeInternal, so I extract a compareTime function rather than
make Compare a method of Time.

if t.IsZero() {
return true
func checkDateRange(t TimeInternal) error {
// if compareTime(t, FromDate(1000, 1, 1, 0, 0, 0, 0)) < 0 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove useless comments

}
if compareTime(t, FromDate(9999, 12, 31, 23, 59, 59, 999999)) > 0 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be extracted to a variable?

hour, minute, second := tm.Clock()
microsec := tm.Nanosecond() / 1000
var err error
// This function will check the result, and return error if it's not the same with the origin input.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/error/an error

if second < 0 || second >= 60 {
return ErrInvalidTimeFormat
}
if hour == 0 && minute == 0 && second == 0 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this judgment.

@@ -85,8 +85,19 @@ func (t mysqlTime) ISOWeek() (int, int) {
}

func (t mysqlTime) GoTime() (gotime.Time, error) {
err := checkTime(int(t.year), int(t.month), int(t.day), int(t.hour), int(t.minute), int(t.second), int(t.microsecond))
// gotime.Time can't represent month 0 or day 0, date contains 0 would be converted to a nearest date,
// for example, 2006-12-00 00:00:00 would become 2015-11-30 23:59:59.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for -> For

if year != t.Year() || int(month) != t.Month() || day != t.Day() ||
hour != t.Hour() || minute != t.Minute() || second != t.Second() ||
microsec != t.Microsecond() {
err = ErrInvalidTimeFormat
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return tm, err directly ? and we needn't init var at line 94

@zimulala
Copy link
Contributor

Rest LGTM

return true
func checkDateType(t TimeInternal) error {
year, month, day := t.Year(), t.Month(), t.Day()
if year == 0 && month == 0 && day == 0 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not move this check into "checkDateRange"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

they are different: checkDateRange check date in range 1000-01-01 to 9999-12-31
while here check whether the date is ZeroDate.

}

func checkTimestampType(t TimeInternal) error {
if t.Year() == 0 && t.Month() == 0 && t.Day() == 0 &&
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a IsZero interface?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you mean add IsZero to TimeInternal interface?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay, I'll extract an IsZero function, but rather keep the TimeInternal a general interface.

@hanfei1991
Copy link
Member

LGTM

1 similar comment
@zimulala
Copy link
Contributor

LGTM

@tiancaiamao tiancaiamao merged commit 4741960 into master Dec 14, 2016
@tiancaiamao tiancaiamao deleted the tiancaiamao/check-time branch December 14, 2016 02:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants