Home > OS >  Change of Date format
Change of Date format

Time:04-23

I have a table with date and temperature, and I need to convert the date from this format 1/1/2021 12:00:00 AM to just 1/1/21. Please help. I tried to add a new column with the new date using this code

SFtemps$Date <- as.Date(strptime(SFtemps$Date, "%m/%d/%y %H:%M"))

but it's not working.

CodePudding user response:

It should be %I to represent hours as decimal number (01–12), not %H, and %y to years without century (00–99).

x <- "1/1/2021 12:00:00 AM"

format(strptime(x, "%m/%d/%Y %I:%M:%S %p"), "%m/%d/%y")
[1] "01/01/21"

Note that after you re-foramt the time object, it'll be a pure character string and lose all attributes of a time object.

CodePudding user response:

Your format is a bit off. These are two options that work (lubridate is my favorite):

SFtemps <- list()
SFtemps$Date <- '1/1/2021 12:00:00 AM'


> as.Date(strptime(SFtemps$Date, "%m/%d/%Y %r"))
[1] "2021-01-01"
> as.Date(lubridate::mdy_hms(SFtemps$Date))
[1] "2021-01-01"

This will give you the date. If you want to see it as 1/1/2021, use the format function

CodePudding user response:

Your string is actually a timestamp, using lubridate you can convert it to the desired format and then leverage stamp function to get your data formatted in the manner that suits you.

org_str <- "1/1/2021 12:00:00 AM"
library("lubridate")
#> 
#> Attaching package: 'lubridate'
#> The following objects are masked from 'package:base':
#> 
#>     date, intersect, setdiff, union
x <- mdy_hms(x = org_str, tz = "UTC")
sf <- stamp("29/01/1997")
#> Multiple formats matched: "%d/%Om/%Y"(1), "%d/%m/%Y"(1)
#> Using: "%d/%Om/%Y"
sf(x)
#> [1] "01/01/2021"

Created on 2022-04-22 by the reprex package (v2.0.1)

Explanation

Contrary to common perception the date doesn't have a format as such. Only string representation of he date can be of a specific format. Consider the following example. Running code:

x <- Sys.Date()
unclass(x)

will return an integer. This is because1:

Thus, objects of the class Date are internally represented as numbers. More specifically, dates in R are actually integers.

The same is applicable to the POSIX objects

library(lubridate)
#> 
#> Attaching package: 'lubridate'
#> The following objects are masked from 'package:base':
#> 
#>     date, intersect, setdiff, union
xn <- now()
class(xn)
#> [1] "POSIXct" "POSIXt"
unclass(xn)
#> [1] 1650644616
#> attr(,"tzone")
#> [1] ""

Created on 2022-04-22 by the reprex package (v2.0.1)

You can always run:

format.Date(lubridate::now(), "%d-%m")
# [1] "22-04"

However, by doing this you are not formatting the date but creating a string representation of the date / timestamp object. Your string representation would have to be converted to timestamp / date object if you want to use it in common date time operations.

Suggestions

Whenever working with date time / date objects I would argue that it's advisable to keep those objects as a correct class maintaining the relevant details (such as time zone in case of timestamps) and only leverage formatting functions when utilising the data in analysis / visual representation, as shown in the sample.


1 Essentials of dates and times

CodePudding user response:

You can try tryFormats

as.Date(x, format, tryFormats = c("%m/%d/%y, %H:%M"),
optional = FALSE)
  • Related