Gostradamus: Better DateTimes for Go 🕰️

Gostradamus logo

Gostradamus: Better DateTimes for Go

Gostradamus Go Report Card codecov Mentioned in Awesome Go go.dev reference

Introduction

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 time library and the main gostradamus' type DateTime can 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.

Features

Easy conversion between time.Time and 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

Basic Usage

package main

import "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
}

Table of Contents

Usage

This part introduces all basic features of gostradamus. Surely there are more, just look them up in the offical documentation.

Types

There are two types in this package, which are important to know:

type DateTime time.Time
type Timezone string

DateTime contains all the creation, transforming, formatting and parsing functions.

Timezone is just a string type but gostradamus has all timezones defined as constants. Look here.

Conversion between time.Time and gostradamus.DateTime

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)

Creation

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:

dateTime := gostradamus.Parse("2017-07-14T02:40:00.000000+0200", gostradamus.Iso8601)

Or from a custom format:

dateTime := gostradamus.Parse("10.02.2010 14:59:53", "DD.MM.YYYY HH:mm:ss")

Or an UNIX timestamp for example:

dateTime := gostradamus.FromUnixTimestamp(1500000000)

Or different ways of the current datetime:

// 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)

Timezones

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+0100

dateTime = dateTime.InTimeZone(America_New_York)
println(dateTime.String())
// 2020-02-15T07:12:12.000000-0500

Shift

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+0000

dateTime = 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

Replace

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+0000

dateTime = 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 Table

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

Parsing

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

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

Floor

dateTimeString := gostradamus.NewDateTime(2017, 7, 14, 2, 40, 0, 0, UTC).FloorDay()
println(dateTimeString.String())
// 2017-07-14T00:00:00.000000Z

dateTimeString := gostradamus.NewDateTime(2017, 7, 14, 2, 40, 0, 0, UTC).FlorHour()
println(dateTimeString.String())
// 2017-07-14T02:00:00.000000Z

Ceil

dateTimeString := gostradamus.NewDateTime(2017, 7, 14, 2, 40, 0, 0, UTC).CeilMonth()
println(dateTimeString.String())
// 2017-07-31T23:59:59.999999Z

dateTimeString := gostradamus.NewDateTime(2017, 7, 14, 2, 40, 0, 0, UTC).CeilSecond()
println(dateTimeString.String())
// 2017-07-14T02:40:00.999999Z

Spans

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.999999Z

start, 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

Utils

Here is the section for some nice helper functions that will save you some time.

IsBetween

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)
// true

isBetween = 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

IsoCalendar

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

Contribution

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

License

MIT licensed. See the LICENSE file for details.

Owner
Michael Bykovski
C'mon dude, u rly programming java?!
Michael Bykovski
Similar Resources

A better Generic Pool (sync.Pool)

A better Generic Pool (sync.Pool)

This package is a thin wrapper over the Pool provided by the sync package. The Pool is an essential package to obtain maximum performance by reducing the number of memory allocations.

Dec 1, 2022

Getting better at Linux with 10 mini-projects.

10 things Linux How do you advance your Linux skills when you are already comfortable with the basics? My solution was to come up with 10 subjects to

Dec 25, 2022

Tigo is an HTTP web framework written in Go (Golang).It features a Tornado-like API with better performance. Tigo是一款用Go语言开发的web应用框架,API特性类似于Tornado并且拥有比Tornado更好的性能。

Tigo is an HTTP web framework written in Go (Golang).It features a Tornado-like API with better performance.  Tigo是一款用Go语言开发的web应用框架,API特性类似于Tornado并且拥有比Tornado更好的性能。

Tigo(For English Documentation Click Here) 一个使用Go语言开发的web框架。 相关工具及插件 tiger tiger是一个专门为Tigo框架量身定做的脚手架工具,可以使用tiger新建Tigo项目或者执行其他操作。

Jan 5, 2023

Debug Dockerized Go applications better

Debug Dockerized Go applications better

