Skip to content

Commit

Permalink
🧙‍♂️ Mischief managed (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
hf-kklein authored Sep 29, 2022
1 parent d71a2e2 commit 5f8975f
Show file tree
Hide file tree
Showing 17 changed files with 618 additions and 59 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ jobs:
uses: VeryGoodOpenSource/[email protected]
with:
path: "coverage.lcov"
min_coverage: 88 # the plan is to increase this with time
min_coverage: 80 # the plan is to increase this with time
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ jobs:
test:
strategy:
matrix:
go-version: [1.19.x]
go-version: [1.18.x, 1.19.x]
os: [ubuntu-latest]
runs-on: ${{ matrix.os }}
steps:
Expand Down
8 changes: 8 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions .idea/mako_time_converter.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

53 changes: 39 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,39 @@
# go-template-repository
![Unittest status badge](https://github.com/hochfrequenz/go-template-repository/workflows/Unittests/badge.svg)
![Coverage status badge](https://github.com/hochfrequenz/go-template-repository/workflows/coverage/badge.svg)
![Linter status badge](https://github.com/hochfrequenz/go-template-repository/workflows/golangci-lint/badge.svg)

This is a template repository for Go packages.
Click "Use Template" in the top right of this page to create an own repository from it.

## Features
It contains
* a minimal working example of a go package in [`foo`](/foo)
* an example of an unittest written in gocrest
* a valid go.mod and go.sum file
* GitHub Actions to test code, measure the coverage, check formatting and prevent linting errors
# make_time_converter (go)
![Unittest status badge](https://github.com/hochfrequenz/mako_time_converter/workflows/Unittests/badge.svg)
![Coverage status badge](https://github.com/hochfrequenz/mako_time_converter/workflows/coverage/badge.svg)
![Linter status badge](https://github.com/hochfrequenz/mako_time_converter/workflows/golangci-lint/badge.svg)

Go package to convert between German "Gastag" and "Stromtag", between inclusive and exclusive end dates and combinations of all them.
This is relevant for German Marktkommunikation ("MaKo").

This is a Golang port of the [`mako_datetime_converter` for .NET](https://github.com/Hochfrequenz/mako_datetime_converter).

## Rationale

The German Marktkommunikation ("MaKo") defines some rules regarding date times:

- you shall communicate end dates as exclusive (which is [generally a good idea](https://hf-kklein.github.io/exclusive_end_dates.github.io/))
- you shall use UTC date times with a specified UTC offset (which is a good idea)
- and you shall always use UTC-offset 0 (which makes things unnecessary complicated)
- in electricity all days (and contracts) start and end at midnight of German local time
- but in gas all days (and contracts) start and end at 6am German local time ("Gas-Tag")

Now imagine there is an interface between two systems:

- one of your systems obeys all of the above rules
- but another one works differently (e.g. models end dates inclusively or is unaware of the differences between electricity and gas)

Then you need a conversion logic for your `time.Time`s.
This library does the conversion for you.

## How To Use
todo: add mwe here

## Implicit Requirements

The package requires your relevant timezone data to be present on the system on which you're using it.
It does _not_ include timezone data itself and will panic if the local timezone data is not found.
Please import the [`time/tzdata`](https://pkg.go.dev/time/tzdata) package from the std library, if necessary.

The package does not include any workarounds to actual timezone data (e.g. in the case of Germany calculating the last Sunday in March or October.)
You can do it but you probably shouldn't.
10 changes: 0 additions & 10 deletions foo/foo.go

This file was deleted.

30 changes: 0 additions & 30 deletions foo/foo_test.go

This file was deleted.

11 changes: 9 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
module github.com/go-template-repository
module github.com/hochfrequenz/mako_time_converter

go 1.19

require (
github.com/corbym/gocrest v1.0.5
github.com/go-playground/validator/v10 v10.11.1
github.com/stretchr/testify v1.8.0
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-playground/locales v0.14.0 // indirect
github.com/go-playground/universal-translator v0.18.0 // indirect
github.com/leodido/go-urn v1.2.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 // indirect
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069 // indirect
golang.org/x/text v0.3.7 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

replace github.com/hochfrequenz/go-template-repository/foo => ./foo
replace github.com/hochfrequenz/mako_time_converter => ./pkg
44 changes: 43 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
@@ -1,17 +1,59 @@
github.com/corbym/gocrest v1.0.5 h1:6FUvLjKkKQ2hwMel8OKIZqN3slYEOHIFY9+lVaroFnU=
github.com/corbym/gocrest v1.0.5/go.mod h1:lF3xBPnOU5DYDpa/vUq63SMxUhd5UAwGgmA8Z2pJ/Tk=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU=
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho=
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ=
github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 h1:0es+/5331RGQPcXlMfP+WrnIIS6dNnNRe0WB02W0F4M=
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069 h1:siQdpVirKtzPhKl3lZWozZraCFObP8S1v6PRp0bLrtU=
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
43 changes: 43 additions & 0 deletions pkg/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package pkg

import (
"github.com/go-playground/validator/v10"
"github.com/hochfrequenz/mako_time_converter/pkg/enddatetimekind"
)

// DateTimeConfiguration describes how a time.Time is meant/interpreted by a system. Two of these configurations allow to convert a time.Time smoothly.
type DateTimeConfiguration struct {
// IsEndDate is true if the datetime describes an "end date", e.g. a contract end date
IsEndDate bool `json:"isEndDate"`
// EndDateTimeKind describes how an end datetime shall be understood (must be set if IsEndDate is true)
EndDateTimeKind *enddatetimekind.EndDateTimeKind `json:"endDateTimeKind,omitempty" validate:"required_if=IsEndDate true"`
// IsGas true iff the datetime describes a datetime in Sparte Gas. Please note that this is independent of the information whether the datetime is actually IsGasTagAware. There are systems that discriminate Gas and non-Gas (this is what this flag is for) but are still unaware of the German Gas-Tag.
IsGas bool `json:"isGas"`
// IsGasTagAware must be set iff IsGas is true and the date time is aware of the German "Gas-Tag" (meaning that start dates are 6:00 German local time and end dates are 06:00 German local time (if the end date is meant exclusive))
IsGasTagAware *bool `json:"isGasTagAware,omitempty" validate:"required_if=IsGas true"`
// Set true to remove all hours, minutes, seconds, milliseconds from the respective time.Time. If set in the DateTimeConversionConfiguration.Source the hours, minutes... will be stripped _before_ the conversion. If set in the DateTimeConversionConfiguration.Target the hours, minutes... will be stripped _after_ the conversion.
StripTime bool `json:"stripTime"`
}

// A DateTimeConversionConfiguration describes which steps are necessary to convert a datetime from a Source to a Target
type DateTimeConversionConfiguration struct {
// Source is the configuration of the datetime before the conversion
Source DateTimeConfiguration `json:"source" validate:"dive,required"`
// Target is the configuration of the datetime after the conversion
Target DateTimeConfiguration `json:"target" validate:"dive,required"`
}

// Invert returns an inverted configuration (switched source and target)
func (dtcc *DateTimeConversionConfiguration) Invert() DateTimeConversionConfiguration {
return DateTimeConversionConfiguration{
Source: dtcc.Target,
Target: dtcc.Source,
}
}

func DateTimeConversionConfigurationStructLevelValidator(sl validator.StructLevel) {
config := sl.Current().Interface().(DateTimeConversionConfiguration)
if config.Source.IsGas != config.Target.IsGas {
sl.ReportError(config.Source, "Source/Target.IsGas", "Target", "Source.IsGas==Target.IsGas", "")
}
}
14 changes: 14 additions & 0 deletions pkg/enddatetimekind/enddatetimekind.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package enddatetimekind

// EndDateTimeKind describes how an end datetime shall be understood
//
//go:generate stringer --type EndDateTimeKind
//go:generate jsonenums --type EndDateTimeKind
type EndDateTimeKind int

const (
// INCLUSIVE means, that the end date shall be understood as inclusive end date; e.g. "2022-10-31" for end of October
INCLUSIVE EndDateTimeKind = iota + 1
// EXCLUSIVE means, that the end date shall be understood as exclusive end date; e.g. "2022-11-01" for end of October
EXCLUSIVE
)
56 changes: 56 additions & 0 deletions pkg/enddatetimekind/enddatetimekind_jsonenums.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 25 additions & 0 deletions pkg/enddatetimekind/enddatetimekind_string.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 5f8975f

Please sign in to comment.