Pergunta

options(digits.secs = 3);

> strptime("2007-03-30 15:00:00.007", format = "%Y-%m-%d %H:%M:%OS");
[1] "2007-03-30 15:00:00.007"
> strptime("2007-03-30 15:00:00.008", format = "%Y-%m-%d %H:%M:%OS");
[1] "2007-03-30 15:00:00.008"
> strptime("2007-03-30 15:00:00.009", format = "%Y-%m-%d %H:%M:%OS");
[1] "2007-03-30 15:00:00.008"
> strptime("2007-03-30 15:00:00.010", format = "%Y-%m-%d %H:%M:%OS");
[1] "2007-03-30 15:00:00.01"
> strptime("2007-03-30 15:00:00.011", format = "%Y-%m-%d %H:%M:%OS");
[1] "2007-03-30 15:00:00.010"
> strptime("2007-03-30 15:00:00.999", format = "%Y-%m-%d %H:%M:%OS");
[1] "2007-03-30 15:00:00.998"

Estou confuso por que há um milissegundo de diferença de "009" e, novamente, de "011".

Foi útil?

Solução

Isso está relacionado a R-FAQ 7.31 , embora tenha uma aparência diferente do normal.

O comportamento que você está vendo resulta de uma combinação de: (a) representação inexata da (maioria) dos valores decimais por computadores binários; e (b) o comportamento documentado de strftime e strptime, que é truncar em vez de arredondar as partes fracionárias de segundos, para o número especificado de casas decimais.

A partir do arquivo de ajuda ?strptime (a palavra-chave sendo 'truncada'):

Específico para R é ‘% OSn’, que para a saída fornece os segundos truncado para ‘0 <= n <= 6’ casas decimais (e se ‘% OS’ não for seguido por um dígito, ele usa a configuração de ‘GetOption (" digits.secs ")’, ou se não estiver definido, ‘n= 3’).

Um exemplo provavelmente ilustrará o que está acontecendo de maneira mais eficaz do que uma explicação adicional:

strftime('2011-10-11 07:49:36.3', format="%Y-%m-%d %H:%M:%OS6")
[1] "2011-10-11 07:49:36.299999"

strptime('2012-01-16 12:00:00.3', format="%Y-%m-%d %H:%M:%OS1")
[1] "2012-01-16 12:00:00.2"

No exemplo acima, o '.3' fracionário deve ser melhor aproximado por um número binário ligeiramente menor que '0,300000000000000000' - algo como '0,29999999999999999'. Como strptime e strftime truncam em vez de arredondar para a casa decimal especificada, 0,3 será convertido para 0,2, se o número de casas decimais for definido como 1. A mesma lógica vale para seus exemplos de vezes, dos quais metade exibe este comportamento, como faria (em média) ser esperado.

Outras dicas

Eu sei que foi "respondido", mas esse problema ainda existe para o R de 32 bits, há uma inconsistência na implementação entre as versões de 32 e 64 bits.O problema de truncamento é parcialmente verdadeiro, mas não é resultado da função strptime, mas do método print.POSIXlt neste caso específico.

Isso pode ser demonstrado substituindo a função por uma função que produz o comportamento esperado.Por exemplo,

print.POSIXlt = function(posix) {
    print(paste0(posix$year+1900,"-",sprintf("%02d",posix$mon+1),"-",sprintf("%02d",posix$mday)," ",
       sprintf("%02d",posix$hour),":",sprintf("%02d",posix$min),":",sprintf("%002.003f",posix$sec)))
    }

Agora, a hora é exibida conforme o esperado:

> strptime("2007-03-30 15:00:00.009", format = "%Y-%m-%d %H:%M:%OS");
[1] "2007-03-30 15:00:0.009"

Para obter mais detalhes, abordei aqui Problema R com arredondamento de milissegundos

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top