R date origin for time in seconds - r

I daily have a time series in seconds since the job start (00:00h UTC). As I want to plot time series of other data, I want convert time series in seconds to dates. All data comes from a hdf5 file read with package rhdf5
>tiempo=h5read("rams2.h5","t_coords")
> class(tiempo)
[1] "array"
> head(tiempo)
[1] 0 1800 3600 5400 7200 9000
Then I have tried and as.POSIXct to build a dataframe (to later use with ggplot2).
> temps<-as.data.frame(as.POSIXct(tiempo, origin = "1960-01-01 00:00"))
> class(temps)
[1] "data.frame"
> head(temps)
as.POSIXct(tiempo, origin = "1960-01-01 00:00")
1 1960-01-01 01:00:00
2 1960-01-01 01:30:00
3 1960-01-01 02:00:00
4 1960-01-01 02:30:00
5 1960-01-01 03:00:00
6 1960-01-01 03:30:00
The problem comes fromt the first value of "temps"
1 1960-01-01 01:00:00
but it should be 1960-01-01 00:00:00 as this is the supplied origin and first value of "tiempo" is 0. It seems that an hour has been added to every time.
Maybe I'm missing something when setting origin? Or while reading h5 file? Any idea?
Thanks in advance
PD: I can't supply example data as the h5 file is a very huge one.
CORRECT CODE
Thanks to ottlngr answer and Richard Telford comment, the problem was a time zone issue solved by adding tz= "UTC"
temps<-as.data.frame(as.POSIXct(tiempo, origin = "1960-01-01 00:00:00",tz = "UTC"))

Possibly you should use the tz argument in as.POSIXct(), but hard to tell without sample data. Take a look at this question, it might help you: Change timezone in a POSIXct object

Related

How can I parse string values to a workable POSIXct format when the duration of some of the values are over 24 hours?

Please see this previous question I asked.
I have a data set in R that has values in hours, minutes, and seconds format. However, some values only have hours and minutes, some only have minutes and seconds, some only have minutes, and some only have seconds. It's also not formatted very favorably. When I use parse_date_time() on it, the parsing only works for values that are less than 24 hours. Sample data can be found below:
example <- as.data.frame(c("25h28m", "17m7s", "15m", "14s"))
Using parse_date_time(), I get this:
Column Title
NA
00:17:07
00:15:00
00:00:14
But would like to get this:
Column Title
25:28:00
00:17:07
00:15:00
00:00:14
We may do this by converting to period class from lubridate and then use hms from hms
library(lubridate)
hms::hms(as.period(toupper(example)))
-output
25:28:00
00:17:07
00:15:00
00:00:14
data
example <- c("25h28m", "17m7s", "15m", "14s")

Convert HH:MM:SS column to ZT time

