Utiliser les jours de la semaine avec n’importe quelle langue sous Windows

J’essaie d’obtenir le jour de la semaine et de le faire fonctionner de manière cohérente dans tous les parameters régionaux. Dans les lieux avec alphabet latin, tout va bien.

Sys.getlocale() ## [1] "LC_COLLATE=English_United Kingdom.1252;LC_CTYPE=English_United Kingdom.1252;LC_MONETARY=English_United Kingdom.1252;LC_NUMERIC=C;LC_TIME=English_United Kingdom.1252" weekdays(Sys.Date()) ## [1] "Tuesday" 

J’ai deux problèmes connexes avec d’autres parameters régionaux.

Si je fixe

 Sys.setlocale("LC_ALL", "Arabic_Qatar") ## [1] "LC_COLLATE=Arabic_Qatar.1256;LC_CTYPE=Arabic_Qatar.1256;LC_MONETARY=Arabic_Qatar.1256;LC_NUMERIC=C;LC_TIME=Arabic_Qatar.1256" 

alors parfois (correctement) obtenir

 weekdays(Sys.Date()) ## [1] "الثلاثاء 

et parfois obtenir

 weekdays(Sys.Date()) ## [1] "ÇáËáÇËÇÁ" 

en fonction de ma configuration. Le problème est que je n’arrive pas à comprendre ce qui cause la différence.

Je pensais que cela pouvait être quelque chose à voir avec getOption("encoding") , mais j’ai essayé de définir explicitement les options(encoding = "native.enc") et les options(encoding = "UTF-8") .

J’ai essayé plusieurs versions récentes de R, et le problème est constant dans tous les cas.

Pour le moment, la chaîne s’affiche correctement dans l’interface utilisateur graphique R, mais de manière incorrecte lorsque j’utilise un IDE (testé par Architect et RStudio).

Que dois-je définir pour que les jours de la semaine s’affichent toujours correctement?

Il peut être utile de savoir que les weekdays(Sys.Date()) sont équivalents au format(as.POSIXlt(Sys.Date()), "%A") , qui appelle un format.POSIXlt interne. Méthode format.POSIXlt .

Deuxièmement, il semble exagéré de changer tous les parameters régionaux. Je pensais que je devrais juste être capable de définir les options de temps. Toutefois, si je définis des composants individuels des parameters régionaux, les weekdays retournent une chaîne de points d’interrogation.

 for(category in c("LC_TIME", "LC_CTYPE", "LC_COLLATE", "LC_MONETARY")) { Sys.setlocale(category, "Arabic_Qatar") print(Sys.getlocale()) print(weekdays(Sys.Date())) } ## [1] "LC_COLLATE=English_United Kingdom.1252;LC_CTYPE=English_United Kingdom.1252;LC_MONETARY=English_United Kingdom.1252;LC_NUMERIC=C;LC_TIME=Arabic_Qatar.1256" ## [1] "????????" ## [1] "LC_COLLATE=English_United Kingdom.1252;LC_CTYPE=Arabic_Qatar.1256;LC_MONETARY=English_United Kingdom.1252;LC_NUMERIC=C;LC_TIME=Arabic_Qatar.1256" ## [1] "????????" ## [1] "LC_COLLATE=Arabic_Qatar.1256;LC_CTYPE=Arabic_Qatar.1256;LC_MONETARY=English_United Kingdom.1252;LC_NUMERIC=C;LC_TIME=Arabic_Qatar.1256" ## [1] "????????" ## [1] "LC_COLLATE=Arabic_Qatar.1256;LC_CTYPE=Arabic_Qatar.1256;LC_MONETARY=Arabic_Qatar.1256;LC_NUMERIC=C;LC_TIME=Arabic_Qatar.1256" ## [1] "????????" 

Quelles parties des parameters régionaux affectent l’impression des jours de la semaine?


Mise à jour: le problème semble être lié à Windows. Lorsque je lance le code sur une "ar_QA.UTF8" Linux avec les parameters régionaux "ar_QA.UTF8" , les jours de la semaine sont correctement affichés.


