Why Is Date Is Being Returned as Type 'Double'

Why is Date is being returned as type 'double'?

Dates are internally represented as double, as you can see in the following example:

> typeof(as.Date("09/12/16", "%m/%d/%y"))
[1] "double"

it is still marked a class Date, as in

> class(as.Date("09/12/16", "%m/%d/%y"))
[1] "Date"

and because it is a double, you can do computations with it. But because it is of class Date, these computations lead to Dates:

> as.Date("09/12/16", "%m/%d/%y") + 1
[1] "2016-09-13"
> as.Date("09/12/16", "%m/%d/%y") + 31
[1] "2016-10-13"

EDIT
I have asked for c() and cbind(), because they can be assciated with some strange behaviour. See the following example, where switching the order within c changes not the type but the class of the result:

> c(as.Date("09/12/16", "%m/%d/%y"), 1)
[1] "2016-09-12" "1970-01-02"
> c(1, as.Date("09/12/16", "%m/%d/%y"))
[1] 1 17056

> class(c(as.Date("09/12/16", "%m/%d/%y"), 1))
[1] "Date"
> class(c(1, as.Date("09/12/16", "%m/%d/%y")))
[1] "numeric"

EDIT 2 - c() and cbind force objects to be of one type. The first edit shows an anomaly of coercion, but generally, the vector must be of one shared type. cbind shares this behavior because it coerces to matrix, which in turn coerces to a single type.

For more help on typeof and class see this link

Why is my date field being returned into R from SQL database as a double etc

this is because, as of today, the months() vector function does not have a translation for MSSQL in dbplyr yet. The nice part how dplyr translations work is that it will let you call a database native command, in MSSQL, the DATENAME function should do what you need. This code should work:


df.out %>%
mutate(month=datename(month, gameDate))

Why is it that wrapping as.Date() in sapply return a numerical data type, but whereas lapply returns a date data type?

Welcome to StackOverflow, and excellent question.

It is due to the result type. sapply returns a vector and the as.vector() step strips the class attribute. This is unfortunate, but documented:

R> dates <- Sys.Date() + 0:2
R> dates
[1] "2020-04-25" "2020-04-26" "2020-04-27"
R> as.vector(dates)
[1] 18377 18378 18379
R>

(And the 'number' is how dates are represented internally: number of days since the epoch aka 1970-01-01. You get the same when you do as.numeric() or as.integer(0 on them.)

Lists have richer semantics, and lapply(), which returns a list, does not incur the side effect seen above:

as.list(dates)
[[1]]
[1] "2020-04-25"

[[2]]
[1] "2020-04-26"

[[3]]
[1] "2020-04-27"

R>

Why does DateTime to Unix time use a double instead of an integer?

Usually, I would implement it with an unsigned long instead of requiring the user to round up or down and cast to an int or long. One reason someone might want a double is if a structure similar to timeval were being used such as in gettimeofday. It allows for sub-second precision...

Date shows up as number

Thanks to wush978 for pointing me in the right direction, In the end I had to do:

for(d in geilodates){
date=format(as.Date(d,origin="1970-01-01"))
mapdate(date,geilo)
}

For some reason, inside the loop the "date" variable was seen as an integer, so I explicitely had to convert it to a date and then format it...

Convert double to date

We convert the 'Date' to character first and then use as.Date with format as %Y%m%d

exchange_rate_1$Date <- as.Date(as.character(exchange_rate_1$Date), "%Y%m%d")

If we need to aggregate by 'week'

library(dplyr)
exchange_rate_1 %>%
mutate(Date = as.Date(as.character(Date))) %>%
group_by(YearWeek = format(Date, "%Y %W")) %>%
summarise(across(ends_with('INR'), ~ sum(., na.rm = TRUE)))

vb.net Date values being converted to time

First, a DateTime is never null/nothing. Since it's a value type(Structure) it will always have a value. In this case the default value is DateTime.MinValue. But VB.NET handles this case for you. The dt.Date = Nothing will automatically compare the value with Date.MinValue so it's working as desired.

But the problem is that you return dt.ToString. Just return "":

Public Shared Function sqlDate(dt As DateTime) As String    
If dt.Date = Nothing Then
Return ""
Else
Return dt.ToString("yyyy-MM-dd")
End If
End Function

Here's a version without method:

Dim result = If(dt = Nothing, "", dt.ToString("yyyy-MM-dd"))

You can see that a Date is never null with this code:

Dim dt As Date = Nothing
Console.WriteLine( dt = Nothing )' true
Console.WriteLine( dt = Date.MinValue )' true
Console.WriteLine( Object.ReferenceEquals(Nothing, dt) )' always false because it's a value type

Update acc. your latest edit, compare with DbNull.Value. I'd also return a Nullable(Of Date):

Public Shared Function dbToDate(o As Object) As DateTime?
If DbNull.Value.Equals(o) OrElse o Is Nothing Then
Return Nothing
Else
Return Convert.ToDateTime(o)
End If
End Function

as.Date returning NA while converting from 'ddmmmyyyy'

Works for me. The reasons it doesn't for you probably has to do with your system locale.

?as.Date has the following to say:

## This will give NA(s) in some locales; setting the C locale
## as in the commented lines will overcome this on most systems.
## lct <- Sys.getlocale("LC_TIME"); Sys.setlocale("LC_TIME", "C")
x <- c("1jan1960", "2jan1960", "31mar1960", "30jul1960")
z <- as.Date(x, "%d%b%Y")
## Sys.setlocale("LC_TIME", lct)

Worth a try.

How to prevent ifelse() from turning Date objects into numeric objects

You may use data.table::fifelse (data.table >= 1.12.3) or dplyr::if_else.



data.table::fifelse

Unlike ifelse, fifelse preserves the type and class of the inputs.

library(data.table)
dates <- fifelse(dates == '2011-01-01', dates - 1, dates)
str(dates)
# Date[1:5], format: "2010-12-31" "2011-01-02" "2011-01-03" "2011-01-04" "2011-01-05"


dplyr::if_else

From dplyr 0.5.0 release notes:

[if_else] have stricter semantics that ifelse(): the true and false arguments must be the same type. This gives a less surprising return type, and preserves S3 vectors like dates" .

library(dplyr)
dates <- if_else(dates == '2011-01-01', dates - 1, dates)
str(dates)
# Date[1:5], format: "2010-12-31" "2011-01-02" "2011-01-03" "2011-01-04" "2011-01-05"


Related Topics



Leave a reply



Submit