Tempo de trabalho rápido para Go
f , err := strftime . New ( `.... pattern ...` )
if err := f . Format ( buf , time . Now ()); err != nil {
log . Println ( err . Error ())
}
Os objetivos desta biblioteca são
Pega o padrão e a hora e os formata. Esta função é uma função utilitária que recompila o padrão toda vez que a função é chamada. Se você sabe de antemão que formatará o mesmo padrão várias vezes, considere usar New
para criar um objeto Strftime
e reutilizá-lo.
Pega o padrão e cria um novo objeto Strftime
.
Retorna a string padrão usada para criar este objeto Strftime
Formata a hora de acordo com o padrão pré-compilado e grava o resultado no io.Writer
especificado
Formata a hora de acordo com o padrão pré-compilado e retorna a sequência de resultados.
padrão | descrição |
---|---|
%UM | representação nacional do nome completo do dia da semana |
%um | representação nacional do dia da semana abreviado |
%B | representação nacional do nome completo do mês |
%b | representação nacional do nome abreviado do mês |
%C | (ano/100) como número decimal; dígitos únicos são precedidos por um zero |
%c | representação nacional de hora e data |
%D | equivalente a %m/%d/%y |
%d | dia do mês como um número decimal (01-31) |
%e | o dia do mês como número decimal (1-31); dígitos únicos são precedidos por um espaço em branco |
%F | equivalente a %Y-%m-%d |
%H | a hora (relógio de 24 horas) como um número decimal (00-23) |
%h | igual a %b |
%EU | a hora (relógio de 12 horas) como um número decimal (01-12) |
% j | o dia do ano como um número decimal (001-366) |
%k | a hora (relógio de 24 horas) como número decimal (0-23); dígitos únicos são precedidos por um espaço em branco |
%l | a hora (relógio de 12 horas) como número decimal (1-12); dígitos únicos são precedidos por um espaço em branco |
%M | o minuto como um número decimal (00-59) |
%m | o mês como um número decimal (01-12) |
%n | uma nova linha |
%p | representação nacional de "ante meridiem" (am) ou "post meridiem" (pm), conforme apropriado. |
%R | equivalente a %H:%M |
%r | equivalente a %I:%M:%S %p |
%S | o segundo como um número decimal (00-60) |
%T | equivalente a %H:%M:%S |
%t | uma guia |
%U | o número da semana do ano (domingo como o primeiro dia da semana) como um número decimal (00-53) |
%você | o dia da semana (segunda-feira como o primeiro dia da semana) como um número decimal (1-7) |
%V | o número da semana do ano (segunda-feira como o primeiro dia da semana) como um número decimal (01-53) |
%v | equivalente a %e-%b-%Y |
%C | o número da semana do ano (segunda-feira como o primeiro dia da semana) como um número decimal (00-53) |
%c | o dia da semana (domingo como o primeiro dia da semana) como um número decimal (0-6) |
%X | representação nacional da época |
%x | representação nacional da data |
%Y | o ano com século como número decimal |
%y | o ano sem século como um número decimal (00-99) |
%Z | o nome do fuso horário |
%z | o deslocamento do fuso horário do UTC |
%% | um '%' |
Esta biblioteca em geral tenta ser compatível com POSIX, mas às vezes você só precisa de uma ou duas especificações extras que são relativamente amplamente usadas, mas não estão incluídas na especificação POSIX.
Por exemplo, POSIX não especifica como imprimir milissegundos, mas implementações populares permitem que %f
ou %L
consigam isso.
Para essas instâncias, strftime.Strftime
pode ser configurado para usar um conjunto personalizado de especificações:
ss := strftime.NewSpecificationSet()
ss.Set('L', ...) // provide implementation for `%L`
// pass this new specification set to the strftime instance
p, err := strftime.New(`%L`, strftime.WithSpecificationSet(ss))
p.Format(..., time.Now())
A implementação deve implementar a interface Appender
, que é
type Appender interface {
Append([]byte, time.Time) []byte
}
Para extensões comumente usadas, como o exemplo de milissegundos e o carimbo de data/hora Unix, fornecemos uma implementação padrão para que o usuário possa fazer o seguinte:
// (1) Pass a specification byte and the Appender
// This allows you to pass arbitrary Appenders
p, err := strftime.New(
`%L`,
strftime.WithSpecification('L', strftime.Milliseconds),
)
// (2) Pass an option that knows to use strftime.Milliseconds
p, err := strftime.New(
`%L`,
strftime.WithMilliseconds('L'),
)
Da mesma forma para carimbo de data/hora Unix:
// (1) Pass a specification byte and the Appender
// This allows you to pass arbitrary Appenders
p, err := strftime.New(
`%s`,
strftime.WithSpecification('s', strftime.UnixSeconds),
)
// (2) Pass an option that knows to use strftime.UnixSeconds
p, err := strftime.New(
`%s`,
strftime.WithUnixSeconds('s'),
)
Se uma especificação comum estiver faltando, sinta-se à vontade para enviar um PR (mas certifique-se de poder defender o quão "comum" ela é)
Milliseconds
(opção relacionada: WithMilliseconds
);
Microseconds
(opção relacionada: WithMicroseconds
);
UnixSeconds
(opção relacionada: WithUnixSeconds
).
Os seguintes benchmarks foram executados separadamente porque algumas bibliotecas estavam usando cgo em plataformas específicas (notavelmente, a versão fastly)
// On my OS X 10.14.6, 2.3 GHz Intel Core i5, 16GB memory.
// go version go1.13.4 darwin/amd64
hummingbird% go test -tags bench -benchmem -bench .
<snip>
BenchmarkTebeka-4 297471 3905 ns/op 257 B/op 20 allocs/op
BenchmarkJehiah-4 818444 1773 ns/op 256 B/op 17 allocs/op
BenchmarkFastly-4 2330794 550 ns/op 80 B/op 5 allocs/op
BenchmarkLestrrat-4 916365 1458 ns/op 80 B/op 2 allocs/op
BenchmarkLestrratCachedString-4 2527428 546 ns/op 128 B/op 2 allocs/op
BenchmarkLestrratCachedWriter-4 537422 2155 ns/op 192 B/op 3 allocs/op
PASS
ok github.com/lestrrat-go/strftime 25.618s
// On a host on Google Cloud Platform, machine-type: f1-micro (vCPU x 1, memory: 0.6GB)
// (Yes, I was being skimpy)
// Linux <snip> 4.9.0-11-amd64 #1 SMP Debian 4.9.189-3+deb9u1 (2019-09-20) x86_64 GNU/Linux
// go version go1.13.4 linux/amd64
hummingbird% go test -tags bench -benchmem -bench .
<snip>
BenchmarkTebeka 254997 4726 ns/op 256 B/op 20 allocs/op
BenchmarkJehiah 659289 1882 ns/op 256 B/op 17 allocs/op
BenchmarkFastly 389150 3044 ns/op 224 B/op 13 allocs/op
BenchmarkLestrrat 699069 1780 ns/op 80 B/op 2 allocs/op
BenchmarkLestrratCachedString 2081594 589 ns/op 128 B/op 2 allocs/op
BenchmarkLestrratCachedWriter 825763 1480 ns/op 192 B/op 3 allocs/op
PASS
ok github.com/lestrrat-go/strftime 11.355s
Esta biblioteca é muito mais rápida que outras bibliotecas SE você puder reutilizar o padrão de formato.
Aqui está a lista anotada dos resultados do benchmark. Você pode ver claramente que (re)usar um objeto Strftime
e produzir uma string é o mais rápido. Escrever em um io.Writer
parece um pouco lento, mas como quem produz a string está fazendo quase exatamente a mesma coisa, acreditamos que isso seja puramente a sobrecarga de escrever em um io.Writer
Caminho de importação | Pontuação | Observação |
---|---|---|
github.com/lestrrat-go/strftime | 3.000.000 | Usando FormatString() (em cache) |
github.com/fastly/go-utils/strftime | 2.000.000 | Versão pura go no OS X |
github.com/lestrrat-go/strftime | 1.000.000 | Usando Format() (NÃO armazenado em cache) |
github.com/jehiah/go-strftime | 1.000.000 | |
github.com/fastly/go-utils/strftime | 1.000.000 | versão cgo no Linux |
github.com/lestrrat-go/strftime | 500.000 | Usando Format() (em cache) |
github.com/tebeka/strftime | 300.000 |
Porém, dependendo do seu padrão, essa velocidade pode variar. Se você encontrar um padrão específico que pareça lento, envie patches ou testes.
Observe também que este benchmark usa apenas o subconjunto de especificações de conversão suportadas por TODAS as bibliotecas comparadas.
Algo a considerar ao fazer comparações de desempenho no futuro:
%specification
ele atende?