Reputation: 91
I originally asked a simpler question on this here and the answer worked fine. However, I now need to do the same thing with a dataset from another country for which I need change the timezone for consistency with my analysis.
So here's a row from my df:
df
Date Name Surname Amount
2015-07-24 23:15:07 John Smith 200
Let's say I want to convert to timezone +8 hours and extract time and date in different columns. Here's what I'd like it to be:
df1
Date Year Month Day Day_w Hour Minute Seconds Name Surname Amount
2015-07-24 23:15:07 2015 7 25 Saturday 07 15 07 John Smith 200
As you can see the original Date column remains the same, but the new column automatically converts the time (7am from 11pm) and also changes the day if necessary (in this case from 24 to 25; and from what was supposed to be Friday to Saturday).
I suppose I can first convert the whole Date column to the new timezone and then split dates and times, but how do I make it change the day automatically if the time requires it to be so (like in my example)?
Thanks!
Upvotes: 2
Views: 5186
Reputation: 23598
You can use the package lubridate. And there is anarticle on revolution analytics about this.
library(lubridate)
library(dplyr)
df <- data.frame(Date = ymd_hms("2015-07-24 23:15:07"), Name = "John", Surname = "Smith", Amount = 200, stringsAsFactors = FALSE)
# date in UTC
df$Date
"2015-07-24 23:15:07 UTC"
# show timezone if you go to +8 hrs, from UTC / GMT to Shanghai.
# df$Date is not changed into new timezone
with_tz(df$Date, tzone = "Asia/Shanghai")
"2015-07-25 07:15:07 CST"
# create output df and for each extraction change timezone
df <- df %>% mutate(year = year(with_tz(df$Date, tzone = "Asia/Shanghai")),
month = month(with_tz(df$Date, tzone = "Asia/Shanghai")),
day = day(with_tz(df$Date, tzone = "Asia/Shanghai")),
hour = hour(with_tz(df$Date, tzone = "Asia/Shanghai")),
minute = minute(with_tz(df$Date, tzone = "Asia/Shanghai")),
second = second(with_tz(df$Date, tzone = "Asia/Shanghai")))
# print df
df
Date Name Surname Amount year month day hour minute second
1 2015-07-24 23:15:07 John Smith 200 2015 7 25 7 15 7
Upvotes: 1
Reputation: 91
Ok, I think I found an answer. Assuming my times are recorded in Sydney time and I want to convert it to UK time:
#Assigns new column as date
df$Date1 <- as.POSIXct(df$Date, tz="Australia/Sydney")
#Convert it to desired time
attributes(df$Date1)$tzone <- "Europe/London"
It worked fine for me, so I thought I'd post it in case others needed it too.
Upvotes: 0
Reputation: 972
library(lubridate)
# For Current date and time
d = now()
d = force_tz(d, "America/Chicago")
hour(d) = hour(d)+8;
df1 = data.frame(Date = d, Year = year(d), Month = month(d), Day = day(d), Day_w = wday(d,label=T), Hour = hour(d), Minute = minute(d), Seconds = second(d), Name ="John", Surname = "Smith", Amount=200)
print(df1);
Upvotes: 1
Reputation: 4686
I assume your date is in a string format, i.e d <- "2015-07-24 23:15:07"
.
You can convert it to date based on your local timezone with as.POSIXct
.
> a <- as.POSIXct(d)
> a
[1] "2015-07-24 23:15:07 MYT"
(MYT is my local timezone)
And you can convert the same date-time in another timezone specifying tz
, e.g.
> b <- as.POSIXct(b, tz="Japan")
> b
[1] "2015-07-24 23:15:07 JST"
For you can convert them to other time zones by changing the tzone
attribute. E.g. I want to convert my first variable with local time to the same timezone as the second one
> attr(a, "tzone") <- "Japan"
> a
[1] "2015-07-25 00:15:07 JST"
(If you want to change to your local time zone, set the tzone
to ""
)
If you want to extract just the time, use format
> format(a, "%H")
[1] "00"
or the full date time
> format(a, "%Y-%m-%d %H:%M:%S")
[1] "2015-07-25 00:15:07"
> format(b, "%Y-%m-%d %H:%M:%S")
[1] "2015-07-24 23:15:07"
Upvotes: 3