github.com/searKing/golang/go@v1.2.117/time/time.go (about)

     1  // Copyright 2021 The searKing Author. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package time
     6  
     7  import (
     8  	"encoding/json"
     9  	"time"
    10  )
    11  
    12  // TruncateByLocation only happens in local semantics, apparently.
    13  // observed values for truncating given time with 24 Hour:
    14  // before truncation: 2012-01-01 04:15:30 +0800 CST
    15  // after  truncation: 2012-01-01 00:00:00 +0800 CST
    16  //
    17  // time.Truncate only happens in UTC semantics, apparently.
    18  // observed values for truncating given time with 24 Hour:
    19  //
    20  // before truncation: 2012-01-01 04:15:30 +0800 CST
    21  // after  truncation: 2011-12-31 08:00:00 +0800 CST
    22  //
    23  // This is really annoying when we want to truncate in local time
    24  // we take the apparent local time in the local zone, and pretend
    25  // that it's in UTC. do our math, and put it back to the local zone
    26  func TruncateByLocation(t time.Time, d time.Duration) time.Time {
    27  	if t.Location() == time.UTC {
    28  		return t.Truncate(d)
    29  	}
    30  
    31  	utc := time.Date(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), time.UTC)
    32  	utc = utc.Truncate(d)
    33  	return time.Date(utc.Year(), utc.Month(), utc.Day(), utc.Hour(), utc.Minute(), utc.Second(), utc.Nanosecond(),
    34  		t.Location())
    35  }
    36  
    37  // Duration is alias of time.Duration for marshal and unmarshal
    38  type Duration time.Duration
    39  
    40  func (d Duration) MarshalJSON() ([]byte, error) {
    41  	return json.Marshal(time.Duration(d).String())
    42  }
    43  
    44  func (d *Duration) UnmarshalJSON(data []byte) error {
    45  	// Ignore null, like in the main JSON package.
    46  	if string(data) == "null" {
    47  		return nil
    48  	}
    49  	var v any
    50  	if err := json.Unmarshal(data, &v); err != nil {
    51  		return err
    52  	}
    53  	switch value := v.(type) {
    54  	case float64:
    55  		*d = Duration(time.Duration(value))
    56  		return nil
    57  	case string:
    58  		tmp, err := time.ParseDuration(value)
    59  		if err != nil {
    60  			return err
    61  		}
    62  		*d = Duration(tmp)
    63  		return nil
    64  	default:
    65  		return &time.ParseError{
    66  			Layout:     "",
    67  			Value:      string(data),
    68  			LayoutElem: "",
    69  			ValueElem:  "",
    70  			Message:    "invalid duration",
    71  		}
    72  	}
    73  }
    74  
    75  func (d Duration) MarshalText() ([]byte, error) {
    76  	return json.Marshal(time.Duration(d).String())
    77  }
    78  
    79  func (d *Duration) UnmarshalText(data []byte) error {
    80  	tmp, err := time.ParseDuration(string(data))
    81  	if err != nil {
    82  		return err
    83  	}
    84  	*d = Duration(tmp)
    85  	return nil
    86  }