Eliaaazzz commented on code in PR #40154: URL: https://github.com/apache/beam/pull/40154#discussion_r4305374679
########## sdks/go/pkg/beam/core/runtime/graphx/schema/standard_logical_types.go: ########## @@ -0,0 +1,136 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You 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, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package schema + +import ( + "time" + + "github.com/apache/beam/sdks/v2/go/pkg/beam/core/runtime" + "github.com/apache/beam/sdks/v2/go/pkg/beam/core/util/reflectx" + "github.com/apache/beam/sdks/v2/go/pkg/beam/internal/errors" +) + +// URNs of the standard logical types defined in schema.proto. +const ( + // URNDate identifies the Date logical type. + URNDate = "beam:logical_type:date:v1" + // URNMicrosInstant identifies the MicrosInstant logical type. + URNMicrosInstant = "beam:logical_type:micros_instant:v1" +) + +// Date is a calendar date without a time zone or time of day, the +// beam:logical_type:date:v1 logical type. It is stored as the number of days +// since 1970-01-01 in an INT64 field. Time and String normalize out of range +// fields as time.Date does. Encoding fails unless the fields form a valid +// date with a year from -999999999 to 999999999, and decoding fails for a day +// count outside that range. +type Date struct { + Year int + Month time.Month + Day int +} Review Comment: Done in e7c4f6c. The zero Date now stands for the epoch, so Date{} encodes as day 0 and prints as 1970-01-01. Decoding day 0 still returns the explicit fields. ########## sdks/go/pkg/beam/core/runtime/graphx/schema/logicaltypes.go: ########## Review Comment: Added in e7c4f6c. RegisterLogicalType now panics on conflicting registrations for a Go type or an identifier and argument. Registering the same logical type again has no effect. ########## sdks/go/pkg/beam/core/runtime/graphx/schema/standard_logical_types.go: ########## @@ -0,0 +1,136 @@ +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You 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, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package schema + +import ( + "time" + + "github.com/apache/beam/sdks/v2/go/pkg/beam/core/runtime" + "github.com/apache/beam/sdks/v2/go/pkg/beam/core/util/reflectx" + "github.com/apache/beam/sdks/v2/go/pkg/beam/internal/errors" +) + +// URNs of the standard logical types defined in schema.proto. +const ( + // URNDate identifies the Date logical type. + URNDate = "beam:logical_type:date:v1" + // URNMicrosInstant identifies the MicrosInstant logical type. + URNMicrosInstant = "beam:logical_type:micros_instant:v1" +) + +// Date is a calendar date without a time zone or time of day, the +// beam:logical_type:date:v1 logical type. It is stored as the number of days +// since 1970-01-01 in an INT64 field. Time and String normalize out of range +// fields as time.Date does. Encoding fails unless the fields form a valid +// date with a year from -999999999 to 999999999, and decoding fails for a day +// count outside that range. +type Date struct { + Year int + Month time.Month + Day int +} + +// DateOf returns the Date of t in t's location. +func DateOf(t time.Time) Date { + y, m, d := t.Date() + return Date{Year: y, Month: m, Day: d} +} + +// Time returns the start of the date in UTC. +func (d Date) Time() time.Time { + return time.Date(d.Year, d.Month, d.Day, 0, 0, 0, 0, time.UTC) +} + +// String returns the date in ISO 8601 format, such as 2006-01-02. +func (d Date) String() string { + return d.Time().Format("2006-01-02") +} + +const secondsPerDay = 24 * 60 * 60 + +// minDateDays and maxDateDays bound the supported days since the epoch. +var ( + minDateDays = time.Date(-999999999, time.January, 1, 0, 0, 0, 0, time.UTC).Unix() / secondsPerDay + maxDateDays = time.Date(999999999, time.December, 31, 0, 0, 0, 0, time.UTC).Unix() / secondsPerDay +) + +func dateToStorage(d Date) (int64, error) { + t := d.Time() + // Out of range fields can overflow in time.Date, so only a date that + // round trips is encoded. + if DateOf(t) != d { + return 0, errors.Errorf("%d-%02d-%02d is not a valid date", d.Year, d.Month, d.Day) + } + days := t.Unix() / secondsPerDay + if days < minDateDays || days > maxDateDays { + return 0, errors.Errorf("date %v is out of range", d) + } + return days, nil +} + +func dateFromStorage(days int64) (Date, error) { + if days < minDateDays || days > maxDateDays { + return Date{}, errors.Errorf("%v days since the epoch is out of the supported date range", days) + } + return DateOf(time.Unix(days*secondsPerDay, 0).UTC()), nil +} + +// MicrosInstant is a timestamp with microsecond precision, the +// beam:logical_type:micros_instant:v1 logical type. It is stored as a row of +// the seconds and the microseconds since the epoch. Encoding a value with +// sub microsecond precision fails; truncate such values with time.Time.Truncate +// first. +type MicrosInstant time.Time Review Comment: Added in e7c4f6c. String prints RFC 3339 with microseconds and Equals wraps time.Time.Equal. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
