Jump to content

Yet another date calculator


Recommended Posts

Date Calculator

 

Hello there!

I needed a bit of motivation to learn Python and Alfred workflows, so I thought I’d kill two horses with one bullet, so to speak.

Right, so this is a date calculator – kind of. It won’t tell you when you will the lottery, or how long you’ve got to hide your ‘arty videos’ before your wife gets home, but it will answer one or two very simple questions about dates.

 

dcalc1.png

For example, if you enter

 

dcalc 25.12.14 - 18.01.14

 

then it will tell you the number of days between those dates. Note that the workflow parses the command as you enter it, so you’ll see invalid commandinvalid expression and invalid formaterrors as you type. Once you’ve completed the command then you’ll be given the result.

You could also try

 

dcalc 25.12.14 - now

 

for the number of days until Christmas. (Always seems so far away . . .)

Maybe you don’t want it in days, but would rather it in weeks:

 

dcalc 25.12.14 - now w

 

or days and weeks

 

dcalc 25.12.14 - now wd

 

or years, months, weeks and days

 

dcalc 25.12.14 - now ymwd

 

or

 

dcalc 25.12.14 - now long

 

will do the same thing. Personally, I always use the long format because it’s more accurate.

For those who like to look ahead, you can add days to a date

 

dcalc now + 6d

 

or weeks

 

dcalc 18.12.14 + 9w

 

or combine ‘em

 

dcalc 18.12.12 + 5y 9d 3w - 2d + 1d 1w

 

What does that mess do?

  • Take the date 18.12.12 
  • Add 5 years
  • Add another 9 days
  • Add another 3 weeks
  • Then take off 2 days
  • Add another 1 day
  • And then add another 1 week

If you want to know what week number you’re in, then try this:

 

dcalc today wn

 

Or for a specific date:

 

dcalc 25.12.14 wn

 

You can also use the today thing in other places too:

 

dcalc today + 4d

 

And we have another thing called time because the workflow can handle times too:

 

dcalc time + 6h 8M

 

will add 6 hours and 8 minutes to the current time. Note the capital ‘M’ to denote minutes. Odd, I know . . . sorry, but the workflow has to distinguish between this and a small ‘m’ (for months). I figured make this one a capital because it would see much less use. (It has for me.)

If you just want the current time, then just enter

 

dcalc time

 

Here’s another time calculation

 

dcalc 14:35 + 6h

 

That’s the time 6 hours from now, and for real nerdiness:

 

dcalc 21.06.14@14:20 - 23.01.12@09:21 long

 

Probably not all that useful, but some of this other stuff might be. You know all about

 

dcalc now

 

For giving you the current time and date. While you can use 

 

dcalc tomorrow

 

for tomorrow’s date, and as you would expect

 

dcalc tomorrow + 1d

 

will give you the day after tomorrow.

 

dcalc next tue

 

will give you the date next Tuesday. Or for for Thursday you could enter

 

dcalc next tue + 2d

if you’re still a little too inebriated to realise that

 

dcalc next thu

 

will give you the same answer.

That about covers it, I think. I haven’t done anything clever with locales, but you can pick a different date format with

 

dcalcset date format

 

And we also support both 12-hour and 24-hour time formats. 

 

dcalcset time format

 

I would recommend sticking with the 24-hour format; it's a lot easier to type because the AM/PM symbols have to be in upper case.

You can also set the combined date and time format using:

 

dcalcset date and time format

 

If you’re ever puzzled by invalid command or invalid expression errors, then start with the settings; they might be set incorrectly.

Oh, almost forgot.

 

dcalc easter

 

Is the date for next Easter Sunday, for no other reason that I can never remember it, and now there’s an easy way to find out how many days until Christmas:

 

dcalc today - christmas

 

And to celebrate finishing my new book, I decided to add:

dcalc passover

 

Alternative parser

If surround a simple expression in double quotes, then something quite magical happens:

 

dcalc "4 hours 8 minutes after 4pm"

 

or

 

dcalc "6 weeks and 4 days after next wednesday"

 

or

 

dcalc "1 day after tomorrow"

 

Yup! A natural date language parser! 

You can even combine it with the existing parser:

 

dcalc "next friday" + 1d

 

This is a little bit experimental (I might drop it later if it proves to be problematic), but I thought I'd throw it in for a bit of a fun.

 

 

Credits

