timefy is a comprehensive Go library designed to enhance productivity by offering a wide range of time-related utilities. Whether you're dealing with date formatting, time zone conversions, or scheduling. Timefy provides a robust toolkit to simplify time management tasks in Go applications.
- Go version 1.23 or higher
To install, you can use the following commands based on your preference:
-
For a specific version:
go get github.com/sivaosorg/timefy@v0.0.1
-
For the latest version:
go get -u github.com/sivaosorg/timefy@latest
With Go's module support, go [build|run|test] automatically fetches the necessary dependencies when you add the import in your code:
import "github.com/sivaosorg/timefy"Calculating the time based on current time
package main
import (
"fmt"
"time"
"github.com/sivaosorg/timefy"
)
func main() {
// time based on current time
tx := timefy.With(time.Now()) // 2024-10-25 21:31:00.690342
fmt.Println(tx.BeginningOfMinute()) // 2024-10-25 21:31:00
fmt.Println(tx.BeginningOfHour()) // 2024-10-25 21:00:00
fmt.Println(tx.BeginningOfDay()) // 2024-10-25 00:00:00
fmt.Println(tx.BeginningOfWeek()) // 2024-10-20 00:00:00
fmt.Println(tx.BeginningOfMonth()) // 2024-10-01 00:00:00
fmt.Println(tx.BeginningOfQuarter()) // 2024-10-01 00:00:00
fmt.Println(tx.BeginningOfHalf()) // 2024-07-01 00:00:00
fmt.Println(tx.BeginningOfYear()) // 2024-01-01 00:00:00
fmt.Println(tx.EndOfMinute()) // 2024-10-25 21:31:59.999999999 +0700 +07
fmt.Println(tx.EndOfHour()) // 2024-10-25 21:59:59.999999999 +0700 +07
fmt.Println(tx.EndOfDay()) // 2024-10-25 23:59:59.999999999 +0700 +07
fmt.Println(tx.EndOfWeek()) // 2024-10-26 23:59:59.999999999 +0700 +07
fmt.Println(tx.EndOfMonth()) // 2024-10-31 23:59:59.999999999 +0700 +07
fmt.Println(tx.EndOfQuarter()) // 2024-12-31 23:59:59.999999999 +0700 +07
fmt.Println(tx.EndOfHalf()) // 2024-12-31 23:59:59.999999999 +0700 +07
fmt.Println(tx.EndOfYear()) // 2024-12-31 23:59:59.999999999 +0700 +07
fmt.Println(tx.EndOfWeek()) // 2024-10-28 23:59:59.999999999 +0700 +07
}Calculating the time based on another time
package main
import (
"fmt"
"time"
"github.com/sivaosorg/timefy"
)
func main() {
// time based on another time
t := time.Date(2025, 01, 15, 17, 51, 49, 123456789, time.Local)
tx := timefy.New(t) // or timefy.With(t)
fmt.Println(tx.EndOfMonth()) // 2025-01-31 23:59:59.999999999 +0700 +07
}Calculating the time based on configuration
package main
import (
"fmt"
"time"
"github.com/sivaosorg/timefy"
)
func main() {
// time based on configuration
rule := timefy.NewRule().WithLocationRFC(timefy.DefaultTimezoneVietnam)
t := time.Date(2025, 01, 15, 17, 51, 49, 123456789, time.Now().Location())
fmt.Println(t) // 2025-01-15 17:51:49.123456789 +0700 +07
fmt.Println(rule.With(t).BeginningOfWeek()) // 2025-01-12 00:00:00 +0700 +07
v, _ := rule.Parse("2025-11-12 22:14:01")
fmt.Println(v) // 2025-11-12 22:14:01 +0700 +07
}Monday / Sunday
package main
import (
"fmt"
"time"
"github.com/sivaosorg/timefy"
)
func main() {
// Monday / Sunday
t := time.Date(2025, 01, 15, 17, 51, 49, 123456789, time.Now().Location())
fmt.Println(timefy.Monday()) // 2024-10-21 00:00:00 +0700 +07
fmt.Println(timefy.Monday("15:35:34")) // 2024-10-21 15:35:34 +0700 +07
fmt.Println(timefy.Sunday()) // 2024-10-27 00:00:00 +0700 +07
fmt.Println(timefy.Sunday("16:45:34")) // 2024-10-27 16:45:34 +0700 +07
fmt.Println(timefy.EndOfSunday()) // 2024-10-27 23:59:59.999999999 +0700 +07
fmt.Println(timefy.With(t).Monday()) // 2025-01-13 00:00:00 +0700 +07
fmt.Println(timefy.With(t).Monday("15:35:34")) // 2025-01-13 15:35:34 +0700 +07
fmt.Println(timefy.With(t).Sunday()) // 2025-01-19 00:00:00 +0700 +07
fmt.Println(timefy.With(t).Sunday("16:45:34")) // 2025-01-19 16:45:34 +0700 +07
fmt.Println(timefy.With(t).EndOfSunday()) // 2025-01-19 23:59:59.999999999 +0700 +07
}Parse String to Time
package main
import (
"fmt"
"github.com/sivaosorg/timefy"
)
func main() {
// String to Time
t, _ := timefy.Parse("2025")
fmt.Println(t) // 2025-01-01 00:00:00 +0700 +07
t, _ = timefy.Parse("2025-02")
fmt.Println(t) // 2025-02-01 00:00:00 +0700 +07
t, _ = timefy.Parse("2025-02-15")
fmt.Println(t) // 2025-02-15 00:00:00 +0700 +07
t, _ = timefy.Parse("11-15")
fmt.Println(t) // 2024-11-15 00:00:00 +0700 +07
t, _ = timefy.Parse("13:15")
fmt.Println(t) // 2024-10-25 13:15:00 +0700 +07
t, _ = timefy.Parse("13:15:45")
fmt.Println(t) // 2024-10-25 13:15:45 +0700 +07
t, _ = timefy.Parse("23")
fmt.Println(t) // 2024-10-25 23:00:00 +0700 +07
// MustParse must parse string to time or it will panic
t = timefy.MustParse("11")
fmt.Println(t) // 2024-10-25 11:00:00 +0700 +07
t = timefy.MustParse("99:99") // panic: can't parse string as time: 99:99
// fmt.Println(t)
// Extend timefy to support more formats is quite easy, just update timefy.TimeFormats with other time layouts, e.g:
timefy.TimeFormats = append(timefy.TimeFormats, "02 Jan 2006 15:04")
fmt.Println(timefy.TimeFormats)
}Parse in Location
package main
import (
"fmt"
"time"
"github.com/sivaosorg/timefy"
)
func main() {
// ParseInLocation parses in a specific timezone
t, err := timefy.ParseInLocation(time.UTC, "2023-10-25")
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println(t) // 2023-10-25 00:00:00 +0000 UTC
// MustParseInLocation panics on error
t = timefy.MustParseInLocation(time.UTC, "2023-10-25 14:30:00")
fmt.Println(t) // 2023-10-25 14:30:00 +0000 UTC
}Day Operations
package main
import (
"fmt"
"time"
"github.com/sivaosorg/timefy"
)
func main() {
now := time.Date(2025, 01, 15, 17, 51, 49, 0, time.UTC)
// BeginOfDay returns the start of the day (00:00:00)
fmt.Println(timefy.BeginOfDay(now)) // 2025-01-15 00:00:00 +0000 UTC
// FEndOfDay returns the end of the day (23:59:59)
fmt.Println(timefy.FEndOfDay(now)) // 2025-01-15 23:59:59 +0000 UTC
// PrevBeginOfDay returns the start of the day N days ago
fmt.Println(timefy.PrevBeginOfDay(now, 2)) // 2025-01-13 00:00:00 +0000 UTC
// PrevEndOfDay returns the end of the day N days ago
fmt.Println(timefy.PrevEndOfDay(now, 2)) // 2025-01-13 23:59:59 +0000 UTC
}Time Manipulation (Add/Subtract)
package main
import (
"fmt"
"time"
"github.com/sivaosorg/timefy"
)
func main() {
now := time.Date(2025, 01, 15, 12, 0, 0, 0, time.UTC)
// AddSecond adds seconds (negative to subtract)
fmt.Println(timefy.AddSecond(now, 30)) // 2025-01-15 12:00:30 +0000 UTC
fmt.Println(timefy.AddSecond(now, -30)) // 2025-01-15 11:59:30 +0000 UTC
// AddMinute adds minutes
fmt.Println(timefy.AddMinute(now, 10)) // 2025-01-15 12:10:00 +0000 UTC
fmt.Println(timefy.AddMinute(now, -10)) // 2025-01-15 11:50:00 +0000 UTC
// AddHour adds hours
fmt.Println(timefy.AddHour(now, 3)) // 2025-01-15 15:00:00 +0000 UTC
fmt.Println(timefy.AddHour(now, -3)) // 2025-01-15 09:00:00 +0000 UTC
// AddDay adds days
fmt.Println(timefy.AddDay(now, 5)) // 2025-01-20 12:00:00 +0000 UTC
fmt.Println(timefy.AddDay(now, -5)) // 2025-01-10 12:00:00 +0000 UTC
}Timezone Utilities
package main
import (
"fmt"
"time"
"github.com/sivaosorg/timefy"
)
func main() {
now := time.Date(2025, 01, 15, 12, 0, 0, 0, time.UTC)
// SetTimezone converts time to a specific timezone (returns error if invalid)
nyTime, err := timefy.SetTimezone(now, "America/New_York")
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println(nyTime) // 2025-01-15 07:00:00 -0500 EST
// AdjustTimezone converts time (returns original time on invalid timezone)
tokyoTime := timefy.AdjustTimezone(now, "Asia/Tokyo")
fmt.Println(tokyoTime) // 2025-01-15 21:00:00 +0900 JST
invalidTZ := timefy.AdjustTimezone(now, "Invalid/Zone")
fmt.Println(invalidTZ) // 2025-01-15 12:00:00 +0000 UTC (original time returned)
}Leap Year & Tolerance Checks
package main
import (
"fmt"
"time"
"github.com/sivaosorg/timefy"
)
func main() {
// IsLeapYear checks if a year is a leap year
fmt.Println(timefy.IsLeapYear(2024)) // true
fmt.Println(timefy.IsLeapYear(2023)) // false
fmt.Println(timefy.IsLeapYear(1900)) // false
fmt.Println(timefy.IsLeapYear(2000)) // true
// IsLeapYearN checks using a time.Time value
t := time.Date(2024, 6, 15, 0, 0, 0, 0, time.UTC)
fmt.Println(timefy.IsLeapYearN(t)) // true
// IsWithinTolerance checks if a time is within 1 minute of now
now := time.Now()
fmt.Println(timefy.IsWithinTolerance(now.Add(30 * time.Second))) // true
fmt.Println(timefy.IsWithinTolerance(now.Add(2 * time.Minute))) // false
}Between (String-based Range Check)
package main
import (
"fmt"
"github.com/sivaosorg/timefy"
)
func main() {
// Between checks if the current time is between two time strings
isWithin := timefy.Between("2020-01-01", "2030-12-31")
fmt.Println(isWithin) // true (current time is between these dates)
isWithin = timefy.Between("2030-01-01", "2030-12-31")
fmt.Println(isWithin) // false (current time is not in 2030 yet)
}Quarter
package main
import (
"fmt"
"time"
"github.com/sivaosorg/timefy"
)
func main() {
// Quarter returns the current quarter (1-4)
fmt.Println(timefy.Quarter()) // e.g., 1 for January-March
// Quarter on a Timex instance
t := time.Date(2025, 7, 15, 0, 0, 0, 0, time.UTC)
fmt.Println(timefy.New(t).Quarter()) // 3 (July is Q3)
}Since (Elapsed Time Calculations)
package main
import (
"fmt"
"time"
"github.com/sivaosorg/timefy"
)
func main() {
past := time.Now().Add(-2 * time.Hour)
// SinceHour returns the number of hours passed
fmt.Println(timefy.SinceHour(past)) // ~2.0
// SinceMinute returns the number of minutes passed
fmt.Println(timefy.SinceMinute(past)) // ~120.0
// SinceSecond returns the number of seconds passed
fmt.Println(timefy.SinceSecond(past)) // ~7200.0
}Weekdays in Range
package main
import (
"fmt"
"time"
"github.com/sivaosorg/timefy"
)
func main() {
start := time.Date(2025, 1, 13, 0, 0, 0, 0, time.UTC) // Monday
end := time.Date(2025, 1, 19, 0, 0, 0, 0, time.UTC) // Sunday
// GetWeekdaysInRange returns all weekdays (Mon-Fri) in the range
weekdays := timefy.GetWeekdaysInRange(start, end)
for _, d := range weekdays {
fmt.Println(d) // 2025-01-13, 2025-01-14, 2025-01-15, 2025-01-16, 2025-01-17
}
}FormatTimex (Extract Time Components)
package main
import (
"fmt"
"time"
"github.com/sivaosorg/timefy"
)
func main() {
t := time.Date(2025, 3, 15, 14, 30, 45, 123456789, time.UTC)
// FormatTimex returns a slice of time components: [nanosecond, second, minute, hour, day, month, year]
components := timefy.FormatTimex(t)
fmt.Println(components) // [123456789 45 30 14 15 3 2025]
}Formatting (RFC Layouts)
package main
import (
"fmt"
"time"
"github.com/sivaosorg/timefy"
)
func main() {
t := time.Date(2025, 8, 15, 13, 45, 30, 0, time.UTC)
// FormatRFC formats the current time using a TimeFormatRFC layout
fmt.Println(timefy.FormatRFC(timefy.TimeFormat20060102T150405))
// FormatRFCshort formats the current time using a short TimeRFC layout
fmt.Println(timefy.FormatRFCshort(timefy.TimeRFC01T150405))
// FFormatRFC formats a specific time with a TimeFormatRFC layout
fmt.Println(timefy.FFormatRFC(t, timefy.TimeFormat20060102T150405)) // 2025-08-15T13:45:30
// FFormatRFCshort formats a specific time with a short TimeRFC layout
fmt.Println(timefy.FFormatRFCshort(t, timefy.TimeRFC01T150405)) // 13:45:30
// DefaultFormatRFC formats the current time with the default layout
fmt.Println(timefy.DefaultFormatRFC())
// FDefaultFormatRFC formats a specific time with the default layout
fmt.Println(timefy.FDefaultFormatRFC(t))
}Relative Time (TimeAgo / TimeUntil)
package main
import (
"fmt"
"time"
"github.com/sivaosorg/timefy"
)
func main() {
// TimeAgo returns a human-readable string for past time
fmt.Println(timefy.New(time.Now().Add(-5 * time.Second)).TimeAgo()) // "just now"
fmt.Println(timefy.New(time.Now().Add(-5 * time.Minute)).TimeAgo()) // "5 minutes ago"
fmt.Println(timefy.New(time.Now().Add(-2 * time.Hour)).TimeAgo()) // "2 hours ago"
fmt.Println(timefy.New(time.Now().Add(-48 * time.Hour)).TimeAgo()) // "2 days ago"
fmt.Println(timefy.New(time.Now().Add(-720 * time.Hour)).TimeAgo()) // "1 month ago"
// TimeUntil returns a human-readable string for future time
fmt.Println(timefy.New(time.Now().Add(5 * time.Second)).TimeUntil()) // "in a few seconds"
fmt.Println(timefy.New(time.Now().Add(5 * time.Minute)).TimeUntil()) // "in 5 minutes"
fmt.Println(timefy.New(time.Now().Add(2 * time.Hour)).TimeUntil()) // "in 2 hours"
fmt.Println(timefy.New(time.Now().Add(48 * time.Hour)).TimeUntil()) // "in 2 days"
// TimeUntil with past time
fmt.Println(timefy.New(time.Now().Add(-1 * time.Hour)).TimeUntil()) // "in the past"
}Duration Calculations
package main
import (
"fmt"
"time"
"github.com/sivaosorg/timefy"
)
func main() {
now := time.Date(2025, 1, 15, 0, 0, 0, 0, time.UTC)
tx := timefy.New(now)
// DurationInDays returns the number of days between two times
future := now.AddDate(0, 0, 10)
fmt.Println(tx.DurationInDays(future)) // 10
// DurationInWeeks returns the number of weeks between two times
future = now.AddDate(0, 0, 21)
fmt.Println(tx.DurationInWeeks(future)) // 3
// DurationInMonths returns the number of months between two times
future = now.AddDate(0, 3, 0)
fmt.Println(tx.DurationInMonths(future)) // 3
// DurationInYears returns the number of years between two times
future = now.AddDate(2, 0, 0)
fmt.Println(tx.DurationInYears(future)) // 2
}Day Type Checks (Weekend / Weekday)
package main
import (
"fmt"
"time"
"github.com/sivaosorg/timefy"
)
func main() {
saturday := time.Date(2025, 1, 18, 12, 0, 0, 0, time.UTC)
monday := time.Date(2025, 1, 20, 12, 0, 0, 0, time.UTC)
// IsWeekend checks if the time is Saturday or Sunday
fmt.Println(timefy.New(saturday).IsWeekend()) // true
fmt.Println(timefy.New(monday).IsWeekend()) // false
// IsWeekday checks if the time is Monday to Friday
fmt.Println(timefy.New(saturday).IsWeekday()) // false
fmt.Println(timefy.New(monday).IsWeekday()) // true
}Time Comparison Helpers
package main
import (
"fmt"
"time"
"github.com/sivaosorg/timefy"
)
func main() {
now := time.Now()
tx := timefy.New(now)
yesterday := now.AddDate(0, 0, -1)
tomorrow := now.AddDate(0, 0, 1)
// IsBefore checks if the time is before another time
fmt.Println(tx.IsBefore(tomorrow)) // true
fmt.Println(tx.IsBefore(yesterday)) // false
// IsAfter checks if the time is after another time
fmt.Println(tx.IsAfter(yesterday)) // true
fmt.Println(tx.IsAfter(tomorrow)) // false
// IsBetween checks if the time falls within a range (inclusive)
fmt.Println(tx.IsBetween(yesterday, tomorrow)) // true
// IsSameDay checks if two times are on the same day
fmt.Println(tx.IsSameDay(now)) // true
fmt.Println(tx.IsSameDay(yesterday)) // false
// IsSameMonth checks if two times are in the same month
nextMonth := now.AddDate(0, 1, 0)
fmt.Println(tx.IsSameMonth(now)) // true
fmt.Println(tx.IsSameMonth(nextMonth)) // false
// IsSameYear checks if two times are in the same year
nextYear := now.AddDate(1, 0, 0)
fmt.Println(tx.IsSameYear(now)) // true
fmt.Println(tx.IsSameYear(nextYear)) // false
}Temporal Checks (Today / Yesterday / Tomorrow / Past / Future)
package main
import (
"fmt"
"time"
"github.com/sivaosorg/timefy"
)
func main() {
now := time.Now()
// IsToday checks if the time is today
fmt.Println(timefy.New(now).IsToday()) // true
// IsYesterday checks if the time is yesterday
yesterday := now.AddDate(0, 0, -1)
fmt.Println(timefy.New(yesterday).IsYesterday()) // true
// IsTomorrow checks if the time is tomorrow
tomorrow := now.AddDate(0, 0, 1)
fmt.Println(timefy.New(tomorrow).IsTomorrow()) // true
// IsPast checks if the time is in the past
past := now.Add(-1 * time.Hour)
fmt.Println(timefy.New(past).IsPast()) // true
// IsFuture checks if the time is in the future
future := now.Add(1 * time.Hour)
fmt.Println(timefy.New(future).IsFuture()) // true
}Global Convenience Functions (BeginningOf / EndOf)
package main
import (
"fmt"
"github.com/sivaosorg/timefy"
)
func main() {
// These global functions use the current time automatically
fmt.Println(timefy.BeginningOfMinute()) // Current time at start of minute
fmt.Println(timefy.BeginningOfHour()) // Current time at start of hour
fmt.Println(timefy.BeginningOfDay()) // Today at 00:00:00
fmt.Println(timefy.BeginningOfWeek()) // Start of current week
fmt.Println(timefy.BeginningOfMonth()) // 1st of current month at 00:00:00
fmt.Println(timefy.BeginningOfQuarter()) // 1st of current quarter
fmt.Println(timefy.BeginningOfYear()) // Jan 1st of current year
fmt.Println(timefy.EndOfMinute()) // Current time at end of minute
fmt.Println(timefy.EndOfHour()) // Current time at end of hour
fmt.Println(timefy.EndOfDay()) // Today at 23:59:59.999999999
fmt.Println(timefy.EndOfWeek()) // End of current week
fmt.Println(timefy.EndOfMonth()) // Last day of current month at 23:59:59.999999999
fmt.Println(timefy.EndOfQuarter()) // Last day of current quarter
fmt.Println(timefy.EndOfYear()) // Dec 31st at 23:59:59.999999999
}Configuration (Rule) — Complete API
package main
import (
"fmt"
"time"
"github.com/sivaosorg/timefy"
)
func main() {
// NewRule creates a rule with default configuration
rule := timefy.NewRule()
// WithWeekStartDay sets the week start day
rule.WithWeekStartDay(time.Monday)
// WithTimeFormats overrides the time formats
rule.WithTimeFormats([]string{"2006-01-02 15:04:05"})
// WithLocation sets the location using *time.Location
rule.WithLocation(time.UTC)
// WithLocationRFC sets location using a predefined zone string
rule.WithLocationRFC(timefy.DefaultTimezoneVietnam)
// ApplyUTCLoc sets location to UTC
rule.ApplyUTCLoc()
// ApplyLocalLoc sets location to Local
rule.ApplyLocalLoc()
// AppendTimeFormat appends custom format strings
rule.AppendTimeFormat("02 Jan 2006 15:04")
// AppendTimeFormatRFC appends defined RFC format constants
rule.AppendTimeFormatRFC(timefy.TimeFormat20060102T150405)
// AppendTimeFormatRFCshort appends defined short RFC format constants
rule.AppendTimeFormatRFCshort(timefy.TimeRFC01T150405)
// Rule.With creates a Timex with the rule's configuration
tx := rule.With(time.Now())
fmt.Println(tx.BeginningOfWeek())
// Rule.Parse parses a string using the rule's configuration
v, _ := rule.Parse("2025-11-12 22:14:01")
fmt.Println(v)
// Rule.MustParse panics on error
v = rule.MustParse("2025-11-12 22:14:01")
fmt.Println(v)
}To contribute to project, follow these steps:
-
Clone the repository:
git clone --depth 1 https://github.com/sivaosorg/timefy.git
-
Navigate to the project directory:
cd timefy -
Prepare the project environment:
go mod tidy