I am hoping somebody can help me with a logic question in R-studio. I have a rather large data set, with "Time" as one of my columns. This column has values from 00:00:00 to 23:59:00, and is in HH:MM:SS format.
Because of some trouble I have had with analysis of time in this format, I am trying to create a new column, called "ZT" where I convert this time column to ZT time. Lights turn on at 7am, so need the time 07:00:00 to correspond to ZT=0, with 07:01:00 to correspond to ZT=0.016... and so on and so forth.
Can anybody help me with this? It would be much appreciated!
Not sure if this is what you are going for or not but this seems to work at converting a character vector of times in the format HH:MM:SS to your ZT time in the format HH:MM:SS starting at 7am as 00:00:00.
I am unclear exactly what you mean when you state that 07:01:00 should correspond to ZT=0.016, but maybe this can be a start.
Fair warning this is a little slow (took about 1 minute on my machine) but maybe someone else can help vectorize it and speed it up:
#Make Some Fake Data
df<-data.frame(Time=format(seq(ISOdate(2020,1,1), ISOdate(2020,2,1), by = "min"), '%H:%M:00'), Variable1=runif(n=44641))
#We need the help of a an external package to handle time in HH:MM:SS format
library(lubridate)
time_store<- hms(df$Time) #Convert your times to HMS format
ZT_vec<-vector() #Create an empty vector that we will fill in
for (i in 1:length(time_store)){ #iterate over each observation
if (hour(time_store[i])<7){ #Make sure the conversions are going the right direction
ZT<-time_store[i]+hours(17)
ZT_vec<-c(ZT_vec,sprintf("%02d:%02d:%02d", hour(ZT), minute(ZT), second(ZT))) #format the times in HH:MM:SS
} else {
ZT<-time_store[i]-hours(7)
ZT_vec<-c(ZT_vec,sprintf("%02d:%02d:%02d", hour(ZT), minute(ZT), second(ZT)))
}
}
df<-cbind(df,ZT_vec) #Bind on our new column
head(df)
Time Variable1 ZT_vec
12:00:00 0.6560604 05:00:00
12:01:00 0.3485023 05:01:00
12:02:00 0.8396784 05:02:00
12:03:00 0.4773929 05:03:00
12:04:00 0.6969242 05:04:00
12:05:00 0.5371502 05:05:00
head(df[4020:4025,])
Time Variable1 ZT_vec
06:59:00 0.6758364 23:59:00
07:00:00 0.1255861 00:00:00
07:01:00 0.2789485 00:01:00
07:02:00 0.2175933 00:02:00
07:03:00 0.1855100 00:03:00
07:04:00 0.1632865 00:04:00

R posixct dates and times not centering on midnight

I have dates and times stored in two columns. The first has the date as "20180831." The time is stored as the number of seconds from midnight; 3am would be stored as 10,800.
I need a combined date time column and am having a hard time with something that should be simple.
I can get the dates in no problem but lubridate "hms" interprets the time field as a period, not a 'time' per se.
I tried converting the date to posix.ct format and then using that as the origin for the time field but posix.ct does not set the time for midnight, instead it sets it for either 1800 or 1900 hours depending on the date. I need it set to midnight for all rows, I don't want any daylight savings time adjustment.
Here's the code:
First I made a function because there are several date and time fields I have to do this for.
mkdate<-function(x){
a<-as.Date(as.character(x),format='%Y%m%d')
a<-as.POSIXct(a)
return(a)
}
df$date<-mkdate(df$date) #applies date making function to date field
df$datetime<-as.POSIXct(df$time,origin=df$date)
I'm sure this has to do with time zones. I'm in Central time zone and I have experimented with adding the "tz" specification into these commands in both the mkdate function and in the time code creating "datetime" column.
I've tried:
tz="America/Chicago"
tz="CST"
tz="UTC"
Help would be much appreciated!
Edited with example:
x<-c(20180831,20180710,20160511,20170105,20180101) #these are dates.
as.POSIXct(as.Date(as.character(x),format="%Y%m%d"))
Above code converts dates to seconds from the Jan 1 1970. I could convert this to numeric and add my 'seconds' value to this field BUT it is not correct. This is what I see instead as the output:
[1] "2018-08-30 19:00:00 CDT" "2018-07-09 19:00:00 CDT" "2016-05-10 19:00:00 CDT" "2017-01-04 18:00:00 CST" "2017-12-31 18:00:00 CST"
Look at the first date - it should be 8/31 but instead it is 8/30. Somewhere in there there is a timezone adjustment taking place. It's moving the clock back 5 or 6 hours because I am on central time. The first entry should be 2018-08-31 00:00:00. I would then convert it to numeric and add the seconds field on and convert back to POSIXct format. I've tried including tz specification all over the place with no luck.
Sys.getlocale("LC_TIME")
returns "English_United States.1252"
I believe the following does what you want.
My locale is the following, so the results are different from yours.
Sys.getlocale("LC_TIME")
#[1] "Portuguese_Portugal.1252"
The difference will be due to the daylight savings time, the summer hour.
As for your problem, all you have to do is to remeber that the objects of class "POSIXct are coded as the number of seconds since an origin, and that origin is usually the midnight of 1970-01-01. So you have to add your seconds since midnight to the seconds of as.Date.
x <- "20180831"
xd <- mkdate(x)
y <- 10800
as.POSIXct(as.integer(xd) + y, origin = "1970-01-01")
#[1] "2018-08-31 04:00:00 BST"
as.POSIXct(as.integer(xd) + y, origin = "1970-01-01", tz = "America/Chicago")
#[1] "2018-08-30 22:00:00 CDT"
There are very many ways to do this:
mktime = function(a, b)modifyList(strptime(a, '%Y%m%d'), list(sec = as.numeric(gsub(',', '', b))))
mktime("20180831",'10,800')
[1] "2018-08-31 03:00:00 PDT"
mktime('20180301','10800')
[1] "2018-03-01 03:00:00 PST"
mktime('20180321','10800')
[1] "2018-03-21 03:00:00 PDT"
Looking at the above code, it does not adjust for the daylight saving time. Irrespective of the date, the seconds still show that it Is 3 AM, including the dates when ST-->DT. This will also take into consideration, your LOCAL timezone.

