{"id":13592903,"url":"https://github.com/lestrrat-go/strftime","last_synced_at":"2025-10-07T10:52:19.206Z","repository":{"id":15170104,"uuid":"77694198","full_name":"lestrrat-go/strftime","owner":"lestrrat-go","description":"Fast strftime for Go","archived":false,"fork":false,"pushed_at":"2025-08-21T01:05:32.000Z","size":143,"stargazers_count":129,"open_issues_count":4,"forks_count":25,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-08-21T03:31:48.642Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lestrrat-go.png","metadata":{"files":{"readme":"README.md","changelog":"Changes","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":["lestrrat"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2016-12-30T15:26:17.000Z","updated_at":"2025-08-21T01:05:34.000Z","dependencies_parsed_at":"2024-01-13T22:55:16.021Z","dependency_job_id":"eda606a7-67e7-4e3b-981b-d648d16491fb","html_url":"https://github.com/lestrrat-go/strftime","commit_stats":{"total_commits":105,"total_committers":9,"mean_commits":"11.666666666666666","dds":"0.24761904761904763","last_synced_commit":"5f3b0c877556002d810d691e14a2d989a1d04d20"},"previous_names":["lestrrat-go/go-strftime"],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/lestrrat-go/strftime","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lestrrat-go%2Fstrftime","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lestrrat-go%2Fstrftime/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lestrrat-go%2Fstrftime/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lestrrat-go%2Fstrftime/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lestrrat-go","download_url":"https://codeload.github.com/lestrrat-go/strftime/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lestrrat-go%2Fstrftime/sbom","scorecard":{"id":585785,"data":{"date":"2025-08-11","repo":{"name":"github.com/lestrrat-go/strftime","commit":"a8371f71591092e60e52e30ba5f8e29484869fca"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.9,"checks":[{"name":"Code-Review","score":3,"reason":"Found 5/13 approved changesets -- score normalized to 3","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":6,"reason":"7 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 6","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/ci.yml:1","Warn: no topLevel permission defined: .github/workflows/lint.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":10,"reason":"all dependencies are pinned","details":["Info:   4 out of   4 GitHub-owned GitHubAction dependencies pinned","Info:   2 out of   2 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 22 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-20T20:28:23.752Z","repository_id":15170104,"created_at":"2025-08-20T20:28:23.752Z","updated_at":"2025-08-20T20:28:23.752Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278762921,"owners_count":26041444,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-07T02:00:06.786Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T16:01:14.555Z","updated_at":"2025-10-07T10:52:19.198Z","avatar_url":"https://github.com/lestrrat-go.png","language":"Go","funding_links":["https://github.com/sponsors/lestrrat"],"categories":["开源类库","Go","Open source library"],"sub_categories":["日期时间","Appointment Time"],"readme":"# strftime\n\nFast strftime for Go\n\n [![](https://github.com/lestrrat-go/strftime/workflows/CI/badge.svg?branch=master)](https://github.com/lestrrat-go/strftime/actions?query=branch%3Amaster) [![Go Reference](https://pkg.go.dev/badge/github.com/lestrrat-go/strftime.svg)](https://pkg.go.dev/github.com/lestrrat-go/strftime)\n\n# SYNOPSIS\n\n```go\nf, err := strftime.New(`.... pattern ...`)\nif err := f.Format(buf, time.Now()); err != nil {\n    log.Println(err.Error())\n}\n```\n\n# DESCRIPTION\n\nThe goals for this library are\n\n* Optimized for the same pattern being called repeatedly\n* Be flexible about destination to write the results out\n* Be as complete as possible in terms of conversion specifications\n\n# API\n\n## Format(string, time.Time) (string, error)\n\nTakes the pattern and the time, and formats it. This function is a utility function that recompiles the pattern every time the function is called. If you know beforehand that you will be formatting the same pattern multiple times, consider using `New` to create a `Strftime` object and reuse it.\n\n## New(string) (\\*Strftime, error)\n\nTakes the pattern and creates a new `Strftime` object.\n\n## obj.Pattern() string\n\nReturns the pattern string used to create this `Strftime` object\n\n## obj.Format(io.Writer, time.Time) error\n\nFormats the time according to the pre-compiled pattern, and writes the result to the specified `io.Writer`\n\n## obj.FormatString(time.Time) string\n\nFormats the time according to the pre-compiled pattern, and returns the result string.\n\n# SUPPORTED CONVERSION SPECIFICATIONS\n\n| pattern | description |\n|:--------|:------------|\n| %A      | national representation of the full weekday name |\n| %a      | national representation of the abbreviated weekday |\n| %B      | national representation of the full month name |\n| %b      | national representation of the abbreviated month name |\n| %C      | (year / 100) as decimal number; single digits are preceded by a zero |\n| %c      | national representation of time and date |\n| %D      | equivalent to %m/%d/%y |\n| %d      | day of the month as a decimal number (01-31) |\n| %e      | the day of the month as a decimal number (1-31); single digits are preceded by a blank |\n| %F      | equivalent to %Y-%m-%d |\n| %G      | the ISO week year with century as a decimal number with 4 digits |\n| %g      | the ISO week year without century as a decimal number (00-99) with 2 digits |\n| %H      | the hour (24-hour clock) as a decimal number (00-23) |\n| %h      | same as %b |\n| %I      | the hour (12-hour clock) as a decimal number (01-12) |\n| %j      | the day of the year as a decimal number (001-366) |\n| %k      | the hour (24-hour clock) as a decimal number (0-23); single digits are preceded by a blank |\n| %l      | the hour (12-hour clock) as a decimal number (1-12); single digits are preceded by a blank |\n| %M      | the minute as a decimal number (00-59) |\n| %m      | the month as a decimal number (01-12) |\n| %n      | a newline |\n| %p      | national representation of either \"ante meridiem\" (a.m.)  or \"post meridiem\" (p.m.)  as appropriate. |\n| %R      | equivalent to %H:%M |\n| %r      | equivalent to %I:%M:%S %p |\n| %S      | the second as a decimal number (00-60) |\n| %T      | equivalent to %H:%M:%S |\n| %t      | a tab |\n| %U      | the week number of the year (Sunday as the first day of the week) as a decimal number (00-53) |\n| %u      | the weekday (Monday as the first day of the week) as a decimal number (1-7) |\n| %V      | the week number of the year (Monday as the first day of the week) as a decimal number (01-53) |\n| %v      | equivalent to %e-%b-%Y |\n| %W      | the week number of the year (Monday as the first day of the week) as a decimal number (00-53) |\n| %w      | the weekday (Sunday as the first day of the week) as a decimal number (0-6) |\n| %X      | national representation of the time |\n| %x      | national representation of the date |\n| %Y      | the year with century as a decimal number |\n| %y      | the year without century as a decimal number (00-99) |\n| %Z      | the time zone name |\n| %z      | the time zone offset from UTC |\n| %%      | a '%' |\n\n# EXTENSIONS / CUSTOM SPECIFICATIONS\n\nThis library in general tries to be POSIX compliant, but sometimes you just need that\nextra specification or two that is relatively widely used but is not included in the\nPOSIX specification.\n\nFor example, POSIX does not specify how to print out milliseconds,\nbut popular implementations allow `%f` or `%L` to achieve this.\n\nFor those instances, `strftime.Strftime` can be configured to use a custom set of\nspecifications:\n\n```\nss := strftime.NewSpecificationSet()\nss.Set('L', ...) // provide implementation for `%L`\n\n// pass this new specification set to the strftime instance\np, err := strftime.New(`%L`, strftime.WithSpecificationSet(ss))\np.Format(..., time.Now())\n```\n\nThe implementation must implement the `Appender` interface, which is\n\n```\ntype Appender interface {\n  Append([]byte, time.Time) []byte\n}\n```\n\nFor commonly used extensions such as the millisecond example and Unix timestamp, we provide a default\nimplementation so the user can do one of the following:\n\n```\n// (1) Pass a specification byte and the Appender\n//     This allows you to pass arbitrary Appenders\np, err := strftime.New(\n  `%L`,\n  strftime.WithSpecification('L', strftime.Milliseconds),\n)\n\n// (2) Pass an option that knows to use strftime.Milliseconds\np, err := strftime.New(\n  `%L`,\n  strftime.WithMilliseconds('L'),\n)\n```\n\nSimilarly for Unix Timestamp:\n```\n// (1) Pass a specification byte and the Appender\n//     This allows you to pass arbitrary Appenders\np, err := strftime.New(\n  `%s`,\n  strftime.WithSpecification('s', strftime.UnixSeconds),\n)\n\n// (2) Pass an option that knows to use strftime.UnixSeconds\np, err := strftime.New(\n  `%s`,\n  strftime.WithUnixSeconds('s'),\n)\n```\n\nIf a common specification is missing, please feel free to submit a PR\n(but please be sure to be able to defend how \"common\" it is)\n\n## List of available extensions\n\n- [`Milliseconds`](https://pkg.go.dev/github.com/lestrrat-go/strftime?tab=doc#Milliseconds) (related option: [`WithMilliseconds`](https://pkg.go.dev/github.com/lestrrat-go/strftime?tab=doc#WithMilliseconds));\n\n- [`Microseconds`](https://pkg.go.dev/github.com/lestrrat-go/strftime?tab=doc#Microseconds) (related option: [`WithMicroseconds`](https://pkg.go.dev/github.com/lestrrat-go/strftime?tab=doc#WithMicroseconds));\n\n- [`UnixSeconds`](https://pkg.go.dev/github.com/lestrrat-go/strftime?tab=doc#UnixSeconds) (related option: [`WithUnixSeconds`](https://pkg.go.dev/github.com/lestrrat-go/strftime?tab=doc#WithUnixSeconds)).\n\n\n# PERFORMANCE / OTHER LIBRARIES\n\nThe following benchmarks were run separately because some libraries were using cgo on specific platforms (notabley, the fastly version)\n\n```\n// On my OS X 10.14.6, 2.3 GHz Intel Core i5, 16GB memory.\n// go version go1.13.4 darwin/amd64\nhummingbird% go test -tags bench -benchmem -bench .\n\u003csnip\u003e\nBenchmarkTebeka-4                 \t  297471\t      3905 ns/op\t     257 B/op\t      20 allocs/op\nBenchmarkJehiah-4                 \t  818444\t      1773 ns/op\t     256 B/op\t      17 allocs/op\nBenchmarkFastly-4                 \t 2330794\t       550 ns/op\t      80 B/op\t       5 allocs/op\nBenchmarkLestrrat-4               \t  916365\t      1458 ns/op\t      80 B/op\t       2 allocs/op\nBenchmarkLestrratCachedString-4   \t 2527428\t       546 ns/op\t     128 B/op\t       2 allocs/op\nBenchmarkLestrratCachedWriter-4   \t  537422\t      2155 ns/op\t     192 B/op\t       3 allocs/op\nPASS\nok  \tgithub.com/lestrrat-go/strftime\t25.618s\n```\n\n```\n// On a host on Google Cloud Platform, machine-type: f1-micro (vCPU x 1, memory: 0.6GB)\n// (Yes, I was being skimpy)\n// Linux \u003csnip\u003e 4.9.0-11-amd64 #1 SMP Debian 4.9.189-3+deb9u1 (2019-09-20) x86_64 GNU/Linux\n// go version go1.13.4 linux/amd64\nhummingbird% go test -tags bench -benchmem -bench .\n\u003csnip\u003e\nBenchmarkTebeka                   254997              4726 ns/op             256 B/op         20 allocs/op\nBenchmarkJehiah                   659289              1882 ns/op             256 B/op         17 allocs/op\nBenchmarkFastly                   389150              3044 ns/op             224 B/op         13 allocs/op\nBenchmarkLestrrat                 699069              1780 ns/op              80 B/op          2 allocs/op\nBenchmarkLestrratCachedString    2081594               589 ns/op             128 B/op          2 allocs/op\nBenchmarkLestrratCachedWriter     825763              1480 ns/op             192 B/op          3 allocs/op\nPASS\nok      github.com/lestrrat-go/strftime 11.355s\n```\n\nThis library is much faster than other libraries *IF* you can reuse the format pattern.\n\nHere's the annotated list from the benchmark results. You can clearly see that (re)using a `Strftime` object\nand producing a string is the fastest. Writing to an `io.Writer` seems a bit sluggish, but since\nthe one producing the string is doing almost exactly the same thing, we believe this is purely the overhead of\nwriting to an `io.Writer`\n\n| Import Path                         | Score   | Note                            |\n|:------------------------------------|--------:|:--------------------------------|\n| github.com/lestrrat-go/strftime     | 3000000 | Using `FormatString()` (cached) |\n| github.com/fastly/go-utils/strftime | 2000000 | Pure go version on OS X         |\n| github.com/lestrrat-go/strftime     | 1000000 | Using `Format()` (NOT cached)   |\n| github.com/jehiah/go-strftime       | 1000000 |                                 |\n| github.com/fastly/go-utils/strftime | 1000000 | cgo version on Linux            |\n| github.com/lestrrat-go/strftime     | 500000  | Using `Format()` (cached)       |\n| github.com/tebeka/strftime          | 300000  |                                 |\n\nHowever, depending on your pattern, this speed may vary. If you find a particular pattern that seems sluggish,\nplease send in patches or tests.\n\nPlease also note that this benchmark only uses the subset of conversion specifications that are supported by *ALL* of the libraries compared.\n\nSomethings to consider when making performance comparisons in the future:\n\n* Can it write to io.Writer?\n* Which `%specification` does it handle?\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flestrrat-go%2Fstrftime","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flestrrat-go%2Fstrftime","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flestrrat-go%2Fstrftime/lists"}