Convert a string into a date class

I have a string with date time information and I need to convert this into a date class.

The string is in the following format:

"2020-05-07T06:05:34Z"

How can I convert this into a date class?

Here is a script borrowed from Shane Stanley’s Everyday AppleScriptObjC.
I just added the Z parameter and changed the string between date part and time part and choose to require at least macOS 10.11

use AppleScript version "2.5"
use framework "Foundation"
use scripting additions
on dateFromString:aString usingFormat:formatString
	set theFormatter to current application's NSDateFormatter's new()
	theFormatter's setDateFormat:formatString
	set theDate to theFormatter's dateFromString:aString
	return theDate as date
end dateFromString:usingFormat:

its dateFromString:"2020-05-07T06:05:34Z" usingFormat:"yyyy-MM-dd'T'HH:mm:ssZ"

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) vendredi 22 mai 2020 16:29:56

Caution: that text format implies UTC time; the returned date object uses local time. With the given string I get

date "donderdag 7 mei 2020 08:05:34"

which is correct for my time zone (CEST = Europe/Amsterdam, summer time).

What need for this “Caution”. The date string passed is using a perfect syntax for a local date.

Here it returns : date “jeudi 7 mai 2020 à 08:05:34”

its dateFromString:“07-05-2020T06:05:34Z” usingFormat:“dd-MM-yyyy’T’HH:mm:ssZ”

would return the same result.

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) vendredi 22 mai 2020 18:25:53

There is a special date formatter for ISO8601 dates

use AppleScript version "2.5"
use framework "Foundation"
use scripting additions

set dateString to "2020-05-07T06:05:34Z"
set formatter to current application's NSISO8601DateFormatter's new()
set theDate to (formatter's dateFromString:dateString) as date

The time going in is “06:05:34”. The time coming out is “08:05:34”, in my location.
Olli may not be wanting this.
And, not being aware of this, it may bite you:

use framework "Foundation"
on dateFromString:aString usingFormat:formatString
	set theFormatter to current application's NSDateFormatter's new()
	theFormatter's setDateFormat:formatString
	set theDate to theFormatter's dateFromString:aString
	return theDate as date
end dateFromString:usingFormat:

its dateFromString:"2020-05-07T22:05:34Z" usingFormat:"yyyy-MM-dd'T'HH:mm:ssZ"
--> date "vrijdag 8 mei 2020 00:05:34"
-- which is the NEXT day!

And this behavior is the correct one.

If he doesn’t want the described behavior he would use the format : “2020-05-07T22:05:34”.
I guess that the final Z is not a typo !

use framework "Foundation"
on dateFromString:aString usingFormat:formatString
	set theFormatter to current application's NSDateFormatter's new()
	theFormatter's setDateFormat:formatString
	set theDate to theFormatter's dateFromString:aString
	return theDate as date
end dateFromString:usingFormat:

its dateFromString:"2020-05-07T22:05:34" usingFormat:"yyyy-MM-dd'T'HH:mm:ss"

As stefanK wrote, the used format (with the ending “Z”) is one of those with an official name.
As far as I know, the one without the “Z” hasn’t a name.

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) vendredi 22 mai 2020 19:29:27

But it’s worth keeping in mind that it requires macOS 10.12, and its enums require 10.13.

The “Z” means GMT/UTC time zone, so this difference is required.

Of course, but Sierra users are very rare.

And what enums are you talking about? Only the fractional seconds format option requires 10.13

The NSISO8601DateFormatOptions enums (not needed in this example). Although they are part of 10.12, they were left out of its Foundation.bridgesupport file.

Firstly thanks for the solution and all the comments! Greatly appreciated!

Well, I do want this. The time is indeed GMT, while I would like to see my local time.

So I can use the code as is. :slight_smile:

ps: The code has lots of stuff I have never seen before. Particularly the colon notation like

":aString"

is totally new to me!

Don’t worry, it was new for me too when I read Shane Stanley’s “Everyday AppleScriptObjC” for the first time.

The relevant part is :

There is one last thing to do. In both the handler and where it is being called, insert an underscore after the name so that cleanUpText(someText) becomes cleanUpText_(someText), and compile the script. You will see that the handler declaration changes to read cleanUpText:someText. The two forms are equivalent, and compile to identical underlying code. The interleaved version was only introduced in Mavericks — before that, you would also have used stringByReplacingOccurrencesOfString_withString_options_range_(…), for example, with the arguments in the parentheses and separated by commas.
The interleaved syntax can be used in AppleScript generally — it is not confined to AppleScriptObjC. You may see the change happen elsewhere if you use underscores in your handler names.

Maybe Shane would give extraneous explanations. :wink:

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) samedi 23 mai 2020 19:44:04

But what is the basic purpose of the colon? Indication of parameters to functions?

Yes. It’s described in the AppleScript Language Guide as “Handlers with Interleaved Parameters”.

Thank you Shane, I forgot this chapter.

On my side I use such syntax when I use ASObjC and remain to the old fashioned one when I code the old way.

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) dimanche 24 mai 2020 23:03:15

Thanks heaps, Shane. Found it in the AppleScript Language Guide .

I was able to di it with pure Applscript using the built in date function


set sDate to "2020-05-07T06:05:34Z"

set cdate to date ((text 6 thru 7 of sDate) & "/" & (text 9 thru 10 of sDate) & "/" & (text 1 thru 4 of sDate) & " at " & (text 12 thru 19 of sDate) & " " & (item (((text 12 thru 13 of sDate) as integer) div 12 mod 2 + 1) of {"AM", "PM"}))

you have to calculate the AM/PM part or the time portion of the resulting date will be default at 12:00:00 AM

– add time to get to adjust for local time

set cdate to cdate + (time to GMT)

Have you ever ran my proposal ?
It returns the correct date but yours fails.

When it’s executed in France where the offset from Greenwich is 2 hours in the given period,
your script return dimanche 5 juillet 2020 à 00:00:00 (and it’s unable to take cate of the summer time component)
when the true result is: jeudi 7 mai 2020 à 06:05:34.

The posted date uses the format “yyyy-MM-dd’T’HH:mm:ssZ”

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) mardi 26 mai 2020 18:09:13