Create list of dates from start/end date in Haskell - date

Starting from the following date range:
startDate = "2020-01-01"
endDate = "2021-01-01"
What would be the most appropriate way to create a list of dates, say, weekly, from start to end?
result = ["2020-01-01", "2020-01-08", "2020-01-15", "2020-01-22"] -- and so on until 2021-01-01

import Data.Time.Calendar
main :: IO ()
main = print [fromGregorian 2020 1 1, fromGregorian 2020 1 8 .. fromGregorian 2021 1 1]
[2020-01-01,2020-01-08,2020-01-15,2020-01-22,2020-01-29,2020-02-05,2020-02-12,2020-02-19,2020-02-26,2020-03-04,2020-03-11,2020-03-18,2020-03-25,2020-04-01,2020-04-08,2020-04-15,2020-04-22,2020-04-29,2020-05-06,2020-05-13,2020-05-20,2020-05-27,2020-06-03,2020-06-10,2020-06-17,2020-06-24,2020-07-01,2020-07-08,2020-07-15,2020-07-22,2020-07-29,2020-08-05,2020-08-12,2020-08-19,2020-08-26,2020-09-02,2020-09-09,2020-09-16,2020-09-23,2020-09-30,2020-10-07,2020-10-14,2020-10-21,2020-10-28,2020-11-04,2020-11-11,2020-11-18,2020-11-25,2020-12-02,2020-12-09,2020-12-16,2020-12-23,2020-12-30]
[I'm not really a fan of this Show instance BTW, as that's totally not sensible Haskell code...]

you can use (fromGregonorianValid,addDays) from Data.Time.Calendar
import Data.Time.Calendar
import Data.Time
getDates :: String -> String -> [String]
getDates from to
| null jdateFrom || null jdateTo = error "error in dates"
| otherwise = map show [dateFrom,addDays 7 dateFrom..dateTo]
where
jdateFrom = getDate from
jdateTo = getDate to
(Just dateFrom) = getDate from
(Just dateTo) = getDate to
getDate dateStr = parseTimeM True defaultTimeLocale "%Y-%-m-%-d" dateStr :: Maybe Day
> getDates "2020-01-01" "2021-01-01"
["2020-01-01","2020-01-08","2020-01-15","2020-01-22","2020-01-29","2020-02-05","2020-02-12","2020-02-19","2020-02-26","2020-03-04","2020-03-11","2020-03-18","2020-03-25","2020-04-01","2020-04-08","2020-04-15","2020-04-22","2020-04-29","2020-05-06","2020-05-13","2020-05-20","2020-05-27","2020-06-03","2020-06-10","2020-06-17","2020-06-24","2020-07-01","2020-07-08","2020-07-15","2020-07-22","2020-07-29","2020-08-05","2020-08-12","2020-08-19","2020-08-26","2020-09-02","2020-09-09","2020-09-16","2020-09-23","2020-09-30","2020-10-07","2020-10-14","2020-10-21","2020-10-28","2020-11-04","2020-11-11","2020-11-18","2020-11-25","2020-12-02","2020-12-09","2020-12-16","2020-12-23","2020-12-30"]

Related

Convert a date string with different formatting's and month abbreviation in Dutch using to_date in PySpark

