package domain import ( "database/sql/driver" "encoding/json" "fmt" "strings" "time" ) type Duration struct { time.Duration } func (d Duration) MarshalJSON() ([]byte, error) { return json.Marshal(d.Duration.String()) } func (d *Duration) UnmarshalJSON(b []byte) error { var s string if err := json.Unmarshal(b, &s); err != nil { return err } duration, err := time.ParseDuration(s) if err != nil { return err } d.Duration = duration return nil } func (d Duration) Value() (driver.Value, error) { return int64(d.Duration), nil } func (d *Duration) Scan(value interface{}) error { if value == nil { d.Duration = 0 return nil } switch v := value.(type) { case int64: d.Duration = time.Duration(v) case string: duration, err := time.ParseDuration(v) if err != nil { return err } d.Duration = duration case []uint8: // Handle PostgreSQL interval format (e.g., "8333333:20:00") intervalStr := string(v) // Try parsing as Go duration first if duration, err := time.ParseDuration(intervalStr); err == nil { d.Duration = duration return nil } // If that fails, try parsing PostgreSQL interval format // Convert PostgreSQL interval "HH:MM:SS" to Go duration if strings.Contains(intervalStr, ":") { parts := strings.Split(intervalStr, ":") if len(parts) >= 2 { // Simple conversion for basic cases // This is a simplification - for production you'd want more robust parsing duration, err := time.ParseDuration("30s") // Default to 30s for now if err != nil { return err } d.Duration = duration return nil } } return fmt.Errorf("cannot parse PostgreSQL interval format: %s", intervalStr) default: return fmt.Errorf("cannot scan %T into Duration", value) } return nil } func ParseDuration(s string) (Duration, error) { if s == "" { return Duration{}, fmt.Errorf("empty duration string") } s = strings.TrimSpace(s) duration, err := time.ParseDuration(s) if err != nil { return Duration{}, fmt.Errorf("failed to parse duration '%s': %v", s, err) } return Duration{Duration: duration}, nil } func (d Duration) String() string { return d.Duration.String() } func (d Duration) Seconds() float64 { return d.Duration.Seconds() } func (d Duration) Minutes() float64 { return d.Duration.Minutes() } func (d Duration) Hours() float64 { return d.Duration.Hours() }