Specifying a duration as a command line parameter - command-line

I'm writing up a command line utility that needs to take a duration parameter. Now my challenge is that the duration can span anywhere from minutes to months.
I had considered using just seconds, but passing in large numbers of seconds to communicate 1 month seemed unwieldy.
Are there any generally accepted ways of passing in a duration with such a high range?

The gnu date command does a very good job of this.
http://www.gnu.org/software/coreutils/manual/html_node/Examples-of-date.html
There is a ruby library with C code that parses these kinds of time specifications.
https://github.com/bbense/ruby-getdate
This one also seems very interesting
https://github.com/mojombo/chronic
Another convention that I've seen in more than one program is to use a letter qualifier after the number to indicate units other than seconds.
2m ( 2 minutes )
2h ( 2 hours )
2d ( 2 days )
2M ( 2 months )

'at' and 'find' both have similar options.
find uses two different options like -ctime and -cmin to take days and minutes respectively.
at will take many different forms (may have useful code you could copy) such as:
at now + 1 month
at 8am monday
Those are the two command line utilities that come to mind immediately.

Related

How to find second last value in Answer Set Programming (ASP Clingo)

I'm modelling a university curriculum timetable with Answer Set Programming (Clingo). The requirements are that each lesson must be asssigned to a specific week , day and start /end hours until the total hours are reached.
In a day there are max 8 hours and each lesson is 2 hours minimum. Also the scheduled lessons are until the 10th week.
week(1..10). time(9,11;11,13;14,16;16,18).
So first I generated each assigned lesson slot
TotalHours { assigned(Week,Day,Start,End,Course,Teacher) : day(Day), time(Start,End), week(Week) } TotalHours :-
lesson(Course,Teacher,TotalHours).
After that for other requirements and rules I needed to find the last course assigned in the timetable. I don't know if this is a good way but I was able to find a solution
MaxWeek = #max {Week : assigned(Week,_,_,_,Course,_)},
MaxDay = #max {Day : assigned(MaxWeek,Day,_,_,Course,_)},
MaxStart= #max {Start : assigned(MaxWeek,MaxDay,Start,_,Course,_)},
assigned(_,_,_,_,Course,_).
I'm new to ASP and so far I couldn't find a good way to find the second last lesson of the course assigned in the timetable(Week,Day,Start,End) needed for other schedule requirements.
So given for example
assigned(1,Monday,9,11,History,John) , assigned(1,Tuesday,11,13,Math,Smith), assigned(4,Tuesday,16,18,History,John),assigned(5,Monday,11,13,History,John)
I want to find the second last lesson of History which is
assigned(4,Tuesday,16,18)
Any tips or solutions is really appreciated
Consider having a second assigned predicate (with a different arity) to be something more absolute, like:
assigned((Week-1)*7*24+Day+Start,End,Course,Teacher) :- assigned(Week,Day,Start,End,Course,Teacher).
Now you just have one field that is completely ordered over all assignments, which is total hours since start of the year.
To find the last courses, the last aggregate performs very badly, and can be optimized using chaining constraints:
auxLastCourse(C,T) :- assigned(T,_,C,_).
auxLastCourse(C,T-1) :- auxLastCourse(C,T), T > 0.
lastCourse(C,T) :- auxLastCourse(C,T), not auxLastCourse(C,T+1).
Also note that in your example aren't any courses during the night, so this could be optimized further by not beeing so finegranular and explicitly representing every hour, but maybe only hours that actually occur in a possible schedule. THis would mean replacing the T-1 in the aux code with an explicit next relation over weeks and days and hours. Currently I'm just too lazy to add something like this.
For the second last course you can do exactly the same thing:
auxSecondLastCourse(C,T) :- assigned(T,_,C,_), not lastCourse(C,T).
auxSecondLastCourse(C,T-1) :- auxSecondLastCourse(C,T), T > 0.
secondLastCourse(C,T) :- auxSecondLastCourse(C,T), not auxSecondLastCourse(C,T+1).
PS: Note that I assume that your days are given as numbers 0..6, and not as words as in your example, I'm sure you will figure out how to translate them using another predicate.
PPS: I haven't tested the code, as you did'nt provide an MWE.

