convert numeric variable into POSIXct - r

i have a variable that contains values about
" the beginning of time interval expressed as the number of millisecond elapsed from the Unix Epoch on January 1st, 1970 at UTC." (according to data source metadata)
This is the head:
x$timeInt
[1] 1.388068e+12 1.388075e+12 1.388096e+12 1.388051e+12 1.388051e+12 1.388072e+12
So i try to convert it as POSIXct
as.POSIXct(x$timeInt, origin = '01-01-1970',tz='UTC')
but i get this result
[1] "43987-03-01 05:20:00 UTC" "43987-05-23 13:20:00 UTC" "43988-01-28 13:20:00 UTC" "43986-08-25 17:20:00 UTC"
[5] "43986-08-25 17:20:00 UTC" "43987-04-25 18:40:00 UTC"
As you can see, the year is totally wrong. I tried using other formats in origin like "1970-01-01", but the result is the same.
I know thata data is taken in december 2013.

You have to take care, that this is in milliseconds, so:
x$timeInt <- x$timeInt/1000
And then one of the two approaches:
as.POSIXct(x$timeInt, origin = '1970-01-01',tz='UTC')
or
library(anytime)
anytime(x$timeInt)
#[1] "2013-12-26 15:26:40 CET" "2013-12-26 17:23:20 CET" "2013-12-26 23:13:20 CET" "2013-12-26 10:43:20 CET" "2013-12-26 10:43:20 CET"
#[6] "2013-12-26 16:33:20 CET"

Related

Generate random times in sample of POSIXct

I want to generate a load of POSIXct dates. I want to have the time component only between 9am and 5pm and only at 15 minute blocks. I know how to generate the random POSIXct between certain dates but how do I specify the minute blocks and the time range. This is where I am at:
sample(seq(as.POSIXct('2013/01/01'), as.POSIXct('2017/05/01'), by="day"), 1000)
Just change the by argument to 15mins:
sample(seq(as.POSIXct('2013/01/01'), as.POSIXct('2017/05/01'), by="15 mins"), 1000)
EDIT:
I overlooked that the time component should be between 9am and 5pm. To take this into account I would filter the sequence:
library(lubridate)
possible_dates <- seq(as.POSIXct('2013/01/01'), as.POSIXct('2017/05/01'), by="15 mins")
possible_dates <- possible_dates[hour(possible_dates) < 17 & hour(possible_dates) >=9]
sample(possible_dates, 1000)
As #AEF also pointed out, you can use the argument by to create the sequence in steps of 15 minutes.
x <- seq(as.POSIXct('2013/01/01'), as.POSIXct('2017/05/01'), by="15 mins")
You then can use lubridate::hour() like this to extract the values from the sequence and create the sample:
library(lubridate)
sample(x[hour(x) > "09:00" & hour(x) < "17:00"], 1000)
# [1] "2015-06-28 12:45:00 CEST" "2014-05-04 10:15:00 CEST" "2017-01-08 01:00:00 CET" "2015-06-22 12:30:00 CEST"
# [5] "2016-01-14 13:30:00 CET" "2015-06-15 14:00:00 CEST" "2014-11-20 13:15:00 CET" "2013-09-23 11:15:00 CEST"
# [9] "2014-11-25 11:30:00 CET" "2014-12-04 15:30:00 CET" "2016-05-28 14:45:00 CEST" "2017-01-12 14:15:00 CET"
# .....
OK so I used this in the end:
ApptDate<-sample(seq(as.Date('2013/01/01'), as.Date('2017/05/01'), by="day"), 1000)
Time<-paste(sample(9:15,1000,replace=T),":",sample(seq(0,59,by=15),1000,replace=T),sep="")
FinalPOSIXDate<-as.POSIXct(paste(ApptDate," ",Time,sep=""))

convert character string with no correct format to posixct

I have downloaded some climate reanalysis data, which took a lot of time to convert from grib, to cdf and finally now I've managed to make it work in R. The next issue I have is that time is a character vector, similar to the following:
tt =c(
"20090101","20090101.25","20090101.5","20090101.75","20090102",
"20090102.25","20090102.5","20090102.75","20090103","20090103.25",
"20090103.5","20090103.75","20090104","20090104.25","20090104.5",
"20090104.75")
where the first four digits are the year, followed by month, then day, and finally fraction of the day: yyyymmdd...
How can I convert this to posixct time with a format yyyy-mm-dd HH:MM?
I would try
as.POSIXct(tt,'%Y%m%d')
but this wont help here due to the day fraction.
The final result should be:
tt
[1] "2009-01-01 00:00" "2009-01-01 06:00" "2009-01-01 12:00"
"2009-01-01 18:00" "2009-01-02 00:00"
Can anyone suggest a solution?
Note: I can get half of the way with
as.Date(tt, "%Y%m%d")
but not sure what to do with the fraction
Starting with:
tt=c("20090101" , "20090101.25" ,"20090101.5" , "20090101.75" ,"20090102")
convert the date part and then extract the fractional part and add as a fraction of the day in seconds:
as.POSIXct(tt,format="%Y%m%d") + (as.numeric(tt) - as.integer(tt))*(60*60*24)
[1] "2009-01-01 00:00:00 GMT" "2009-01-01 06:00:00 GMT"
[3] "2009-01-01 12:00:00 GMT" "2009-01-01 18:00:00 GMT"
[5] "2009-01-02 00:00:00 GMT"

How to add the time to a date when using as.date?

