Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use a consistent argument order for trunc (Dates) #50949

Open
timholy opened this issue Aug 17, 2023 · 7 comments
Open

Use a consistent argument order for trunc (Dates) #50949

timholy opened this issue Aug 17, 2023 · 7 comments
Labels
dates Dates, times, and the Dates stdlib module
Milestone

Comments

@timholy
Copy link
Member

timholy commented Aug 17, 2023

@barucden noted that we have this:

help?> trunc
search: trunc truncate unsafe_trunc setrounding AbstractUnitRange set_zero_subnormals get_zero_subnormals

  trunc([T,] x)

  trunc(T, x) converts the result to type T, throwing an InexactError if the value is not representable.

────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

  trunc(dt::TimeType, ::Type{Period}) -> TimeType

  Truncates the value of dt according to the provided Period type.

  Examples
  ≡≡≡≡≡≡≡≡≡≡

  julia> trunc(DateTime("1996-01-01T12:30:00"), Day)
  1996-01-01T00:00:00

Dates should not violate the normal argument order here, it should put the destination type first (just like convert, round, floor, etc..)

This also applies to floor, ceil, and round.

@timholy timholy added the dates Dates, times, and the Dates stdlib module label Aug 17, 2023
@timholy timholy added this to the 2.0 milestone Aug 17, 2023
@barucden
Copy link
Contributor

There is an discussion on this in #18574 and #34782.

@timholy
Copy link
Member Author

timholy commented Aug 17, 2023

Oh, interesting. The (valid) justification in #18574 doesn't really apply to round(Millisecond, Nanosecond(10^6+1)) because with that I'm asking to return a Millisecond quantity; convert(Millisecond, Nanosecond(10^6+1)) throws an error because it is not exact, which is exactly what round is intended to circumvent.

@timholy
Copy link
Member Author

timholy commented Aug 17, 2023

The doc strings for these operations are also all messed up. We have

round(x::Period, precision::T, [r::RoundingMode]) where T <: Union{TimePeriod, Week, Day} -> T

  Round x to the nearest multiple of precision. If x and precision are different subtypes of Period, the return
  value will have the same type as precision. By default (RoundNearestTiesUp), ties (e.g., rounding 90 minutes
  to the nearest hour) will be rounded up.

  For convenience, precision may be a type instead of a value: round(x, Dates.Hour) is a shortcut for round(x,
  Dates.Hour(1)).

  julia> round(Day(16), Week)
  2 weeks

That "for convenience..." clause is describing round(x::Period, precision::Type{T}...) where T <:... (i.e., ::Type{T} rather than ::T). And the order should be round(::Type{T}, x::Period) rather than the way it is.

@sostock
Copy link
Contributor

sostock commented Aug 17, 2023

The (valid) justification in #18574 doesn't really apply to round(Millisecond, Nanosecond(10^6+1)) because with that I'm asking to return a Millisecond quantity; convert(Millisecond, Nanosecond(10^6+1)) throws an error because it is not exact, which is exactly what round is intended to circumvent.

I think the same argument could be applied here. The second argument is not just specifying the return type but also the precision (digits), because we have

round(Nanosecond(1234567890), Millisecond) != round(Nanosecond(1234567890), Second)

@timholy
Copy link
Member Author

timholy commented Aug 17, 2023

IMO the latter should only specify the precision; the return type should still be Nanosecond. It's basically like round(x::AbstractFloat; digits=2), except it's a positional rather than keyword argument. Maybe it should really be round(::Nanosecond; precision=Second) although we'd have to check carefully whether that infers well.

@jariji
Copy link
Contributor

jariji commented Aug 17, 2023

Here too #47786

@PallHaraldsson
Copy link
Contributor

It's fixed here #47843? New correct order should be added, but is there really a reason to drop or deprecate the old order? It could be a no-inline (or not) cheap version, to not break compatibility.

[Currently DateTimes supports only one precision, plus in seconds, which is implied if no fractional part (is trunc mean to that, to state it implicitly?). It seems then you can't represent down to .000 meaning those are meaningful. It's to discuss elsewhere, and I guess more than allowing just two precision, both even finer as currently ongoing, and lesser, e.g. to the hour or to week of the year.]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
dates Dates, times, and the Dates stdlib module
Projects
None yet
Development

No branches or pull requests

5 participants