r - 将 POSIXct 转换为毫秒
r - converting POSIXct to milliseconds
从?POSIXct
我们知道
Class "POSIXct" represents the (signed) number of seconds since the beginning of 1970 (in the UTC time zone) as a numeric vector.
因此,我假设要获得以毫秒为单位的 POSIXct
值,我们需要乘以 1000
考虑 2015 年 12 月的日子
## generate sequence of days in December 2015
d <- seq(as.POSIXct("2015-12-01"), as.POSIXct("2015-12-31"), by = 60*60*24)
# [1] "2015-12-01 AEDT" "2015-12-02 AEDT"
# ...
# [29] "2015-12-29 AEDT" "2015-12-30 AEDT" "2015-12-31 AEDT"
将它们转换为整数
d <- as.integer(d)
我们看到每个整数都是10
位
nchar(d)
# [1] 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
当乘以 1000 转换为毫秒时,我们得到
nchar(d * 1000)
# [1] 13 13 13 13 12 13 13 13 13 12 13 13 13 13 12 13 13 13 13 11 13 13 13 13 12 13 13 13 13 12 13
有些值只有 11 或 12 位数字(而我本以为 10 位数字乘以 1000 会增加 3 位数字)
是否有我没有看到的解释?
总结回答
对此的简短回答是关于如何以科学格式打印数字
要看到这一点,我们可以设置 options(scipen=1000)
并得到预期的结果。
options(scipen=1000);
nchar(d*1000)
# [1] 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13
更长的答案
这个问题的背景来自尝试使用 library(mongolite)
中的日期范围查询 mongodb 数据库
例如, and this issue 表明要查询日期,需要将其转换为 numberLong
才能使查询正常工作。
为了说明这一点以及我遇到的问题,请考虑此数据和后续查询
library(mongolite)
df <- data.frame(date = as.POSIXct(c("2015-12-19","2015-12-20","2015-12-21")),
val = c(1,2,3))
mongo <- mongo(collection = "test", db = "test", url = "mongodb://localhost")
## insert data into test database
mongo$insert(df)
## querying the 19th December 2015 works as expected, because d is formatted with 13 digits
d <- as.integer(as.POSIXct("2015-12-19")) * 1000
q <- paste0('{"date" : {"$date" : { "$numberLong" : "', d,'" } } }')
mongo$find(query = q)
#
# Imported 1 records. Simplifying into dataframe...
# date val
# 1 2015-12-19 1
## the 20th December 2015 errors, as d is formatted with < 13 digits
d <- as.integer(as.POSIXct(("2015-12-20"))) * 1000
q <- paste0('{"date" : {"$date" : { "$numberLong" : "', d,'" } } }')
mongo$find(query = q)
#
# Error: Invalid input string 1.45053e+12, looking for 11
## the 21st December 2015 works as expected because d is formatted with 13 digits.
d <- as.integer(as.POSIXct("2015-12-21")) * 1000
q <- paste0('{"date" : {"$date" : { "$numberLong" : "', d,'" } } }')
mongo$find(query = q)
#
# Imported 1 records. Simplifying into dataframe...
# date val
# 1 2015-12-21 3
## cleanup
rm(mongo); gc()
所以要解决这个问题,我要么需要设置 options(scipen=1000)
,要么在进入查询时用零右填充我的 d
。
从?POSIXct
我们知道
Class "POSIXct" represents the (signed) number of seconds since the beginning of 1970 (in the UTC time zone) as a numeric vector.
因此,我假设要获得以毫秒为单位的 POSIXct
值,我们需要乘以 1000
考虑 2015 年 12 月的日子
## generate sequence of days in December 2015
d <- seq(as.POSIXct("2015-12-01"), as.POSIXct("2015-12-31"), by = 60*60*24)
# [1] "2015-12-01 AEDT" "2015-12-02 AEDT"
# ...
# [29] "2015-12-29 AEDT" "2015-12-30 AEDT" "2015-12-31 AEDT"
将它们转换为整数
d <- as.integer(d)
我们看到每个整数都是10
位
nchar(d)
# [1] 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
当乘以 1000 转换为毫秒时,我们得到
nchar(d * 1000)
# [1] 13 13 13 13 12 13 13 13 13 12 13 13 13 13 12 13 13 13 13 11 13 13 13 13 12 13 13 13 13 12 13
有些值只有 11 或 12 位数字(而我本以为 10 位数字乘以 1000 会增加 3 位数字)
是否有我没有看到的解释?
总结回答
对此的简短回答是关于如何以科学格式打印数字
要看到这一点,我们可以设置 options(scipen=1000)
并得到预期的结果。
options(scipen=1000);
nchar(d*1000)
# [1] 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13
更长的答案
这个问题的背景来自尝试使用 library(mongolite)
例如,numberLong
才能使查询正常工作。
为了说明这一点以及我遇到的问题,请考虑此数据和后续查询
library(mongolite)
df <- data.frame(date = as.POSIXct(c("2015-12-19","2015-12-20","2015-12-21")),
val = c(1,2,3))
mongo <- mongo(collection = "test", db = "test", url = "mongodb://localhost")
## insert data into test database
mongo$insert(df)
## querying the 19th December 2015 works as expected, because d is formatted with 13 digits
d <- as.integer(as.POSIXct("2015-12-19")) * 1000
q <- paste0('{"date" : {"$date" : { "$numberLong" : "', d,'" } } }')
mongo$find(query = q)
#
# Imported 1 records. Simplifying into dataframe...
# date val
# 1 2015-12-19 1
## the 20th December 2015 errors, as d is formatted with < 13 digits
d <- as.integer(as.POSIXct(("2015-12-20"))) * 1000
q <- paste0('{"date" : {"$date" : { "$numberLong" : "', d,'" } } }')
mongo$find(query = q)
#
# Error: Invalid input string 1.45053e+12, looking for 11
## the 21st December 2015 works as expected because d is formatted with 13 digits.
d <- as.integer(as.POSIXct("2015-12-21")) * 1000
q <- paste0('{"date" : {"$date" : { "$numberLong" : "', d,'" } } }')
mongo$find(query = q)
#
# Imported 1 records. Simplifying into dataframe...
# date val
# 1 2015-12-21 3
## cleanup
rm(mongo); gc()
所以要解决这个问题,我要么需要设置 options(scipen=1000)
,要么在进入查询时用零右填充我的 d
。