How do I get just the time from R


#1

I am trying to write a programme where I have to add certain hours and minutes on a given date based on certain criteria.

But Sys.time pulls out a posixct format with tz and so does now() function of the lubridate.

Is there a function by which I can get just the Time and nothing else. no dates no timezones and I could add certain minutes or hours onto it.

Please help me out.


#2

What about using lubridate::hour, lubridate::minute and lubridate::second? You can apply your logic to number directly. Examples for these functions in lubridate show that it is possible to do some arithmetic while still respecting the fact that it’s supposed to be time, e.g.:

library(lubridate)
#> 
#> Attaching package: 'lubridate'
#> The following object is masked from 'package:base':
#> 
#>     date
x <- ymd("2012-03-26")
second(x)
#> [1] 0
second(x) <- 1
second(x) <- second(x) + 61
x
#> [1] "2012-03-26 00:01:02 UTC"

Created on 2018-03-08 by the reprex package (v0.2.0).


#3

Is there a way just to get the current time with it.

Like

Hh:mm:ss

As the current time. Just the time


#4

Just strip the date off a POSIXct object if you only want the time part. This is just a variation of what Misha proposed.


#5

I solved it using format() function but I didn’t like the solution. Because I was converting it to string adding them back to number to add a certain value and then concatenating it back to create a date object.

I had to do it in the morning today I managed to finish it. But i would appreciate if someone has an elegant solution.

Let me define you the problem.

I have a csv with a certain start date column. And I have to check if it meets certain criteria and then add some hours or minute into the column. Generate some sheets and distribute them. The TIME of the start date should always be at least one hour more than the current time.

Any solution would do. Please let me know the optimal solution for such problem. Please


#6

You could use hms:


#7

A prose description of what you want to do is not sufficient, you need to include a simple reprex that:

  1. Builds the input data you are using.
  2. The function you are trying to write, even if it doesn’t work.
  3. Usage of the function you are trying to write, even if it doesn’t work.
  4. Builds the output data you want the function to produce.

You can learn more about reprex’s here:

Right now the is an issue with the version of reprex that is in CRAN so you should download it directly from github.

Until CRAN catches up with the latest version install reprex with

devtools::install_github("tidyverse/reprex")


#8

A reprex would be helpful since it’s hard to understand specifically what you’re looking for from prose. Do you want the current time, without the date? One way to get that and make it easy to operate on would be to convert to decimal hours:

t <- Sys.time()
lubridate::hour(t) + lubridate::minute(t)/60
#> [1] 21.86667

Add 1 to add an hour, add 1/60 to add a minute. That might suffice for some uses if all the times you’re dealing with are during the daytime. If any of the adjustments you’re talking about span midnight, then it gets complicated fast, and it would help to understand more specifically what inputs you have and what results you want.


#9

This is the Code that I wrote to solve the problem. It has to be printed in a csv so I don't mind changing everything into character. But I would really prefer a more elegant solution to this problem.


# Loadlibraries -----------------------------------------------------------
library(data.table)
library(magrittr)


# LoadData ----------------------------------------------------------------



upload_file<-data.frame(stringsAsFactors=FALSE,
               sku = c("SA421WA00MIGINDFAS", "SA421WA00XZGINDFAS",
                       "SA421WA01BIJINDFAS", "SA421WA01CFPINDFAS",
                       "SA421WA01EBVINDFAS", "SA421WA01XZFINDFAS", "SA421WA02FPMINDFAS",
                       "SA421WA02KEKINDFAS", "SA421WA02XZEINDFAS",
                       "SA421WA03SRHINDFAS"),
      specialPrice = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
   discountPercent = c(35L, 35L, 35L, 35L, 35L, 35L, 35L, 35L, 35L, 35L),
            margin = c(49L, 43L, 49L, 49L, 43L, 43L, 43L, 49L, 43L, 43L),
         StartDate = c("2018-03-13", "2018-03-12",
                       "2018-03-12", "2018-03-11",
                       "2018-03-01", "2018-03-02", "2018-03-12",
                       "2018-03-12", "2018-03-21", "2018-03-12"),
          EndDate = c("2018-03-31", "2018-03-29",
                       "2018-03-31", "2018-03-30",
                       "2018-03-31", "2018-03-31", "2018-03-31",
                       "2018-03-31", "2018-03-28", "2018-03-30"),
          vendorPD = c(35L, 35L, 35L, 35L, 35L, 35L, 35L, 35L, 35L, 35L)
)