A tool that makes debugging of Dockerized Go applications super easy by enabling Debugger and Hot-Reload features, seamlessly. Installing go get -u gi

Jan 4, 2023

Disk Usage/Free Utility - a better 'df' alternative

Disk Usage/Free Utility - a better 'df' alternative

duf Disk Usage/Free Utility (Linux, BSD, macOS & Windows) Features User-friendly, colorful output Adjusts to your terminal's width Sort the results ac

Jan 9, 2023

A better way to marshal and unmarshal YAML in Golang

YAML marshaling and unmarshaling support for Go Introduction A wrapper around go-yaml designed to enable a better way of handling YAML when marshaling

Jan 4, 2023

A better way to clone, organize and manage multiple git repositories

A better way to clone, organize and manage multiple git repositories

git-get git-get is a better way to clone, organize and manage multiple git repositories. git-get Description Installation macOS Linux Windows Usage gi

Nov 16, 2022

A better ORM for Go, based on non-empty interfaces and code generation.

A better ORM for Go, based on non-empty interfaces and code generation.

A better ORM for Go and database/sql. It uses non-empty interfaces, code generation (go generate), and initialization-time reflection as opposed to interface{}, type system sidestepping, and runtime reflection. It will be kept simple.

Dec 29, 2022

Better sync package for Go.

synx Better sync package for Go. Rationale TODO. Note For better sync/atomic package see atomix. Features Simple API. Easy to integrate. Optimized for

Dec 16, 2022

gopkg is a universal utility collection for Go, it complements offerings such as Boost, Better std, Cloud tools.

gopkg is a universal utility collection for Go, it complements offerings such as Boost, Better std, Cloud tools. Table of Contents Introduction

Jan 5, 2023

Golang AMQP wrapper for RabbitMQ with better API

go-rabbitmq Golang AMQP wrapper for RabbitMQ with better API Table of Contents Background Features Usage Installation Connect to RabbitMQ Declare Queu

Dec 21, 2022

Simple system for writing HTML/XML as Go code. Better-performing replacement for html/template and text/template

Simple system for writing HTML as Go code. Use normal Go conditionals, loops and functions. Benefit from typing and code analysis. Better performance than templating. Tiny and dependency-free.

Dec 5, 2022

ControllerMesh is a solution that helps developers manage their controllers/operators better.

ControllerMesh is a solution that helps developers manage their controllers/operators better.

ControllerMesh ControllerMesh is a solution that helps developers manage their controllers/operators better. Key Features Canary update: the controlle

Jan 6, 2023

Minecraft server made in go, faster and better!

ElytraGo Minecraft server made in go, faster and better! Project is in early stage, but I'm trying continuously update it with new lines of code :)) L

Dec 9, 2022

Default godoc generator - make your first steps towards better code documentation

godoc-generate Overview godoc-generate is a simple command line tool that generates default godoc comments on all exported types, functions, consts an

Sep 14, 2022

golang sdk for BRCC ( BRCC:Better Remote Config Center)

golang sdk for BRCC ( BRCC:Better Remote Config Center)

brcc-go-sdk golang sdk for BRCC BRCC:Better Remote Config Center

Dec 6, 2021

GoTSQL : A Better Way to Organize SQL codebase using Templates in Golang

GoTSQL - A Better Way to Organize SQL codebase using Templates in Golang Installation through Go Get command $ go get github.com/migopsrepos/gotsql In

Aug 17, 2022

Use Golang to achieve better console backend services

Use Golang to achieve better console backend services

