在具有德语语言环境的Windows上将ISO 8601的年度数字与年度的数字匹配 [英] Match ISO 8601 week-of-year numbers to month-of-year numbers on Windows with German locale
问题描述
这与我的问题> POSIX日期(从每周的日期)直接相关时间格式。
但是,在这个问题中,我想具体询问如何映射 ISO 8601 周号到一年中的月份号。
However, in this question I'd like to specifically ask for how to map ISO 8601 week numbers to month of the year numbers.
在我看来,这是不可能和/或涉及一些非直觉的黑客行为(甚至这些黑客工具确实无法可靠地工作),因此 IMO应该被认为是需要在基础R中修复的东西。如果我错了,请纠正我
To me, it seems it is not possible and/or involves some non-intuitive hacks (and even these don't really work reliably) and IMO should thus be considered as something that needs to be fixed in base R. Please correct me if I'm wrong, though
编辑:似乎问题与Windows上运行的语言和/或您所使用的语言环境密切相关(
seems like it the issue is closely related to either running on Windows and/or the locale you're on (standard German, in my case)
posix <- as.POSIXct(c("2015-12-24", "2015-12-31", "2016-01-01", "2016-01-08"))
ISO 8601
ISO 8601
(yw <- format(posix, "%Y-%V"))
# [1] "2015-52" "2015-53" "2016-53" "2016-01"
ywd <- sprintf("%s-1", yw)
(as.POSIXct(ywd, format = "%Y-%V-%u"))
# [1] "2015-01-12 CET" "2015-01-12 CET" "2016-01-12 CET" "2016-01-12 CET"
# -> utterly wrong!!!
ywd <- sprintf("%s-4", yw)
(as.POSIXct(ywd, format = "%Y-%V-%u"))
# -> still wrong -> the day of the week is not the reason
# -> no way to use ISO 8601 convention to map week of the year to month of the year
为了尽职调查:在尝试使用美国或英国约定时也是不可能的:
For the sake of due dilligence: it's also not possible when trying to use the US or UK conventions:
(yw <- format(posix, "%Y-%U"))
# [1] "2015-51" "2015-52" "2016-00" "2016-01"
ywd <- sprintf("%s-1", yw)
(as.POSIXct(ywd, format = "%Y-%U-%u"))
# [1] "2015-12-21 CET" "2015-12-28 CET" NA "2016-01-04 CET"
# -> NA problem for week 00
ywd <- sprintf("%s-4", yw)
# -> does not work for week 00
(as.POSIXct(ywd, format = "%Y-%U-%u"))
# The day of the week is not the reason
# -> no way to use this convention to reliably map week of the year to month of the year
英国约定
UK convention
(yw <- format(posix, "%Y-%W"))
# [1] "2015-51" "2015-52" "2016-00" "2016-01"
ywd <- sprintf("%s-1", yw)
(as.POSIXct(ywd, format = "%Y-%W-%u"))
# [1] "2015-12-21 CET" "2015-12-28 CET" NA "2016-01-04 CET"
# -> NA problem for week 00
ywd <- sprintf("%s-4", yw)
# -> does not work for week 00
(as.POSIXct(ywd, format = "%Y-%W-%u"))
# The day of the week is not the reason
# -> no way to use this convention to reliably map week of the year to month of the year
会话信息
Session info
> sessionInfo()
R version 3.3.2 (2016-10-31)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows >= 8 x64 (build 9200)
locale:
[1] LC_COLLATE=German_Germany.1252 LC_CTYPE=German_Germany.1252 LC_MONETARY=German_Germany.1252
[4] LC_NUMERIC=C LC_TIME=English_United States.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] fva_0.1.0 digest_0.6.10 readxl_0.1.1 dplyr_0.5.0 plyr_1.8.4 magrittr_1.5
[7] memoise_1.0.0 testthat_1.0.2 roxygen2_5.0.1 devtools_1.12.0
loaded via a namespace (and not attached):
[1] Rcpp_0.12.8 lubridate_1.6.0 assertthat_0.1 packrat_0.4.8-1 crayon_1.3.2 withr_1.0.2
[7] R6_2.2.0 DBI_0.5-1 stringi_1.1.2 rstudioapi_0.6 tools_3.3.2 stringr_1.1.0
[13] tibble_1.2
> devtools::session_info()
Session info -----------------------------------------------------------------------------------------------
setting value
version R version 3.3.2 (2016-10-31)
system x86_64, mingw32
ui RStudio (1.0.136)
language en
collate German_Germany.1252
tz Europe/Berlin
date 2017-01-12
Packages ---------------------------------------------------------------------------------------------------
package * version date source
assertthat 0.1 2013-12-06 CRAN (R 3.3.2)
crayon 1.3.2 2016-06-28 CRAN (R 3.3.2)
DBI 0.5-1 2016-09-10 CRAN (R 3.3.2)
devtools * 1.12.0 2016-06-24 CRAN (R 3.3.2)
digest * 0.6.10 2016-08-02 CRAN (R 3.3.2)
dplyr * 0.5.0 2016-06-24 CRAN (R 3.3.2)
fva * 0.1.0 <NA> local
lubridate 1.6.0 2016-09-13 CRAN (R 3.3.2)
magrittr * 1.5 2014-11-22 CRAN (R 3.3.2)
memoise * 1.0.0 2016-01-29 CRAN (R 3.3.2)
packrat 0.4.8-1 2016-09-07 CRAN (R 3.3.2)
plyr * 1.8.4 2016-06-08 CRAN (R 3.3.2)
R6 2.2.0 2016-10-05 CRAN (R 3.3.2)
Rcpp 0.12.8 2016-11-17 CRAN (R 3.3.2)
readxl * 0.1.1 2016-03-28 CRAN (R 3.3.2)
roxygen2 * 5.0.1 2015-11-11 CRAN (R 3.3.2)
stringi 1.1.2 2016-10-01 CRAN (R 3.3.2)
stringr 1.1.0 2016-08-19 CRAN (R 3.3.2)
testthat * 1.0.2 2016-04-23 CRAN (R 3.3.2)
tibble 1.2 2016-08-26 CRAN (R 3.3.2)
withr 1.0.2 2016-06-20 CRAN (R 3.3.2)
推荐答案
披露:如此答案我创建了 ISOweek
包以处理基于ISO 8601的基于星期的日期。
Disclosure: As mentioned in this answer I have created the ISOweek
package to deal with ISO 8601 week-based dates.
该问题包含几个缺陷:
- 基于ISO 8601的年份不同于日历年。
- 不指定星期几,将年周转换为年月是不明确的。
基于周的年份与日历年
OP使用
Week-based year vs calendar year
The OP has created sample data using
posix <- as.POSIXct(c("2015-12-24", "2015-12-31", "2016-01-01", "2016-01-08"))
(yw <- format(posix, "%Y-%V"))
[1] "2015-52" "2015-53" "2016-53" "2016-01"
格式说明%Y
返回日历年,这显然对第三个元素是错误的。
The format specification %Y
returns the calendar year which apparently is wrong for the third element.
使用正确的格式规范%G
,我们可以得到
With the correct format specification %G
we do get
(yw <- format(posix, "%G-%V"))
[1] "2015-52" "2015-53" "2015-53" "2016-01"
一年中的一周到一年中的一个月的转换
仅提供基于ISO周的年和周号 而没有 星期几 模棱两可的结果。
这可以用(更正后的)样本数据证明,该数据现在包含OP自身(非标准)年周中的连续三周格式:
This can be demonstrated with the (corrected) sample data which now contain three consecutive weeks in the OP's own (non-standard) year-week format:
yw
[1] "2015-52" "2015-53" "2016-01"
借助 ISOweek2date()$ c
ISOweek
包中的$ c>函数将数据转换为日历日期。请注意, ISOweek2date()
需要一个完整的基于ISO 8601的日期,格式为 yyyy-Www-d
,包括星期几。如果我们选择一周的第一天(星期一),则会得到:
With help of the ISOweek2date()
function from the ISOweek
package the data are converted to calendar dates. Note that ISOweek2date()
requires a full ISO 8601 week-based date in the format yyyy-Www-d
including the day of week. If we choose the first day of the week (Monday) we do get:
library(ISOweek)
library(magrittr)
yw %>%
# insert "W" to conform with ISO 8601 format
sub("-", "-W", .) %>%
# append day of week
paste0("-1") %>%
# convert to class Date and print as yyyy-mm
ISOweek2date() %>%
format("%Y-%m")
[1] "2015-12" "2015-12" "2016-01"
现在,我们使用一周的最后一天(星期日)重复此操作:
Now, we repeat this using the last day of the week (Sunday):
yw %>%
sub("-", "-W", .) %>%
paste0("-7") %>%
ISOweek2date() %>%
format("%Y-%m")
[1] "2015-12" "2016-01" "2016-01"
请注意,第二个元素现在指的是2016年1月而不是2015年12月,因为星期日第53周的1月为1月,本周的星期一仍为12月。
Note that the second element now refers to January 2016 instead of December 2015 because the Sunday of week 53 is in January and the Monday of this week still is in December.
这篇关于在具有德语语言环境的Windows上将ISO 8601的年度数字与年度的数字匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!