# ConvertIntoData.table ---------------------------------------------------


upload_file %>% setDT()


# MainLogic ---------------------------------------------------------------


if(format(Sys.time(), format="%H") %>% as.numeric() <9){
    
    upload_file[,':='(
                      StartDate=
                          ifelse(
                              as.Date(StartDate) == Sys.Date(),
                              paste(as.character(StartDate)," 0",format(Sys.time(), format="%H") %>% as.numeric()+1,':10:00',sep=''),
                              paste(as.character(StartDate),"00:00:00")
                          ),
                      EndDate=paste(as.character(EndDate),'23:59:00'))]
    
    
}else{
    upload_file[,':='(
                      StartDate=
                          ifelse(
                              as.Date(StartDate) == Sys.Date(),
                              paste(as.character(StartDate)," ",format(Sys.time(), format="%H") %>% as.numeric()+1,':10:00',sep=''),
                              paste(as.character(StartDate),"00:00:00")
                          ),
                      EndDate=paste(as.character(EndDate),'23:59:00'))]
    
}


# ViewFile ----------------------------------------------------------------


upload_file

Kindly run the code on your Machine and Let me know if you still don't understand the problem. I just need the fastest and most elegant solution.


#10

Thanks, the example helps me to understand what you’re looking for (I hope!).

It sounds like you want to update the StartDate field conditionally based on the current Sys.Date and Sys.time.

If the StartDate is not today, you want StartDate to be updated with the time 00:00:00.

If the StartDate is today, you want StartDate to show a time that is ten minutes after the next hour today. I presume the point of the if/else structure is that you want to pad the hour digits before 10 so that 8am shows up as 08 instead of just 8.

Given all that, the way I might approach the conversion this way. (I’m not so strong with data.table so this is a tidyverse solution.)

# LoadData ----------------------------------------------------------------

library(tidyverse)
#> -- Attaching packages -------------------------------------------------------------------------------------------------- tidyverse 1.2.1 --
#> v ggplot2 2.2.1.9000     v purrr   0.2.4     
#> v tibble  1.4.1          v dplyr   0.7.4     
#> v tidyr   0.8.0          v stringr 1.3.0     
#> v readr   1.1.1          v forcats 0.3.0
#> -- Conflicts ----------------------------------------------------------------------------------------------------- tidyverse_conflicts() --
#> x dplyr::filter() masks stats::filter()
#> x dplyr::lag()    masks stats::lag()

upload_file<-data.frame(stringsAsFactors=FALSE,
                        sku = c("SA421WA00MIGINDFAS", "SA421WA00XZGINDFAS",
                                "SA421WA01BIJINDFAS", "SA421WA01CFPINDFAS",
                                "SA421WA01EBVINDFAS", "SA421WA01XZFINDFAS", "SA421WA02FPMINDFAS",
                                "SA421WA02KEKINDFAS", "SA421WA02XZEINDFAS",
                                "SA421WA03SRHINDFAS"),
                        specialPrice = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
                        discountPercent = c(35L, 35L, 35L, 35L, 35L, 35L, 35L, 35L, 35L, 35L),
                        margin = c(49L, 43L, 49L, 49L, 43L, 43L, 43L, 49L, 43L, 43L),
                        StartDate = c("2018-03-13", "2018-03-12",
                                      "2018-03-12", "2018-03-11",
                                      "2018-03-01", "2018-03-02", "2018-03-12",
                                      "2018-03-12", "2018-03-21", "2018-03-12"),
                        EndDate = c("2018-03-31", "2018-03-29",
                                    "2018-03-31", "2018-03-30",
                                    "2018-03-31", "2018-03-31", "2018-03-31",
                                    "2018-03-31", "2018-03-28", "2018-03-30"),
                        vendorPD = c(35L, 35L, 35L, 35L, 35L, 35L, 35L, 35L, 35L, 35L)
)

