New Upstream Snapshot - golang-github-itchyny-timefmt-go

Ready changes

Summary

Merged new upstream version: 0.1.5 (was: 0.1.4).

Resulting package

Built on 2022-12-19T18:31 (took 17m7s)

The resulting binary packages can be installed (if you have the apt repository enabled) by running one of:

apt install -t fresh-snapshots golang-github-itchyny-timefmt-go-dev

Lintian Result

Diff

diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
deleted file mode 100644
index 100d628..0000000
--- a/.github/workflows/ci.yaml
+++ /dev/null
@@ -1,35 +0,0 @@
-name: CI
-
-on:
-  push:
-    branches:
-    - main
-  pull_request:
-
-jobs:
-  test:
-    name: Test
-    runs-on: ubuntu-latest
-    strategy:
-      matrix:
-        go: [1.16.x, 1.15.x, 1.14.x]
-    steps:
-    - name: Checkout code
-      uses: actions/checkout@v2
-    - name: Setup Go
-      uses: actions/setup-go@v2
-      with:
-        go-version: ${{ matrix.go }}
-    - name: Test
-      run: make test
-    - name: Test with GOARCH=386
-      run: env GOARCH=386 make test
-    - name: Test Coverage
-      run: |
-        go test -cover ./... | grep 100.0% || {
-          go test -cover ./...
-          echo Coverage decreased!
-          exit 1
-        } >&2
-    - name: Lint
-      run: make lint
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 52b37d0..61a4e9d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,11 @@
 # Changelog
+## [v0.1.5](https://github.com/itchyny/timefmt-go/compare/v0.1.4..v0.1.5) (2022-12-01)
+* support parsing time zone offset with name using both `%z` and `%Z`
+
+## [v0.1.4](https://github.com/itchyny/timefmt-go/compare/v0.1.3..v0.1.4) (2022-09-01)
+* improve documents
+* drop support for Go 1.16
+
 ## [v0.1.3](https://github.com/itchyny/timefmt-go/compare/v0.1.2..v0.1.3) (2021-04-14)
 * implement `ParseInLocation` for configuring the default location
 
diff --git a/LICENSE b/LICENSE
index 4d650fa..84d6cb0 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
 The MIT License (MIT)
 
-Copyright (c) 2020,2021 itchyny
+Copyright (c) 2020-2022 itchyny
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
diff --git a/Makefile b/Makefile
index bacef7b..a87cb28 100644
--- a/Makefile
+++ b/Makefile
@@ -1,20 +1,19 @@
 GOBIN ?= $(shell go env GOPATH)/bin
-export GO111MODULE=on
 
 .PHONY: all
 all: test
 
 .PHONY: test
 test:
-	go test -v ./...
+	go test -v -race ./...
 
 .PHONY: lint
-lint: $(GOBIN)/golint
+lint: $(GOBIN)/staticcheck
 	go vet ./...
-	golint -set_exit_status ./...
+	staticcheck -checks all,-ST1000 ./...
 
-$(GOBIN)/golint:
-	cd && go get golang.org/x/lint/golint
+$(GOBIN)/staticcheck:
+	go install honnef.co/go/tools/cmd/staticcheck@latest
 
 .PHONY: clean
 clean:
diff --git a/README.md b/README.md
index 078b1e1..f01af96 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
 # timefmt-go
 [![CI Status](https://github.com/itchyny/timefmt-go/workflows/CI/badge.svg)](https://github.com/itchyny/timefmt-go/actions)
 [![Go Report Card](https://goreportcard.com/badge/github.com/itchyny/timefmt-go)](https://goreportcard.com/report/github.com/itchyny/timefmt-go)
-[![MIT License](http://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/itchyny/timefmt-go/blob/main/LICENSE)
+[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/itchyny/timefmt-go/blob/main/LICENSE)
 [![release](https://img.shields.io/github/release/itchyny/timefmt-go/all.svg)](https://github.com/itchyny/timefmt-go/releases)
 [![pkg.go.dev](https://pkg.go.dev/badge/github.com/itchyny/timefmt-go)](https://pkg.go.dev/github.com/itchyny/timefmt-go)
 
@@ -35,14 +35,15 @@ func main() {
 
 Please refer to [`man 3 strftime`](https://linux.die.net/man/3/strftime) and
 [`man 3 strptime`](https://linux.die.net/man/3/strptime) for formatters.
+As an extension, `%f` directive is supported for zero-padded microseconds, which originates from Python.
 Note that `E` and `O` modifier characters are not supported.
 
 ## Comparison to other libraries
 - This library
   - provides both formatting and parsing functions in pure Go language,
-  - depends only on the Go standard libraries not to grows up the module file.
+  - depends only on the Go standard libraries not to grow up dependency.
 - `Format` (`strftime`) implements glibc extensions including
-  - width specifier like `%10A, %10B %2k:%M`,
+  - width specifier like `%6Y %10B %4Z` (limited to 1024 bytes),
   - omitting padding modifier like `%-y-%-m-%-d`,
   - space padding modifier like `%_y-%_m-%_d`,
   - upper case modifier like `%^a %^b`,
diff --git a/debian/changelog b/debian/changelog
index 531220c..8528b3b 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+golang-github-itchyny-timefmt-go (0.1.5-1) UNRELEASED; urgency=low
+
+  * New upstream release.
+  * New upstream release.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Mon, 19 Dec 2022 18:18:48 -0000
+
 golang-github-itchyny-timefmt-go (0.1.3-2) unstable; urgency=medium
 
   * Source-only upload for migration to testing
diff --git a/format.go b/format.go
index 1d9b367..eea976e 100644
--- a/format.go
+++ b/format.go
@@ -1,6 +1,7 @@
 package timefmt
 
 import (
+	"math"
 	"strconv"
 	"time"
 )
@@ -10,8 +11,7 @@ func Format(t time.Time, format string) string {
 	return string(AppendFormat(make([]byte, 0, 64), t, format))
 }
 
-// AppendFormat appends formatted time to the bytes.
-// You can use this method to reduce allocations.
+// AppendFormat appends formatted time string to the buffer.
 func AppendFormat(buf []byte, t time.Time, format string) []byte {
 	year, month, day := t.Date()
 	hour, min, sec := t.Clock()
@@ -74,7 +74,7 @@ func AppendFormat(buf []byte, t time.Time, format string) []byte {
 					b = format[i]
 					if b <= '9' && '0' <= b {
 						width = width*10 + int(b&0x0F)
-						if width >= int((^uint(0)>>1)/10) {
+						if width >= math.MaxInt/10 {
 							width = maxWidth
 						}
 					} else {
diff --git a/format_test.go b/format_test.go
index a08a9d6..080aa74 100644
--- a/format_test.go
+++ b/format_test.go
@@ -624,7 +624,7 @@ func TestFormat(t *testing.T) {
 		if len(tc.expected) < 1000 {
 			name = tc.expected + "/" + tc.format
 		} else {
-			name = strings.Replace(tc.expected+"/"+tc.format, strings.Repeat("0", 30), "0.", -1)
+			name = strings.ReplaceAll(tc.expected+"/"+tc.format, strings.Repeat("0", 30), "0.")
 		}
 		t.Run(name, func(t *testing.T) {
 			got := timefmt.Format(tc.t, tc.format)
@@ -649,3 +649,13 @@ func ExampleFormat() {
 	fmt.Println(str)
 	// Output: 2020-07-24 09:07:29
 }
+
+func ExampleAppendFormat() {
+	t := time.Date(2020, time.July, 24, 9, 7, 29, 0, time.UTC)
+	buf := make([]byte, 0, 64)
+	buf = append(buf, '(')
+	buf = timefmt.AppendFormat(buf, t, "%Y-%m-%d %H:%M:%S")
+	buf = append(buf, ')')
+	fmt.Println(string(buf))
+	// Output: (2020-07-24 09:07:29)
+}
diff --git a/go.mod b/go.mod
index 047e976..f459a79 100644
--- a/go.mod
+++ b/go.mod
@@ -1,3 +1,3 @@
 module github.com/itchyny/timefmt-go
 
-go 1.14
+go 1.17
diff --git a/parse.go b/parse.go
index 2d2b5f4..83b0df2 100644
--- a/parse.go
+++ b/parse.go
@@ -25,7 +25,7 @@ func parse(source, format string, loc, base *time.Location) (t time.Time, err er
 		}
 	}()
 	var j, century, yday, colons int
-	var pm bool
+	var pm, hasZoneName, hasZoneOffset bool
 	var pending string
 	for i, l := 0, len(source); i < len(format); i++ {
 		if b := format[i]; b == '%' {
@@ -158,14 +158,14 @@ func parse(source, format string, loc, base *time.Location) (t time.Time, err er
 				hour, min, sec = t.Clock()
 				month = int(mon)
 			case 'f':
-				var msec, k, d int
-				if msec, k, err = parseNumber(source, j, 6, 'f'); err != nil {
+				var usec, k, d int
+				if usec, k, err = parseNumber(source, j, 6, 'f'); err != nil {
 					return
 				}
-				nsec = msec * 1000
 				for j, d = k, k-j; d < 6; d++ {
-					nsec *= 10
+					usec *= 10
 				}
+				nsec = usec * 1000
 			case 'Z':
 				k := j
 				for ; k < l; k++ {
@@ -178,7 +178,14 @@ func parse(source, format string, loc, base *time.Location) (t time.Time, err er
 					err = fmt.Errorf(`cannot parse %q with "%%Z"`, source[j:k])
 					return
 				}
-				loc = t.Location()
+				if hasZoneOffset {
+					name, _ := t.Zone()
+					_, offset := locationZone(loc)
+					loc = time.FixedZone(name, offset)
+				} else {
+					loc = t.Location()
+				}
+				hasZoneName = true
 				j = k
 			case 'z':
 				if j >= l {
@@ -231,7 +238,12 @@ func parse(source, format string, loc, base *time.Location) (t time.Time, err er
 							j = k
 						}
 					}
-					loc, colons = time.FixedZone("", sign*((hour*60+min)*60+sec)), 0
+					var name string
+					if hasZoneName {
+						name, _ = locationZone(loc)
+					}
+					loc, colons = time.FixedZone(name, sign*((hour*60+min)*60+sec)), 0
+					hasZoneOffset = true
 				case 'Z':
 					loc, colons, j = time.UTC, 0, j+1
 				default:
@@ -328,6 +340,10 @@ func parse(source, format string, loc, base *time.Location) (t time.Time, err er
 	return time.Date(year, time.Month(month), day, hour, min, sec, nsec, loc), nil
 }
 
+func locationZone(loc *time.Location) (name string, offset int) {
+	return time.Date(2000, time.January, 1, 0, 0, 0, 0, loc).Zone()
+}
+
 type parseFormatError byte
 
 func (err parseFormatError) Error() string {
diff --git a/parse_test.go b/parse_test.go
index c8b8ca7..ae23873 100644
--- a/parse_test.go
+++ b/parse_test.go
@@ -445,7 +445,7 @@ var parseTestCases = []struct {
 	{
 		source: "2020-07-24 23:14:15 +0000",
 		format: "%F %T %z",
-		t:      time.Date(2020, time.July, 24, 23, 14, 15, 0, time.UTC),
+		t:      time.Date(2020, time.July, 24, 23, 14, 15, 0, time.FixedZone("", 0)),
 	},
 	{
 		source: "2020-07-24T23:14:15Z",
@@ -702,6 +702,16 @@ var parseTestCases = []struct {
 		format:   "%Z",
 		parseErr: errors.New(`cannot parse "X" with "%Z"`),
 	},
+	{
+		source: "2020-07-24 23:14:15 +0530 (AAA)",
+		format: "%F %T %z (%Z)",
+		t:      time.Date(2020, time.July, 24, 23, 14, 15, 0, time.FixedZone("AAA", (5*60+30)*60)),
+	},
+	{
+		source: "2020-07-24 23:14:15 (AAA) +0530",
+		format: "%F %T (%Z) %z",
+		t:      time.Date(2020, time.July, 24, 23, 14, 15, 0, time.FixedZone("AAA", (5*60+30)*60)),
+	},
 	{
 		source: "01%02\t03\n450000",
 		format: "%H%%%M%t%S%n%f",
@@ -743,6 +753,14 @@ func TestParse(t *testing.T) {
 				if !got.Equal(tc.t) {
 					t.Errorf("expected: %v, got: %v", tc.t, got)
 				}
+				name, offset := tc.t.Zone()
+				gotName, gotOffset := got.Zone()
+				if name != gotName || offset != gotOffset {
+					t.Errorf("expected zone: name = %s, offset = %d, got zone: name = %s, offset = %d",
+						name, offset,
+						gotName, gotOffset,
+					)
+				}
 			} else {
 				if err == nil {
 					t.Fatalf("expected error %v but got: %v", tc.parseErr, err)
diff --git a/timefmt.go b/timefmt.go
new file mode 100644
index 0000000..45bf6ae
--- /dev/null
+++ b/timefmt.go
@@ -0,0 +1,2 @@
+// Package timefmt provides functions for formatting and parsing date time strings.
+package timefmt

Debdiff

[The following lists of changes regard files as different if they have different names, permissions or owners.]

Files in second set of .debs but not in first

-rw-r--r--  root/root   /usr/share/gocode/src/github.com/itchyny/timefmt-go/timefmt.go

No differences were encountered in the control files

More details

Full run details