CoffeeScript Experiments: Magic Date
by Vijay Kiran
I started learning CoffeeScript recently and wanted to get my hands dirty. Here’s the first experiment.
########################################################################################## # Magic Date # # Author: Vijay Kiran<mail@vijaykiran.com> # # Allows conversion of natural date string to real date object. # e.g. tomorrow, today, 2w etc. # # # Implementation is shame-lessly based on MagicDate in Python. ########################################################################################## ## Requirements/Specs ## ## ## # # One liner - should work like OmniFocus date field ## # # Details: # • 2d, -3w, 1h, 1y1m, and so on — Relative dates and times put the date at # a certain amount of time from right now. Negative numbers represent times in the past. # # • 2 days, -3 weeks, 1 hour, 1 year 1 month, and so on — # You can use the full names of units too. # # • yesterday, tomorrow, next thursday, last month, this friday, and so on — # You can refer to relative dates using common words. # “This”, “next”, and “last” have specific meanings: this friday always means # the Friday in this week, next friday always means # the Friday in the next week, and last friday always means # the Friday in last week, regardless of what day today is. # Other units work in the same way. # # • september, thurs, 2019, and so on — If you enter the name of a specific time period, # the date will be at its beginning. So september means September first. # # • 5/23/08 10a, 9.30.09 2:00 PM, and so on — You can use the short date format as # defined in your International system preferences. # # • 2w sat, 4d @ 5p, tues 6a, aug 6 tues 5p, and so on — # Mix the available formats however you like. # # • now, 9, 14:00, tom, and so on — OmniFocus makes its best guess # at things like bare numbers, times, and word fragments. # If you think something might work, give it a try. weekdays = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'] magicDate = (str) -> d = new Date regs = [ # Today [ /^tod/i, Date ], # Tomorrow [ /^tom/i, -> d.setDate(d.getDate() + 1) ; d ], # Now [ /^now/i, Date], # Yesterday [ /^yes/i, -> d.setDate(d.getDate() - 1) ; d ], [ /^(last|next|this)\s(week)/, (result) -> switch result[1].toLowerCase() when "last" then d.setDate(d.getDate() - 7) when "this" then d.setDate(d.getDate() + 1) when "next" then d.setDate(d.getDate() + 7) d ], # <last> <this>/<next> <weekday> [ /^(last|this|next)\s(\S+)/i, (result) -> rel = result[1].toLowerCase() weekday = result[2].toLowerCase() today = d.getDay() # Pick index + 1 because getDay is 1 = Monday, 2 = Tuesday and so on index = (i + 1 for item, i in weekdays when new RegExp(weekday).test(item)) switch result[1].toLowerCase() when "last" then d.setDate(d.getDate() - (today - index + (if (index < today ) then 0 else 7)) ) when "this" then d.setDate(d.getDate() + index - today) when "next" then d.setDate(d.getDate() + index + today - 1 ) d ] ] # for x in regs re = x[0] fn = x[1] if re.test str then return fn(str.match re) |
And here’s how you can use it:
testStrings = [ "yes", "yesterda", "Yes", "ye", "-" "tod", "todd", "today", "TodaY", "-" "now", "nowww", "Now", "ANDNOW","-" "tom", "tomorrow", "Tomorrow", "to", "-" "last mon", "last tuesday", "last wed", "last thurs", "last fri", "last sat" , "LAst Sunda", "-" "last week", "tHIS Week", "next week", "-" "this mon", "this tuesday", "this weDNE", "this thursday", "THIS FRIDAY", "this sat", "this sun", "-" "next mon", "NExt tue", "nex wednesday", "next thursday", "Next Friday", "Next Satur", "next sun", "-"] for str in testStrings if str is "-" console.log "---------------------------------------------------" else console.log "#{str} = #{magicDate str}" |