# Possible approach  ---------------------------------------------------


currentHour <- lubridate::hour(Sys.time())
currentHour
#> [1] 11

upload_file2 <- 
  upload_file %>%
  mutate(StartDate  = lubridate::ymd(StartDate),
         today      = StartDate == Sys.Date(),   #temporary flag b/c I had trouble getting the conditional to work inside case_when
         StartDate  = case_when(today  ~ lubridate::ymd_hms(paste(StartDate, currentHour+1, 10, 0)),
                               TRUE    ~ lubridate::ymd_hms(paste(StartDate, '00:00:00'))),
         EndDate    = lubridate::ymd_hms(paste(EndDate,   '23:59:00'))) %>%
  select(-today) %>%        
  mutate(StartDate  = as.character(StartDate),
         EndDate    = as.character(EndDate))

upload_file2
#>                   sku specialPrice discountPercent margin
#> 1  SA421WA00MIGINDFAS           NA              35     49
#> 2  SA421WA00XZGINDFAS           NA              35     43
#> 3  SA421WA01BIJINDFAS           NA              35     49
#> 4  SA421WA01CFPINDFAS           NA              35     49
#> 5  SA421WA01EBVINDFAS           NA              35     43
#> 6  SA421WA01XZFINDFAS           NA              35     43
#> 7  SA421WA02FPMINDFAS           NA              35     43
#> 8  SA421WA02KEKINDFAS           NA              35     49
#> 9  SA421WA02XZEINDFAS           NA              35     43
#> 10 SA421WA03SRHINDFAS           NA              35     43
#>              StartDate             EndDate vendorPD
#> 1  2018-03-13 00:00:00 2018-03-31 23:59:00       35
#> 2  2018-03-12 12:10:00 2018-03-29 23:59:00       35
#> 3  2018-03-12 12:10:00 2018-03-31 23:59:00       35
#> 4  2018-03-11 00:00:00 2018-03-30 23:59:00       35
#> 5  2018-03-01 00:00:00 2018-03-31 23:59:00       35
#> 6  2018-03-02 00:00:00 2018-03-31 23:59:00       35
#> 7  2018-03-12 12:10:00 2018-03-31 23:59:00       35
#> 8  2018-03-12 12:10:00 2018-03-31 23:59:00       35
#> 9  2018-03-21 00:00:00 2018-03-28 23:59:00       35
#> 10 2018-03-12 12:10:00 2018-03-30 23:59:00       35

#11

Thanks for your response. I just wanted to let you know that I do not want to add 10 minutes and an hour.

I just want to add at least 10 minutes more.

Since I was converting it to text. adding 10 minutes would sometime make it like 69 minutes which is invalid of course. and Adding an hour would sometime change it from 03:59 to 4:00 and that is not something that I would like. that is the reason I am looking for a genuine way to play with a time object in R. I am planning to learn time series analysis later on so it would be helpful their as well.


#12

I would highly suggest you review the lubridate vignette, it walks through various time arithmetic examples that should apply to your question.

https://cran.r-project.org/web/packages/lubridate/vignettes/lubridate.html


#13

Thanks @jonspring I highly appreciate your efforts in writing a solution and replying back in time.

But I already read the vignette before posting it here. I didn't find anything that would suit my need. And your solution involves paste() function. It was more or less like what I produced with format().

I wanted to know if there is any way we can easily add or substract time from one another and use if statements and loops and so on...

Thanks for your reply man.


#14

I think this does what you've most recently described. POSIXct is based in seconds, so if you want to add 10 minutes to the time you add 60*10 to it once it's a POSIXct date-time, but before it's converted back to text.

library(tidyverse)
#> -- Attaching packages ------------------------------------------ tidyverse 1.2.1 --
#> v ggplot2 2.2.1.9000     v purrr   0.2.4     
#> v tibble  1.4.1          v dplyr   0.7.4     
#> v tidyr   0.8.0          v stringr 1.3.0     
#> v readr   1.1.1          v forcats 0.3.0
#> -- Conflicts --------------------------------------------- tidyverse_conflicts() --
#> x dplyr::filter() masks stats::filter()
#> x dplyr::lag()    masks stats::lag()

