Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert mixed time formats with strings to military time?

Tags:

string

regex

time

r

I have a variable that needs to be converted to military time. This variable is very messy because it lacks consistency in the format.

Here is an example of what might be found in the variable.

x <- c("0.9305555555555547", "15:20 Found", "10:00:00 AM Found", "0.125", "Found 1525")

So far I had some success in getting everything in a more consistent format with RegEx:

x <- str_extract(x, "[0-9]+.+[0-9]|[0-9][0-9][:][0-9][0-9]")
x <- str_remove(x, "[:]") 
x <- str_remove(x, "[:][0-9][0-9]$")

As you can see I get: "0.9305555555555547", "1520", "1000", "0.125", "1525"

The problem is the decimals need to be multiplied by 2400 to get back to military time but I also don't want to multiply integers (since those are already in military time).

x is essentially a variable in a dataframe.

I was thinking about using if/else logic but I don't know how to implement that.

To clarify, I want:

Input: "0.9305555555555547", "15:20 Found", "10:00:00 AM Found", "0.125", "Found 15:25"

Output: "2233", "1520", "1000", "0300", "1525"

like image 316
fkn_ez Avatar asked Dec 19 '25 21:12

fkn_ez


2 Answers

After the pre-processing you did with your regexes, you can implement if/else logic here by using str_detect()

x <- ifelse(str_detect(x, "\\."),
            as.integer(as.numeric(x) * 2400),
            as.integer(x)) %>% 
  sprintf("%04d", .)

This will return your desired output as character

Then you could do something like this to parse it to POSIXct

x <- as.POSIXct(x,
         format = "%H%M",
         origin = "1970-01-01",
         tz = "UTC")
like image 57
Francisco Yirá Avatar answered Dec 22 '25 12:12

Francisco Yirá


We should extend the regex for AM/PM indicators so that the forces do not miss each other. Next, in subsets we handle decimal time, imperial time, 24h time, and return the result.

milt <- function(x) {
  u <- trimws(gsub('\\D*(\\d*\\W?[AP]?M?)\\D*', '\\1', x))
  u[grep('\\.', u)] <- sprintf('%04d', round(as.double(u[grep('\\.', u)])*2400))
  u[grep('[AP]M', u)] <- strftime(strptime(u[grep('[AP]M', u)], '%I:%M:%S %p'), '%H%M')
  u[grep(':', u)] <- gsub(':', '', u[grep(':', u)] )
  return(u)
}

milt(x)
# [1] "2233" "1520" "1000" "2200" "0300" "1525" "0000" "1020"

Data:

x <- c("0.9305555555555547", "15:20 Found", "10:00:00 AM Found",
       "10:00:00 PM Found", "0.125", "Found 1525", "0000", "10:20")
like image 45
jay.sf Avatar answered Dec 22 '25 12:12

jay.sf



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!