Формат даты и R против региональных настроек - PullRequest
0 голосов
/ 25 января 2019

Я изо всех сил пытаюсь позволить R придерживаться формата даты / региональных настроек, как указано на моем компьютере с Windows.

У меня есть:

> Sys.getlocale("LC_TIME")
[1] "English_United States.1252"

Но когда я проверяю свою Панель управления \ Региональные и языковые настройки, у меня есть:

Format: English (United States)
Short date: M/d/yyyy

Похоже, что R игнорирует дату-специфичные настройки целиком.Даты, отформатированные с помощью R, жестко закодированы (?) В фиксированном формате "% Y-% m-% d":

format.Date(Sys.Date())
[1] "2019-01-25"

Проблема возникает при взаимодействии с данными из внешних программ, которые придерживаютсяместные региональные настройки.Например, даты в формате Microsoft Excel.И делая код универсальным для разных региональных настроек, с разными форматами даты.

Я обнаружил, что это работает до некоторой степени:

sShortDate <- readRegistry("Control Panel\\International", "HCU")$sShortDate
# convert Windows date format strings into R-date-format-strings
CPformat2Rformat <- function(f) {
  f %>%  
  gsub("yyyy", "%Y", .) %>%
  gsub("M",    "%m", .) %>%
  gsub('d',    '%d', .) 
}
sShortDate <- CPformat2Rformat(sShortDate)

# now we have the right format
format.Date(Sys.Date(), sShortDate)
# and the other way around;
strptime("01/25/2019", sShortDate)

Это лучший способ справиться с этим?Или это лучшая функция, которая лучше обрабатывает форматы ShortDate и LongDate?

Ответы [ 2 ]

0 голосов
/ 25 января 2019

Если я правильно вас прочитал, вы спрашиваете, почему R не отображает даты в вашем регионе.Я согласен, было бы неплохо, если бы вы могли контролировать формат отображаемого объекта Date, сохраняя его как объект Date.Но нет реального способа без предоставления собственного расширения без малейших усилий.

Вот хак: переопределить метод print.Date по умолчанию, хотя он работает только с прямыми переменными в консоли, а не со встроенными переменными.например, data.frame:

x <- data.frame(dt = Sys.Date(), dttm = Sys.time())
x$dt
# [1] "2019-01-25"
class(x$dt)
# [1] "Date"

print.Date <- function (x, max = NULL, ...) {
    fmt <- getOption("date.format", "%m/%d/%Y")
    if (is.null(max)) 
        max <- getOption("max.print", 9999L)
    if (max < length(x)) {
        print(format(x[seq_len(max)], format=fmt), max = max, ...)
        cat(" [ reached getOption(\"max.print\") -- omitted", 
            length(x) - max, "entries ]\n")
    }
    else if (length(x)) 
        print(format(x, format=fmt), max = max, ...)
    else cat(class(x)[1L], "of length 0\n")
    invisible(x)
}

x
#           dt                dttm
# 1 2019-01-25 2019-01-25 00:22:38
x$dt
# [1] "01/25/2019"
class(x$dt)
# [1] "Date"
options(date.format="%b %d, %Y")
x$dt
# [1] "Jan 25, 2019"

Я определил здесь значение по умолчанию "%m/%d/%Y", но это отвечает вашим предпочтениям.Более общее применение этой функции может по умолчанию использовать R-default "%Y-%m-%d", и пользователь может изменить его в какой-то момент в зависимости от своих потребностей.

(я не знаю, как получитьна эту функцию ссылаются для представлений data.frame. Вероятно, это связано с областью видимости, где она использует base::print.Date из-за пути поиска в пространствах имен. Если вы спросите "могу ли я заменить это" , этоспросили, и, как правило, ответ такой: «это может сработать, но ...» или «caveat emptor» , и, по моему опыту, никогда не было полностью решено, особенно когдапытается перебрать базовые функции.)

0 голосов
/ 25 января 2019

Вы можете использовать функцию as.Date() для адаптации к различным форматам даты, например:

as.Date("01/25/2019", format='%m/%d/%Y')
as.Date("Jan-30-2019", format='%b-%d-%Y')
as.Date("25012019", format='%d%m%Y')

все даст один и тот же универсальный объект даты.

...