MacOS – Issue when trying to convert the month number to word form in AppleScript (but only when that month contains 31 days)

applescriptcommand linemacos

I have a piece of AppleScript code that converts a numerical date to that date in words.

The code accepts a variable that contains a date in the following format:

2017_04_01

The code converts this numerical date to the following word-based format:

Saturday, April 1, 2017

My code has been modified from the answer provided to this question, by user markhunte:

Applescript date manipulation to get multiple formats

My code works perfectly when it is given today's date of 2017_04_01. But, for some reason, it does not work when it is given the date of day 31 of any given month.

For example, my code will not work if theNumericalDate is 2017_03_31.

Here is my AppleScript code:

set theNumericalDate to "2017_04_01"    

-- Remove the underscores:
set temp to AppleScript's text item delimiters
set AppleScript's text item delimiters to {"_"}
set listOfTheNumbersOfDate to text items of theNumericalDate
set AppleScript's text item delimiters to temp

-- Separate each individual element:    
set onlyTheYear to (item 1 of (listOfTheNumbersOfDate))
set onlyTheMonth to (item 2 of (listOfTheNumbersOfDate))
set onlyTheDay to (item 3 of (listOfTheNumbersOfDate))

-- I don't want to display "March 03" as the date. I would prefer: "March 3". So, remove the first character from the day if it is a zero:
if (character 1 of onlyTheDay is "0") then
    set onlyTheDay to text 2 thru -1 of onlyTheDay
end if

set stringForShellScript to " date -v" & onlyTheDay & "d -v" & onlyTheMonth & "m -v" & onlyTheYear & "y +%"

set theMonthAsWord to (do shell script (stringForShellScript & "B"))

set theDayAsWord to (do shell script (stringForShellScript & "A"))


set theDisplayDateString to (theDayAsWord & ", " & theMonthAsWord & " " & onlyTheDay & ", " & onlyTheYear)

Based on some debugging that I have done, I think that the source of the issue lies in this line:

set theMonthAsWord to (do shell script (stringForShellScript & "B"))

Can you identify and solve the issue?


I realize that I can easily accomplish the desired effect of determining the month name by implementing an if statement such as:

if onlyTheMonth is "01" then
    set theMonthAsWord to "January"
else if onlyTheMonth is "02" then
    set theMonthAsWord to "February"
else if onlyTheMonth is "03" then
    set theMonthAsWord to "March"
...

I shied away from this method because it's lengthy and unsophisticated.

Also, I'd still have to figure out the day of the week somehow, which is more complicated and cannot be accomplished by a simple if statement. Thus, the line:

set theDayAsWord to (do shell script (stringForShellScript & "A"))

would still terminate my code when theNumericalDate ends in _31.

Best Answer

Solution
Use the following stringForShellScript:
"date -v" & onlyTheMonth & "m -v" & onlyTheDay & "d -v" & onlyTheYear & "y +%"

Explanation
Interestingly enough, you need to shift the month before the day, but only if you’re going to shift the day to the 31st of the month.

-v30d -v2m will produce February just fine, but the 31st of the month causes date to bug out (up to the version that ships with macOS Sierra 10.12.4).

You can shift the year at any point in the command without any issue.

Side Notes

  1. set onlyTheDay to (onlyTheDay as integer) as string will remove any leading 0s from a number string. It’s less error-prone than parsing a string. Performance is inconsequential in this case.
  2. You have a leading space before date. Not that it matters—just pointing it out.