upload_file<-data.frame(stringsAsFactors=FALSE,
                        sku = c("SA421WA00MIGINDFAS", "SA421WA00XZGINDFAS",
                                "SA421WA01BIJINDFAS", "SA421WA01CFPINDFAS",
                                "SA421WA01EBVINDFAS", "SA421WA01XZFINDFAS", "SA421WA02FPMINDFAS",
                                "SA421WA02KEKINDFAS", "SA421WA02XZEINDFAS",
                                "SA421WA03SRHINDFAS"),
                        specialPrice = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
                        discountPercent = c(35L, 35L, 35L, 35L, 35L, 35L, 35L, 35L, 35L, 35L),
                        margin = c(49L, 43L, 49L, 49L, 43L, 43L, 43L, 49L, 43L, 43L),
                        StartDate = c("2018-03-15", "2018-03-12",
                                      "2018-03-16", "2018-03-11",
                                      "2018-03-14", "2018-03-02", "2018-03-12",
                                      "2018-03-12", "2018-03-21", "2018-03-12"),
                        EndDate = c("2018-03-31", "2018-03-29",
                                    "2018-03-31", "2018-03-30",
                                    "2018-03-31", "2018-03-31", "2018-03-31",
                                    "2018-03-31", "2018-03-28", "2018-03-30"),
                        vendorPD = c(35L, 35L, 35L, 35L, 35L, 35L, 35L, 35L, 35L, 35L)
)

# Possible approach v2 ---------------------------------------------------

# This is the StartTime for uploads from today. 
# 60*10 adds 10 minutes of seconds to the current time.
# Converting to character to avoid potential time zone confusion.
upload_time <- (Sys.time() + 60*10) %>% as.character() 
  

upload_file2 <- 
  upload_file %>%
  mutate(StartDate = if_else(StartDate == Sys.Date(),
                             lubridate::ymd_hms(upload_time),
                             lubridate::ymd_hms(paste(StartDate, '00:00:00'))) %>%
           as.character,
         EndDate    = lubridate::ymd_hms(paste(EndDate,   '23:59:00')) %>%
           as.character()
  )

upload_file2
#>                   sku specialPrice discountPercent margin
#> 1  SA421WA00MIGINDFAS           NA              35     49
#> 2  SA421WA00XZGINDFAS           NA              35     43
#> 3  SA421WA01BIJINDFAS           NA              35     49
#> 4  SA421WA01CFPINDFAS           NA              35     49
#> 5  SA421WA01EBVINDFAS           NA              35     43
#> 6  SA421WA01XZFINDFAS           NA              35     43
#> 7  SA421WA02FPMINDFAS           NA              35     43
#> 8  SA421WA02KEKINDFAS           NA              35     49
#> 9  SA421WA02XZEINDFAS           NA              35     43
#> 10 SA421WA03SRHINDFAS           NA              35     43
#>              StartDate             EndDate vendorPD
#> 1  2018-03-15 14:58:52 2018-03-31 23:59:00       35
#> 2  2018-03-12 00:00:00 2018-03-29 23:59:00       35
#> 3  2018-03-16 00:00:00 2018-03-31 23:59:00       35
#> 4  2018-03-11 00:00:00 2018-03-30 23:59:00       35
#> 5  2018-03-14 00:00:00 2018-03-31 23:59:00       35
#> 6  2018-03-02 00:00:00 2018-03-31 23:59:00       35
#> 7  2018-03-12 00:00:00 2018-03-31 23:59:00       35
#> 8  2018-03-12 00:00:00 2018-03-31 23:59:00       35
#> 9  2018-03-21 00:00:00 2018-03-28 23:59:00       35
#> 10 2018-03-12 00:00:00 2018-03-30 23:59:00       35

#15

Thanks @jonspring

It was exactly what I was looking for. it had been much better if we didn't have to use paste function but it's awesome. Thanks for the reply man. I owe you one.

:grin: :grin::grin::grin::grin::grin::grin::grin: