Skip to content

Commit eca8f2c

Browse files
authored
Merge pull request #1 from agentstation/feature/enhanced-utc-package
feat: comprehensive UTC package enhancements
2 parents 6681315 + c08c0fd commit eca8f2c

File tree

8 files changed

+587
-53
lines changed

8 files changed

+587
-53
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
# Coverage file
2121
coverage.txt
2222
coverage.out
23+
coverage.html
2324

2425
# Go workspace file
2526
go.work

README.md

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ The `utc` package provides an enhanced alias of Go's `time.Time` that ensures yo
1919
## Features
2020

2121
- Guaranteed UTC time handling
22-
- JSON marshaling/unmarshaling support
23-
- SQL database compatibility
22+
- JSON marshaling/unmarshaling support with flexible parsing
23+
- SQL database compatibility with enhanced type support
2424
- Automatic timezone handling (PST/PDT, EST/EDT, etc.)
2525
- Extensive formatting options:
2626
- US date formats (MM/DD/YYYY)
@@ -29,6 +29,10 @@ The `utc` package provides an enhanced alias of Go's `time.Time` that ensures yo
2929
- Common components (weekday, month, etc.)
3030
- Timezone conversion methods with fallback support
3131
- Full compatibility with Go's standard `time.Time` methods
32+
- Nil-safe operations that return errors instead of panicking
33+
- Debug mode with detailed logging for development
34+
- Text encoding support for broader codec compatibility
35+
- Unix timestamp helpers and day boundary utilities
3236
3337
## Installation
3438
@@ -38,6 +42,8 @@ To install the `utc` package, use the following command:
3842
go get github.com/agentstation/utc
3943
```
4044
45+
**Requirements**: Go 1.18 or later (uses `any` type and other modern Go features)
46+
4147
## Usage
4248
4349
1. Import the package:
@@ -109,6 +115,45 @@ type Record struct {
109115
}
110116
```
111117
118+
## Debug Mode
119+
120+
The package includes a debug mode that helps identify potential bugs during development:
121+
122+
```sh
123+
# Build with debug mode enabled
124+
go build -tags debug
125+
126+
# Run tests with debug mode
127+
go test -tags debug ./...
128+
```
129+
130+
When debug mode is enabled, the package logs warnings when methods are called on nil receivers:
131+
132+
```
133+
[UTC DEBUG] 2024/01/02 15:04:05 debug.go:26: String() called on nil *Time receiver
134+
[UTC DEBUG] 2024/01/02 15:04:05 debug.go:26: Value() called on nil *Time receiver
135+
```
136+
137+
## Additional Utilities
138+
139+
The package includes several convenience methods:
140+
141+
```go
142+
// Unix timestamp conversions
143+
t1 := utc.FromUnix(1704199445) // From Unix seconds
144+
t2 := utc.FromUnixMilli(1704199445000) // From Unix milliseconds
145+
seconds := t.Unix() // To Unix seconds
146+
millis := t.UnixMilli() // To Unix milliseconds
147+
148+
// Day boundaries
149+
start := t.StartOfDay() // 2024-01-02 00:00:00.000000000 UTC
150+
end := t.EndOfDay() // 2024-01-02 23:59:59.999999999 UTC
151+
152+
// Generic timezone conversion
153+
eastern, err := t.In("America/New_York")
154+
tokyo, err := t.In("Asia/Tokyo")
155+
```
156+
112157
<!-- gomarkdoc:embed:start -->
113158
114159
<!-- Code generated by gomarkdoc. DO NOT EDIT -->

debug.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//go:build debug
2+
// +build debug
3+
4+
package utc
5+
6+
import (
7+
"log"
8+
"os"
9+
"sync"
10+
)
11+
12+
// debugLogger is only available in debug builds
13+
var (
14+
debugLogger *log.Logger
15+
debugOnce sync.Once
16+
)
17+
18+
func initDebugLogger() {
19+
debugOnce.Do(func() {
20+
debugLogger = log.New(os.Stderr, "[UTC DEBUG] ", log.Ldate|log.Ltime|log.Lshortfile)
21+
})
22+
}
23+
24+
func debugLog(format string, v ...any) {
25+
initDebugLogger()
26+
debugLogger.Printf(format, v...)
27+
}

debug_test.go

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
//go:build debug
2+
// +build debug
3+
4+
package utc
5+
6+
import (
7+
"bytes"
8+
"os"
9+
"strings"
10+
"testing"
11+
)
12+
13+
// TestDebugLogging verifies that debug logging works when enabled
14+
func TestDebugLogging(t *testing.T) {
15+
// Capture stderr
16+
old := os.Stderr
17+
r, w, _ := os.Pipe()
18+
os.Stderr = w
19+
20+
// Test nil receiver calls
21+
var nilTime *Time
22+
23+
// These should log to stderr in debug mode
24+
_ = nilTime.String()
25+
_, _ = nilTime.Value()
26+
_, _ = nilTime.MarshalJSON()
27+
28+
// Restore stderr and read output
29+
w.Close()
30+
os.Stderr = old
31+
32+
var buf bytes.Buffer
33+
buf.ReadFrom(r)
34+
output := buf.String()
35+
36+
// Verify debug logs were written
37+
expectedLogs := []string{
38+
"String() called on nil *Time receiver",
39+
"Value() called on nil *Time receiver",
40+
"MarshalJSON() called on nil *Time receiver",
41+
}
42+
43+
for _, expected := range expectedLogs {
44+
if !strings.Contains(output, expected) {
45+
t.Errorf("Expected debug log containing %q, but got: %s", expected, output)
46+
}
47+
}
48+
49+
// Verify the format includes timestamp and file info
50+
if !strings.Contains(output, "[UTC DEBUG]") {
51+
t.Error("Debug logs should include [UTC DEBUG] prefix")
52+
}
53+
}
54+
55+
// TestDebugLogDirect tests the debugLog function directly
56+
func TestDebugLogDirect(t *testing.T) {
57+
// This test just verifies debugLog doesn't panic and initializes correctly
58+
// The actual output verification is done in TestDebugLogging which captures
59+
// output in a more controlled way by testing real usage patterns
60+
61+
// This should not panic
62+
debugLog("test message: %s", "hello")
63+
debugLog("another test")
64+
65+
// Verify debugLogger is initialized (it should be after first call)
66+
if debugLogger == nil {
67+
t.Error("debugLogger should be initialized after debugLog calls")
68+
}
69+
}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
module github.com/agentstation/utc
22

3-
go 1.22.5
3+
go 1.18

nodebug.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//go:build !debug
2+
// +build !debug
3+
4+
package utc
5+
6+
// debugLog is a no-op in non-debug builds
7+
func debugLog(format string, v ...any) {
8+
// No-op in production builds
9+
}

0 commit comments

Comments
 (0)