Using weekdays with any locale under Windows

前端 未结 2 1050
盖世英雄少女心
盖世英雄少女心 2021-01-04 19:34

I\'m trying to get the day of the week, and have it work consistently in any locale. In locales with Latin alphabets, everything is fine.

Sys.getlocale()
##         


        
2条回答
  •  太阳男子
    2021-01-04 20:10

    The RStudio/Architect problem

    This can be solved, slightly messily, by explicitly changing the encoding of the weekdays string to UTF-8.

    current_codepage <- as.character(l10n_info()$codepage)
    iconv(weekdays(Sys.Date()), from = current_codepage, to = "utf8")
    

    Note that codepages only exist on Windows; l10n_info()$codepage is NULL on Linux.

    The LC_TIME problem

    It turns out that under Windows you have to set both the LC_CTYPE and LC_TIME locale categories, and you have to set LC_CTYPE before LC_TIME, or it won't work.


    In the end, we need different implementations for different OSes.

    Windows version:

    get_today_windows <- function(locale = NULL)
    {
      if(!is.null(locale))
      {
        lc_ctype <- Sys.getlocale("LC_CTYPE")
        lc_time <- Sys.getlocale("LC_TIME")
        on.exit(Sys.setlocale("LC_CTYPE", lc_ctype))
        on.exit(Sys.setlocale("LC_TIME", lc_time), add = TRUE)
        Sys.setlocale("LC_CTYPE", locale)
        Sys.setlocale("LC_TIME", locale)
      }
      today <- weekdays(Sys.Date())
      current_codepage <- as.character(l10n_info()$codepage)
      iconv(today, from = current_codepage, to = "utf8")
    }
    get_today_windows() 
    ## [1] "Tuesday"
    get_today_windows("French_France")
    ## [1] "mardi"
    get_today_windows("Arabic_Qatar")
    ## [1] "الثلاثاء"
    get_today_windows("Serbian (Cyrillic)") 
    ## [1] "уторак"
    get_today_windows("Chinese (Traditional)_Taiwan") 
    ## [1] "星期二"
    

    Linux version:

    get_today_linux <- function(locale = NULL)
    {
      if(!is.null(locale))
      {
        lc_time <- Sys.getlocale("LC_TIME")
        on.exit(Sys.setlocale("LC_TIME", lc_time), add = TRUE)
        Sys.setlocale("LC_TIME", locale)
      }
      weekdays(Sys.Date())
    }
    get_today_linux() 
    ## [1] "Tuesday"
    get_today_linux("fr_FR.utf8")
    ## [1] "mardi"
    get_today_linux("ar_QA.utf8")
    ## [1] "الثلاثاء"
    get_today_linux("sr_RS.utf8") 
    ## [1] "уторак"
    get_today_linux("zh_TW.utf8") 
    ## [1] "週二"
    

    Enforcing the .utf8 encoding in the locale seems important get_today_linux("zh_TW") doesn't display properly.

提交回复
热议问题