简体   繁体   English

获取第53周第一天的POSIX日期(ISO约定)

[英]Get POSIX date of the first day of week 53 (ISO convention)

I have date information given as <YEAR>-<WEEK-OF-YEAR> and I'd like to tell R "give me the POSIX dates of the first days for each of those weeks", how would I do that? 我将日期信息指定为<YEAR>-<WEEK-OF-YEAR> ,我想告诉R“给我每个星期的第一天的POSIX日期”,我该怎么做?

I do get it working by pasting "-1" (for "1st day of week") to the vector of <YEAR>-<WEEK-OF-YEAR> strings and then using conversion spec %u in the call to as.POSIXct for weeks 1-52, but not for week 53. 我通过将"-1" (“一周中的第一天”)粘贴到<YEAR>-<WEEK-OF-YEAR>字符串的向量上,然后在对as.POSIXct的调用中使用转换规范%uas.POSIXct在1至52周内,但不在53周内。

Example

weeks <- as.character(1:53)
weeks[nchar(weeks) == 1] <- paste0("0", weeks[nchar(weeks) == 1])
first_day_of_week_wday <- paste0("2015-", weeks, "-1")
first_day_of_week_posix <- as.POSIXct(first_day_of_week_wday,
  format = "%Y-%U-%u")

data.frame(
  wday = first_day_of_week_wday,
  posix = first_day_of_week_posix,
  stringsAsFactors = FALSE
)
#>         wday      posix
#> 1  2015-01-1 2015-01-05
#> 2  2015-02-1 2015-01-12
#> 3  2015-03-1 2015-01-19
#> 4  2015-04-1 2015-01-26
#> 5  2015-05-1 2015-02-02
#> 6  2015-06-1 2015-02-09
#> 7  2015-07-1 2015-02-16
#> 8  2015-08-1 2015-02-23
#> 9  2015-09-1 2015-03-02
#> 10 2015-10-1 2015-03-09
#> 11 2015-11-1 2015-03-16
#> 12 2015-12-1 2015-03-23
#> 13 2015-13-1 2015-03-30
#> 14 2015-14-1 2015-04-06
#> 15 2015-15-1 2015-04-13
#> 16 2015-16-1 2015-04-20
#> 17 2015-17-1 2015-04-27
#> 18 2015-18-1 2015-05-04
#> 19 2015-19-1 2015-05-11
#> 20 2015-20-1 2015-05-18
#> 21 2015-21-1 2015-05-25
#> 22 2015-22-1 2015-06-01
#> 23 2015-23-1 2015-06-08
#> 24 2015-24-1 2015-06-15
#> 25 2015-25-1 2015-06-22
#> 26 2015-26-1 2015-06-29
#> 27 2015-27-1 2015-07-06
#> 28 2015-28-1 2015-07-13
#> 29 2015-29-1 2015-07-20
#> 30 2015-30-1 2015-07-27
#> 31 2015-31-1 2015-08-03
#> 32 2015-32-1 2015-08-10
#> 33 2015-33-1 2015-08-17
#> 34 2015-34-1 2015-08-24
#> 35 2015-35-1 2015-08-31
#> 36 2015-36-1 2015-09-07
#> 37 2015-37-1 2015-09-14
#> 38 2015-38-1 2015-09-21
#> 39 2015-39-1 2015-09-28
#> 40 2015-40-1 2015-10-05
#> 41 2015-41-1 2015-10-12
#> 42 2015-42-1 2015-10-19
#> 43 2015-43-1 2015-10-26
#> 44 2015-44-1 2015-11-02
#> 45 2015-45-1 2015-11-09
#> 46 2015-46-1 2015-11-16
#> 47 2015-47-1 2015-11-23
#> 48 2015-48-1 2015-11-30
#> 49 2015-49-1 2015-12-07
#> 50 2015-50-1 2015-12-14
#> 51 2015-51-1 2015-12-21
#> 52 2015-52-1 2015-12-28
#> 53 2015-53-1       <NA>