Determine number of days represented by a time range in Java

Using Java 8 time I am simply trying to figure out the number of days represented in a time range. Consider the following:
LocalDate start = LocalDate.of(2016, Month.MARCH, 28);
LocalDate end = LocalDate.of(2016, Month.MARCH, 31);
Period period = Period.between(start, end);
The number of days in period is 3 which represents the number of days between the 2 dates, inclusive of start and exclusive of end. What I want is the number of days represented by the 2 dates which is actually 4 (March 28, March 29, March 30, March 31).
I know I can just add 1 to the number of days returned from Period.between() but I guess I was surprised that I couldn't find another call to return exactly what I want. Am I missing something or is adding 1 the only solution?
tl;dr
Always define your spans of time by the Half-Open approach where:
Beginning is inclusive.
Ending is exclusive.
When you want the four days of March 28, March 29, March 30, March 31, make the beginning March 28 and the ending April 1. Run through those dates starting at the first (March 28th) while going up to, but not including, the last (April 1st).
2016-03-28/2016-04-01
Half-Open
Am I missing something
You may be missing an appreciation for the usefulness of the Half-Open approach in defining spans of time.
Generally, the best practice for defining spans of time is the Half-Open approach. In Half-Open, the beginning is inclusive while the ending is exclusive.
This approach solves the problem of dealing with fractional seconds. Intuitively, many programmers will try to find the last possible moment as the ending of a span of time. But that last moment involves an infinitely divisible last second. You might think, "Well, just go to three decimal place for milliseconds, 12:59.59.999 for the end of noon lunch break, as that is all the resolution I will ever need, and that is the resolution of the legacy java.util.Date class.”. But then you would fail to find matches in your database like Postgres that store date-time values with a resolution of microseconds, 12:59:59.999999. So you decide to use six decimal places of fraction, x.999999. But the start experiencing mismatches with date-time values in the java.time classes, and you learn the offer a resolution of nanoseconds for nine digits of fractional second, x.999999999. You can disembark this carousel of frustrating bugs by using the Half-Open approach where the ending runs up to, but does not include, the next whole second.
I believe you will find consistent use of the Half-Open approach throughout your date-time handling code (whether fractional seconds may be involved or not) will:
Make your code easier to read and comprehend.
Ease the cognitive load overall.Knowing all your spans of time carry the same definition eliminates ambiguity.
Reduce bugs.
Examples:
A noon lunch period starts at the moment the clock strikes noon (12:00:00) and runs up to, but does not include, the moment when the clock strikes one o’clock. That means 12:00:00 to 13:00:00.
A full day starts at the first moment of the day (not always 00:00:00, by the way) and runs up to, but does not include, the first moment of the following day.
A week starts on a Monday and runs up to, but does not include, the following Monday. That means seven days in Monday-Monday.
A month starts of the first of the month and runs up to, but not including, the first of the following month. So the month of March is March 1 to April 1.
LocalDate
Rather than one adding 1 to get a total of days, define your span of time as Half-Open: beginning-is-inclusive, ending-is-exclusive. If you are trying to represent the four dates of March 28, 29, 30, and 31, then I suggest you define a span of time from March 28 to April 1.
LocalDate start = LocalDate.of( 2016, Month.MARCH, 28 ) ; // inclusive
LocalDate stop = LocalDate.of( 2016, Month.APRIL, 1 ) ; // exclusive
Period
The java.time classes wisely use the Half-Open approach. So the Period.between method treats the ending as exclusive, as noted in the Question. I suggest you go-with-the-flow here rather than fight it. Search Stack Overflow for many more examples of how well this approach works.
Period p = Period.between( start , stop );
p.toString(): P4D
ChronoUnit
If you want a total number of days, such as 45 for a month and a half, use the ChronoUnit enum, an implementation of TemporalUnit. See this Question for discussion.
Again, the java.time classes use the Half-Open approach. So
long daysBetween = ChronoUnit.DAYS.between( start, stop );
4
Live code
See this example code run live at IdeOne.com.
There doesn't seem to be an inclusive end date method in either Period or LocalDate so it seems that the only thing to do is something like:
Period.between(start, end.plusDays(1))
or
start.until(end.plusDays(1))
(Period.between just calls LocalDate.until)
I belive your day counting differs from java's. Period.between according to documentation: http://docs.oracle.com/javase/8/docs/api/java/time/Period.html#between-java.time.LocalDate-java.time.LocalDate-
"The start date is included, but the end date is not." Having that in mind - yes, adding 1 is the only solution.
the signature of the method is
between(LocalDate startDateInclusive, LocalDate endDateExclusive) {
and the method is not oerloaded, you have no choice other than add 1 to the given result...

Configure sp_add_schedule to run on the first day of every X months/weeks

I need to configure my jobs scheduling dynamically.
The jobs will always run on the first day of the week once every X weeks. Same for months.
Looking at the documentation,
I see that for weeks option I would need to use freq_type=8 (weekly) with freq_interval=1 (Sunday). But which parameter should be used to mark that the repetition should be once every X weeks?
You should set freq_recurrence_factor = X

How to tweak the SET intervalstyle (change the Interval Output) in PostgreSQL?

I have read in this online PostgreSQL documentation... http://www.postgresql.org/docs/9.4/static/datatype-datetime.html#INTERVAL-STYLE-OUTPUT-TABLE
in the point 8.5.5 something about how to tweak the default Interval Output. . I mean the default interval is shown like this...
00:00:00.000 (if the timedifference is lower than a day or month or year)
1 day 00:00:00.000 (if the timedifference reaches days, but is lower than a month or a year)
1 month 1 day 00:00:00.000 (if the timediffence reaches months, but is lower than a year)
1 year 1 month 1 day 00:00:00.000 (if it reaches years, months, days)
it evens uses plurarl cases (years, mons, days) when their values are greater than one.
All these variations make difficult to any other app when SELECTing (query) this interval values (as text) to convert it to a proper time. So I would like postgresql to always show year, month n days, even if their value are 0 (it could be even better if it could show the date part of the interval like this... 01-11-30, adding zeros to the left side when values are less than ten)
I know I can change the interval to text, using to_char() but I really would like to avoid that, I would like some good fellow postgresql programmer to tell me if it is true that there is a way to tweak the Interval Output as is said in the postgresql documentation.
Thanks Advanced.
PD: two more links about the subject
https://my.vertica.com/docs/7.1.x/HTML/Content/Authoring/SQLReferenceManual/Statements/SET/SETDATESTYLE.htm
http://my.vertica.com/docs/6.1.x/HTML/index.htm#13874.htm
You can set the interval output style, but only to one of a few pre-defined formats that are unambigious on input, and that PostgreSQL knows how to parse back into intervals. Per the documentation these are the SQL standard interval format, two variants of PostgreSQL specific syntax, and iso_8601 intervals.
If you want something familiar and easy to parse, consider using:
SET intervalstyle = 'iso_8601'
and using an off-the-shelf parser for ISO1601 intervals.

Cron expression to run twice monthly using day of week with "#'

I'm trying to figure out how to setup quartz to run twice monthly specifying the day of week using the symbol "#".
My expression:
0 0 8 ? * 6#2,6#4
My goal is to run every second and fourth Friday of every month at 8:00
The expression is valid, but it runs only at forth Friday. The second one is ignored.
How to achieve this?
Thank you.
Unfortunately, there's not way now.
If the '#' character is used, there can only be one expression in the
day-of-week field ("3#1,6#3" is not valid, since there are two
expressions).
source: http://quartz-scheduler.org/api/2.2.0/org/quartz/CronExpression.html
if fourth is working fine. You can simply separate the two out and load the job again for second friday.
if API does not provide you the solution it always comes down to your implementation and code logic.