I need to convert a date string to a DateType, but I've several challenges using to_date.
Formatting for day works well (1 or 2 digits), month is a Dutch abbreviation and doesn't work (works only if the abbreviation is equal to English), and year is 2 or 4 digits (missing centuries!).
What's the best way to convert these all to a DateType?
I couldn't find an option to set locale to NL using the formatting.
I created an UDF, but don't know if this is the best way to fix this.
The 19 for century is debatable.
Code:
#F.udf(T.StringType())
def convert_date(s):
month_dict = {"jan":"01", "feb":"02", "mrt":"03", "apr":"04", "mei":"05", "jun":"06", "jul":"07", "aug":"08", "sep":"09", "okt":"10", "nov":"11", "dec":"12" }
day, month, year = s.split("-")
if len(day) == 1:
day = '0' + day
if len(year) < 4:
year = '19' + year
date = day + "-" + month_dict[month] + "-" + year
return date
df = df.withColumn('DateOfBirth_new', F.to_date(convert_date(F.col("DateOfBirth"), "dd-M-yyyy"))
DateFrame:
df = spark.createDataFrame([
["2-feb-1966"],
["05-mei-1974"],
["3-mrt-83"],
["05-mrt-1983"],
["12-jun-75"]
]).toDF("DateOfBirth")
Here is a similar solution without a UDF, using a when expression for the month conversion.
month_conversion = F.expr("""CASE
WHEN (month = 'jan') THEN 01
WHEN (month = 'feb') THEN 02
WHEN (month = 'mrt') THEN 03
WHEN (month = 'apr') THEN 04
WHEN (month = 'mei') THEN 05
WHEN (month = 'jun') THEN 06
WHEN (month = 'jul') THEN 07
WHEN (month = 'aug') THEN 08
WHEN (month = 'sep') THEN 09
WHEN (month = 'okt') THEN 10
WHEN (month = 'nov') THEN 11
WHEN (month = 'dec') THEN 12
ELSE NULL END
""").alias("m")
day_conversion = F.when(F.length("day") == 1, F.concat(F.lit("0"), F.col("day"))).otherwise(F.col("day"))
year_conversion = F.when(F.length("year") < 4, F.concat(F.lit("19"), F.col("year"))).otherwise(F.col("year"))
(df.withColumn("split",
F.split("DateOfBirth", "-")
)
.withColumn("day",
F.col("split").getItem(0)
)
.withColumn("month",
F.col("split").getItem(1)
)
.withColumn("year",
F.col("split").getItem(2)
)
.select(
F.concat_ws("-",
day_conversion,
month_conversion,
year_conversion
).alias("DateOfBirth_new")
)
.show())

How to convert and check date with different format in Groovy

In my groovy code, I have 2 Dates
def date1 = "2021-08-02T03:22:12Z"
dev date2 = new Date()
my goal is, if date1 is 5 days older than date2 return true.,
date2 looks like that Thu Aug 05 10:13:56 UTC 2021
but How to convert 2 dates with right date format before comparing?
any solutions?
def date1 = Date.parse("yyyy-MM-dd'T'HH:mm:ss","2021-08-02T03:22:12Z")
def date2 = new Date()
def daysDiff = date2-date1
println daysDiff

Parse a user input string into Day type and subtract two dates in Haskell

I'm new to Haskell and I need some help. I will like to create a function that takes in a user's input in the format yyyy, mm, dd and convert it to type Day in order to use diffDays.
This is what I tried:
today :: IO (Integer, Int, Int)
today = getCurrentTime >>= return . toGregorian . utctDay
getDiffDays' :: IO Integer
getDiffDays' = do
putStr "What is your birthdate (year, month, day)?: "
dateOfBirth <- getLine
let dob = read dateOfBirth :: Day
return diffDays today dob
I think you want something below,
import Data.Time.Calender
import Data.List (intercalate)
replace :: String -> String
replace src = intercalate "-" $ words $ filter (/= ',') src
main :: IO ()
main = do
-- Example input: 2018, 11, 12
dayString <- getLine
let day = read (replace dayString) :: Day
-- Example output: 2018-11-12
print day
the problem was that Day expect to read of format YYYY-MM-DD but YYYY, MM, DD

Check if Day is Saturday or Sunday

I'm looking to do a difference between 2 date in scala. These 2 date are should not saturday not sunday.
I did a scala function to test if the day if Saturday or Sunday:
I edited my question, this is my code to test if a day is saturday or sunday.
I should use it using tow dates : start_date and finish_date, because after this operation I'll do the difference between these tow dates.
My function jourouvree took one parameter, not a dates.
How can I modify my code to pass the tow dates.
Check if Day is Saturday or Sunday:
import java.time.{LocalDate, DayOfWeek}
def isWeekend(day: LocalDate) =
day.getDayOfWeek == DayOfWeek.SATURDAY ||
day.getDayOfWeek == DayOfWeek.SUNDAY
Using Java 8 datetime api:
import java.time._
import java.time.format.DateTimeFormatter
val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
//Assume d2,d2 themselves are not weekend days
def jourOuvree(sd1:String, sd2:String): Unit = {
val d1 = LocalDateTime.parse(sd1, formatter)
val d2 = LocalDateTime.parse(sd2, formatter)
//return if d1 is not earlier than d2. TODO: handle what to be done
if(d2.isAfter(d1) == false) return
var (days, dayCtr) = (1, 1)
while(d1.plusDays(dayCtr).isBefore(d2)){
dayCtr+=1
val dow = d1.plusDays(dayCtr).getDayOfWeek()
if(!dow.equals(DayOfWeek.SATURDAY) && !dow.equals(DayOfWeek.SUNDAY))
days+=1
}
println(days)
}
Invoke as below:
jourOuvree("2011-03-31 07:55:00", "2011-04-06 15:41:00")
You get 5 printed.
NOTE: The code doesn't handle exceptions in parsing.
Also, there may be other requirement fine points, for which you are the best judge to make required changes.

current year and quantity days in month

I have two questions:
How can I get current year (not date) in haskell ?
How can I get quantity days in some month some year ? For example 04.2011 has got 30 days.
This will give you the year, month and day:
import Data.Time.Clock
import Data.Time.Calendar
date :: IO (Integer,Int,Int) -- :: (year,month,day)
date = getCurrentTime >>= return . toGregorian . utctDay
Source: http://www.haskell.org/haskellwiki/Date
There's a function in Date.Time.Calendar called gregorianMonthLength with type Integer -> Int -> Int.
It takes a year and a month as arguments, returns the number of days, just like you need.
http://www.haskell.org/ghc/docs/7.0.2/html/libraries/time-1.2.0.3/Data-Time-Calendar.html
A full example:
import Data.Time.Clock
import Data.Time.Calendar
date :: IO (Integer,Int,Int) -- :: (year,month,day)
date = getCurrentTime >>= return . toGregorian . utctDay
main = do
(year, month, day) <- date
putStrLn $ "Days in this month: " ++ (show $ gregorianMonthLength year month)