I was looking for someway to transform a date in POSIXct format to Julian day
_
The Julian Day Number (JDN) is the integer assigned to a whole solar day in the Julian day count starting from noon Universal time, with Julian day number 0 assigned to the day starting at noon on Monday, January 1, 4713 BC, proleptic Julian calendar (November 24, 4714 BC, in the proleptic Gregorian calendar)
_
But I just figured out how to make a year day - 1 to 365 for leap year.
Could someone help me find some function that turns POSIXct dates (like: 2010-10-02 21:00:00) into Julian dates?
I have a column on a dataframe with several dates to be transformed into Julian days.
head(head(all_jub2$timestamp_adjusted)
[1] 2010-10-02 21:00:00 2010-10-03 03:00:00 2010-10-03 09:00:00 2010-10-03 15:00:00
[5] 2010-10-03 21:00:00 2010-10-04 03:00:00
6120 Levels: 2003-10-17 21:00:00 2003-10-18 03:00:00 ... 2020-01-10 09:00:00
The lubridate package makes it easy to deal with dates. Does this solve your issue?
library(lubridate)
date <- as.POSIXct('2010-10-02 21:00:00')
julian <- yday(date)
You can do this with base R provided you start at the right point. The text in your question your data is still a factor-type variable. That is not good -- you need to parse this, and for example the anytime() function of the anytime package can help you. See other questions here on that.
Back to the question. If you start with a POSIXct variable from current time, and for argument's sake an hour ago to have vector, we can a) convert it to Date and then b) from Date to a Julian:
R> input <- Sys.time() + c(-3600,0)
R> input
[1] "2020-09-29 13:07:50.225898 CDT" "2020-09-29 14:07:50.225898 CDT"
R> as.Date(input)
[1] "2020-09-29" "2020-09-29"
R> julian(as.Date(input))
[1] 18534 18534
attr(,"origin")
[1] "1970-01-01"
R>
So for today our Julian date is 18534. For your first two data points, we get 14884 and 14885.
R> input <- c("2010-10-02 21:00:00", "2010-10-03 03:00:00")
R> anytime::anydate(input)
[1] "2010-10-02" "2010-10-03"
R> julian(anytime::anydate(input))
[1] 14884 14885
attr(,"tzone")
[1] "America/Chicago"
attr(,"origin")
[1] "1970-01-01"
R>
If you only want to day of the year, you get that as the component yday of the POSIXlt representation but you need to adjust by one as it is zero based:
R> as.POSIXlt(anytime::anytime(input))$yday + 1
[1] 275 276
R>
Thanks for the answers, but i foun what i've been looking for using the package insol
library(insol)
julian_day <- insol::JD(as.POSIXct('2010-10-02 21:00:00'))
[1] 2455473
Related
I'm converting a string vector to date format with as.POSIXct().
Here is the strange thing:
as.POSIXct("2017-03-26 03:00:00.000",format="%Y-%m-%d %H")
#Gives
"2017-03-26 03:00:00 CEST"
#While
as.POSIXct("2017-03-26 02:00:00.000",format="%Y-%m-%d %H")
#Outputs
NA
This is really confusing and frustrating. It seem like the function really doesn't like the specific time:
02:00:00.000
We can specify the %T for time. In the format, there are minutes, seconds and millseconds. So, the %H is only matching the hour part
as.POSIXct("2017-03-26 02:00:00.000",format="%Y-%m-%d %T")
[1] "2017-03-26 02:00:00 EDT"
Or to take care of the milliseconds as well
as.POSIXct("2017-03-26 02:00:00.000",format="%Y-%m-%d %H:%M:%OS")
#[1] "2017-03-26 02:00:00 EDT"
Or using lubridate
library(lubridate)
ymd_hms("2017-03-26 02:00:00.000")
This was a daylight savings issue, the time:
"2017-03-26 02:00:00.000" does not exist in Sweden as we lost an hour this date when changing to "summer time".
This code causes the julian year to default to the current year, but how can I specifiy that the year should be 2011?
fractionalDayofYear <-seq(300,302,0.1)
julianDate<- format(strptime((fractionalDayofYear), format='%j'),'%Y-%m-%d')
It depends on what you are using and how you intend to use it.
Both Date and POSIXt objects are relative to "1970-01-01 00:00:00 -00:00". The Date "integer" value is a day, whereas the POSIXt "integer" value is one second.
If you are using Dates, then to make this somewhat convert-able, then you should add the "int" of the preceding Dec 31 (since Jan 1 is julian day 1). For today, that would be
as.Date("2017-12-31")
# [1] "2017-12-31"
as.numeric(as.Date("2017-12-31"))
# [1] 17531
so 17531 + fractionalDayofYear.
If you are using POSIXt, then you'll need to do two things: find the numeric component for time, and convert your "integer-means-day" to seconds:
as.POSIXct("2017-12-31")
# [1] "2017-12-31 PST"
as.numeric(as.POSIXct("2017-12-31"))
# [1] 1514707200
(3600*24*fractionalDayofYear) + 1514707200
Note that this may not properly handle daylight-savings ...
Use as.difftime to add the days + fractional days more accurately:
as.POSIXct("2010-12-31", tz="UTC") + as.difftime(fractionalDayofYear, units="days")
#[1] "2011-10-27 00:00:00 UTC" "2011-10-27 02:24:00 UTC" "2011-10-27 04:48:00 UTC" ...
If you don't care about the part days, then just paste a "2011" in there:
as.Date(paste("2011",fractionalDayofYear), format="%Y %j")
# [1] "2011-10-27" "2011-10-27" "2011-10-27" "2011-10-27" "2011-10-27" ...
I have a data set containing the following date, along with several others
03/12/2017 02:17:13
I want to put the whole data set into a data table, so I used read_csv and as.data.table to create DT which contained the date/time information in date.
Next I used
DT[, date := as.POSIXct(date, format = "%m/%d/%Y %H:%M:%S")]
Everything looked fine except I had some NA values where the original data had dates. The following expression returns an NA
as.POSIXct("03/12/2017 02:17:13", format = "%m/%d/%Y %H:%M:%S")
The question is why and how to fix.
Just use functions anytime() or utctime() from package anytime
R> library(anytime)
R> anytime("03/12/2017 02:17:13")
[1] "2017-03-12 01:17:13 CST"
R>
or
R> utctime("03/12/2017 02:17:13")
[1] "2017-03-11 20:17:13 CST"
R>
The real crux is that time did not exists in North America due to DST. You could parse it as UTC as UTC does not observer daylight savings:
R> utctime("03/12/2017 02:17:13", tz="UTC")
[1] "2017-03-12 02:17:13 UTC"
R>
You can express that UTC time as Mountain time, but it gets you the previous day:
R> utctime("03/12/2017 02:17:13", tz="America/Denver")
[1] "2017-03-11 19:17:13 MST"
R>
Ultimately, you (as the analyst) have to provide as to what was measured. UTC would make sense, the others may need adjustment.
My solution is below but ways to improve appreciated.
The explanation for the NA is that in the mountain time zone in the US, that date and time is in the window of the switch to daylight savings where the time doesn't exist, hence NA. While the time zone is not explicitly specified, I guess R must be picking it up from the computer's time, which is in "America/Denver"
The solution is to explicitly state the date/time string is in UTC and then convert back as follows:
time.utc <- as.POSIXct("03/12/2017 02:17:13", format = "%m/%d/%Y %H:%M:%S", tz = "UTC")
> time.utc
[1] "2017-03-12 02:17:13 UTC"
>
Next, add 6 hours to the UTC time which is the difference between UTC and MST
time.utc2 <- time.utc + 6 * 60 * 60
> time.utc2
[1] "2017-03-12 08:17:13 UTC"
>
Now convert to America/Denver time using daylight savings.
time.mdt <- format(time.utc2, usetz = TRUE, tz = "America/Denver")
> time.mdt
[1] "2017-03-12 01:17:13 MST"
>
Note that this is in standard time, because daylight savings doesn't start until 2 am.
If you change the original string from 2 am to 3 am, you get the following
> time.mdt
[1] "2017-03-12 03:17:13 MDT"
>
The hour between 2 and 3 is lost in the change from standard to daylight savings but the data are now correct.
I am having trouble calculating a date that is imported in from a .csv file. What I want to do is take that date in the factor DateClosed and generate a date in a date field (a). Example if a=203 I want the date to be the equivalent of DateClosed-203. However, I am having trouble with the code listed below.
DateClose is a factor.
> head(DateClosed)
[1] 7/30/2007 12/12/2007 5/8/2009 6/24/2009 6/24/2009 2/29/2008
165 Levels: 1/12/2010 1/15/2011 1/15/2013 1/17/2009 1/18/2008 1/19/2012 1/2/2013 1/21/2013 1/22/2010 1/24/2013 1/26/2014 ... 9/7/2010
> head(as.Date(DateClosed,format="%m/%d/%y"))
[1] "2020-07-30" "2020-12-12" "2020-05-08" "2020-06-24" "2020-06-24" "2020-02-29"
head(as.Date(DateClosed,format="%m/%d/%y"))-203
[1] "2020-01-09" "2020-05-23" "2019-10-18" "2019-12-04" "2019-12-04" "2019-08-10"
It subtracts 203 days correctly but for some reason reads the date wrong.
DateClosed <- factor(c("7/30/2007","12/12/2007", "5/8/2009"))
as.Date(DateClosed, format="%m/%d/%Y")
Produces:
[1] "2007-07-30" "2007-12-12" "2009-05-08"
Notice the capital "Y" in the format param. The lower case "y" is for 2 digit years, so as.Date reads the first two digits of the year token ("20"), and then assumes that refers to just the last two digits of the year, and adds the current date's century (also "20"), so you end up with dates in 2020.
Manipulating dates becomes really easy using lubridate package.
mdy(factor(c("7/30/2007","12/12/2007", "5/8/2009")))
"2007-07-30 UTC" "2007-12-12 UTC" "2009-05-08 UTC"
Or using parse_date_time with the same package:
parse_date_time(factor(c("7/30/2007","12/12/2007", "5/8/2009")),c('mdY'))
[1] "2007-07-30 UTC" "2007-12-12 UTC" "2009-05-08 UTC"
I would like to add 1 hour to a POSIXct object, but it does not support '+'.
This command:
as.POSIXct("2012/06/30","GMT")
+ as.POSIXct(paste(event_hour, event_minute,0,":"), ,"%H:%M:$S")
returns this error:
Error in `+.POSIXt`(as.POSIXct("2012/06/30", "GMT"), as.POSIXct(paste(event_hour, :
binary '+' is not defined for "POSIXt" objects
How can I add a few hours to a POSIXct object ?
POSIXct objects are a measure of seconds from an origin, usually the UNIX epoch (1st Jan 1970). Just add the requisite number of seconds to the object:
x <- Sys.time()
x
[1] "2012-08-12 13:33:13 BST"
x + 3*60*60 # add 3 hours
[1] "2012-08-12 16:33:13 BST"
The lubridate package also implements this nicely with convenience functions hours, minutes, etc.
x = Sys.time()
library(lubridate)
x + hours(3) # add 3 hours
James and Gregor's answers are great, but they handle daylight saving differently. Here's an elaboration of them.
# Start with d1 set to 12AM on March 3rd, 2019 in U.S. Central time, two hours before daylight saving
d1 <- as.POSIXct("2019-03-10 00:00:00", tz = "America/Chicago")
print(d1) # "2019-03-10 CST"
# Daylight saving begins # 2AM. See how a sequence of hours works. (Basically it skips the time between 2AM and 3AM)
seq.POSIXt(from = d1, by = "hour", length.out = 4)
# "2019-03-10 00:00:00 CST" "2019-03-10 01:00:00 CST" "2019-03-10 03:00:00 CDT" "2019-03-10 04:00:00 CDT"
# Now let's add 24 hours to d1 by adding 86400 seconds to it.
d1 + 24*60*60 # "2019-03-11 01:00:00 CDT"
# Next we add 24 hours to d1 via lubridate seconds/hours/days
d1 + lubridate::seconds(24*60*60) # "2019-03-11 CDT" (i.e. 2019-03-11 00:00:00 CDT)
d1 + lubridate::hours(24) # "2019-03-11 CDT" (i.e. 2019-03-11 00:00:00 CDT)
d1 + lubridate::days(1) # "2019-03-11 CDT" (i.e. 2019-03-11 00:00:00 CDT)
So, either answer is correct depending on what you want. Of course, if you're using UTC or some other timezone that doesn't observe daylight saving, these two methods should be the same.