Number as Text to Date Conversion

Is this the most efficient way to go from a date in the form “20070904” to an AppleScript date?


set U to "20070904"
tell U to set {dd, mm, yy} to {text 7 thru 8 & " ", text 5 thru 6, text 1 thru 4}
-- convert month as number to abbreviated month name, prepend day, append year
-- then coerce to date (coercion requires at least an abbreviated month, won't accept a number).
set D to date (dd & (text ((3 * mm) - 2) thru (3 * mm) of ("JanFebMarAprMayJunJulAugSepOctNovDec") & ", " & yy))

Hi, Adam.

set U to "20070904"
set D to U as «class isot» as date

Defines what?

ISO 8601

I was sure I had seen something clever like that, Mr. G. but couldn’t for the life of me recall it - hence the post. Thank you.

And seeing your answer, I recall: date “Thursday 2 January 1000 00:00:00” as «class isot» as string for going the other way in Code Exchange.

Interesting Addendum. The coercion doesn’t work if the date string is Unicode text; e.g.:

set U to "20070730T025959Z" -- where the string is in UTF-16 as returned from iCal for instance.
set D to U as «class isot» as date
--> errors with: Can't make "20070730T025959Z" into type «class isot».

Works perfectly if I type the date in my script editor.

Nor does the Arthur Knapp fix succeed:

set {text:U} to ("20070730" as Unicode text)
set D to U as «class isot» as date

You missed a coercion Adam:

set {text:U} to ("20070730" as Unicode text)
class of U
--> Unicode text
set {text:U} to ("20070730" as Unicode text as string)
class of U
--> string
set {text:U} to ("20070730" as Unicode text as string)
set D to U as «class isot» as date
--> date "Monday, 30 July 2007 12:00:0 AM"

See also: “Author Knapp method

http://bbs.applescript.net/viewtopic.php?pid=79003#p79003

Thanks for the reply, Bruce - that fixes my problem.

-- snippet:
set {text:U} to item 2 as string
U -->"20070730T025959Z" a date returned from an iCal Repeat event with an "Until" limit set. It's Unicode text in raw form.
set D to U as «class isot» as date --> date "Friday, August 3, 2007 1:00:00 AM"

What disturbs me still about this is that the isot string seems to read: July 30, 2007 @ 2:59:59 GMT. I am at -3 hours local time. The date returned is several days later, so there’s more to this than meets the eye.

My original method:


set U to "20070730T025959Z"
tell U to set {dd, mm, yy} to {text 7 thru 8 & " ", text 5 thru 6, text 1 thru 4}
-- convert month as number to abbreviated month name, prepend day, append year
-- then coerce to date (coercion requires at least an abbreviated month, won't accept a number).
set D to date (dd & (text ((3 * mm) - 2) thru (3 * mm) of ("JanFebMarAprMayJunJulAugSepOctNovDec") & ", " & yy))
--> date "Monday, July 30, 2007 12:00:00 AM"

What gives??

Apparently the difficulty arises because although the iCal date is, in fact, a proper «class isot» according to the ISO, the implementation in AppleScript seems to require colons; i.e., it works properly if the date looks like this: “20070730T02:59:59Z” with the colons added, or if only the first 8 characters are used: text 1 thru 8 of “20070730T025959Z”. I’ve discussed this (PM) with Nigel Garvey who suspects that it’s a bug. Examples:


set {text:U} to ((text 1 thru 8 of "20070730T025959Z") as Unicode text as string)
set D1 to U as «class isot» as date
--> date "Monday, July 30, 2007 12:00:00 AM"

-- or 

set {text:U} to (("20070730T02:59:59Z") as Unicode text as string)
set D2 to U as «class isot» as date
--> date "Monday, July 30, 2007 2:59:59 AM"

-- with dashes (acceptable to ISO):

set {text:U} to (("2007-07-30T02-59-59Z") as Unicode text as string)
set D3 to U as «class isot» as date
--> date "Wednesday, August 1, 2007 1:00:00 PM"

-- yet another version works:

set {text:U} to (("2007-07-30T02:59:59Z") as Unicode text as string)
set D4 to U as «class isot» as date
--> date "Monday, July 30, 2007 2:59:59 AM"

-- but without the colons:

set {text:U} to (("2007-07-30T025959Z") as Unicode text as string)
set D5 to U as «class isot» as date
--> date "Friday, August 3, 2007 1:00:00 AM"

Clearly, «class isot» is not fully compliant with the ISO time standard

I’m afraid I have to protest my innocence of having used the term “bug”. I actually described it as “some peculiarity in the implementation.”

If we’re using something that’s not advertised for our use, we can only say it’s not doing what we expect, not that it has a bug. :slight_smile:

I stand corrected. You said “some peculiarity in the implementation” and I took that to mean “bug”. :rolleyes:

No problem. :slight_smile:

If you wanted the time as well, there’s this:

set {text:U} to ("20070730T025959Z" as Unicode text as string)
set T to text 10 thru 15 of U as integer
set D to (text 1 thru 8 of U as «class isot» as date) + (T div 10000 * hours + T mod 10000 div 100 * minutes + T mod 100)
--> date "Monday 30 July 2007 02:59:59"

Or even this:

set U to "20070730T025959Z" as Unicode text

tell U to set {D, T} to {text 1 thru 8 as integer, text 10 thru 15 as integer}
tell («data isot3130303030313031» as date) to set {year, day, day, time, D1} to {D div 10000, (D mod 10000 div 100 - 1) * 32, D mod 100, T div 10000 * hours + T mod 10000 div 100 * minutes + T mod 100, it}
D1

Thanks for those. What I was doing (I do want the time locally) was to construct the form that the undocumented «class isot» seems to expect (at least it works) with the colons (as you discovered earlier, above):


set {text:U} to "20070730T025959Z" as Unicode text as string
-- where in use the "as Unicode text" is unecessary, the string being processed is Unicode. Further, the Z doesn't seem to matter but I included it.
tell U to set DR to ((text 1 thru 11 & ":" & text 12 thru 13 & ":" & text 14 thru -1) as «class isot» as date) + (my (time to GMT))
--> date "Sunday, July 29, 2007 11:59:59 PM"