-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
zhangliang
committed
Apr 25, 2023
0 parents
commit ef38130
Showing
8 changed files
with
438 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# Binaries for programs and plugins | ||
*.exe | ||
*.exe~ | ||
*.dll | ||
*.so | ||
*.dylib | ||
|
||
# Test binary, build with `go test -c` | ||
*.test | ||
|
||
# Output of the go coverage tool, specifically when used with LiteIDE | ||
*.out |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
language: go | ||
|
||
go: | ||
- 1.9 | ||
- "1.10" | ||
- 1.11 | ||
- 1.12 | ||
|
||
install: | ||
- go get github.com/mattn/goveralls | ||
|
||
script: | ||
- go test -v -covermode=count -coverprofile=coverage.out | ||
- $HOME/gopath/bin/goveralls -coverprofile=coverage.out -service=travis-ci -repotoken $COVERALLS_TOKEN | ||
|
||
env: | ||
global: | ||
secure: "RKp8cn1fCYU6PM4V7CUzW7R0T79e8MAwLpLV/NjjLKzckFnI2DT5Td1s2hdiYaqncN/PbIl/SHMt6CJadEJOFZqiagc8blywnsPMp8ABpAIMQS3Ae7ZeQoPDotuP5pPMmmCryVqWH75XzmsicNFDXbd6z+9dWyoSVHIfxrOOmmrmsMzdg/MFiM8EDFe0xrgJQIuyjzhR34dtTHgbvzNaixBivIIIU3w0LAietuagQjWA7sNNfwFTOVl97usiLJfiSxIta6rvV6oFcpxe3YuGwlSbNEeaJoeLC564nGrJFcLmrUs0M6ZYQ1uOAoADiWSv/t3K1pdQRO51VbEl3LveEOQyPV3p06TKVhvdC9aZz2KJqM6DdrJ/rkU5zUCYtv75dbT31QU3FW0rcdQjoMdWp/m/Llyv0KaUPk7JNOwfpCNPlrj0zQzk1/4dqQwmsJGL21kO+mABWWJamFOD1kJ/52DnJE3hbeZFnHMfsml14RZeDSDJnzlHjyIalPfC/koJpPuxu/9O7qxxjOJ5WSKRU9p1a5zmTD/9mUNOvVHOR0ohJa92DL8WPyVqoYJuFvgK+2QI/CboRYTXbyMFC7Tv0OGxjzDBlqUwsztHa43LsvvL0aONT69ogjUKrblNFcFNt+q368QE021cKw2D1yP6NpDcIVeCkkDfJ4dXMopl/o0=" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
BSD 3-Clause License | ||
|
||
Copyright (c) 2019, Andrew Chang | ||
All rights reserved. | ||
|
||
Redistribution and use in source and binary forms, with or without | ||
modification, are permitted provided that the following conditions are met: | ||
|
||
1. Redistributions of source code must retain the above copyright notice, this | ||
list of conditions and the following disclaimer. | ||
|
||
2. Redistributions in binary form must reproduce the above copyright notice, | ||
this list of conditions and the following disclaimer in the documentation | ||
and/or other materials provided with the distribution. | ||
|
||
3. Neither the name of the copyright holder nor the names of its | ||
contributors may be used to endorse or promote products derived from | ||
this software without specific prior written permission. | ||
|
||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | ||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
# timeconv | ||
|
||
Package timeconv provides some simple function to convert go time.Time values. | ||
|
||
[](https://godoc.org/github.com/Andrew-M-C/go.timeconv) | ||
[](https://travis-ci.org/Andrew-M-C/go.timeconv) | ||
[](https://coveralls.io/github/Andrew-M-C/go.timeconv?branch=master) | ||
[](https://github.com/Andrew-M-C/go.timeconv/tree/v0.4.0) | ||
|
||
The function `AddDate` in [package time](https://golang.org/pkg/time/) adds dates passed in format of years, months and days. In the biginning, I thought it did handle different date of month. However, it is NOT. | ||
|
||
For example, in many case in real life, if a month is added to 2019-01-31, the result should be 2019-01-28, identifying last day of the month. But the result with `AddDate` in package `time` will be 2019-03-03 ([Playground](https://play.golang.org/p/3eWrvAVzHUm)) | ||
|
||
This simple package `timeconv` provides a simple alternate of `AddDate` function, it focus on month operation and corrects result day for return. Please refer to the demo below for usage: | ||
|
||
```go | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"time" | ||
"github.com/Andrew-M-C/go.timeconv" | ||
) | ||
|
||
func main() { | ||
t := time.Date(2019, 1, 31, 0, 0, 0, 0, time.UTC) | ||
nt := t.AddDate(0, 1, 0) // Add one month | ||
fmt.Printf("%v\n", nt) // 2019-03-03 00:00:00 +0000 UTC, not expected | ||
|
||
nt = timeconv.AddDate(t, 0, 1, 0) | ||
fmt.Printf("%v\n", nt) // 2019-02-28 00:00:00 +0000 UTC | ||
} | ||
``` | ||
|
||
[Playground](https://play.golang.org/p/-2tnI8Ejxwh) | ||
|
||
Additionally, there is a pointer version: `func AddDateP(t *time.Time, years, months, days int)` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package timeconv_test | ||
|
||
import ( | ||
"fmt" | ||
|
||
timeconv "github.com/Andrew-M-C/go.timeconv" | ||
) | ||
|
||
func Example() { | ||
p := fmt.Println | ||
t := timeconv.Date(2020, 1, 31) | ||
|
||
p(t) | ||
p(t.AddDate(0, 1, 0)) | ||
p(timeconv.AddDate(t, 0, 1, 0)) | ||
|
||
// Output: | ||
// 2020-01-31 00:00:00 +0000 UTC | ||
// 2020-03-02 00:00:00 +0000 UTC | ||
// 2020-02-29 00:00:00 +0000 UTC | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
module github.com/Andrew-M-C/go.timeconv | ||
|
||
go 1.13 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,171 @@ | ||
// Package timeconv provides some simple function to convert go time.Time values. Please refer to functions below. | ||
package timeconv | ||
|
||
import ( | ||
// "log" | ||
"bytes" | ||
"fmt" | ||
"time" | ||
) | ||
|
||
var ( | ||
uptime = time.Now() | ||
) | ||
|
||
// AddDate returns the time corresponding to adding the given number of years, months, and days to t. For example, AddDate(-1, 2, 3) applied to January 1, 2011 returns March 4, 2010. | ||
// | ||
// However, this version of AddDate will examine the date of month. For example, AddDate(0, 1, 0) applied to January 31, 2011 returns Feburary 28, 2011 instead of March 3, 2011. | ||
func AddDate(t time.Time, years, months, days int) time.Time { | ||
// limit month | ||
if months >= 12 || months <= 12 { | ||
years += months / 12 | ||
months = months % 12 | ||
} | ||
|
||
// get datetime parts | ||
ye := t.Year() | ||
mo := t.Month() | ||
da := t.Day() | ||
hr := t.Hour() | ||
mi := t.Minute() | ||
se := t.Second() | ||
ns := t.Nanosecond() | ||
lo := t.Location() | ||
|
||
// log.Printf("input: %d - %d - %d\n", ye, mo, da) | ||
// log.Printf("delta: %d - %d - %d\n", years, months, days) | ||
|
||
// years | ||
ye += years | ||
|
||
// months | ||
mo += time.Month(months) | ||
if mo > 12 { | ||
mo -= 12 | ||
ye++ | ||
} else if mo < 1 { | ||
mo += 12 | ||
ye-- | ||
} | ||
|
||
// after adding month, we should adjust day of month value | ||
if da <= 28 { | ||
// nothing to change | ||
} else if da == 29 { | ||
if mo == 2 { | ||
if !isLeapYear(ye) { | ||
da = 28 | ||
} | ||
} | ||
// else, OK | ||
|
||
} else if da == 30 { | ||
if mo == 2 { | ||
if isLeapYear(ye) { | ||
da = 29 | ||
} else { | ||
da = 28 | ||
} | ||
} | ||
// else, OK | ||
|
||
} else if da == 31 { | ||
switch mo { | ||
case 2: | ||
if isLeapYear(ye) { | ||
da = 29 | ||
} else { | ||
da = 28 | ||
} | ||
case 1, 3, 5, 7, 8, 10, 12: | ||
da = 31 | ||
case 4, 6, 9, 11: | ||
da = 30 | ||
} | ||
} | ||
|
||
// date | ||
da += days | ||
|
||
// return | ||
return time.Date(ye, mo, da, hr, mi, se, ns, lo) | ||
} | ||
|
||
func isLeapYear(year int) bool { | ||
if year%4 == 0 { | ||
if year%100 == 0 { | ||
return year%400 == 0 | ||
} | ||
return true | ||
} | ||
return false | ||
} | ||
|
||
// AddDateP is the pointer version of AddDate() | ||
func AddDateP(t *time.Time, years, months, days int) { | ||
*t = AddDate(*t, years, months, days) | ||
} | ||
|
||
// Date returns a time.Time value with year, month, day and location only. If not indecating loc, UTC will be used. | ||
func Date(year int, month time.Month, day int, loc ...*time.Location) time.Time { | ||
if len(loc) == 0 { | ||
return time.Date(year, month, day, 0, 0, 0, 0, time.UTC) | ||
} | ||
return time.Date(year, month, day, 0, 0, 0, 0, loc[0]) | ||
} | ||
|
||
// UnixMilli returns Unix timestamp in milliseconds | ||
func UnixMilli(t time.Time) int64 { | ||
return t.UnixNano() / int64(time.Millisecond) | ||
} | ||
|
||
// UnixMicro returns Unix timestamp in microseconds | ||
func UnixMicro(t time.Time) int64 { | ||
return t.UnixNano() / int64(time.Microsecond) | ||
} | ||
|
||
// ProcUpDuration returns a rough duration indecating how long current process has run. | ||
func ProcUpDuration() time.Duration { | ||
return time.Since(uptime) | ||
} | ||
|
||
// YYYYMMDD is equivalent to t.Format(fmt.Sprintf("2006%s01%s02", seperator, seperator)) | ||
func YYYYMMDD(t time.Time, seperator string) string { | ||
f := fmt.Sprintf("2006%s01%s02", seperator, seperator) | ||
return t.Format(f) | ||
} | ||
|
||
// YYMMDD is equivalent to t.Format(fmt.Sprintf("06%s01%s02", seperator, seperator)) | ||
func YYMMDD(t time.Time, seperator string) string { | ||
f := fmt.Sprintf("06%s01%s02", seperator, seperator) | ||
return t.Format(f) | ||
} | ||
|
||
// HHMM is equivalent to t.Format(fmt.Sprintf("03%s04", seperator)) | ||
func HHMM(t time.Time, seperator string) string { | ||
f := fmt.Sprintf("03%s04", seperator) | ||
return t.Format(f) | ||
} | ||
|
||
// HHMMSS is equivalent to t.Format(fmt.Sprintf("03%s04%s05", seperator, seperator)). | ||
// With decimal, additional decimal digits of seconds will be added after a dot. | ||
func HHMMSS(t time.Time, seperator string, decimal ...int) string { | ||
buff := bytes.Buffer{} | ||
|
||
buff.WriteString("03") | ||
buff.WriteString(seperator) | ||
buff.WriteString("04") | ||
buff.WriteString(seperator) | ||
buff.WriteString("05") | ||
|
||
if len(decimal) > 0 && decimal[0] != 0 { | ||
buff.WriteRune('.') | ||
dec := decimal[0] | ||
|
||
for i := 0; i < dec && i < 9; i++ { | ||
buff.WriteRune('0') | ||
} | ||
} | ||
|
||
return t.Format(buff.String()) | ||
} |
Oops, something went wrong.