Mise à jour supplémentaire: Comme mentionné dans sa réponse, définir des parameters régionaux sous Windows est étrange, car vous ne pouvez pas simplement utiliser des codes ISO comme “en-GB”. Pour Windows 7 / Vista / Server 2003 / XP, vous pouvez définir un paramètre régional en utilisant les chaînes de langue setlocale ou les valeurs de prise en charge linguistique nationale . Pour l’arabe qatari, il n’y a pas de chaîne de langue setlocale, nous devons donc utiliser une valeur NLS. Nous avons plusieurs choix:

 Sys.setlocale("LC_TIME", "ARQ") # the language abbreviation name Sys.setlocale("LC_TIME", "Arabic_Qatar") # corresponding to the language/country pair "Arabic (Qatar)" Sys.setlocale("LC_TIME", "Arabic_Qatar.1256") # explicitly including the ANSI codepage Sys.setlocale("LC_TIME", "Arabic") # would sometimes be a possibility too, but it defaults to Saudi Arabic 

Le problème n’est donc pas que R ne supporte pas les locales en arabe sous Windows (même si je ne suis pas entièrement convaincu de la robustesse de Sys.setlocale ).


Tentative désespérée dernière tentative: essayer de réparer les choses par magie à l’aide de la commande Windows Management Instrumentation pour modifier les parameters régionaux du système d’exploitation ne fonctionne pas, car R ne semble pas reconnaître les modifications.

 system("wmic os set locale=MS_4001") ## Updating property(s) of '\\PC402729\ROOT\CIMV2:Win32_OperatingSystem=@' ## Property(s) update successful. system("wmic os get locale") # same as before 

    Le système de nommage des locales est spécifique au système d’exploitation. Je vous recommande de lire les parameters régionaux du manuel R Installation and Administration pour une explication complète.

    sous windows:

    La liste des langues sockets en charge est répertoriée dans MSDN Language Ssortingngs . Et étonnamment il n’y a pas de langue arabe là-bas. La colonne “Chaîne de langue” contient l’entrée légale pour la définition de parameters régionaux dans R et même dans la liste contry / regions, il n’y a pas de pays parlé en arabe.

    Bien sûr, vous pouvez modifier les parameters globaux de vos parameters régionaux (paramètre du panneau -> région -> ..), mais cela changera la configuration globale et il ne sera pas sûr d’obtenir le bon résultat sans problème de codage.

    sous Linux (Ubuntu dans mon cas):

    L’arabe n’est généralement pas pris en charge par défaut, mais il est facile de le définir en utilisant les locale .

      locale -a ## to list all already supported language sudo locale-gen ar_QA.UTF-8 ## install it in case does not exist 

    sous RStudio maintenant:

      Sys.setlocale('LC_TIME','ar_QA.UTF-8') [1] "ar_QA.UTF-8" > format(Sys.Date(),'%A') [1] "الثلاثاء 

    Notez également que sous R console, l’impression n’est pas aussi jolie qu’en studio R car elle est écrite de gauche à droite et non de droite à gauche .

    Le problème RStudio / Architect

    Cela peut être résolu, légèrement en désordre, en changeant explicitement l’encodage de la chaîne de jours de la semaine en UTF-8.

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

    Notez que les pages de code n'existent que sous Windows. l10n_info()$codepage est NULL sous Linux.

    Le problème LC_TIME

    Il s'avère que sous Windows, vous devez définir les catégories de parameters régionaux LC_CTYPE et LC_TIME et définir LC_CTYPE avant LC_TIME , LC_CTYPE cela ne fonctionnera pas.


    Au final, nous avons besoin de différentes implémentations pour différents systèmes d'exploitation.

    Version Windows:

     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] "星期二" 

    Version Linux:

     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] "週二" 

    L'application du codage .utf8 dans l'environnement local semble importante. get_today_linux("zh_TW") ne s'affiche pas correctement.