Due dilligence 尽职调查

Apparently dates are treated quite differently on Windows vs. MacOS/Linux. 在Windows和MacOS / Linux上,日期的处理方式显然有所不同。 Suggestion based on using %G instead of %Y as in the comments of this question gives the following result: 基于使用%G代替%Y该问题的注释所示)得出以下结果:

as.POSIXct(first_day_of_week_wday, format = "%G-%U-%u")
#>  [1] "2018-01-08 CET"  "2018-01-15 CET"  "2018-01-22 CET" 
#>  [4] "2018-01-29 CET"  "2018-02-05 CET"  "2018-02-12 CET" 
#>  [7] "2018-02-19 CET"  "2018-02-26 CET"  "2018-03-04 CET" 
#> [10] "2018-03-11 CET"  "2018-03-18 CET"  "2018-03-25 CET" 
#> [13] "2018-04-01 CEST" "2018-04-08 CEST" "2018-04-15 CEST"
#> [16] "2018-04-22 CEST" "2018-04-29 CEST" "2018-05-06 CEST"
#> [19] "2018-05-13 CEST" "2018-05-20 CEST" "2018-05-27 CEST"
#> [22] "2018-06-03 CEST" "2018-06-10 CEST" "2018-06-17 CEST"
#> [25] "2018-06-24 CEST" "2018-07-01 CEST" "2018-07-08 CEST"
#> [28] "2018-07-15 CEST" "2018-07-22 CEST" "2018-07-29 CEST"
#> [31] "2018-08-05 CEST" "2018-08-12 CEST" "2018-08-19 CEST"
#> [34] "2018-08-26 CEST" "2018-09-02 CEST" "2018-09-09 CEST"
#> [37] "2018-09-16 CEST" "2018-09-23 CEST" "2018-09-30 CEST"
#> [40] "2018-10-07 CEST" "2018-10-14 CEST" "2018-10-21 CEST"
#> [43] "2018-10-28 CEST" "2018-11-04 CET"  "2018-11-11 CET" 
#> [46] "2018-11-18 CET"  "2018-11-25 CET"  "2018-12-02 CET" 
#> [49] "2018-12-09 CET"  "2018-12-16 CET"  "2018-12-23 CET" 
#> [52] "2018-12-30 CET"  NA

as.POSIXct(first_day_of_week_wday, format = "%G-%V-%u")
#>  [1] "2018-01-26 CET" "2018-01-26 CET" "2018-01-26 CET" "2018-01-26 CET"
#>  [5] "2018-01-26 CET" "2018-01-26 CET" "2018-01-26 CET" "2018-01-26 CET"
#>  [9] "2018-01-26 CET" "2018-01-26 CET" "2018-01-26 CET" "2018-01-26 CET"
#> [13] "2018-01-26 CET" "2018-01-26 CET" "2018-01-26 CET" "2018-01-26 CET"
#> [17] "2018-01-26 CET" "2018-01-26 CET" "2018-01-26 CET" "2018-01-26 CET"
#> [21] "2018-01-26 CET" "2018-01-26 CET" "2018-01-26 CET" "2018-01-26 CET"
#> [25] "2018-01-26 CET" "2018-01-26 CET" "2018-01-26 CET" "2018-01-26 CET"
#> [29] "2018-01-26 CET" "2018-01-26 CET" "2018-01-26 CET" "2018-01-26 CET"
#> [33] "2018-01-26 CET" "2018-01-26 CET" "2018-01-26 CET" "2018-01-26 CET"
#> [37] "2018-01-26 CET" "2018-01-26 CET" "2018-01-26 CET" "2018-01-26 CET"
#> [41] "2018-01-26 CET" "2018-01-26 CET" "2018-01-26 CET" "2018-01-26 CET"
#> [45] "2018-01-26 CET" "2018-01-26 CET" "2018-01-26 CET" "2018-01-26 CET"
#> [49] "2018-01-26 CET" "2018-01-26 CET" "2018-01-26 CET" "2018-01-26 CET"
#> [53] "2018-01-26 CET"

