Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add Strftime method and Strptime function #26

Merged
merged 4 commits into from
Nov 12, 2023
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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ If you have a feature request, please open an issue. It would be great if you co
- [Advance](https://pkg.go.dev/github.com/Code-Hex/synchro#Time.Advance)
- `Advance` allows you to specify the date and time components you want to increment and make modifications.
- [Period](https://pkg.go.dev/github.com/Code-Hex/synchro#Period)
- [Strptime](https://pkg.go.dev/github.com/Code-Hex/synchro#Strptime)
- [Strftime](https://pkg.go.dev/github.com/Code-Hex/synchro#Time.Strftime)


## TODO
Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ module github.com/Code-Hex/synchro
go 1.20.0

require github.com/google/go-cmp v0.5.9

require github.com/itchyny/timefmt-go v0.1.5
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/itchyny/timefmt-go v0.1.5 h1:G0INE2la8S6ru/ZI5JecgyzbbJNs5lG1RcBqa7Jm6GE=
github.com/itchyny/timefmt-go v0.1.5/go.mod h1:nEP7L+2YmAbT2kZ2HfSs1d8Xtw9LY8D2stDBckWakZ8=
114 changes: 114 additions & 0 deletions time.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package synchro
import (
"math"
"time"

"github.com/itchyny/timefmt-go"
)

type empty[T TimeZone] struct{}
Expand Down Expand Up @@ -108,3 +110,115 @@ func (t Time[T]) DiffInCalendarDays(u Time[T]) int {
u1 := u.Truncate(day)
return int(math.Ceil(float64(t1.Sub(u1)) / float64(day)))
}

// Strftime formats the time according to the given format string.
//
// This method is a wrapper for the [github.com/itchyny/timefmt-go] library.
//
// Example:
// - %Y-%m-%d %H:%M:%S => 2023-09-02 14:09:56
// - %a, %d %b %Y %T %z => Sat, 02 Sep 2023 14:09:56 +0900
//
// The format string should follow the format of [strftime(3)] in man pages.
// The following list shows the supported format specifiers:
// - %a: Abbreviated weekday name (Sun)
// - %A: Full weekday name (Sunday)
// - %b: Abbreviated month name (Jan)
// - %B: Full month name (January)
// - %c: Date and time representation
// - %C: Year divided by 100 (00-99)
// - %d: Day of the month (01-31)
// - %D: Short MM/DD/YY date, equivalent to %m/%d/%y
// - %e: Day of the month, with a space preceding single digits ( 1-31)
// - %F: Equivalent to %Y-%m-%d (the ISO 8601 date format)
// - %g: Week-based year, last two digits (00-99)
// - %G: Week-based year
// - %h: Abbreviated month name (Jan)
// - %H: Hour in 24h format (00-23)
// - %I: Hour in 12h format (01-12)
// - %j: Day of the year (001-366)
// - %m: Month as a decimal number (01-12)
// - %M: Minute (00-59)
// - %n: New-line character
// - %p: AM or PM designation
// - %P: am or pm designation
// - %r: 12-hour clock time
// - %R: 24-hour HH:MM time, equivalent to %H:%M
// - %S: Second (00-59)
// - %t: Horizontal-tab character
// - %T: 24-hour clock time, equivalent to %H:%M:%S
// - %u: ISO 8601 weekday as number with Monday as 1 (1-7)
// - %U: Week number with the first Sunday as the first day of week (00-53)
// - %V: ISO 8601 week number (01-53)
// - %w: Weekday as a decimal number with Sunday as 0 (0-6)
// - %W: Week number with the first Monday as the first day of week (00-53)
// - %x: Date representation
// - %X: Time representation
// - %y: Year, last two digits (00-99)
// - %Y: Year
// - %z: ISO 8601 offset from UTC in timezone (+HHMM)
// - %Z: Timezone name or abbreviation
// - %+: Extended date and time representation
// - %::z: Colon-separated offset from UTC in timezone (e.g. +05:00)
// - %:::z: Like %::z, but with optional seconds
//
// [strftime(3)]: https://linux.die.net/man/3/strftime
// [github.com/itchyny/timefmt-go]: https://github.com/itchyny/timefmt-go
func (t Time[T]) Strftime(format string) string {
return timefmt.Format(t.StdTime(), format)
}

// Strptime parses time string with the default location.
// The location is also used to parse the time zone name (%Z).
//
// The format string should follow the format of [strptime(3)] in man pages.
// The following list shows the supported format specifiers:
// - %a: abbreviated weekday name
// - %A: full weekday name
// - %b: abbreviated month name
// - %B: full month name
// - %c: preferred date and time representation
// - %C: century number (00-99)
// - %d: day of the month (01-31)
// - %D: same as %m/%d/%y
// - %e: day of the month (1-31)
// - %F: same as %Y-%m-%d
// - %g: last two digits of the year (00-99)
// - %G: year as a 4-digit number
// - %h: same as %b
// - %H: hour (00-23)
// - %I: hour (01-12)
// - %j: day of the year (001-366)
// - %m: month (01-12)
// - %M: minute (00-59)
// - %n: newline character
// - %p: either "am" or "pm" according to the given time value
// - %r: time in a.m. and p.m. notation
// - %R: time in 24 hour notation
// - %S: second (00-60)
// - %t: tab character
// - %T: current time, equal to %H:%M:%S
// - %u: weekday as a number (1-7)
// - %U: week number of the current year, starting with the first Sunday as the first day of the first week
// - %V: week number of the current year, starting with the first week that has at least 4 days in the new year
// - %w: day of the week as a decimal, Sunday being 0
// - %W: week number of the current year, starting with the first Monday as the first day of the first week
// - %x: preferred date representation without the time
// - %X: preferred time representation without the date
// - %y: year without a century (00-99)
// - %Y: year with century
// - %z: time zone offset, such as "-0700"
// - %Z: time zone name, such as "UTC" or "GMT"
//
// This is a wrapper for the [github.com/itchyny/timefmt-go] library.
//
// [strptime(3)]: https://linux.die.net/man/3/strptime
// [github.com/itchyny/timefmt-go]: https://github.com/itchyny/timefmt-go
func Strptime[T TimeZone](source string, format string) (Time[T], error) {
var tz T
tm, err := timefmt.ParseInLocation(source, format, tz.Location())
if err != nil {
return Time[T]{}, err
}
return In[T](tm), nil
}
20 changes: 20 additions & 0 deletions time_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -614,3 +614,23 @@ func TestDiffInCalendarDays(t *testing.T) {
})
}
}

func ExampleTime_Strftime() {
t := synchro.New[tz.AsiaTokyo](2023, 9, 2, 14, 9, 56, 0)
fmt.Println(t.Strftime("%Y-%m-%d %H:%M:%S"))
fmt.Println(t.Strftime("%a, %d %b %Y %T %z"))
// Output:
// 2023-09-02 14:09:56
// Sat, 02 Sep 2023 14:09:56 +0900
}

func ExampleStrptime() {
t, _ := synchro.Strptime[tz.AsiaTokyo]("2023-09-02 14:09:56", "%Y-%m-%d %H:%M:%S")
fmt.Println(t)

_, err := synchro.Strptime[tz.UTC]("invalid", "%Y")
fmt.Println("error", err) // Returns an error as the layout is not a valid time value
// Output:
// 2023-09-02 14:09:56 +0900 JST
// error failed to parse "invalid" with "%Y": cannot parse %Y
}