I clearly don’t yet understand the typing mechinsm in Applescript.
I have a date variable that I need to try and convert to a string in the format MM/DD/YY
What’s the easiest and fastest way to do this?
Thanks,
Maddog
I clearly don’t yet understand the typing mechinsm in Applescript.
I have a date variable that I need to try and convert to a string in the format MM/DD/YY
What’s the easiest and fastest way to do this?
Thanks,
Maddog
It might depend on which version of Mac OS/AppleScript you are running. If I’m not mistaken, Panther introduced some changes to the way dates can be manipulated.
– Rob
How do I determine that? I’m running Panther with the very latest updates of XCode for AppleScript Studio.
There’s probably a better way of doing this but this works for me:
set the_date to date "Saturday, January 1, 2000 12:00:00 AM"
return format_date(the_date, "/", false)
-->"01/01/00"
on format_date(the_date, the_sep, inc_time)
set the_month to month of the_date as integer
if the_month < 10 then set the_month to "0" & the_month as string
set the_day to day of the_date as integer
if the_day < 10 then set the_day to "0" & the_day as string
set the_year to (text 3 thru 4 of (year of the_date as string))
set date_string to the_month & the_sep & the_day & the_sep & the_year
if inc_time = true then set date_string to date_string & ", " & (time string of the_date)
return date_string as string
end format_date
Jon
Thanks much, using other peoples code is so much better than having to write it yourself… 8)
Seriously though, I really appreciate the help. This is a really great forum.
Well, there’s easiest and there’s fastest…which do you really want?
on DateToString(d, s)
(* d = date
* s = format string, (case sensitive):
*
* yyyy year, 4 digits
* yy year, 2 digits
* mmmm month, full name
* mmm month, 3 character abbreviation
* mm month, 1 - 12, zero padded
* m month, 1 - 12
* dddd day, full name
* ddd day, 3 character abbreviation
* dd date, 1 - 31, zero padded
* d date, 1 - 31
* hh hour, 1 - 12, zero padded
* h hour, 1 - 12
* HH hour, 0 - 23, zero padded
* H hour, 0 - 23
* MM minutes, 0 - 59, zero padded
* M minutes, 0 - 59
* ss seconds, 0 - 59, zero padded
* s seconds, 0 - 59
* AP AM or PM
* zzzz 4 digit offset from GMT, +hhmm or -hhmm
* zz 2 digit offset from GMT, +hh or -hh
*
* ` escape character
* ~ null character
*
* Parsing Rules:
* Reading the format string from left to right, the script
* always obtains the longest possible match:
*
* "mmmmmmmmm" --> "mmmm" + "mmmm" + "m"
*
* The escape and null meta-characters can be used to avoid
* any possible ambiguity:
*
* "mmmmmmmm~m" --> "mmmm" + "mmmm" + "m"
* "mmmmmmm~mm" --> "mmmm" + "mmm" + "mm"
* "mmmmmm~mmm" --> "mmmm" + "mm" + "mmm"
* "mmmmm~mmmm" --> "mmmm" + "m" + "mmmm"
* "mmmm~mmmmm" --> "mmmm" + "mmmm" + "m"
* "mmm~mmmmmm" --> "mmm" + "mmmm" + "mm"
* "mm~mmmmmmm" --> "mm" + "mmmm" + "mmm"
* "m~mmmmmmmm" --> "m" + "mmmm" + "mmmm"
*
*
* set d to current date
*
* DateToString(d, "mmm~mm") --> Sep17
* DateToString(d, "mm~mmm") --> 17Sep
*
* DateToString(d, "Today is dddd.") --> "To17ay i30 Wednesday."
* DateToString(d, "To`day i`s dddd.") --> "Today is Wednesday."
*)
if (s's class is not string) or (s's length = 0) then return d as string
set s to s & " " --> prevent out-of-bounds in parsing
set t to ""
considering case
repeat until s's length < 5
if (s starts with "yy") then
set v to d's year as string
if (s starts with "yyyy") then
set t to t & v
set s to s's text 5 thru -1
else
set t to t & v's text -2 thru -1
set s to s's text 3 thru -1
end if
else if (s starts with "m") then
if (s starts with "mmm") then
set v to d's month as string
if (s starts with "mmmm") then
set t to t & v
set s to s's text 5 thru -1
else
set t to t & v's text 1 thru 3
set s to s's text 4 thru -1
end if
else
(* Modified from:
* Nigel Garvey's "English Toffee," via
* Richard Hartman's "Vanille Américaine," via
* Emmanuel Lévy's "French Vanilla"
*)
copy d to mm
set mm's month to January
set mm to (((mm - 2500000 - d) div -2500000 + 100) as string)'s text -2 thru -1
if (s starts with "mm") then
set t to t & mm
set s to s's text 3 thru -1
else
set t to t & (mm as integer)
set s to s's text 2 thru -1
end if
end if
else if (s starts with "d") then
if (s starts with "ddd") then
set v to d's weekday as string
if (s starts with "dddd") then
set t to t & v
set s to s's text 5 thru -1
else
set t to t & v's text 1 thru 3
set s to s's text 4 thru -1
end if
else
set v to d's day as string
if (s starts with "dd") then
set t to t & ("0" & v)'s text -2 thru -1
set s to s's text 3 thru -1
else
set t to t & v
set s to s's text 2 thru -1
end if
end if
else if (s starts with "h") or (s starts with "H") then
set v to (d's time) div 60 div 60
if (s starts with "h") and (v > 12) then set v to v - 12
ignoring case
if (s starts with "hh") then
set t to t & ("0" & v)'s text -2 thru -1
set s to s's text 3 thru -1
else
set t to t & v
set s to s's text 2 thru -1
end if
end ignoring
else if (s starts with "M") then
set v to (d's time) div 60 mod 60
if (s starts with "MM") then
set t to t & ("0" & v)'s text -2 thru -1
set s to s's text 3 thru -1
else
set t to t & v
set s to s's text 2 thru -1
end if
else if (s starts with "s") then
set v to (d's time) mod 60
if (s starts with "ss") then
set t to t & ("0" & v)'s text -2 thru -1
set s to s's text 3 thru -1
else
set t to t & v
set s to s's text 2 thru -1
end if
else if (s starts with "AP") then
if ((d's time) div 60 div 60 < 12) then
set t to t & "AM"
else
set t to t & "PM"
end if
set s to s's text 3 thru -1
else if (s starts with "zz") then
tell (time to GMT) / 60 div 60 * 100 to if it < 0 then
set zzzz to "-" & ("0" & -it)'s text -4 thru -1
else
set zzzz to "+" & ("0" & it)'s text -4 thru -1
end if
if (s starts with "zzzz") then
set t to t & zzzz
set s to s's text 5 thru -1
else
set t to t & zzzz's text 1 thru 3
set s to s's text 3 thru -1
end if
else if (s starts with "`") then
set t to t & s's character 2
set s to s's text 3 thru -1
else if (s starts with "~") then
set s to s's text 2 thru -1
else
set t to t & s's character 1
set s to s's text 2 thru -1
end if
end repeat
end considering
return t
end DateToString
Here’s something that is slightly more involved, but is almost infinitely flexible, with fairly little code (compared to how flexible it is). It uses a shell command built in to OS X:
set sampleDate to (current date) - 3 * days
return dateUnixFormat(sampleDate, "%D")
on dateUnixFormat(theDate, unixFormatString)
-- version 1.0, Daniel A. Shockley, http://www.danshockley.com
-- based on code from Paul Berkowitz and Nigel Garvey on applescript-users mailing list
try
set uniDate to theDate - (time to GMT)
set theEpoch to (date (do shell script "date -r 0 "+%a %b %e %Y
%H:%M:%S""))
set unixSecs to uniDate - (theEpoch)
set unixSecs to my NumberToString(unixSecs)
set theDate to do shell script "date -r " & unixSecs & " +"" & unixFormatString & """
--there are lots and lots of other date formats you can use
on error errMsg number errNum
error "dateUnixFormat FAILED: " & errMsg number errNum
end try
end dateUnixFormat
To find out all the amazing ways you can format your date using this, go to the Terminal and type
man strftime
It explains what you can send as the format string. %D means MM/DD/YY, which you could also get with the format string “%m/%d/%y”
Krioni, it looks like you left out the “NumberToString” handler. Also, in this line:
you have an extra space after "-r " and perhaps you should use the “quoted form” syntax:
set theDate to do shell script "date -r " & unixSecs & " +" & (quoted form of unixFormatString)
Jon
Yikes, and I thought I asked a fairly simple question. Guess not, huh?
Thanks for all your help.
I’ve read that Panther’s StandardAdditions has a “short date string” function, which returns a short date in the format set in the user’s preferences. That would be the easiest if it’s known that the script will only be run on a Panther (or later) machine by a user whose preferences are MM/DD/YY.
set shortDateStr to (short date string of (current date))
Otherwise, the fastest and easiest way to enforce that format on any machine would be:
on MMDDYY(theDate)
set {day:d, year:y} to theDate
copy theDate to b
set b's month to January
tell (y * 10000 + (b - 2500000 - theDate) div -2500000 * 100 + d) as string
return text 5 thru 6 & "/" & text 7 thru 8 & "/" & text 3 thru 4
end tell
end MMDDYY
set shortDateStr to MMDDYY(current date)
--> "03/12/04"
I don’t recognise my bit.
Nigel’s two suggestions are definitely the fastest and/or easiest. But, to make sure my (flexible for other uses) suggestion is correct, let me respond to Jonn8. Also, Nigel, I think there was a general discussion about using the UNIX date command, and you made some good points on applescript-users.
I most certainly did. It’s a handler by Paul Berkowitz, a great AS programmer. Here’s the whole thing, with the NumberToString handler and with Jonn8’s suggestions about using “quoted from of” included. I would have used those if I had written dateUnixFormat now, but I didn’t notice when posting it here before just how old the code was.
on dateUnixFormat(theDate, unixFormatString)
-- version 1.1, Daniel A. Shockley, http://www.danshockley.com
-- based on code from Paul Berkowitz and Nigel Garvey on applescript-users mailing list
-- updates suggested by Jonn8 on macscripter.net BBS
try
set uniDate to theDate - (time to GMT)
set theEpoch to (date (do shell script "date -r 0 '+%a %b %e %Y %H:%M:%S'"))
set unixSecs to uniDate - (theEpoch)
set unixSecs to my NumberToString(unixSecs)
set theDate to do shell script "date -r " & unixSecs & " +" & quoted form of unixFormatString & ""
--there are lots and lots of other date formats you can use
--> "03/17/02"
on error errMsg number errNum
error "dateUnixFormat FAILED: " & errMsg number errNum
end try
end dateUnixFormat
on NumberToString(bigNumber)
-- by Paul Berkowitz
set bigNumber to bigNumber as string
if bigNumber does not contain "E+" then return bigNumber
set {tids, AppleScript's text item delimiters} to {AppleScript's text item delimiters, {"E+"}}
try
set {basicReal, powersOfTen} to {bigNumber's text item 1, (bigNumber's text item 2) as integer}
on error -- e.g. Python strings have lower-case "e", tids case-sensitive
set AppleScript's text item delimiters to {"e+"}
set {basicReal, powersOfTen} to {bigNumber's text item 1, (bigNumber's text item 2) as integer}
end try
set AppleScript's text item delimiters to {"."}
try
set {integerPart, decimalPart} to basicReal's {text item 1, text item 2}
set decimalSign to "."
on error
set AppleScript's text item delimiters to {","}
set {integerPart, decimalPart} to basicReal's {text item 1, text item 2}
set decimalSign to ","
end try
set AppleScript's text item delimiters to tids
set n to count decimalPart
if powersOfTen is greater than or equal to n then
repeat (powersOfTen - n) times
set decimalPart to decimalPart & "0"
end repeat
set bigNumber to integerPart & decimalPart
else
set bigNumber to integerPart & decimalPart
set bigNumber to text 1 thru (powersOfTen + 1) of bigNumber & decimalSign & text (powersOfTen + 2) thru -1 of bigNumber
end if
return bigNumber
end NumberToString
Krioni,
Using the GMT date is, well, returning the GMT for any date I use with this formatter, not my local time. Are you getting your local time?
Amending the routine to not coerce to GMT returns the proper time on my system:
set the_date to (current date)
dateUnixFormat(the_date, "%m/%d/%y %H:%M:%S")
(*
Event Log:
tell current application
current date
date "Friday, March 12, 2004 11:56:17 AM"
do shell script "date -r 0 '+%a %b %e %Y %H:%M:%S'"
"Wed Dec 31 1969 19:00:00"
do shell script "date -r 1079110577 +'%m/%d/%y %H:%M:%S'"
"03/12/04 11:56:17"
end tell
*)
on dateUnixFormat(theDate, unixFormatString)
-- version 1.1, Daniel A. Shockley, http://www.danshockley.com
-- based on code from Paul Berkowitz and Nigel Garvey on applescript-users mailing list
-- updates suggested by Jonn8 on macscripter.net BBS
try
set theEpoch to (date (do shell script "date -r 0 '+%a %b %e %Y %H:%M:%S'"))
set unixSecs to theDate - (theEpoch)
set unixSecs to my NumberToString(unixSecs)
return (do shell script "date -r " & unixSecs & " +" & quoted form of unixFormatString)
on error errMsg number errNum
error "dateUnixFormat FAILED: " & errMsg number errNum
end try
end dateUnixFormat
on NumberToString(bigNumber)
-- by Paul Berkowitz
set bigNumber to bigNumber as string
if bigNumber does not contain "E+" then return bigNumber
set {tids, AppleScript's text item delimiters} to {AppleScript's text item delimiters, {"E+"}}
try
set {basicReal, powersOfTen} to {bigNumber's text item 1, (bigNumber's text item 2) as integer}
on error -- e.g. Python strings have lower-case "e", tids case-sensitive
set AppleScript's text item delimiters to {"e+"}
set {basicReal, powersOfTen} to {bigNumber's text item 1, (bigNumber's text item 2) as integer}
end try
set AppleScript's text item delimiters to {"."}
try
set {integerPart, decimalPart} to basicReal's {text item 1, text item 2}
set decimalSign to "."
on error
set AppleScript's text item delimiters to {","}
set {integerPart, decimalPart} to basicReal's {text item 1, text item 2}
set decimalSign to ","
end try
set AppleScript's text item delimiters to tids
set n to count decimalPart
if powersOfTen is greater than or equal to n then
repeat (powersOfTen - n) times
set decimalPart to decimalPart & "0"
end repeat
set bigNumber to integerPart & decimalPart
else
set bigNumber to integerPart & decimalPart
set bigNumber to text 1 thru (powersOfTen + 1) of bigNumber & decimalSign & text (powersOfTen + 2) thru -1 of bigNumber
end if
return bigNumber
end NumberToString
Jon
Jonn8, you’re right, of course. I should look over old code before posting it. I must not have used this handler much myself, or I would have noticed that. Thanks.
Hello. In Panther,
Try short date string of (current date)
It will return a date in whatever format your default short date is.
Bill
Right on, Rob (in Ohio), and Nigel Garvey.
I don’t know about jonn8 (usually pretty helpful) or AdmiralNova, but just noticed Krioni joined in 1969. My respects. I was 23 years old that year (seriously).
Sorry if I misunderstood anybody. Were any of these posts helpful, maddog?
Bill
Actually as an adequate programming hack with no Applescript experience all the posts were very helpful. The more, well explained, code samples I see, the more I understand this language. I have now been able to do just about everything I need to do.
I’m waiting on one thing from the AppleScript studio forum, although it may be that this forum could help me.
I need to set the height of a window separately from the width, essentially I need to be able to add a constant to the second co-ordinate of an array, and don’t know how to do this.
Essentially:
set size of window “windowName” to (call method size of object)
– Given that I don’t know the values of A or B, how can I now make a statement like:
set size of window “windowName” to {A, B + constant}
DOH!! - just writing this down made me realize how easy this is to do.
{widthVar, heightVar} = (call method size of object)
set size of window “windowName” to {widthVar, heightVar + constant}
See, I told you ALL the posts in this reponse were helpful, even this one.
Thanks much to all,
Maddog
I just noticed that Krioni’s location is given as Philadelphia. Yo, homeboy!
In 1969, my parents had just met each other in highschool.