I have measurements that were taken at this time: 13880 and they represent "days since 1970-01-01 00:00:00"
So now I want to know the dat and time:
as.Date(13880, origin="1970-01-01")
[1] "2008-01-02" # works fine
Now to add the time:
as.Date(13880, origin="1970-01-01",tz = "UTC", format="%Y/%m/%d %H:%M:%S")
[1] NA
or
as.POSIXct(13880, origin="1970-01-01")
[1] "1970-01-01 04:51:20 CET"
as.POSIXlt(13879, origin="1970-01-01")
[1] "1970-01-01 04:51:19 CET"
None of these worked for me. Any idea?
as.POSIXct(as.Date("1970-01-01") + 13880) # returns "2008-01-01 19:00:00 EST"
as.POSIXct(as.Date("1970-01-01") + 13880.5) # returns "2008-01-02 07:00:00 EST"
You can also set your time zone:
How to change the default time zone in R?
also: http://blog.revolutionanalytics.com/2009/06/converting-time-zones.html

Best way to deal with differing date data [duplicate]

I am trying to do some simple operation in R, after loading a table i encountered a date column which has many formats combined.
**Date**
1/28/14 6:43 PM
1/29/14 4:10 PM
1/30/14 12:09 PM
1/30/14 12:12 PM
02-03-14 19:49
02-03-14 20:03
02-05-14 14:33
I need to convert this to format like 28-01-2014 18:43 i.e. %d-%m-%y %h:%m
I tried this
tablename$Date <- as.Date(as.character(tablename$Date), "%d-%m-%y %h:%m")
but doing this its filling NA in the entire column. Please help me to get this right!
The lubridate package makes quick work of this:
library(lubridate)
d <- parse_date_time(dates, names(guess_formats(dates, c("mdy HM", "mdy IMp"))))
d
## [1] "2014-01-28 18:43:00 UTC" "2014-01-29 16:10:00 UTC"
## [3] "2014-01-30 12:09:00 UTC" "2014-01-30 12:12:00 UTC"
## [5] "2014-02-03 19:49:00 UTC" "2014-02-03 20:03:00 UTC"
## [7] "2014-02-05 14:33:00 UTC"
# put in desired format
format(d, "%m-%d-%Y %H:%M:%S")
## [1] "01-28-2014 18:43:00" "01-29-2014 16:10:00" "01-30-2014 12:09:00"
## [4] "01-30-2014 12:12:00" "02-03-2014 19:49:00" "02-03-2014 20:03:00"
## [7] "02-05-2014 14:33:00"
You'll need to adjust the vector in guess_formats if you come across other format variations.

Round a POSIX date (POSIXct) with base R functionality

I'm currently playing around a lot with dates and times for a package I'm building.
Stumbling across this post reminded me again that it's generally not a bad idea to check out if something can be done with basic R features before turning to contrib packages.
Thus, is it possible to round a date of class POSIXct with base R functionality?
I checked
methods(round)
which "only" gave me
[1] round.Date round.timeDate*
Non-visible functions are asterisked
This is what I'd like to do (Pseudo Code)
x <- as.POSIXct(Sys.time())
[1] "2012-07-04 10:33:55 CEST"
round(x, atom="minute")
[1] "2012-07-04 10:34:00 CEST"
round(x, atom="hour")
[1] "2012-07-04 11:00:00 CEST"
round(x, atom="day")
[1] "2012-07-04 CEST"
I know this can be done with timeDate, lubridate etc., but I'd like to keep package dependencies down. So before going ahead and checking out the source code of the respective packages, I thought I'd ask if someone has already done something like this.
base has round.POSIXt to do this. Not sure why it doesn't come up with methods.
x <- as.POSIXct(Sys.time())
x
[1] "2012-07-04 10:01:08 BST"
round(x,"mins")
[1] "2012-07-04 10:01:00 BST"
round(x,"hours")
[1] "2012-07-04 10:00:00 BST"
round(x,"days")
[1] "2012-07-04"
On this theme with lubridate, also look into the ceiling_date() and floor_date() functions:
x <- as.POSIXct("2009-08-03 12:01:59.23")
ceiling_date(x, "second")
# "2009-08-03 12:02:00 CDT"
ceiling_date(x, "hour")
# "2009-08-03 13:00:00 CDT"
ceiling_date(x, "day")
# "2009-08-04 CDT"
ceiling_date(x, "week")
# "2009-08-09 CDT"
ceiling_date(x, "month")
# "2009-09-01 CDT"
If you don't want to call external libraries and want to keep POSIXct as I do this is one idea (inspired by this question): use strptime and paste a fake month and day. It should be possible to do it more straight forward, as said in this comment
"For strptime the input string need not specify the date completely:
it is assumed that unspecified seconds, minutes or hours are zero, and
an unspecified year, month or day is the current one."
Thus it seems that you have to use strftime to output a truncated string, paste the missing part and convert again in POSIXct.
This is how an update answer could look:
x <- as.POSIXct(Sys.time())
x
[1] "2018-12-27 10:58:51 CET"
round(x,"mins")
[1] "2018-12-27 10:59:00 CET"
round(x,"hours")
[1] "2018-12-27 11:00:00 CET"
round(x,"days")
[1] "2018-12-27 CET"
as.POSIXct(paste0(strftime(x,format="%Y-%m"),"-01")) #trunc by month
[1] "2018-12-01 CET"
as.POSIXct(paste0(strftime(x,format="%Y"),"-01-01")) #trunc by year
[1] "2018-01-01 CET"

Resources