Dec 7, 2021
Comments
  • Getting issue

    Getting issue "The system cannot find the path specified" while finding current datetime in given timezone in windows

    Hello,

    I am getting an issue "The system cannot find the path specified" while finding current datetime in given timezone in windows. here is the code. error

    from_date := gostradamus.NowInTimezone(gostradamus.AsiaKolkata)

    This code works perfectly in linux but getting an error in windows.

    Please let me know if I am making any mistakes.

    Thanks in advance.

  • feat: support ordinal days

    feat: support ordinal days

    As per discussion in issue https://github.com/bykof/gostradamus/issues/4, tried to have a crack at this

    I think this is an imperfect solution - lack of localisation being one such wrinkle, and it's a bit imprecise too, particularly when parsing to a time.Time as we also need to replace anything in the input value that uses the Do format as this is not a recognised Go format token

    Happy to work through with you on this - seemed like a reasonably quick task to complete. Let me know if the approach could be better! :)

  • [Question] Days counting across DST in Gostradamus

    [Question] Days counting across DST in Gostradamus

    Ran across your library after a user pointed out a strange daylight savings time bug in my app harsh.

    Largely, because Golang's time.Time() and addDate() punts on the days construct across DST and no-DST, so I was wondering if you'd puzzled out a way to count days properly between DST days in Gostradamus.

    As an example, in my app the fact I am using AddDate(0, 0, -1) across the DST boundary causes a bug if a user tries to look at the date range between 1am and 2am BST only. ( I am gathering this occures, since when it counts backwards daily, the day BST kicks in does not have that hour actually existing -- as I'm gathering after digging into the issue and some golang bug reports on this issue).

    But really, what I really want is a simple way to count iso dates that a local user experiences. so even across DST.

    Does Gostradamus handle day math "properly" across DSTs for adding and subtracting days.

    Had to ask since I noticed you said it is using the underlying go time library. =]

Golang library with POSIX-compliant command-line UI (CLI) and Hierarchical-configuration. Better substitute for stdlib flag.
Golang library with POSIX-compliant command-line UI (CLI) and Hierarchical-configuration. Better substitute for stdlib flag.

cmdr cmdr is a POSIX-compliant, command-line UI (CLI) library in Golang. It is a getopt-like parser of command-line options, be compatible with the ge

Oct 28, 2022
Cuckoo Filter: Practically Better Than Bloom

Cuckoo Filter Cuckoo filter is a Bloom filter replacement for approximated set-membership queries. While Bloom filters are well-known space-efficient

Jan 4, 2023
:clock8: Better time duration formatting in Go!

durafmt durafmt is a tiny Go library that formats time.Duration strings (and types) into a human readable format. go get github.com/hako/durafmt Why

Dec 16, 2022
A better ORM for Go, based on non-empty interfaces and code generation.

reform A better ORM for Go and database/sql. It uses non-empty interfaces, code generation (go generate), and initialization-time reflection as oppose

Dec 31, 2022
eris provides a better way to handle, trace, and log errors in Go 🎆

eris Package eris provides a better way to handle, trace, and log errors in Go. go get github.com/rotisserie/eris Why you'll want to switch to eris Us

Dec 29, 2022
go websocket, a better way to buid your IM server
go websocket, a better way to buid your IM server

Your star is my power!! ?? ⭐ ⭐ ⭐ ⭐ ⭐ Discribe lhttp is a http like protocol using websocket to provide long live, build your IM service quickly scalab

Dec 30, 2022
Utilities for slightly better logging in Go (Golang).

logutils logutils is a Go package that augments the standard library "log" package to make logging a bit more modern, without fragmenting the Go ecosy

Dec 16, 2022
a better customizable tool to embed files in go; also update embedded files remotely without restarting the server

fileb0x What is fileb0x? A better customizable tool to embed files in go. It is an alternative to go-bindata that have better features and organized c

Dec 27, 2022
Gin is a HTTP web framework written in Go (Golang). It features a Martini-like API with much better performance -- up to 40 times faster. If you need smashing performance, get yourself some Gin.
Gin is a HTTP web framework written in Go (Golang). It features a Martini-like API with much better performance -- up to 40 times faster. If you need smashing performance, get yourself some Gin.

Gin Web Framework Gin is a web framework written in Go (Golang). It features a martini-like API with performance that is up to 40 times faster thanks

Jan 2, 2023