I have some data with an unconventional date format for midnight. In the raw data, midnight is being treated as "1/1/2018 24:00 AM" instead of "1/2/2018 00:00 AM". Why would anyone do this?!
I'd like to convert this character vector into a POSIXct() format.
Here is some example data:
datetime <- c("1/1/2018 11:00 PM", "1/1/2018 24:00 AM", "1/2/2018 01:00 AM")
The following code fails to parse midnight but does what I want otherwise:
as.POSIXct(datetime, format = "%m/%d/%Y %I:%M %p")
This returns the following:
[1] "2018-01-01 23:00:00 GMT" NA "2018-01-02 01:00:00 GMT"
An alternative is to use lubridate::mdy_hm which parses 24:00 AM correctly as 00:00 AM on the next day.
library(lubridate)
mdy_hm(datetime)
#[1] "2018-01-01 23:00:00 UTC" "2018-01-02 00:00:00 UTC"
#[3] "2018-01-02 01:00:00 UTC"
Related
The reformatting works for just the date, but when I add in the am/pm data it doesn't work. Here is the code and data:
str(Hourly_Steps$activity_hour)
chr [1:22099] "4/12/2016 12:00:00 AM" "4/12/2016 1:00:00 AM" ...
This worked to format just the date...
> day <- strptime(Hourly_Steps$activity_hour, format = "%m/%d/%Y %I:%M:%S")
> day
[1] "2016-04-12 00:00:00 IST" "2016-04-12 01:00:00 IST"
[3] "2016-04-12 02:00:00 IST" "2016-04-12 03:00:00 IST"
[5] "2016-04-12 04:00:00 IST" "2016-04-12 05:00:00 IST"
[7] "2016-04-12 06:00:00 IST" "2016-04-12 07:00:00 IST"
[9] "2016-04-12 08:00:00 IST" "2016-04-12 09:00:00 IST"
[11] "2016-04-12 10:00:00 IST" "2016-04-12 11:00:00 IST"
But when I try add in the %p for am/pm info, it goes back to 24hr...
> day <- strptime(Hourly_Steps$activity_hour, format = "%m/%d/%Y %I:%M:%S %p")
> day
[1] "2016-04-12 00:00:00 IST" "2016-04-12 01:00:00 IST"
[3] "2016-04-12 02:00:00 IST" "2016-04-12 03:00:00 IST"
[5] "2016-04-12 04:00:00 IST" "2016-04-12 05:00:00 IST"
[7] "2016-04-12 06:00:00 IST" "2016-04-12 07:00:00 IST"
[9] "2016-04-12 08:00:00 IST" "2016-04-12 09:00:00 IST"
[11] "2016-04-12 10:00:00 IST" "2016-04-12 11:00:00 IST"
[13] "2016-04-12 12:00:00 IST" "2016-04-12 13:00:00 IST"
[15] "2016-04-12 14:00:00 IST" "2016-04-12 15:00:00 IST"
What am I missing here?
Your code works correctly.
You are starting with a "character" vector, and strptime() correctly reads your imperial time into "POSIXt" time format. The "POSIXt" is only stored in this specific "YYYY-MM-DD HH:MM:SS TZ" format and this is what you see displayed.
x <- c("4/12/2016 1:00:00 AM", "4/12/2016 1:00:00 PM", "4/12/2016 12:00:00 AM",
"4/12/2016 12:00:00 PM")
y <- strptime(x, '%d/%m/%Y %I:%M:%S %p')
y
# [1] "2016-04-12 01:00:00 CEST" "2016-04-12 13:00:00 CEST"
# [3] "2016-04-12 00:00:00 CEST" "2016-04-12 12:00:00 CEST"
and
class(y)
# [1] "POSIXlt" "POSIXt"
Maybe you are looking for a way to change your output format, where you'd want to use strftime().
z <- strftime(y, '%m/%d/%Y %I:%M:%S %p')
z
# [1] "04/12/2016 01:00:00 am" "04/12/2016 01:00:00 pm"
# [3] "04/12/2016 12:00:00 am" "04/12/2016 12:00:00 pm"
Note, however, that you now have a "character" class.
class(z)
# [1] "character"
So, altogether you may want:
strftime(strptime(x, '%m/%d/%Y %I:%M:%S %p'), '%d/%m/%Y %I:%M:%S %p')
# [1] "12/04/2016 01:00:00 am" "12/04/2016 01:00:00 pm"
# [3] "12/04/2016 12:00:00 am" "12/04/2016 12:00:00 pm"
Sidenote: Midnight may not be displayed even though it is stored internally.
strptime("4/12/2016 12:00:00 AM", '%m/%d/%Y %I:%M:%S %p')
# [1] "2016-04-12 CEST"
I am working in R.
I have to generate a series of dates and times. In particular, I would like to have two data points per day, hence to assign twice each date with a different time, for instance:
"2001-05-13 00:00:00"
"2001-05-13 12:00:00"
"2001-05-14 00:00:00"
"2001-05-14 12:00:00"
I found the following code to produce a series of dates:
seq(as.Date("2000/1/1"), as.Date("2003/1/1"), by = 0.5)
Nevertheless, even if I set the by = 0.5, the code returns only a date , not a datetime.
Any idea how to produce a series of datetimes?
as.Date will produce only dates, use as.POSIXct to produce date-time.
seq(as.POSIXct("2000-01-01 00:00:00", tz = 'UTC'),
as.POSIXct("2003-01-01 00:00:00", tz = 'UTC'), by = '12 hours')
# [1] "2000-01-01 00:00:00 UTC" "2000-01-01 12:00:00 UTC"
# [3] "2000-01-02 00:00:00 UTC" "2000-01-02 12:00:00 UTC"
# [5] "2000-01-03 00:00:00 UTC" "2000-01-03 12:00:00 UTC"
# [7] "2000-01-04 00:00:00 UTC" "2000-01-04 12:00:00 UTC"
# [9] "2000-01-05 00:00:00 UTC" "2000-01-05 12:00:00 UTC"
#[11] "2000-01-06 00:00:00 UTC" "2000-01-06 12:00:00 UTC"
#[13] "2000-01-07 00:00:00 UTC" "2000-01-07 12:00:00 UTC"
#...
#...
This question already has answers here:
Parse datetime with lubridate
(3 answers)
Parsing dates with different formats
(3 answers)
Closed 2 years ago.
I have a dataframe with a column containing Date Time values, but the values are in different formats.
I want to bring them all to the format "dd/mm/yyyy hh:mm". I tried using the lubridate package to convert the dates with the AM/PM text appended to the dates, but am unable to do so.
Date_Time
"11/01/2019 10:00"
"11/01/2019 11:00"
"11/01/2019 12:00"
"11/01/2019 13:00"
"11/01/2019 14:00"
"11/01/2019 15:00"
"11/01/2019 16:00"
"10/03/2019 23:00"
"10/04/2019 1:00"
"10/28/2019 05:00:00 AM"
"10/28/2019 10:00:00 PM"
"10/29/2019 02:00:00 AM"
"10/29/2019 03:00:00 AM"
"10/31/2019 01:00:00 PM"
"10/31/2019 02:00:00 PM"
"10/31/2019 10:00:00 PM"
You can use lubridate's parse_date_time :
lubridate::parse_date_time(df$Date_Time, c('mdYHM', 'mdYIMSp'))
#[1] "2019-11-01 10:00:00 UTC" "2019-11-01 11:00:00 UTC" "2019-11-01 12:00:00 UTC"
#[4] "2019-11-01 13:00:00 UTC" "2019-11-01 14:00:00 UTC" "2019-11-01 15:00:00 UTC"
#[7] "2019-11-01 16:00:00 UTC" "2019-10-03 23:00:00 UTC" "2019-10-04 01:00:00 UTC"
#[10]"2019-10-28 05:00:00 UTC" "2019-10-28 22:00:00 UTC" "2019-10-29 02:00:00 UTC"
#[13]"2019-10-29 03:00:00 UTC" "2019-10-31 13:00:00 UTC" "2019-10-31 14:00:00 UTC"
#[16]"2019-10-31 22:00:00 UTC"
data
df <- structure(list(Date_Time = c("11/01/2019 10:00", "11/01/2019 11:00",
"11/01/2019 12:00", "11/01/2019 13:00", "11/01/2019 14:00", "11/01/2019 15:00",
"11/01/2019 16:00", "10/03/2019 23:00","10/04/2019 1:00","10/28/2019 05:00:00 AM",
"10/28/2019 10:00:00 PM", "10/29/2019 02:00:00 AM", "10/29/2019 03:00:00 AM",
"10/31/2019 01:00:00 PM", "10/31/2019 02:00:00 PM", "10/31/2019 10:00:00 PM"
)), class = "data.frame", row.names = c(NA, -16L))
I have been trying to convert a string with times in AM/PM format to 24 hour date object. 'strtime` coverts to 24 hour format, by keeps adding today's date on the output. The problem is that I need ONLY TIME, such as '13:00'.
Thank you very much in advance!
am_pm <- c("8:00 am","3:30 PM", "10:00 AM", "8:00 AM", "9:00 PM", "9:00
AM")
strptime(am_pm, "%I:%M %p")
[1] "2017-10-19 08:00:00 UTC" "2017-10-19 15:30:00 UTC" "2017-10-19 10:00:00
UTC" "2017-10-19 08:00:00 UTC"
[5] "2017-10-19 21:00:00 UTC" "2017-10-19 09:00:00 UTC"
You will need to add an extra step for that. Use as.ITime() function from the lubridate package.
am_pm <- c("8:00 am","3:30 PM", "10:00 AM", "8:00 AM", "9:00 PM", "9:00 AM")
mytime <- strptime(am_pm, "%I:%M %p")
as.ITime(mytime)
"08:00:00" "15:30:00" "10:00:00" "08:00:00" "21:00:00" "09:00:00"
from the docs
I have a data set with the time in character format. I’m attempting to covert this from a 12 hour format to 24. I have done some searching, but everything I have found seems to assume the characters are already in 24 hour format. Here is an example of the times I'm working with.
times <- c("9:06 AM", "4:42 PM", "3:05 PM", "12:00 PM", "3:38 AM")
This should work:
times <- c("9:06 AM", "4:42 PM", "3:05 PM", "12:00 PM", "3:38 AM")
strptime(times, "%I:%M %p")
## [1] "2015-04-23 09:06:00 EDT" "2015-04-23 16:42:00 EDT"
## [3] "2015-04-23 15:05:00 EDT" "2015-04-23 12:00:00 EDT"
## [5] "2015-04-23 03:38:00 EDT"
If you want just the times:
format(strptime(times, "%I:%M %p"), format="%H:%M:%S")
## [1] "09:06:00" "16:42:00" "15:05:00" "12:00:00" "03:38:00"
times <- c("9:06 AM", "4:42 PM", "3:05 PM", "12:00 PM", "3:38 AM")
print(as.POSIXct(times, format='%I:%M %p'))
[1] "2015-04-23 09:06:00 CDT" "2015-04-23 16:42:00 CDT" "2015-04-23 15:05:00 CDT" "2015-04-23 12:00:00 CDT"
[5] "2015-04-23 03:38:00 CDT"
#Tyler - you type faster than I do. To Topic Starter - please see how the CDT and EDT are auto-populated based on your Time Zone - this might be potentially an issue when converting times within 1 hour of the day change