Gostradamus: Better DateTimes for Go 🕰️
Gostradamus is a Go library that offers a lightweight and human-friendly way to create, transform, format, and parse datetimes. It uses the underlying Go
timelibrary and the main gostradamus' type
DateTimecan be easily converted to and from
time.Time.
Gostradamus is named after the french pharmacist Nostradamus. He is known for his prophecies, therefore he worked a lot with time, like Gostradamus.
âś… Easy conversion between
time.Timeand
gostradamus.DateTime
âś… Format with common and known format tokens like
YYYY-MM-DD HH:mm:ss
âś… Generates time spans, floors, ceilings from second to year (weeks included)
âś… Weeks manipulation and helper functions
âś… Timezone-aware with conversion
âś… Fully tested and ready for production
package mainimport "github.com/bykof/gostradamus"
func main() { // Easy parsing dateTime, err := gostradamus.Parse("14.07.2017 02:40:00", "DD.MM.YYYY HH:mm:ss") if err != nil { panic(err) }
// Easy manipulation dateTime = dateTime.ShiftMonths(-5).ShiftDays(2) // Easy formatting println(dateTime.Format("DD.MM.YYYY HH:mm:ss")) // 16.02.2017 02:40:00 // Easy helper functions start, end := dateTime.SpanWeek() println(start.String(), end.String()) // 2017-02-13T00:00:00.000000Z 2017-02-19T23:59:59.999999Z
}
This part introduces all basic features of gostradamus. Surely there are more, just look them up in the offical documentation.
There are two types in this package, which are important to know:
go type DateTime time.Time type Timezone string
DateTimecontains all the creation, transforming, formatting and parsing functions.
Timezoneis just a string type but gostradamus has all timezones defined as constants. Look here.
You can easily convert between gostradamus.DateTime and time.Time package. Either with helper functions or with golang's type conversion
import "time"// From gostradamus.DateTime to time.Time dateTime := gostradamus.Now() firstTime := dateTime.Time() secondTime := time.Time(dateTime)
// From time.Time to gostradamus.DateTime t := time.Now() dateTime = gostradamus.DateTimeFromTime(t) dateTime = gostradamus.DateTime(t)
If you want to create a gostradamus.DateTime you have several ways:
Just create the DateTime from scratch:
// Create it with a defined timezone as you know it dateTime := gostradamus.NewDateTime(2020, 1, 1, 12, 0, 0, 0, gostradamus.EuropeBerlin)// Create it with predefined UTC timezone dateTime := gostradamus.NewUTCDateTime(2020, 1, 1, 12, 0, 0, 0)
// Create it with local timzone dateTime := gostradamus.NewLocalDateTime(2020, 1, 1, 12, 0, 0, 0)
Or create a DateTime from an ISO-8601 format:
go dateTime := gostradamus.Parse("2017-07-14T02:40:00.000000+0200", gostradamus.Iso8601)
Or from a custom format:
go dateTime := gostradamus.Parse("10.02.2010 14:59:53", "DD.MM.YYYY HH:mm:ss")
Or an UNIX timestamp for example:
go dateTime := gostradamus.FromUnixTimestamp(1500000000)
Or different ways of the current datetime: ```go // Current DateTime in local timezone dateTime := gostradamus.Now()
// Current DateTime in UTC timezone dateTime = gostradamus.UTCNow()
// Current DateTime in given timezone dateTime = gostradamus.NowInTimezone(gostradamus.EuropeParis) ```
Feel free to use all available timezones, defined here:
gostradamus.EuropeParis // Europe/Paris gostradamus.EuropeBerlin // Europe/Berlin gostradamus.AmericaNewYork // America/New_York ... and many more
Convert between timezones easily:
dateTime := gostradamus.NewUTC(2020, 1, 1, 12, 12, 12, 0).InTimezone(gostradamus.EuropeBerlin) println(dateTime.String()) // 2020-02-15T13:12:12.000000+0100dateTime = dateTime.InTimeZone(America_New_York) println(dateTime.String()) // 2020-02-15T07:12:12.000000-0500
Shifting helps you to add or subtract years, months, days, hours, minutes, seconds, milliseconds, microseconds, and nanoseconds.
To add a value use positive integer, to subtract use negative integer.
dateTime := gostradamus.NewUTCDateTime(2020, 1, 1, 1, 1, 1, 1) dateTime = dateTime.ShiftYears(10) println(dateTime.String()) // 2030-01-01T01:01:01.000000+0000dateTime = gostradamus.NewUTCDateTime(2020, 1, 1, 1, 1, 1, 1) dateTime = dateTime.ShiftDays(-10) println(dateTime.String()) // 2019-12-22T01:01:01.000000+0000
dateTime = gostradamus.NewUTCDateTime(2020, 1, 1, 1, 1, 1, 1) dateTime = dateTime.ShiftWeeks(2) println(dateTime.String()) // 2020-01-15T01:01:01.000000+0000
dateTime = gostradamus.NewUTCDateTime(2020, 1, 1, 1, 1, 1, 1) dateTime = dateTime.Shift(0, 1, 10, 0, 0, 0, 0) println(dateTime.String()) // 2020-02-11T01:01:01.000000+0000
Replacing values can be done easily.
dateTime := gostradamus.NewUTCDateTime(2020, 1, 1, 1, 1, 1, 1) dateTime = dateTime.ReplaceYear(2010) println(dateTime.String()) // 2010-01-01T01:01:01.000000+0000dateTime = gostradamus.NewUTCDateTime(2020, 1, 1, 1, 1, 1, 1) dateTime = dateTime.ReplaceYear(2010).ReplaceMonth(2) println(dateTime.String()) // 2010-02-01T01:01:01.000000+0000
| | Token | Output | |-------------- |------- |----------------------------------------- | | Year | YYYY | 2000, 2001, 2002 … 2012, 2013 | | | YY | 00, 01, 02 … 12, 13 | | Month | MMMM | January, February, March … | | | MMM | Jan, Feb, Mar … | | | MM | 01, 02, 03 … 11, 12 | | | M | 1, 2, 3 … 11, 12 | | Day of Year | DDDD | 001, 002, 003 … 364, 365 | | Day of Month | DD | 01, 02, 03 … 30, 31 | | | D | 1, 2, 3 … 30, 31 | | Day of Week | dddd | Monday, Tuesday, Wednesday … | | | ddd | Mon, Tue, Wed … | | Hour | HH | 00, 01, 02 … 23, 24 | | | hh | 01, 02, 03 … 11, 12 | | | h | 1, 2, 3 … 11, 12 | | AM / PM | A | AM, PM | | | a | am, pm | | Minute | mm | 00, 01, 02 … 58, 59 | | | m | 0, 1, 2 … 58, 59 | | Second | ss | 00, 01, 02 … 58, 59 | | | s | 0, 1, 2 … 58, 59 | | Microsecond | S | 000000 … 999999 | | Timezone | ZZZ | Asia/Baku, Europe/Warsaw, GMT | | | zz | -07:00, -06:00 … +06:00, +07:00, +08, Z | | | Z | -0700, -0600 … +0600, +0700, +08, Z |
Please consider that you cannot put custom tokens or custom letters into the parsing string
Easily parse with
Parse:
dateTime, err := gostradamus.Parse("10.02.2010 14:59:53", "DD.MM.YYYY HH:mm:ss") println(dateTime.String()) // 2010-02-10T14:59:53.000000Z
You can also specify a timezone while parsing:
dateTime, err := gostradamus.ParseInTimezone("10.02.2010 14:59:53", "DD.MM.YYYY HH:mm:ss", gostradamus.EuropeBerlin) println(dateTime.String()) // 2010-02-10T14:59:53.000000+0100
Formatting is as easy as parsing:
dateTimeString := gostradamus.NewDateTime(2017, 7, 14, 2, 40, 0, 0, UTC).Format("DD.MM.YYYY Time: HH:mm:ss") println(dateTimeString) // 14.07.2017 Time: 02:40:00
dateTimeString := gostradamus.NewDateTime(2017, 7, 14, 2, 40, 0, 0, UTC).FloorDay() println(dateTimeString.String()) // 2017-07-14T00:00:00.000000ZdateTimeString := gostradamus.NewDateTime(2017, 7, 14, 2, 40, 0, 0, UTC).FlorHour() println(dateTimeString.String()) // 2017-07-14T02:00:00.000000Z
dateTimeString := gostradamus.NewDateTime(2017, 7, 14, 2, 40, 0, 0, UTC).CeilMonth() println(dateTimeString.String()) // 2017-07-31T23:59:59.999999ZdateTimeString := gostradamus.NewDateTime(2017, 7, 14, 2, 40, 0, 0, UTC).CeilSecond() println(dateTimeString.String()) // 2017-07-14T02:40:00.999999Z
Spans can help you to get quickly the current span of the month or the day:
start, end := NewDateTime(2017, 7, 14, 2, 40, 0, 0, UTC).SpanMonth() println(start.String()) // 2017-07-01T00:00:00.000000Z println(end.String()) // 2017-07-31T23:59:59.999999Zstart, end = NewDateTime(2017, 7, 14, 2, 40, 0, 0, UTC).SpanDay() println(start.String()) // 2017-07-14T00:00:00.000000Z println(end.String()) // 2017-07-14T23:59:59.999999Z
start, end = NewDateTime(2012, 12, 12, 2, 40, 0, 0, UTC).SpanWeek() println(start.String()) // 2012-12-10T00:00:00.000000Z println(end.String()) // 2012-12-16T23:59:59.999999Z
Here is the section for some nice helper functions that will save you some time.
isBetween := gostradamus.NewUTCDateTime(2020, 1, 1, 12, 0, 0, 0).IsBetween( gostradamus.NewUTCDateTime(2020, 1, 1, 11, 0, 0, 0), gostradamus.NewUTCDateTime(2020, 1, 1, 13, 0, 0, 0), ) println(isBetween) // trueisBetween = gostradamus.NewUTCDateTime(2020, 1, 1, 12, 0, 0, 0).IsBetween( gostradamus.NewUTCDateTime(2020, 1, 1, 13, 0, 0, 0), gostradamus.NewUTCDateTime(2020, 1, 1, 14, 0, 0, 0), ) println(isBetween) // false
Retrieve year, month, day directly as a 3-tuple:
year, month, day := gostradamus.NewUTCDateTime(2020, 1, 1, 12, 0, 0, 0).IsoCalendar() println(year, month, day) // 2020 1 1
Do you have an idea to improve Gostradamus? -> Create an issue
Do you have already coded something for Gostradamus? -> Create a pull request.
Did you discover a bug? -> Create an issue
Otherwise feel free to contact me:
[email protected]or visit my webpage: bykovski.de
MIT licensed. See the LICENSE file for details.