The ISOweek solution: ISOweek解决方案:

library(ISOweek)
weeks <- as.character(1:53)
weeks[nchar(weeks) == 1] <- paste0("0", weeks[nchar(weeks) == 1])
first_day_of_week_wday <- paste0("2015-W", weeks, "-1")
ISOweek2date(first_day_of_week_wday)

Just some more clarification on why your second attempt with the %V won't work on windows. 关于Windows上为什么第二次尝试使用%V的原因,需要更多说明。

From the package description: This is an substitute for the %V and %u formats which are not implemented on Windows. 从软件包描述中:这可以替代Windows中未实现的%V和%u格式。 In addition, the package offers functions to convert from standard calender format yyyy-mm-dd to and from ISO 8601 week format yyyy-Www-d 此外,该软件包还提供了将标准压光机格式yyyy-mm-dd转换为ISO 8601周格式yyyy-Www-d的功能。

The Base R solution: Base R解决方案:

You cannot produce a value for week 53 because strptime does not recognize there being a 'full' monday during that period. 您无法产生第53周的值,因为strptime无法识别该时段内的“满”星期一。 The code works if the date becomes 2016, week 1 instead of 2015, week 53. 如果日期变为2016年的第1周而不是2015年的第53周,则该代码有效。

weeks <- c(1:52,1)
yr <- c(rep('2015-',52),'2016-')
weeks[nchar(weeks) == 1] <- paste0("0", weeks[nchar(weeks) == 1])
first_day_of_week_wday <- paste0(yr, weeks, "-1")
first_day_of_week_posix <- as.POSIXct(first_day_of_week_wday,
                                      format = "%Y-%U-%u")

data.frame(
  wday = first_day_of_week_wday,
  posix = first_day_of_week_posix,
  stringsAsFactors = FALSE
)

        wday      posix
1   2015-1-1 2015-01-05
2   2015-2-1 2015-01-12
3   2015-3-1 2015-01-19
4   2015-4-1 2015-01-26
5   2015-5-1 2015-02-02
6   2015-6-1 2015-02-09
7   2015-7-1 2015-02-16
8   2015-8-1 2015-02-23
9   2015-9-1 2015-03-02
10 2015-10-1 2015-03-09
11 2015-11-1 2015-03-16
12 2015-12-1 2015-03-23
13 2015-13-1 2015-03-30
14 2015-14-1 2015-04-06
15 2015-15-1 2015-04-13
16 2015-16-1 2015-04-20
17 2015-17-1 2015-04-27
18 2015-18-1 2015-05-04
19 2015-19-1 2015-05-11
20 2015-20-1 2015-05-18
21 2015-21-1 2015-05-25
22 2015-22-1 2015-06-01
23 2015-23-1 2015-06-08
24 2015-24-1 2015-06-15
25 2015-25-1 2015-06-22
26 2015-26-1 2015-06-29
27 2015-27-1 2015-07-06
28 2015-28-1 2015-07-13
29 2015-29-1 2015-07-20
30 2015-30-1 2015-07-27
31 2015-31-1 2015-08-03
32 2015-32-1 2015-08-10
33 2015-33-1 2015-08-17
34 2015-34-1 2015-08-24
35 2015-35-1 2015-08-31
36 2015-36-1 2015-09-07
37 2015-37-1 2015-09-14
38 2015-38-1 2015-09-21
39 2015-39-1 2015-09-28
40 2015-40-1 2015-10-05
41 2015-41-1 2015-10-12
42 2015-42-1 2015-10-19
43 2015-43-1 2015-10-26
44 2015-44-1 2015-11-02
45 2015-45-1 2015-11-09
46 2015-46-1 2015-11-16
47 2015-47-1 2015-11-23
48 2015-48-1 2015-11-30
49 2015-49-1 2015-12-07
50 2015-50-1 2015-12-14
51 2015-51-1 2015-12-21
52 2015-52-1 2015-12-28
53  2016-1-1 2016-01-04

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM