Skip to content

Commit

Permalink
Merge pull request #12 from mistermichaelll/add-week-to-floor-date
Browse files Browse the repository at this point in the history
#11: add "week" as a unit for `floor_date`
  • Loading branch information
drizk1 authored Jul 26, 2024
2 parents 2f6cdfb + 6fc5830 commit a152c24
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 24 deletions.
29 changes: 16 additions & 13 deletions src/TidierDates.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ include("datedocstrings.jl")
export mdy, mdy_hms, dmy, dmy_hms, ymd, ymd_hms, hms, difftime, floor_date, round_date, now, today, am, pm, leap_year, days_in_month
### Functions below include:
### mdy()
### mdy_hms()
### mdy_hms()
### dmy()
### dmy_hms()
### ymd()
### ymd_hms()
### hms()
### ymd_hms()
### hms()
### difftime() (returns answer in seconds, minutes, hours or days)
### floor_date() (only supports hour, minute, day, month, year).
### round_date() (only supports hour, minute, day (not really viable until YMDHMS exists), month, year).
Expand Down Expand Up @@ -68,7 +68,7 @@ function mdy(date_string::Union{AbstractString, Missing})
year = parse(Int, year_str)
return Date(year, month, day)
end

# Add new regex match for "m/d/y" and "m-d-y" formats
m = match(r"(\d{1,2})[/-](\d{1,2})[/-](\d{4})", date_string)
if m !== nothing
Expand Down Expand Up @@ -136,7 +136,7 @@ function dmy(date_string::Union{AbstractString, Missing})
year = parse(Int, year_str)
return Date(year, month, day)
end

return nothing
end

Expand All @@ -157,7 +157,7 @@ function ymd(date_string::Union{AbstractString, Missing})
day = parse(Int, day_str)
return Date(year, month, day)
end

# Try "yyyy/mm/dd" and "yyyy-mm-dd" formats
m = match(r"(\d{4})[/-](\d{1,2})[/-](\d{1,2})", date_string)
if m !== nothing
Expand All @@ -179,7 +179,7 @@ function ymd(date_string::Union{AbstractString, Missing})
day = parse(Int, day_str)
return Date(year, month, day)
end

return nothing
end

Expand Down Expand Up @@ -220,14 +220,17 @@ function floor_date(dt::Union{DateTime, Missing}, unit::String)
return DateTime(year(dt))
elseif unit == "month"
return DateTime(year(dt), month(dt))
elseif unit == "week"
start_of_week = firstdayofweek(dt) - Day(1)
return DateTime(year(start_of_week), month(start_of_week), day(start_of_week))
elseif unit == "day"
return DateTime(year(dt), month(dt), day(dt))
elseif unit == "hour"
return DateTime(year(dt), month(dt), day(dt), hour(dt))
elseif unit == "minute"
return DateTime(year(dt), month(dt), day(dt), hour(dt), minute(dt))
else
throw(ArgumentError("Unit must be one of 'year', 'month', 'day', 'hour', or 'minute'."))
throw(ArgumentError("Unit must be one of 'year', 'month', 'week', 'day', 'hour', or 'minute'."))
end
end

Expand All @@ -242,7 +245,7 @@ function round_date(dt::Union{DateTime, Date, Time, Missing}, unit::String)
if ismissing(dt)
return missing
end

if dt isa DateTime || dt isa Date
if unit == "year"
return month(dt) > 6 || (month(dt) == 6 && day(dt) > 15) ? Date(year(dt) + 1) : Date(year(dt))
Expand Down Expand Up @@ -286,7 +289,7 @@ function ymd_hms(datetime_string::Union{AbstractString, Missing})
end
# Extract year, month, day, hour, minute, and second using a flexible regular expression
m = match(r"(\d{4}).*?(\d{1,2}).*?(\d{1,2}).*?(\d{1,2}).*?(\d{1,2}).*?(\d{1,2})", datetime_string)

if m !== nothing
year_str, month_str, day_str, hour_str, minute_str, second_str = m.captures
year = parse(Int, year_str)
Expand All @@ -313,7 +316,7 @@ function dmy_hms(datetime_string::Union{AbstractString, Missing})
if ismissing(datetime_string)
return missing
end

# Extract day, month, year, hour, minute, and second using a flexible regular expression
m = match(r"(\d{1,2}).*?(\d{1,2}).*?(\d{4}).*?(\d{1,2}).*?(\d{1,2}).*?(\d{1,2})", datetime_string)

Expand Down Expand Up @@ -346,7 +349,7 @@ function mdy_hms(datetime_string::Union{AbstractString, Missing})

# Extract year, month, day, hour, minute, and second using a flexible regular expression
m = match(r"(\d{1,2}).*?(\d{1,2}).*?(\d{4}).*?(\d{1,2}).*?(\d{1,2}).*?(\d{1,2})", datetime_string)

if m !== nothing
month_str, day_str, year_str, hour_str, minute_str, second_str = m.captures
year = parse(Int, year_str)
Expand Down Expand Up @@ -374,7 +377,7 @@ function difftime(time1::Union{DateTime, Missing}, time2::Union{DateTime, Missin
if ismissing(time1) | ismissing(time2)
return missing
end

# Calculate the difference
diff = time1 - time2

Expand Down
27 changes: 16 additions & 11 deletions src/datedocstrings.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const docstring_mdy =
const docstring_mdy =
"""
mdy(date_string::Union{AbstractString, Missing})
Expand Down Expand Up @@ -27,7 +27,7 @@ missing
```
"""

const docstring_dmy =
const docstring_dmy =
"""
dmy(date_string::Union{AbstractString, Missing})
Expand Down Expand Up @@ -61,7 +61,7 @@ missing
```
"""

const docstring_ymd =
const docstring_ymd =
"""
ymd(date_string::Union{AbstractString, Missing})
Expand Down Expand Up @@ -90,7 +90,7 @@ missing
"""


const docstring_hms =
const docstring_hms =
"""
hms(time_string::Union{String, Missing})
Expand All @@ -110,19 +110,21 @@ missing
```
"""

const docstring_floor_date =
const docstring_floor_date =
"""
floor_date(dt::Union{DateTime, Missing}, unit::String)
Round down a DateTime object to the nearest specified unit.
# Arguments
`dt`: A DateTime object (can contain missing values in a DataFrame).
`unit`: A string specifying the units to use for rounding down. The units can be one of the following: "year", "month", "day", "hour", "minute".
`unit`: A string specifying the units to use for rounding down. The units can be one of the following: "year", "month", "week", "day", "hour", "minute".
# Returns
The DateTime object rounded down to the nearest specified unit. If the input is missing, the function returns a missing value.
When using the "week" unit, Sunday is considered the first day of the week.
# Examples
```jldoctest
julia> dt = DateTime(2023, 6, 15, 9, 45)
Expand All @@ -134,12 +136,15 @@ julia> floor_date(dt, "hour")
julia> floor_date(dt, "day")
2023-06-15T00:00:00
julia> floor_date(dt, "week")
2023-06-11T00:00:00
julia> floor_date(missing, "day")
missing
```
"""

const docstring_round_date =
const docstring_round_date =
"""
round_date(dt::Union{DateTime, Date, Time, Missing}, unit::String)
Expand Down Expand Up @@ -168,7 +173,7 @@ missing
```
"""

const docstring_ymd_hms =
const docstring_ymd_hms =
"""
ymd_hms(datetime_string::Union{AbstractString, Missing})
Expand All @@ -194,7 +199,7 @@ missing
```
"""

const docstring_mdy_hms =
const docstring_mdy_hms =
"""
mdy_hms(datetime_string::Union{AbstractString, Missing})
Expand Down Expand Up @@ -247,7 +252,7 @@ missing
```
"""

const docstring_difftime =
const docstring_difftime =
"""
difftime(time1::Union{DateTime, Missing}, time2::Union{DateTime, Missing}, units::AbstractString)
Expand Down Expand Up @@ -403,4 +408,4 @@ julia> days_in_month(Date(2016, 2, 3))
29
```
"""
"""

0 comments on commit a152c24

Please sign in to comment.