Files
gf/os/gtime/gtime_time.go

562 lines
15 KiB
Go
Raw Permalink Normal View History

2021-01-03 23:37:45 +08:00
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
2018-07-11 13:51:03 +08:00
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
2018-07-11 13:51:03 +08:00
package gtime
import (
2019-09-30 15:26:32 +08:00
"bytes"
"strconv"
"time"
2021-11-15 20:49:02 +08:00
"github.com/gogf/gf/v2/errors/gcode"
"github.com/gogf/gf/v2/errors/gerror"
)
2018-07-11 13:51:03 +08:00
2019-09-30 15:26:32 +08:00
// Time is a wrapper for time.Time for additional features.
2018-07-11 13:51:03 +08:00
type Time struct {
wrapper
2018-07-11 13:51:03 +08:00
}
// iUnixNano is an interface definition commonly for custom time.Time wrapper.
type iUnixNano interface {
2020-09-18 23:59:49 +08:00
UnixNano() int64
}
// New creates and returns a Time object with given parameter.
2024-02-05 20:40:03 +08:00
// The optional parameter is the time object which can be type of: time.Time/*time.Time, string or integer.
// Example:
// New("2024-10-29")
// New(1390876568)
// New(t) // The t is type of time.Time.
refactor: interface{} to any and reflect.Ptr to reflect.Pointer (#4395) This pull request standardizes the use of the Go 1.18+ `any` type alias instead of `interface{}` throughout the codebase. The change improves code readability and aligns with modern Go best practices. The update touches many files, including core data structures, code generation templates, logging utilities, and test data, ensuring consistency across all usages. **Type alias migration to `any`:** * Replaced all instances of `interface{}` with `any` in core data structures such as `garray` and in generated model structs (e.g., `TableUser`, `User1`, `User2`) to modernize type usage. [[1]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L31-R31) [[2]](diffhunk://#diff-6c19859cb32c7516ea95ddc8f8235460818eb2f24d2204308e0d9e1b19e7d90fL15-R19) [[3]](diffhunk://#diff-a15ba2f5e830b4833c47b902515a4f9e5a4f83a3707698f3229b307ec3776b41L15-R18) [[4]](diffhunk://#diff-52e0837e84d49221d1b810d88fdf78221f36cffcd664fb42f8aba49a79b974dcL15-R19) [[5]](diffhunk://#diff-11c3457d1a23a4ca6ecd00d6b856289774936b6a708384cf03aff164044e7546L15-R19) [[6]](diffhunk://#diff-2cff9cf8e6a0cc34087326d8c8149c3bbaf74c76fdbdf5a73daed13cc04249e1L15-R19) * Updated function signatures, method parameters, and return types from `interface{}` to `any` in various parts of the codebase, including code generation, service logic, and logging utilities (e.g., `mlog`). [[1]](diffhunk://#diff-175edfeea54490b8fe4e18ffcbea5835efaf8f0b8acf623359073987cae7eb76L48-R55) [[2]](diffhunk://#diff-2b1953fb78cf3593d8c2c7d911e95b65fd0b847c30ed0b4d167d16fe6d781235L54-R74) [[3]](diffhunk://#diff-e001b7a4b63603b9b14f00de78a4d570bb76c5f57d856a24643f071032e12356L66-R73) [[4]](diffhunk://#diff-5582954e8a9983988dc8854ad82067fb2ac6269b988e07357ad8db1dfec5f1a0L39-R41) [[5]](diffhunk://#diff-c5d51d56f487779a2b6207c7ad26c7a20bbadcc846ce094fe60ab4cabff58c51L107-R107) [[6]](diffhunk://#diff-f96e6a9fdb416eb1804ceaba1fe0ac637bff22c43837f8bb849c2366ce72d4a1L116-R121) [[7]](diffhunk://#diff-f94c83a1b08ae060d9346f4a6031fc4a7b9a0b894e02d9afaa09018b6598eac0L112-R112) [[8]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L36-R36) [[9]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L74-R74) [[10]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L96-R96) **Generated code and templates:** * Adjusted generated files and code generation templates to output `any` instead of `interface{}` for relevant struct fields and function signatures, ensuring that new code generation aligns with the updated convention. [[1]](diffhunk://#diff-6c19859cb32c7516ea95ddc8f8235460818eb2f24d2204308e0d9e1b19e7d90fL15-R19) [[2]](diffhunk://#diff-a15ba2f5e830b4833c47b902515a4f9e5a4f83a3707698f3229b307ec3776b41L15-R18) [[3]](diffhunk://#diff-52e0837e84d49221d1b810d88fdf78221f36cffcd664fb42f8aba49a79b974dcL15-R19) [[4]](diffhunk://#diff-11c3457d1a23a4ca6ecd00d6b856289774936b6a708384cf03aff164044e7546L15-R19) [[5]](diffhunk://#diff-2cff9cf8e6a0cc34087326d8c8149c3bbaf74c76fdbdf5a73daed13cc04249e1L15-R19) [[6]](diffhunk://#diff-175edfeea54490b8fe4e18ffcbea5835efaf8f0b8acf623359073987cae7eb76L48-R55) [[7]](diffhunk://#diff-e001b7a4b63603b9b14f00de78a4d570bb76c5f57d856a24643f071032e12356L66-R73) [[8]](diffhunk://#diff-5582954e8a9983988dc8854ad82067fb2ac6269b988e07357ad8db1dfec5f1a0L39-R41) **Container and utility updates:** * Refactored the `garray` container implementation and related constructors/methods to use `[]any` instead of `[]interface{}`, along with corresponding function signatures. [[1]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L31-R31) [[2]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L52-R52) [[3]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L62-R62) [[4]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L73-R86) [[5]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L96-R97) [[6]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L107-R114) [[7]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L124-R124) [[8]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L135-R143) [[9]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L167-R167) These changes collectively modernize the codebase and prepare it for future Go developments by using the idiomatic `any` type.
2025-08-28 16:53:19 +08:00
func New(param ...any) *Time {
if len(param) > 0 {
switch r := param[0].(type) {
case time.Time:
return NewFromTime(r)
2020-09-18 23:59:49 +08:00
case *time.Time:
if r != nil {
return NewFromTime(*r)
}
2021-08-30 22:26:02 +08:00
2020-11-26 22:40:55 +08:00
case Time:
return &r
2021-08-30 22:26:02 +08:00
2020-11-26 22:40:55 +08:00
case *Time:
return r
2021-08-30 22:26:02 +08:00
case string:
2021-01-03 23:37:45 +08:00
if len(param) > 1 {
switch t := param[1].(type) {
case string:
return NewFromStrFormat(r, t)
case []byte:
return NewFromStrFormat(r, string(t))
}
}
return NewFromStr(r)
2021-08-30 22:26:02 +08:00
case []byte:
2021-01-03 23:37:45 +08:00
if len(param) > 1 {
switch t := param[1].(type) {
case string:
return NewFromStrFormat(string(r), t)
case []byte:
return NewFromStrFormat(string(r), string(t))
}
}
return NewFromStr(string(r))
2021-08-30 22:26:02 +08:00
case int:
return NewFromTimeStamp(int64(r))
2021-08-30 22:26:02 +08:00
case int64:
return NewFromTimeStamp(r)
2021-08-30 22:26:02 +08:00
2020-09-18 23:59:49 +08:00
default:
if v, ok := r.(iUnixNano); ok {
2020-09-18 23:59:49 +08:00
return NewFromTimeStamp(v.UnixNano())
}
}
2019-06-19 09:06:52 +08:00
}
return &Time{
wrapper{time.Time{}},
2019-06-19 09:06:52 +08:00
}
2018-07-11 13:51:03 +08:00
}
// Now creates and returns a time object of now.
2018-07-11 13:51:03 +08:00
func Now() *Time {
2019-06-19 09:06:52 +08:00
return &Time{
wrapper{time.Now()},
2019-06-19 09:06:52 +08:00
}
2018-07-11 13:51:03 +08:00
}
2019-09-30 15:26:32 +08:00
// NewFromTime creates and returns a Time object with given time.Time object.
func NewFromTime(t time.Time) *Time {
2019-06-19 09:06:52 +08:00
return &Time{
wrapper{t},
2019-06-19 09:06:52 +08:00
}
2018-07-11 13:51:03 +08:00
}
2019-09-30 15:26:32 +08:00
// NewFromStr creates and returns a Time object with given string.
2020-06-22 19:46:39 +08:00
// Note that it returns nil if there's error occurs.
func NewFromStr(str string) *Time {
2019-06-19 09:06:52 +08:00
if t, err := StrToTime(str); err == nil {
return t
}
return nil
2018-07-11 17:06:47 +08:00
}
// NewFromStrFormat creates and returns a Time object with given string and
// custom format like: Y-m-d H:i:s.
2020-06-22 19:46:39 +08:00
// Note that it returns nil if there's error occurs.
func NewFromStrFormat(str string, format string) *Time {
2019-06-19 09:06:52 +08:00
if t, err := StrToTimeFormat(str, format); err == nil {
return t
}
return nil
2018-07-11 17:06:47 +08:00
}
// NewFromStrLayout creates and returns a Time object with given string and
// stdlib layout like: 2006-01-02 15:04:05.
2020-06-22 19:46:39 +08:00
// Note that it returns nil if there's error occurs.
func NewFromStrLayout(str string, layout string) *Time {
2019-06-19 09:06:52 +08:00
if t, err := StrToTimeLayout(str, layout); err == nil {
return t
}
return nil
2018-07-11 13:51:03 +08:00
}
// NewFromTimeStamp creates and returns a Time object with given timestamp,
// which can be in seconds to nanoseconds.
2020-09-18 23:59:49 +08:00
// Eg: 1600443866 and 1600443866199266000 are both considered as valid timestamp number.
func NewFromTimeStamp(timestamp int64) *Time {
2019-06-19 09:06:52 +08:00
if timestamp == 0 {
return &Time{}
}
var sec, nano int64
if timestamp > 1e9 {
for timestamp < 1e18 {
timestamp *= 10
}
sec = timestamp / 1e9
nano = timestamp % 1e9
} else {
sec = timestamp
2019-06-19 09:06:52 +08:00
}
return &Time{
wrapper{time.Unix(sec, nano)},
2019-06-19 09:06:52 +08:00
}
2018-07-11 13:51:03 +08:00
}
2019-12-17 21:06:34 +08:00
// Timestamp returns the timestamp in seconds.
func (t *Time) Timestamp() int64 {
if t.IsZero() {
return 0
}
2019-06-19 09:06:52 +08:00
return t.UnixNano() / 1e9
2018-07-11 13:51:03 +08:00
}
2019-12-17 21:06:34 +08:00
// TimestampMilli returns the timestamp in milliseconds.
func (t *Time) TimestampMilli() int64 {
if t.IsZero() {
return 0
}
2019-12-17 21:06:34 +08:00
return t.UnixNano() / 1e6
2018-07-11 13:51:03 +08:00
}
2019-12-17 21:06:34 +08:00
// TimestampMicro returns the timestamp in microseconds.
func (t *Time) TimestampMicro() int64 {
if t.IsZero() {
return 0
}
2019-06-19 09:06:52 +08:00
return t.UnixNano() / 1e3
2018-07-11 13:51:03 +08:00
}
2019-12-17 21:06:34 +08:00
// TimestampNano returns the timestamp in nanoseconds.
func (t *Time) TimestampNano() int64 {
if t.IsZero() {
return 0
}
2019-12-17 21:06:34 +08:00
return t.UnixNano()
}
// TimestampStr is a convenience method which retrieves and returns
// the timestamp in seconds as string.
func (t *Time) TimestampStr() string {
if t.IsZero() {
return ""
}
return strconv.FormatInt(t.Timestamp(), 10)
}
// TimestampMilliStr is a convenience method which retrieves and returns
// the timestamp in milliseconds as string.
func (t *Time) TimestampMilliStr() string {
if t.IsZero() {
return ""
}
return strconv.FormatInt(t.TimestampMilli(), 10)
}
// TimestampMicroStr is a convenience method which retrieves and returns
// the timestamp in microseconds as string.
func (t *Time) TimestampMicroStr() string {
if t.IsZero() {
return ""
}
return strconv.FormatInt(t.TimestampMicro(), 10)
}
// TimestampNanoStr is a convenience method which retrieves and returns
// the timestamp in nanoseconds as string.
func (t *Time) TimestampNanoStr() string {
if t.IsZero() {
return ""
}
return strconv.FormatInt(t.TimestampNano(), 10)
}
// Month returns the month of the year specified by t.
func (t *Time) Month() int {
if t.IsZero() {
return 0
}
return int(t.Time.Month())
}
2019-12-17 21:06:34 +08:00
// Second returns the second offset within the minute specified by t,
// in the range [0, 59].
func (t *Time) Second() int {
if t.IsZero() {
return 0
}
2019-12-17 21:06:34 +08:00
return t.Time.Second()
}
// Millisecond returns the millisecond offset within the second specified by t,
// in the range [0, 999].
func (t *Time) Millisecond() int {
if t.IsZero() {
return 0
}
2019-12-17 21:06:34 +08:00
return t.Time.Nanosecond() / 1e6
}
// Microsecond returns the microsecond offset within the second specified by t,
// in the range [0, 999999].
func (t *Time) Microsecond() int {
if t.IsZero() {
return 0
}
2019-12-17 21:06:34 +08:00
return t.Time.Nanosecond() / 1e3
}
// Nanosecond returns the nanosecond offset within the second specified by t,
// in the range [0, 999999999].
func (t *Time) Nanosecond() int {
if t.IsZero() {
return 0
}
2019-12-17 21:06:34 +08:00
return t.Time.Nanosecond()
2018-07-11 13:51:03 +08:00
}
// String returns current time object as string.
2018-07-11 13:51:03 +08:00
func (t *Time) String() string {
2020-02-16 18:07:05 +08:00
if t.IsZero() {
return ""
}
return t.wrapper.String()
2018-07-11 13:51:03 +08:00
}
// IsZero reports whether t represents the zero time instant,
// January 1, year 1, 00:00:00 UTC.
func (t *Time) IsZero() bool {
if t == nil {
return true
}
return t.Time.IsZero()
}
2019-09-30 15:26:32 +08:00
// Clone returns a new Time object which is a clone of current time object.
2018-07-11 13:51:03 +08:00
func (t *Time) Clone() *Time {
2019-06-19 09:06:52 +08:00
return New(t.Time)
2018-07-11 13:51:03 +08:00
}
2019-09-30 15:26:32 +08:00
// Add adds the duration to current time.
2018-07-20 18:16:51 +08:00
func (t *Time) Add(d time.Duration) *Time {
2020-10-12 23:32:32 +08:00
newTime := t.Clone()
newTime.Time = newTime.Time.Add(d)
return newTime
2018-07-11 13:51:03 +08:00
}
2019-09-30 15:26:32 +08:00
// AddStr parses the given duration as string and adds it to current time.
2020-10-12 23:32:32 +08:00
func (t *Time) AddStr(duration string) (*Time, error) {
if d, err := time.ParseDuration(duration); err != nil {
err = gerror.Wrapf(err, `time.ParseDuration failed for string "%s"`, duration)
2020-10-12 23:32:32 +08:00
return nil, err
} else {
2020-10-12 23:32:32 +08:00
return t.Add(d), nil
}
}
2019-09-30 15:26:32 +08:00
// UTC converts current time to UTC timezone.
2018-07-20 18:16:51 +08:00
func (t *Time) UTC() *Time {
2020-10-12 23:32:32 +08:00
newTime := t.Clone()
newTime.Time = newTime.Time.UTC()
return newTime
2018-07-11 13:51:03 +08:00
}
2019-09-30 15:26:32 +08:00
// ISO8601 formats the time as ISO8601 and returns it as string.
func (t *Time) ISO8601() string {
return t.Layout("2006-01-02T15:04:05-07:00")
}
2019-09-30 15:26:32 +08:00
// RFC822 formats the time as RFC822 and returns it as string.
func (t *Time) RFC822() string {
return t.Layout("Mon, 02 Jan 06 15:04 MST")
}
2019-09-30 15:26:32 +08:00
// AddDate adds year, month and day to the time.
2018-07-20 18:16:51 +08:00
func (t *Time) AddDate(years int, months int, days int) *Time {
2020-10-12 23:32:32 +08:00
newTime := t.Clone()
newTime.Time = newTime.Time.AddDate(years, months, days)
return newTime
2018-07-11 13:51:03 +08:00
}
2019-09-30 15:26:32 +08:00
// Round returns the result of rounding t to the nearest multiple of d (since the zero time).
// The rounding behavior for halfway values is to round up.
// If d <= 0, Round returns t stripped of any monotonic clock reading but otherwise unchanged.
//
// Round operates on the time as an absolute duration since the
// zero time; it does not operate on the presentation form of the
// time. Thus, Round(Hour) may return a time with a non-zero
// minute, depending on the time's Location.
2018-07-20 18:16:51 +08:00
func (t *Time) Round(d time.Duration) *Time {
2020-10-12 23:32:32 +08:00
newTime := t.Clone()
newTime.Time = newTime.Time.Round(d)
return newTime
2018-07-11 13:51:03 +08:00
}
2019-09-30 15:26:32 +08:00
// Truncate returns the result of rounding t down to a multiple of d (since the zero time).
// If d <= 0, Truncate returns t stripped of any monotonic clock reading but otherwise unchanged.
//
// Truncate operates on the time as an absolute duration since the
// zero time; it does not operate on the presentation form of the
// time. Thus, Truncate(Hour) may return a time with a non-zero
// minute, depending on the time's Location.
2018-07-20 18:16:51 +08:00
func (t *Time) Truncate(d time.Duration) *Time {
2020-10-12 23:32:32 +08:00
newTime := t.Clone()
newTime.Time = newTime.Time.Truncate(d)
return newTime
2019-06-19 09:06:52 +08:00
}
2019-12-17 21:06:34 +08:00
// Equal reports whether t and u represent the same time instant.
// Two times can be equal even if they are in different locations.
// For example, 6:00 +0200 CEST and 4:00 UTC are Equal.
// See the documentation on the Time type for the pitfalls of using == with
// Time values; most code should use Equal instead.
func (t *Time) Equal(u *Time) bool {
switch {
case t == nil && u != nil:
return false
case t == nil && u == nil:
return true
case t != nil && u == nil:
return false
default:
return t.Time.Equal(u.Time)
}
2019-12-17 21:06:34 +08:00
}
// Before reports whether the time instant t is before u.
func (t *Time) Before(u *Time) bool {
return t.Time.Before(u.Time)
}
// After reports whether the time instant t is after u.
func (t *Time) After(u *Time) bool {
switch {
case t == nil:
return false
case t != nil && u == nil:
return true
default:
return t.Time.After(u.Time)
}
2019-12-17 21:06:34 +08:00
}
2019-12-14 17:01:27 +08:00
// Sub returns the duration t-u. If the result exceeds the maximum (or minimum)
// value that can be stored in a Duration, the maximum (or minimum) duration
// will be returned.
// To compute t-d for a duration d, use t.Add(-d).
func (t *Time) Sub(u *Time) time.Duration {
if t == nil || u == nil {
return 0
}
2019-12-14 17:01:27 +08:00
return t.Time.Sub(u.Time)
}
2021-01-14 00:27:01 +08:00
// StartOfMinute clones and returns a new time of which the seconds is set to 0.
2020-12-29 18:05:00 +08:00
func (t *Time) StartOfMinute() *Time {
newTime := t.Clone()
newTime.Time = newTime.Time.Truncate(time.Minute)
return newTime
}
2021-01-14 00:27:01 +08:00
// StartOfHour clones and returns a new time of which the hour, minutes and seconds are set to 0.
2020-12-29 18:05:00 +08:00
func (t *Time) StartOfHour() *Time {
y, m, d := t.Date()
newTime := t.Clone()
newTime.Time = time.Date(y, m, d, newTime.Hour(), 0, 0, 0, newTime.Location())
2020-12-29 18:05:00 +08:00
return newTime
}
2021-01-14 00:27:01 +08:00
// StartOfDay clones and returns a new time which is the start of day, its time is set to 00:00:00.
2020-12-29 18:05:00 +08:00
func (t *Time) StartOfDay() *Time {
y, m, d := t.Date()
newTime := t.Clone()
newTime.Time = time.Date(y, m, d, 0, 0, 0, 0, newTime.Location())
2020-12-29 18:05:00 +08:00
return newTime
}
2021-01-14 00:27:01 +08:00
// StartOfWeek clones and returns a new time which is the first day of week and its time is set to
// 00:00:00.
2020-12-29 18:05:00 +08:00
func (t *Time) StartOfWeek() *Time {
weekday := int(t.Weekday())
return t.StartOfDay().AddDate(0, 0, -weekday)
}
2021-01-14 00:27:01 +08:00
// StartOfMonth clones and returns a new time which is the first day of the month and its is set to
// 00:00:00
2020-12-29 18:05:00 +08:00
func (t *Time) StartOfMonth() *Time {
y, m, _ := t.Date()
newTime := t.Clone()
newTime.Time = time.Date(y, m, 1, 0, 0, 0, 0, newTime.Location())
2020-12-29 18:05:00 +08:00
return newTime
}
2021-01-14 00:27:01 +08:00
// StartOfQuarter clones and returns a new time which is the first day of the quarter and its time is set
// to 00:00:00.
2020-12-29 18:05:00 +08:00
func (t *Time) StartOfQuarter() *Time {
month := t.StartOfMonth()
offset := (int(month.Month()) - 1) % 3
return month.AddDate(0, -offset, 0)
}
2021-01-14 00:27:01 +08:00
// StartOfHalf clones and returns a new time which is the first day of the half year and its time is set
// to 00:00:00.
2020-12-29 18:05:00 +08:00
func (t *Time) StartOfHalf() *Time {
month := t.StartOfMonth()
offset := (int(month.Month()) - 1) % 6
return month.AddDate(0, -offset, 0)
}
2021-01-14 00:27:01 +08:00
// StartOfYear clones and returns a new time which is the first day of the year and its time is set to
// 00:00:00.
2020-12-29 18:05:00 +08:00
func (t *Time) StartOfYear() *Time {
y, _, _ := t.Date()
newTime := t.Clone()
newTime.Time = time.Date(y, time.January, 1, 0, 0, 0, 0, newTime.Location())
2020-12-29 18:05:00 +08:00
return newTime
}
// getPrecisionDelta returns the precision parameter for time calculation depending on `withNanoPrecision` option.
func getPrecisionDelta(withNanoPrecision ...bool) time.Duration {
if len(withNanoPrecision) > 0 && withNanoPrecision[0] {
return time.Nanosecond
}
return time.Second
}
2021-01-14 00:27:01 +08:00
// EndOfMinute clones and returns a new time of which the seconds is set to 59.
func (t *Time) EndOfMinute(withNanoPrecision ...bool) *Time {
return t.StartOfMinute().Add(time.Minute - getPrecisionDelta(withNanoPrecision...))
2020-12-29 18:05:00 +08:00
}
2021-01-14 00:27:01 +08:00
// EndOfHour clones and returns a new time of which the minutes and seconds are both set to 59.
func (t *Time) EndOfHour(withNanoPrecision ...bool) *Time {
return t.StartOfHour().Add(time.Hour - getPrecisionDelta(withNanoPrecision...))
2020-12-29 18:05:00 +08:00
}
2021-01-14 00:27:01 +08:00
// EndOfDay clones and returns a new time which is the end of day the and its time is set to 23:59:59.
func (t *Time) EndOfDay(withNanoPrecision ...bool) *Time {
2020-12-29 18:05:00 +08:00
y, m, d := t.Date()
newTime := t.Clone()
newTime.Time = time.Date(
y, m, d, 23, 59, 59, int(time.Second-getPrecisionDelta(withNanoPrecision...)), newTime.Location(),
)
2020-12-29 18:05:00 +08:00
return newTime
}
2021-01-14 00:27:01 +08:00
// EndOfWeek clones and returns a new time which is the end of week and its time is set to 23:59:59.
func (t *Time) EndOfWeek(withNanoPrecision ...bool) *Time {
return t.StartOfWeek().AddDate(0, 0, 7).Add(-getPrecisionDelta(withNanoPrecision...))
2020-12-29 18:05:00 +08:00
}
2021-01-14 00:27:01 +08:00
// EndOfMonth clones and returns a new time which is the end of the month and its time is set to 23:59:59.
func (t *Time) EndOfMonth(withNanoPrecision ...bool) *Time {
return t.StartOfMonth().AddDate(0, 1, 0).Add(-getPrecisionDelta(withNanoPrecision...))
2020-12-29 18:05:00 +08:00
}
2021-01-14 00:27:01 +08:00
// EndOfQuarter clones and returns a new time which is end of the quarter and its time is set to 23:59:59.
func (t *Time) EndOfQuarter(withNanoPrecision ...bool) *Time {
return t.StartOfQuarter().AddDate(0, 3, 0).Add(-getPrecisionDelta(withNanoPrecision...))
2020-12-29 18:05:00 +08:00
}
2021-01-14 00:27:01 +08:00
// EndOfHalf clones and returns a new time which is the end of the half year and its time is set to 23:59:59.
func (t *Time) EndOfHalf(withNanoPrecision ...bool) *Time {
return t.StartOfHalf().AddDate(0, 6, 0).Add(-getPrecisionDelta(withNanoPrecision...))
2020-12-29 18:05:00 +08:00
}
2021-01-14 00:27:01 +08:00
// EndOfYear clones and returns a new time which is the end of the year and its time is set to 23:59:59.
func (t *Time) EndOfYear(withNanoPrecision ...bool) *Time {
return t.StartOfYear().AddDate(1, 0, 0).Add(-getPrecisionDelta(withNanoPrecision...))
2020-12-29 18:05:00 +08:00
}
// MarshalJSON implements the interface MarshalJSON for json.Marshal.
// Note that, DO NOT use `(t *Time) MarshalJSON() ([]byte, error)` as it looses interface
// implement of `MarshalJSON` for struct of Time.
func (t Time) MarshalJSON() ([]byte, error) {
2019-09-30 15:51:15 +08:00
return []byte(`"` + t.String() + `"`), nil
2019-09-30 15:26:32 +08:00
}
// UnmarshalJSON implements the interface UnmarshalJSON for json.Unmarshal.
func (t *Time) UnmarshalJSON(b []byte) error {
2019-10-21 19:13:25 +08:00
if len(b) == 0 {
t.Time = time.Time{}
return nil
}
2019-09-30 15:51:15 +08:00
newTime, err := StrToTime(string(bytes.Trim(b, `"`)))
2019-09-30 15:26:32 +08:00
if err != nil {
return err
}
t.Time = newTime.Time
return nil
}
2021-01-17 20:56:38 +08:00
// UnmarshalText implements the encoding.TextUnmarshaler interface.
// Note that it overwrites the same implementer of `time.Time`.
func (t *Time) UnmarshalText(data []byte) error {
vTime := New(data)
if vTime != nil {
*t = *vTime
return nil
}
return gerror.NewCodef(gcode.CodeInvalidParameter, `invalid time value: %s`, data)
}
2021-05-17 19:59:34 +08:00
// NoValidation marks this struct object will not be validated by package gvalid.
func (t *Time) NoValidation() {}
2022-05-23 16:51:10 +08:00
// DeepCopy implements interface for deep copy of current type.
refactor: interface{} to any and reflect.Ptr to reflect.Pointer (#4395) This pull request standardizes the use of the Go 1.18+ `any` type alias instead of `interface{}` throughout the codebase. The change improves code readability and aligns with modern Go best practices. The update touches many files, including core data structures, code generation templates, logging utilities, and test data, ensuring consistency across all usages. **Type alias migration to `any`:** * Replaced all instances of `interface{}` with `any` in core data structures such as `garray` and in generated model structs (e.g., `TableUser`, `User1`, `User2`) to modernize type usage. [[1]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L31-R31) [[2]](diffhunk://#diff-6c19859cb32c7516ea95ddc8f8235460818eb2f24d2204308e0d9e1b19e7d90fL15-R19) [[3]](diffhunk://#diff-a15ba2f5e830b4833c47b902515a4f9e5a4f83a3707698f3229b307ec3776b41L15-R18) [[4]](diffhunk://#diff-52e0837e84d49221d1b810d88fdf78221f36cffcd664fb42f8aba49a79b974dcL15-R19) [[5]](diffhunk://#diff-11c3457d1a23a4ca6ecd00d6b856289774936b6a708384cf03aff164044e7546L15-R19) [[6]](diffhunk://#diff-2cff9cf8e6a0cc34087326d8c8149c3bbaf74c76fdbdf5a73daed13cc04249e1L15-R19) * Updated function signatures, method parameters, and return types from `interface{}` to `any` in various parts of the codebase, including code generation, service logic, and logging utilities (e.g., `mlog`). [[1]](diffhunk://#diff-175edfeea54490b8fe4e18ffcbea5835efaf8f0b8acf623359073987cae7eb76L48-R55) [[2]](diffhunk://#diff-2b1953fb78cf3593d8c2c7d911e95b65fd0b847c30ed0b4d167d16fe6d781235L54-R74) [[3]](diffhunk://#diff-e001b7a4b63603b9b14f00de78a4d570bb76c5f57d856a24643f071032e12356L66-R73) [[4]](diffhunk://#diff-5582954e8a9983988dc8854ad82067fb2ac6269b988e07357ad8db1dfec5f1a0L39-R41) [[5]](diffhunk://#diff-c5d51d56f487779a2b6207c7ad26c7a20bbadcc846ce094fe60ab4cabff58c51L107-R107) [[6]](diffhunk://#diff-f96e6a9fdb416eb1804ceaba1fe0ac637bff22c43837f8bb849c2366ce72d4a1L116-R121) [[7]](diffhunk://#diff-f94c83a1b08ae060d9346f4a6031fc4a7b9a0b894e02d9afaa09018b6598eac0L112-R112) [[8]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L36-R36) [[9]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L74-R74) [[10]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L96-R96) **Generated code and templates:** * Adjusted generated files and code generation templates to output `any` instead of `interface{}` for relevant struct fields and function signatures, ensuring that new code generation aligns with the updated convention. [[1]](diffhunk://#diff-6c19859cb32c7516ea95ddc8f8235460818eb2f24d2204308e0d9e1b19e7d90fL15-R19) [[2]](diffhunk://#diff-a15ba2f5e830b4833c47b902515a4f9e5a4f83a3707698f3229b307ec3776b41L15-R18) [[3]](diffhunk://#diff-52e0837e84d49221d1b810d88fdf78221f36cffcd664fb42f8aba49a79b974dcL15-R19) [[4]](diffhunk://#diff-11c3457d1a23a4ca6ecd00d6b856289774936b6a708384cf03aff164044e7546L15-R19) [[5]](diffhunk://#diff-2cff9cf8e6a0cc34087326d8c8149c3bbaf74c76fdbdf5a73daed13cc04249e1L15-R19) [[6]](diffhunk://#diff-175edfeea54490b8fe4e18ffcbea5835efaf8f0b8acf623359073987cae7eb76L48-R55) [[7]](diffhunk://#diff-e001b7a4b63603b9b14f00de78a4d570bb76c5f57d856a24643f071032e12356L66-R73) [[8]](diffhunk://#diff-5582954e8a9983988dc8854ad82067fb2ac6269b988e07357ad8db1dfec5f1a0L39-R41) **Container and utility updates:** * Refactored the `garray` container implementation and related constructors/methods to use `[]any` instead of `[]interface{}`, along with corresponding function signatures. [[1]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L31-R31) [[2]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L52-R52) [[3]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L62-R62) [[4]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L73-R86) [[5]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L96-R97) [[6]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L107-R114) [[7]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L124-R124) [[8]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L135-R143) [[9]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L167-R167) These changes collectively modernize the codebase and prepare it for future Go developments by using the idiomatic `any` type.
2025-08-28 16:53:19 +08:00
func (t *Time) DeepCopy() any {
if t == nil {
return nil
}
2022-05-23 16:51:10 +08:00
return New(t.Time)
}