Documentation ¶
Overview ¶
Package pgdate contains parsing functions and types for dates and times in a manner that is compatible with PostgreSQL.
The implementation here is inspired by the following https://github.com/postgres/postgres/blob/REL_10_5/src/backend/utils/adt/datetime.c
The general approach is to take each input string and break it into contiguous runs of alphanumeric characters. Then, we attempt to interpret the input in order to populate a collection of date/time fields. We track which fields have been set in order to be able to apply various parsing heuristics to map the input chunks into date/time fields.
Index ¶
- Variables
- func ParseTime(now time.Time, mode ParseMode, s string) (_ time.Time, dependsOnContext bool, _ error)
- func ParseTimeWithoutTimezone(now time.Time, mode ParseMode, s string) (_ time.Time, dependsOnContext bool, _ error)
- func ParseTimestamp(now time.Time, mode ParseMode, s string) (_ time.Time, dependsOnContext bool, _ error)
- func ParseTimestampWithoutTimezone(now time.Time, mode ParseMode, s string) (_ time.Time, dependsOnContext bool, _ error)
- type Date
- func MakeCompatibleDateFromDisk(unixDays int64) Date
- func MakeDateFromPGEpoch(days int32) (Date, error)
- func MakeDateFromTime(t time.Time) (Date, error)
- func MakeDateFromUnixEpoch(days int64) (Date, error)
- func ParseDate(now time.Time, mode ParseMode, s string) (_ Date, dependsOnContext bool, _ error)
- func (d Date) AddDays(days int64) (Date, error)
- func (d Date) Compare(other Date) int
- func (d Date) Format(buf *bytes.Buffer)
- func (d Date) IsFinite() bool
- func (d Date) PGEpochDays() int32
- func (d Date) String() string
- func (d Date) SubDays(days int64) (Date, error)
- func (d Date) ToTime() (time.Time, error)
- func (d Date) UnixEpochDays() int64
- func (d Date) UnixEpochDaysWithOrig() int64
- type ParseMode
Constants ¶
This section is empty.
Variables ¶
var ( TimeEpoch = time.Unix(0, 0).UTC() // TimeInfinity represents the "highest" possible time. // TODO (#41564): this should actually behave as infinity, i.e. any operator // leaves this as infinity. This time should always be greater than any other time. // We should probably use the next microsecond after this value, i.e. timeutil.Unix(9224318016000, 0). // Postgres uses math.MaxInt64 microseconds as the infinity value. // See: https://github.com/postgres/postgres/blob/42aa1f0ab321fd43cbfdd875dd9e13940b485900/src/include/datatype/timestamp.h#L107. TimeInfinity = time.Unix(9224318016000-1, 999999000).UTC() // TimeNegativeInfinity represents the "lowest" possible time. // TODO (#41564): this should actually behave as -infinity, i.e. any operator // leaves this as -infinity. This time should always be less than any other time. // We should probably use the next microsecond before this value, i.e. timeutil.Unix(9224318016000-1, 999999000). // Postgres uses math.MinInt64 microseconds as the -infinity value. // See: https://github.com/postgres/postgres/blob/42aa1f0ab321fd43cbfdd875dd9e13940b485900/src/include/datatype/timestamp.h#L107. TimeNegativeInfinity = time.Unix(-210866803200, 0).UTC() )
These are sentinel values for handling special values: https://www.postgresql.org/docs/10/static/datatype-datetime.html#DATATYPE-DATETIME-SPECIAL-TABLE
var ( // LowDate is the lowest non-infinite Date. LowDate = Date{/* contains filtered or unexported fields */} // HighDate is the highest non-infinite Date. HighDate = Date{/* contains filtered or unexported fields */} // PosInfDate is the positive infinity Date. PosInfDate = Date{/* contains filtered or unexported fields */} // NegInfDate is the negative infinity date. NegInfDate = Date{/* contains filtered or unexported fields */} )
Functions ¶
func ParseTime ¶
func ParseTime( now time.Time, mode ParseMode, s string, ) (_ time.Time, dependsOnContext bool, _ error)
ParseTime converts a string into a time value on the epoch day.
The dependsOnContext return value indicates if we had to consult the given `now` value (either for the time or the local timezone).
func ParseTimeWithoutTimezone ¶
func ParseTimeWithoutTimezone( now time.Time, mode ParseMode, s string, ) (_ time.Time, dependsOnContext bool, _ error)
ParseTimeWithoutTimezone converts a string into a time value on the epoch day, dropping any timezone information. The returned time always has UTC location.
Any specified timezone is inconsequential. Examples:
- "now": parses to the local time of day (in the current timezone)
- "01:09:15.511971" and "01:09:15.511971-05" parse to the same result
The dependsOnContext return value indicates if we had to consult the given `now` value (either for the time or the local timezone).
func ParseTimestamp ¶
func ParseTimestamp( now time.Time, mode ParseMode, s string, ) (_ time.Time, dependsOnContext bool, _ error)
ParseTimestamp converts a string into a timestamp.
The dependsOnContext return value indicates if we had to consult the given `now` value (either for the time or the local timezone).
func ParseTimestampWithoutTimezone ¶
func ParseTimestampWithoutTimezone( now time.Time, mode ParseMode, s string, ) (_ time.Time, dependsOnContext bool, _ error)
ParseTimestampWithoutTimezone converts a string into a timestamp, stripping away any timezone information. Any specified timezone is inconsequential. The returned time always has UTC location.
For example, all these inputs return 2020-06-26 01:02:03 +0000 UTC:
- '2020-06-26 01:02:03';
- '2020-06-26 01:02:03+04';
- 'now', if the local local time (in the current timezone) is 2020-06-26 01:02:03. Note that this does not represent the same time instant, but the one that "reads" the same in UTC.
The dependsOnContext return value indicates if we had to consult the given `now` value (either for the time or the local timezone).
Types ¶
type Date ¶
type Date struct {
// contains filtered or unexported fields
}
Date is a postgres-compatible date implementation. It stores the number of days from the postgres epoch (2000-01-01). Its properties are unexported so that it cannot be misused by external packages. This package takes care to prevent silent problems like overflow that can occur when adding days or converting to and from a time.Time.
func MakeCompatibleDateFromDisk ¶
MakeCompatibleDateFromDisk creates a Date from the number of days since the Unix epoch. If it is out of range of LowDate and HighDate, positive or negative infinity dates are returned. This function should be used only by the on-disk decoder to maintain backward compatibility. It retains the origin days argument which is returned by UnixEpochDaysWithOrig.
func MakeDateFromPGEpoch ¶
MakeDateFromPGEpoch creates a Date from the number of days since 2000-01-01. MaxInt32 or MinInt32 represent the positive and negative infinity dates.
func MakeDateFromTime ¶
MakeDateFromTime creates a Date from the specified time. The timezone-relative date is used.
func MakeDateFromUnixEpoch ¶
MakeDateFromUnixEpoch creates a Date from the number of days since the Unix epoch.
func ParseDate ¶
ParseDate converts a string into Date.
Any specified timezone is inconsequential. Examples:
- "now": parses to the local date (in the current timezone)
- "2020-06-26 01:09:15.511971": parses to '2020-06-26'
- "2020-06-26 01:09:15.511971-05": parses to '2020-06-26'
The dependsOnContext return value indicates if we had to consult the given `now` value (either for the time or the local timezone).
func (Date) PGEpochDays ¶
PGEpochDays returns the number of days since 2001-01-01. This value can also be MinInt32 or MaxInt32, indicating negative or positive infinity.
func (Date) UnixEpochDays ¶
UnixEpochDays returns the number of days since the Unix epoch. Infinite dates are converted to MinInt64 or MaxInt64.
func (Date) UnixEpochDaysWithOrig ¶
UnixEpochDaysWithOrig returns the original on-disk representation if present, otherwise UnixEpochDays().