A list of things that made my first attempt at Python programming possible:

  • Dean Jackson for his more-than-slightly awesome Alfred Workflow framework(Jetbrains(HumanFriendly(Python-DateUtil(PyPEG(ParseDateTime(Programming Praxis(MIT(http://opensource.org/licenses/MIT) one will do. :-)

    The MIT License (MIT)

    Copyright © 2014 MuppetGate Media

    Permission is hereby granted, free of charge, to any person obtaining a copy

    of this software and associated documentation files (the "Software"), to deal

    in the Software without restriction, including without limitation the rights

    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell

    copies of the Software, and to permit persons to whom the Software is

    furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included in

    all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

    FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE

    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,

    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Edited by MuppetGate
Link to comment

It's child's play compared to the rest of the workflow. Very impressive stuff!

 

You just need to change the Keyword to a Script Filter and use wf.add_item() and wf.send_feedback() instead of print().

 

Here's the hacky wrapper I made to turn it into a Script Filter. Lines 26, 28 and 31 are the important bits, the rest is just boilerplate:

from __future__ import print_function, unicode_literals

import sys
from StringIO import StringIO

from workflow import Workflow, ICON_ERROR

from date_calculator import main as other_main
from date_format_mappings import DEFAULT_WORKFLOW_SETTINGS


def main(wf):
    # Replace sys.stdout to capture the script output
    stdout_orig = sys.stdout
    sys.stdout = StringIO()
    # Run the script and grab the output
    other_main(wf)
    result = sys.stdout.getvalue()
    # Put sys.stdout back together again, so wf.send_feedback() sends its
    # output to the right place
    sys.stdout.close()
    sys.stdout = stdout_orig

    # Add error/output to list of results
    if result.startswith('Invalid '):
        wf.add_item(result, valid=False, icon=ICON_ERROR)
    else:
        wf.add_item(result, 'Copy to clipboard', valid=True, arg=result)

    # Send XML output to Alfred
    wf.send_feedback()


if __name__ == '__main__':
    wf = Workflow(default_settings=DEFAULT_WORKFLOW_SETTINGS)
    sys.exit(wf.run(main))
Here's how to make a Script Filter with Alfred-Workflow (you should probably skip straight to the section on Actions), and here are the docs on add_item().

 

You need to set a value for arg and valid=True in add_item() to make a result actionable.

 

I just used one of the system icons supported by Alfred-Workflow for the error message.

Edited by deanishe
Fix URLs
Link to comment

Nice.  

 

I've made a couple modifications you might consider:

 

I added one line to the DATE_MAPPINGS array in date_format_mappings.py - very clear code that was easy to customize:

 

   
 'yyyy-mm-dd':{'name': 'long inverted US date (-)','date-format':'%Y-%m-%d','regex':'\d{4}-\d{2}-\d{2}'},
 
I added an additional Applescript output from the dcalc script filter with a shift modifier to open Fantastical to the calculated date, with the following very simple script:
 
on alfred_script(q)
  	tell application "Fantastical"
		parse sentence (q)
	end tell
end alfred_script

This makes for a nice quick way to quickly calculate a date and immediately start adding an event or checking what's on my calendar for that date.

 

 

Link to comment

Good thinking, dfay!

 

Especially sending it to Fantastical. I think Apple Calendar can handle simpler dates, too, but I'm not sure.

 

One minor gripe: yyyy-mm-dd is an international date format, not a US one.

 

Everyone uses it.

Link to comment

 

Nice.  

 

I've made a couple modifications you might consider:

 

I added one line to the DATE_MAPPINGS array in date_format_mappings.py - very clear code that was easy to customize:

 

   
 'yyyy-mm-dd':{'name': 'long inverted US date (-)','date-format':'%Y-%m-%d','regex':'\d{4}-\d{2}-\d{2}'},
 
I added an additional Applescript output from the dcalc script filter with a shift modifier to open Fantastical to the calculated date, with the following very simple script:
 
on alfred_script(q)
  	tell application "Fantastical"
		parse sentence (q)
	end tell
end alfred_script

This makes for a nice quick way to quickly calculate a date and immediately start adding an event or checking what's on my calendar for that date.

 

 

 

 

Thanks very much for that.

 

I'll add in the date format (not sure how I managed to miss it to be honest).

 

I figure that any additional outputs should be pretty easy for anyone to add; that's why I decided to keep the extra text down to a minimum, and tried to make it easy to parse. But a great suggestion, and I'm going to try out Fantastical.

Link to comment

:D

 

It doesn't work for me :(

 

I followed the instructions above, but "dcalcset list add dean xx-xx-xxxx" give me an "Invalid command" error :(

 

"dcalcset format" now appears to be an unknown command :(

 

You also appear to have removed the download link from the OP. It's got links to all the stuff you used to make the workflow (apart from Smirnoff), but there doesn't appear to be one to the actual workflow any more!

Link to comment

:D

 

It doesn't work for me :(

 

I followed the instructions above, but "dcalcset list add dean xx-xx-xxxx" give me an "Invalid command" error :(

 

"dcalcset format" now appears to be an unknown command :(

 

You also appear to have removed the download link from the OP. It's got links to all the stuff you used to make the workflow (apart from Smirnoff), but there doesn't appear to be one to the actual workflow any more!

 

Okay, I imagine you're entering in the correct date format. 

 

The dcalcset format seems to be okay at my end too.

 

I'll try loading it from packal to make sure I haven't missed anything.

 

Are you running with Python 2.7?

Edited by MuppetGate
Link to comment

Yeah, double-checked the format, deleted the settings file and re-installed before posting.

I'm on Mavericks, so Python 2.7.

FWIW, python will always refer to the system Python in Alfred, as it doesn't use your PATH. Unless someone was dumb enough to overwrite /usr/bin/python

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...