11.3 日期与字符串的相互转换

许多数据的文本文件格式并没有明确支持某种特定的日期类型。例如,在一个CSV文件中,每个值只是一个字符串。为了使用R中日期函数,你必须把日期字符串转换成某一个日期类型的变量。类似地,往CSV文件中写数据时,你也必须首先把日期转换成字符串。

11.3.1 解析日期

当我们从文本或电子表格文件读取日期时,它们通常被存储为一个字符向量或因子。为了把它们转换为日期,我们需要解析这些字符串。这可以使用另一种命名得同样糟糕的函数:strptime(string parse time的简称),它将返回POSIXlt日期(还有as.POSIXctas.POSIXlt函数。调用它们时,如果输入的是字符,那么它们只是strptime的封装函数罢了)。解析日期时,你必须把字符串与日期相对应的那些位告诉strptime。日期的格式使用带有百分比符号和字母的字符串来指定。例如,当月的第几天被指定为%d。把它们与其他固定字符相结合可以形成一个完整的规范,例如:冒号、破折号和日期中的斜杠号。时区的规范取决于你的操作系统。它可能很复杂,细节将在稍后讨论,但通常你希望把“ UTC ”当成格林尼治时间或把“ ”当作当前时区(以你的操作系统的区域设置为主) 。

在下例中,%H是小时( 24小时制),%M是分钟,%S是秒,%m是月数,%d(如前所述)是当月的第几天,还有%Y为四位数的年份。完整的组成列表在不同的系统上是不同的。详情请参见?strptime帮助页面:

  1. moon_landings_str <- c(
  2. "20:17:40 20/07/1969",
  3. "06:54:35 19/11/1969",
  4. "09:18:11 05/02/1971",
  5. "22:16:29 30/07/1971",
  6. "02:23:35 21/04/1972",
  7. "19:54:57 11/12/1972"
  8. )
  9. (moon_landings_lt <- strptime(
  10. moon_landings_str,
  11. "%H:%M:%S %d/%m/%Y",
  12. tz = "UTC"
  13. ))
  14. ## [1] "1969-07-20 20:17:40 UTC" "1969-11-19 06:54:35 UTC"
  15. ## [3] "1971-02-05 09:18:11 UTC" "1971-07-30 22:16:29 UTC"
  16. ## [5] "1972-04-21 02:23:35 UTC" "1972-12-11 19:54:57 UTC"

如果字符串不匹配格式字符串中的格式,那么它就取NA值 。例如,如果给出的是破折号而不是斜线,将使得解析失败:

  1. strptime(
  2. moon_landings_str,
  3. "%H:%M:%S %d-%m-%Y",
  4. tz = "UTC"
  5. )
  6. ## [1] NA NA NA NA NA NA

11.3.2 格式化日期

与解析相反的问题是如何把日期变量转换为字符串,即格式化。在这种情况下,我们将使用与指定格式字符串相同的系统,不过现在调用strftime(字符串格式的时间)来反转解析操作。如果觉得strftime不好记,你可以使用format函数来轻松地完成日期的格式化,它与strftime的使用方式几乎完全相同。

在下例中,%I表示小时(12小时制),%p是AM/PM指示,%A是星期几的全名,而%B是月的全名。strftime可使用POSIXctPOSIXlt的输入参数:

  1. strftime(now_ct, "It's %I:%M%p on %A %d %B, %Y.")
  2. ## [1] "It's 10:47PM on Wednesday 17 July, 2013."