I'm having difficulties formatting a datetime variable that originally came from Excel:
The data was read from Excel using package openxlsx with the detectDates = FALSE option. In the original Excel file they look like this:
udate utime
1/30/2015 4:48:44 PM
1/29/2015 4:17:23 PM
And this is what they look like when imported into R with the detectDates = FALSE
#-----------------------------------------------------------------------------------------#
# EXAMPLE DATA
#-----------------------------------------------------------------------------------------#
udate <- c(42034, 42033)
utime <- c(0.7005093, 0.6787384)
#-----------------------------------------------------------------------------------------#
# FORMAT DATE
#-----------------------------------------------------------------------------------------#
udate <- as.Date(udate - 25569, origin = "1970-01-01")
> udate
[1] "2015-01-30" "2015-01-29"
#-----------------------------------------------------------------------------------------#
# FORMAT TIME
#-----------------------------------------------------------------------------------------#
utime <- as.POSIXct((utime - 25569) * 86400, tz="GMT", origin="1970-01-01")
> utime
[1] "1899-12-30 16:48:45 GMT" "1899-12-30 16:17:23 GMT"
As one can see the time doesn't fully work (that is, the date component of the time does not work).
How can I properly have a single variable with the correct date AND time? It seems like simply adding 116 years may do the trick but I know it's not that simple because I suspect datetime formats are measures in millisec.
There is no time object. POSIXct is a datetime class, i.e., must contain a date and a time.
as.POSIXct(
as.POSIXlt(
as.Date(udate, origin = "1899-12-30"), #see ?as.Date
tz = "GMT"),
tz = "GMT") + utime * 3600 * 24
#[1] "2015-01-30 16:48:44 GMT" "2015-01-29 16:17:22 GMT"
Times without dates don't work due to fun things like DST or leap seconds.
Related
I have a vector a = 40208.64507.
In excel, I can automatically change a to a datetime: 2010/1/30 15:28:54 by click the Date type.
I tried some methods but I cannot get the same result in R, just as in excel.
a = 40208.64507
# in Excel, a can change into: 2010/1/30 15:28:54
as.Date(a, origin = "1899-12-30")
lubridate::as_datetime(a, origin = "1899-12-30")
Is there any way to get the same results in R as in Excel?
Here are several ways. chron class is the closest to Excel in terms of internal representations -- they are the same except for origin -- and the simplest so we list that one first. We also show how to use chron as an intermediate step to get POSIXct.
Base R provides an approach which avoids package dependencies and lubridate might be used if you are already using it.
1) Add the appropriate origin using chron to get a chron datetime or convert that to POSIXct. Like Excel, chron works in days and fractions of a day, but chron uses the UNIX Epoch as origin whereas Excel uses the one shown below.
library(chron)
a <- 40208.64507
# chron date/time
ch <- as.chron("1899-12-30") + a; ch
## [1] (01/30/10 15:28:54)
# POSIXct date/time in local time zone
ct <- as.POSIXct(ch); ct
## [1] "2010-01-30 10:28:54 EST"
# POSIXct date/time in UTC
as.POSIXct(format(ct), tz = "UTC")
## [1] "2010-01-30 10:28:54 UTC"
2) Using only base R convert the number to Date class using the indicated origin and then to POSIXct.
# POSIXct with local time zone
ct <- as.POSIXct(as.Date(a, origin = "1899-12-30")); ct
## [1] "2010-01-30 10:28:54 EST"
# POSIXct with UTC time zone
as.POSIXct(format(ct), tz = "UTC")
## [1] "2010-01-30 15:28:54 UTC"
3) Using lubridate it is similar to base R so we can write
library(lubridate)
# local time zone
as_datetime(as_date(a, origin = "1899-12-30"), tz = "")
[1] "2010-01-30 15:28:54 EST"
# UTC time zone
as_datetime(as_date(a, origin = "1899-12-30"))
[1] "2010-01-30 15:28:54 UTC"
I am doing some animal movement analysis and I want to submit data to an organisation called Movebank for annotation, but they require the timestamp to have milliseconds included with 3 decimal places.
I have a column in my data frame (dat) with my timestamps as characters (without milliseconds), for example "2017-07-19 16:30:24"
To convert them to time and date format with milliseconds I am using the code:
options(digits.secs = 3)
dat$timestamp <- as.POSIXct(dat$timestamp, format = "%Y-%m-%d %H:%M:%OS", tz = "UTC")
Which works fine at converting my timestamp column to POSIXct which I can use to make tracks etc., but it does not add .000 milliseconds to the end of each timestamp which I was hoping it would.
I have also tried:
dat$timestamp <- as.POSIXct(dat$timestamp, format = "%Y-%m-%d %H:%M:%OS3", tz = "UTC")
(Note: I added .. %OS3 ...)
But this returns an NA for my for my timestamps.
Can anybody shed some light on this? I essentially need to add .000 to the end of each of my timestamps so that, using the example given above, I would have the format "2017-07-19 16:30:24.000"
The milliseconds will be dropped if there are no times with effective milliseconds.
options(digits.secs=4)
x1 <- as.POSIXct("2017-07-19 16:30:25")
as.POSIXct(paste0(x1, ".000"), format="%Y-%m-%d %H:%M:%OS")
# [1] "2017-07-19 16:30:25 UTC"
However, they will be added automatically if there are.
x2 <- as.POSIXct("2017-07-19 16:30:25.002")
c(x1, x2)
# [1] "2017-07-19 18:30:25.000 CEST" "2017-07-19 18:30:25.002 CEST"
How can convert a timestamp to local time and date?
I have tried the following options for this specific timestamp: 1594598065352:
x <- as.POSIXct(as.numeric(as.character('1594598065352'))/1000, origin="1970-01-01", tz="UTC")
x
"2020-07-12 23:54:25 UTC"
x <- as.POSIXct(as.numeric(as.character('1594598065352'))/1000, origin="1970-01-01", tz="DST")
x
"2020-07-12 23:54:25 DST"
x <- as.POSIXct(as.numeric(as.character('1594598065352'))/1000, origin="1970-01-01", tz="GMT")
x
"2020-07-12 23:54:25 GMT"
I get the same result in all options:
2020-07-12 23:54:25
According to this timestamp converter page, I should get this below in my local time zone:
Monday, 13 July 2020 01:54:25.352 GMT+02:00 DST
Any ideas of how I can get this right in R?
You get the same output in all 3 cases because 1) and 3) are same (UTC and GMT) whereas 2) (DST) is not a valid tz value.
If you don't mention the timezone value it should by default give you time in your local time zone.
as.POSIXct(as.numeric('1594598065352')/1000, origin="1970-01-01")
Alternatively, you can run OlsonNames() in your console to get list of valid timezones in R. 'Etc/GMT-2' seems to be the one for you.
as.POSIXct(as.numeric('1594598065352')/1000,origin="1970-01-01", tz = 'Etc/GMT-2')
#[1] "2020-07-13 01:54:25 +02"
I feel like I'm missing something obvious here. I'm importing some data which is stored as HH:MM:SS. I'm trying to convert this to POSIXct and manually specify the origin as the date the data was collected.
datIn$TimeComplete <- as.POSIXct(datIn$Time, format="%H:%M:%S", origin="2000-01-01", tz="CET")
The output of this registers the HH:MM:SS correctly but says the day is 2019-03-05 (today) and I can't seem to convince it to do anything different.
You are misunderstanding the concept of origin. Origin is there to help convert numbers to dates. Those numbers represent seconds so you need the origin in order to add those seconds to the origin and get the datetime object. For example,
as.POSIXct(60, tz = "GMT", origin = '2015-03-05')
#[1] "2015-03-05 00:01:00 GMT"
as.POSIXct(3600, tz = "GMT", origin = '2015-07-05')
#[1] "2015-07-05 01:00:00 GMT"
What you are trying to do can be easily achieved by pasting the desired date to your times and converting to datetime, i.e.
as.POSIXct(paste0('2000-01-01 ', '11:03:15'), format = "%Y-%m-%d %H:%M:%S", origin = "", tz = "CET")
#[1] "2000-01-01 11:03:15 CET"
I want to read this date 1199145600000, which is saved in JSON, in R.
to convert the numerical representation of the date to a string
but when I type:
as.Date(1199145600000,origin = "1904-01-01")
I get the following:
"-5877641-06-23"
When I should be getting this date
1 Jan 2008 00:00:00 GMT
I tried library(lubridate) still with no success.
Any help will be most appreciated.
Your time value is in milliseconds, so you'll need to divide it by 1000 to get it in seconds. Then you can use as.POSIXct() to convert to a datetime
as.POSIXct(1199145600000/1000, origin = "1970-01-01", tz = "GMT")
# [1] "2008-01-01 GMT"