convert hours since date to datetime format in r

I've downloaded some climate data from a website and am trying to analyse it in R.
The time format for the data is hours since 1800-01-01 00:00. For example:
ss <- seq(447042,455802, length.out = 1461)
which shows data at 6 hour intervals.
How can I convert this to a an actual time in R. This example should give data for 1851:
1851-01-01 00:00
1851-01-01 06:00
and so on...
How can this be done?
Any advice would be appreciated.
I think you have a typo as well as incorrect calculations. Let's assume you want time in the future of 1880 rather than the past. So it might be 1951 you wanted? Then to convert hours to seconds which are the basis for the POSIXt classed objects, just multiply by 3600 = 60*60:
> tail( as.POSIXct(ss*3600,origin='1880-01-01 00:00') )
[1] "1931-12-30 04:00:00 PST" "1931-12-30 10:00:00 PST" "1931-12-30 16:00:00 PST"
[4] "1931-12-30 22:00:00 PST" "1931-12-31 04:00:00 PST" "1931-12-31 10:00:00 PST"
As you can see it's nowhere the year 1951 either, but maybe you had two digits off and you wanted 1931? Conversions that span the range of years before the onset of daylight savings time and cross century boundaries where leap years and leap seconds were used may not "line up" with your expectations.

Binning time series in R?

I'm new to R. My data has 600k objects defined by three attributes: Id, Date and TimeOfCall.
TimeofCall has a 00:00:00 format and range from 00:00:00 to 23:59:59.
I want to bin the TimeOfCall attribute, into 24 bins, each one representing hourly slot (first bin 00:00:00 to 00:59:59 and so on).
Can someone talk me through how to do this? I tried using cut() but apparently my format is not numeric. Thanks in advance!
While you could convert to a formal time representation, in this case it might be easier to just use substr:
test <- c("00:00:01","02:07:01","22:30:15")
as.numeric(substr(test,1,2))
#[1] 0 2 22
Using a POSIXct time to deal with it would also work, and might be handy if you plan on further calculations (differences in time etc):
testtime <- as.POSIXct(test,format="%H:%M:%S")
#[1]"2013-12-09 00:00:01 EST" "2013-12-09 02:07:01 EST" "2013-12-09 22:30:15 EST"
as.numeric(format(testtime,"%H"))
#[1] 0 2 22
You can use cut.POsixlt function. But you should coerce your data to a valid time object. here I am using handy hms from lubridate. And strftime to get the time format.
library(lubridate)
x <- c("09:10:01", "08:10:02", "08:20:02","06:10:03 ", "Collided at 9:20:04 pm")
x.h <- strftime(cut(as.POSIXct(hms(x),origin=Sys.Date()),'hours'),
format='%H:%M:%S')
data.frame(x,x.h)
x x.h
1 09:10:01 10:00:00
2 08:10:02 09:00:00
3 08:20:02 09:00:00
4 06:10:03 07:00:00
5 Collided at 9:20:04 pm 22:00:00

Resources