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
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())
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
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
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.
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)