Skip to content

Commit

Permalink
Merge pull request #26 from Code-Hex/add/strftime
Browse files Browse the repository at this point in the history
add Strftime method and Strptime function
  • Loading branch information
Code-Hex committed Nov 12, 2023
2 parents 66a5888 + 75dcef1 commit 8e5c2fd
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 0 deletions.
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
}

0 comments on commit 8e5c2fd

Please sign in to comment.