strptime: Parse and Format Date-time Objects


Note that the date-time processing functions in stringx are a work in progress. Feature requests/comments/remarks are welcome.

strptime parses strings representing date-time data and converts it to a date-time object.

strftime formats a date-time object and outputs it as a character vector.

The functions are meant to be operable with each other, especially with regards to formatting/printing. This is why they return/deal with objects of a new class, POSIXxt, which expends upon the built-in POSIXct.


strptime(x, format, tz = "", lenient = FALSE, locale = NULL)

  format = "%Y-%m-%dT%H:%M:%S%z",
  tz = attr(x, "tzone")[1L],
  usetz = FALSE,
  locale = NULL

## S3 method for class 'POSIXxt'
  format = "%Y-%m-%dT%H:%M:%S%z",
  tz = attr(x, "tzone")[1L],
  usetz = FALSE,
  locale = NULL


as.POSIXxt(x, tz = "", ...)

## S3 method for class 'POSIXt'
as.POSIXxt(x, tz = attr(x, "tzone")[1L], ...)

## S3 method for class 'POSIXxt'
as.POSIXlt(x, tz = attr(x, "tzone")[1L], ..., locale = NULL)

## Default S3 method:
as.POSIXxt(x, tz = "", ...)

## S3 method for class 'POSIXxt'
as.Date(x, ...)

## S3 method for class 'Date'
as.POSIXxt(x, ...)

## S3 method for class 'character'
as.POSIXxt(x, tz = "", format = NULL, ..., lenient = FALSE, locale = NULL)

## S3 method for class 'POSIXxt'
Ops(e1, e2)

## S3 method for class 'POSIXxt'
seq(from, to, by, length.out = NULL, along.with = NULL, ...)

## S3 method for class 'POSIXxt'
c(..., recursive = FALSE)

## S3 method for class 'POSIXxt'
rep(..., recursive = FALSE)



object to be converted: a character vector for strptime and as.POSIXxt.character, an object of class POSIXxt for strftime an object of class Date for as.POSIXxt.Date, or objects coercible to


character vector of date-time format specifiers, see stri_datetime_fstr; e.g., "%Y-%m-%d" or "datetime_full"; the default conforms to the ISO 8601 guideline


NULL or '' for the default time zone (see stri_timezone_get) or a single string with a timezone identifier, see stri_timezone_list; note that when x is equipped with tzone attribute, this datum is used; as.POSIXxt.character treats dates as being at midnight local time


single logical value; should date/time parsing be lenient?


NULL or '' for the default locale (see stri_locale_get) or a single string with a locale identifier, see stri_locale_list


not used (with a warning if attempting to do so) [DEPRECATED]


not used

e1, e2, from, to, by, length.out, along.with, recursive

arguments to c, rep, seq, etc.


Note that the ISO 8601 guideline suggests a year-month-day date format and a 24-hour time format always indicating the effective time zone, e.g., 2015-12-31T23:59:59+0100. This is so as to avoid ambiguity.

When parsing strings, ICU fills the ‘blanks’ with current date/time, the skipped ‘%s’ part will be replaced by the current seconds at ‘now’.


strftime and format return a character vector (in UTF-8).

strptime, as.POSIXxt.Date, and asPOSIXxt.character return an object of class POSIXxt, which extends upon POSIXct, see also DateTimeClasses.

If a string cannot be recognised as valid date/time specifier (as per the given format string), the corresponding output will be NA.

Differences from Base R

Replacements for base strptime and strftime implemented with stri_datetime_parse and stri_datetime_format.

format.POSIXxt is a thin wrapper around strftime.

  • formatting/parsing date-time in different locales and calendars is difficult and non-portable across platforms [fixed here – using services provided by ICU]

  • default format not conforming to ISO 8601, in particular not displaying the current time zone [fixed here]

  • only the names attribute in x is propagated [fixed here]

  • partial recycling with no warning [fixed here]

  • strptime returns an object of class POSIXlt, which is not the most convenient to work with, e.g., when including in data frames [fixed here]

  • Ideally, there should be only one class to represent dates and one to represent date/time; POSIXlt is no longer needed as we have stri_datetime_fields; our new POSIXxt class aims to solve the underlying problems with POSIXct’s not being consistent with regards to working in different time zones and dates (see, e.g., as.Date(as.POSIXct(strftime(Sys.Date())))) [addressed here]

  • dates without times are not always treated as being at midnight (despite that being stated in the help page for as.POSIXct) [fixed here]

  • strftime does not honour the tzone attribute, which is used whilst displaying time (via format) [fixed here]


Marek Gagolewski

See Also

The official online manual of stringx at

Related function(s): sprintf, ISOdatetime


strftime(Sys.time())  # default format - ISO 8601
## [1] "2021-09-03T10:25:50+1000"
f <- c("date_full", "%Y-%m-%d", "date_relative_short", "datetime_full")
strftime(Sys.time(), f)  # current default locale
## [1] "Friday, 3 September 2021"                                                
## [2] "2021-09-03"                                                              
## [3] "today"                                                                   
## [4] "Friday, 3 September 2021 at 10:25:50 am Australian Eastern Standard Time"
strftime(Sys.time(), f, locale="de_DE")
## [1] "Freitag, 3. September 2021"                                       
## [2] "2021-09-03"                                                       
## [3] "heute"                                                            
## [4] "Freitag, 3. September 2021 um 10:25:50 Ostaustralische Normalzeit"
strftime(Sys.time(), "date_short", locale="en_IL@calendar=hebrew")
## [1] "26 Elul 5781"
strptime("1970-01-01 00:00:00", "%Y-%m-%d %H:%M:%S", tz="GMT")
## [1] "1970-01-01T00:00:00+0000"
strptime("1970-01-01", "%Y-%m-%d")  # missing time info replaced with current
## [1] "1970-01-01T10:25:50+1000"
strptime("14 Nisan 5703", "date_short", locale="en_IL@calendar=hebrew")
## [1] "1943-04-19T10:25:50+1000"
## [1] "1970-01-01T00:00:00+1000"
as.POSIXxt("1970/01/01 12:00")
## [1] "1970-01-01T12:00:00+1000"