Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,46 @@ follows:
timetrace get record 2021-05-14-03-00PM
```

### Prefer decimal hours for status and reports

If your prefer to use decimal hours instead of the default hours min format,
add this to your `confg.yaml` file:

```yaml
useDecimalHours: "On"
```

To view both hours mins and decimal minutes,
add this to your `config.yaml` file

```yaml
useDecimalHours: "Both"
```

Sample Output
```
default (useDecimalHours = "Off")
+-------------------+----------------------+----------------+----------+
| CURRENT PROJECT | WORKED SINCE START | WORKED TODAY | BREAKS |
+-------------------+----------------------+----------------+----------+
| make-coffee | 1h 8min | 3h 8min | 0h 11min |
+-------------------+----------------------+----------------+----------+

Decimal Hours (useDecimalHours = "On")
+-------------------+----------------------+----------------+----------+
| CURRENT PROJECT | WORKED SINCE START | WORKED TODAY | BREAKS |
+-------------------+----------------------+----------------+----------+
| make-coffee | 1.2h | 3.2h | 0.2h |
+-------------------+----------------------+----------------+----------+

Both (useDecimalHours = "Both")
+-------------------+----------------------+----------------+---------------+
| CURRENT PROJECT | WORKED SINCE START | WORKED TODAY | BREAKS |
+-------------------+----------------------+----------------+---------------+
| make-coffee | 1h 8min 1.2h | 3h 8min 3.2h | 0h 11min 0.2h |
+-------------------+----------------------+----------------+---------------+
```

### Set your preferred editor

By default, timetrace will open the editor specified in `$EDITOR` or fall back
Expand Down
11 changes: 6 additions & 5 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ import (
)

type Config struct {
Store string `json:"store"`
Use12Hours bool `json:"use12hours"`
Editor string `json:"editor"`
ReportPath string `json:"report-path"`
Projects map[string]Project `json:"projects"`
Store string `json:"store"`
Use12Hours bool `json:"use12hours"`
UseDecimalHours string `json:"usedecimalhours"` //"On", "Off", "Both" valid values
Editor string `json:"editor"`
ReportPath string `json:"report-path"`
Projects map[string]Project `json:"projects"`
}

type Project struct {
Expand Down
20 changes: 17 additions & 3 deletions core/formatter.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import (
// Formatter represents a date- and time formatter. It provides all displayed
// date- and time layouts and is capable of parsing those layouts.
type Formatter struct {
use12Hours bool
use12Hours bool
useDecimalHours string
}

const dateLayout = "2006-01-02"
Expand Down Expand Up @@ -93,11 +94,24 @@ func (f *Formatter) RecordKey(record *Record) string {
}

// formatDuration formats the passed duration into a string.
// The format will be "8h 24min".
// The format is determined by value of UseDecimalHours in config file and
// will be "8h 24min", "8.4h, or "8h 24min 8.4h".
// seconds information is ignored.
func (f *Formatter) FormatDuration(duration time.Duration) string {

hours := int64(duration.Hours()) % 60
minutes := int64(duration.Minutes()) % 60
return fmt.Sprintf("%dh %dmin", hours, minutes)
dec := duration.Minutes() / 60
var response string
switch f.useDecimalHours {
case "Both":
response = fmt.Sprintf("%dh %dmin %.1fh", hours, minutes, dec)
case "On":
response = fmt.Sprintf("%.1fh", dec)
case "Off":
response = fmt.Sprintf("%dh %dmin", hours, minutes)
default:
response = fmt.Sprintf("%dh %dmin", hours, minutes)
}
return response
}
3 changes: 2 additions & 1 deletion core/timetrace.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ func New(config *config.Config, fs Filesystem) *Timetrace {
config: config,
fs: fs,
formatter: &Formatter{
use12Hours: config.Use12Hours,
useDecimalHours: config.UseDecimalHours,
use12Hours: config.Use12Hours,
},
}
}
Expand Down
59 changes: 45 additions & 14 deletions core/timetrace_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,41 +103,72 @@ func TestCollides(t *testing.T) {
func TestFormatDuration(t *testing.T) {

tt := []struct {
Duration time.Duration
Expected string
Duration time.Duration
Expected string
ExpectedDec string
ExpectedBoth string
}{
{
Duration: time.Duration(12 * time.Second),
Expected: "0h 0min",
Duration: time.Duration(12 * time.Second),
Expected: "0h 0min",
ExpectedDec: "0.0h",
ExpectedBoth: "0h 0min 0.0h",
},
{
Duration: time.Duration(60 * time.Minute),
Expected: "1h 0min",
Duration: time.Duration(60 * time.Minute),
Expected: "1h 0min",
ExpectedDec: "1.0h",
ExpectedBoth: "1h 0min 1.0h",
},
{
Duration: time.Duration(24 * time.Minute),
Expected: "0h 24min",
Duration: time.Duration(24 * time.Minute),
Expected: "0h 24min",
ExpectedDec: "0.4h",
ExpectedBoth: "0h 24min 0.4h",
},
{
Duration: time.Duration((60*8 + 24) * time.Minute),
Expected: "8h 24min",
Duration: time.Duration((60*8 + 24) * time.Minute),
Expected: "8h 24min",
ExpectedDec: "8.4h",
ExpectedBoth: "8h 24min 8.4h",
},
{
Duration: time.Duration((60*8+24)*time.Minute + 12*time.Second),
Expected: "8h 24min",
Duration: time.Duration((60*8+24)*time.Minute + 12*time.Second),
Expected: "8h 24min",
ExpectedDec: "8.4h",
ExpectedBoth: "8h 24min 8.4h",
},
{
Duration: time.Duration(0 * time.Second),
Expected: "0h 0min",
Duration: time.Duration(0 * time.Second),
Expected: "0h 0min",
ExpectedDec: "0.0h",
ExpectedBoth: "0h 0min 0.0h",
},
}

formatter := Formatter{}

//Default Case
for _, test := range tt {
strFormat := formatter.FormatDuration(test.Duration)
if strFormat != test.Expected {
t.Fatalf("format error: %s != %s", strFormat, test.Expected)
}
}
//Decimal Hours true
formatter.useDecimalHours = "On"
for _, test := range tt {
strFormat := formatter.FormatDuration(test.Duration)
if strFormat != test.ExpectedDec {
t.Fatalf("format error: %s != %s", strFormat, test.ExpectedDec)
}
}
//Decimal Hours both
formatter.useDecimalHours = "Both"
for _, test := range tt {
strFormat := formatter.FormatDuration(test.Duration)
if strFormat != test.ExpectedBoth {
t.Fatalf("format error: %s != %s", strFormat, test.ExpectedBoth)
}
}
}
Binary file added timetrace
Binary file not shown.