org-read-date-analyze is the underlying function for parsing
the input with org-mode time format, e.g., understanding AM/PM suffixes.
It is a complicated function containing many parts, and IMO advice is the
easiest way. Below is an example. This advice adds 12 hours to
the final time when the input doesn't contain am and the final
time is between 1:00 and 6:...
You have to change parse-time-weekdays and parse-time-months. For example, something like this will do:
'(("sund" . 0) ("tues" . 2) ("thurs" . 4))
'(("janu" . 1) ("dece" . 12)))
(setq parse-time-weekdays (nconc parse-time-weekdays
You can use the apply function to pass a function arguments
contained in a list as separate arguments. For example:
(apply #'format "%04d-%02d-%02d" '(2017 8 21))
That way you can store the list in a variable or compute it with a
function call, etc.
(let ((best-day-ever '(2017 8 21)))
(apply #'format "%04d-%02d-%02d" best-day-ever))
parse-time-string parses "standard" time strings, as does org-parse-time-string. The documentation claims the latter will be faster. Neither gives a way to specify the format of the string.
There is also an undocumented function parse-iso8601-time-string that parses ISO8601 into something. It isn't clear to me what the output is supposed to be.
The function you are looking for is file-attributes. The help text is fairly detailed but you will be wanting:
4. Last access time, as a list of integers (HIGH LOW USEC PSEC) in the
same style as (current-time).
(See a note below about access time on FAT-based filesystems.)
5. Last modification time, likewise. This is the time of the last
change to the ...
To input a value in non-standardized HMS form you can press ' to start algebraic entry and then use the hms function. For example, to enter the equivalent of 0@8000'0" you would type ' hms(0, 8000, 0) RET.
Another possibility is to input the number of days and then convert them to HMS form using the function calc-to-hms (bound to ch). So for your example ...
Convert the date strings to time values, then use time-less-p to compare the time values.
C-h f time-less-p:
time-less-p is a built-in function in ‘C source code’.
(time-less-p T1 T2)
Return non-nil if time value T1 is earlier than time value T2.
A nil value for either argument stands for the current time.
See current-time-string for the various forms of a ...
See org-element-timestamp-parser (parses the timestamp at point, including the repeater part) and org-element-timestamp-interpreter (transforms a timestamp object back into Org syntax).
For example, calling (org-element-timestamp-parser) with the point at the "<" of "<2016-01-25 Mon 14:51 +1w>" produces
(timestamp (:type active
One way of going from an HMS form to the number of seconds is hinted by a line from the HMS forms page:
Dividing two HMS forms produces a real-valued ratio of the two angles.
So if an HMS form is on the stack
5@ 30' 0"
entering one second to the stack
and dividing by it
gives the number of seconds:
Not exactly a convert but it's only ...
parse-iso8601-time-string already returns a time value that format-time-string accepts:
I had a similar situation but couldn't find anything working out of the box. But since org-time-stamp handles all kinds of formats, I figured the code was there. The function below will insert an org time stamp from a provided time string. I haven't tested it for all kinds of times, but for "15-03-12 Thu 16:49" it will give "[2015-03-12 tor 16:49]". ("tor" ...
Seems like we can build on @lawlist's idea and do something similar to this:
(advice-add 'org-read-date-analyze :around
(lambda (orig ans org-def org-defdecode)
(funcall orig (if (string-match "tom" ans) "+1d" ans) org-def org-defdecode)))
Just for fun and profit:
(destructuring-bind (year month day) '(2017 8 21)
(format "%04d-%02d-%02d" year month day))
An unfortunate use of eval:
(eval `(format "%04d-%02d-%02d" ,@ '(2017 8 21)))
A macro form of that:
(defmacro dformat (date)
`(format "%04d-%02d-%02d" ,@date))
(dformat (2017 8 21))
In keeping with tradition, I was able to find the answer in Emacs itself while asking this question.
It turns out the standard time functions work with different kinds of values:
Function arguments, e.g., the TIME argument to current-time-string,
accept a more-general "time value" format, which can be a list of
integers as above, or a single number ...
This bug was reported as bug 39001 and fixed in this commit in upstream emacs. The patch to apply can be found here.
The function parse-iso8601-time-string does parse ISO8601 string but eventually encode it with encode-time. The following snippet does what parse-time-string was supposed to do.
#'time-subtract's docstring says "See ‘current-time-string’ for the various forms of a time value." #'current-time-string specifies times to be in this format:
If SPECIFIED-TIME is given, it is a time to format instead of the
current time. The argument should have the form (HIGH LOW . IGNORED).
However, #'parse-time-string says this:
Parse the time-...
Following is a way to apply a list of arguments to a function, which I believe is what you need:
(let ((x '(2017 8 21))
(f (lambda(x y z) (format "%04d-%02d-%02d" x y z ))))
(apply f x))
apply applies a list of arguments to a given function.
Below should work. It does not strictly follow your pseudo-code but I have put in your pseudo code as comments in-between so that you can get a rough idea of how elisp correlates to that.
(defun my/return-time-diff-frac-hours ()
(let (begin-hh begin-mm end-hh end-mm diff)
;; $end-time = (search back from ...
I figured out a somewhat convoluted way to get the functionality without modifying org-read-date or org-read-date-analyze. It uses the same approach in the question, but defining a timer that runs every 24-hours at midnight that resets the value of tom:
(defun tomorrow-day ()
"Returns the day of the week for tomorrow."
(let ((day (1+ (string-to-number (...