Re-formating date string for Excel

Hi

I have a script that extracts text from a file and writes a CSV file that can be opened in Excel. However one of the extracted strings is the date and time an action was performed.

The string (generated by another -un-scriptable- program) looks like this.

“Wed Mar 01 11:03:27 2017”

I am having a lot of trouble getting Excel to recognise this as a date and time.

Can anyone suggest how I could take this string and re-format it in such a way that I could get Excel see it as a date/time.

Thanks for any suggestions.

Hi,

the Cocoa class NSDateFormatter is able to convert custom date formats

use framework "Foundation"

set dateString to "Wed Mar 01 11:03:27 2017"
set dateFormatter to current application's NSDateFormatter's alloc()'s init()
set dateFormatter's locale to current application's NSLocale's localeWithLocaleIdentifier:"en_US_POSIX"
set dateFormatter's dateFormat to "EEE MMM dd HH:mm:ss yyyy"
set theDate to (dateFormatter's dateFromString:dateString) as date

Consider that the bridging from NSDate to AppleScript date is only supported in El Capitan and later

You may try :

set theString to "Wed Mar 01 11:03:27 2017"
set theDate to my normalizeThisDate(theString)
# If the active date format is dd/mm/yyyy it would return
--> "01/03/2017 11:03:27" 
# If the active date format is mm/dd/yyyy it would return
--> "03/01/2017 11:03:27" 
# If the active date format is yyyy/mm/dd it would return
--> "2017/03/01 11:03:27" 


#=====

on normalizeThisDate(theString)
	set {oTIDs, AppleScript's text item delimiters} to {AppleScript's text item delimiters, space}
	set splitted to text items of theString
	set AppleScript's text item delimiters to oTIDs
	set monthNum to 1 + (offset of (item 2 of splitted) in "JanFebMarAprMayJunJulAugSepOctNovDec") div 3
	set fakeDate to "12/12/12"
	set theDate to date fakeDate
	set year of theDate to item 5 of splitted
	set month of theDate to monthNum
	set day of theDate to item 3 of splitted
	set theDate to (short date string of theDate) & space & item 4 of splitted
	return theDate
end normalizeThisDate

#=====

If you run Yosemite or higher you may use :

# Borrowed to Shane STANLEY and Christopher STONE

use AppleScript version "2.4" # requires at least Yosemite
use framework "Foundation"
use scripting additions
-------------------------------------------------------------------------------------------

set theString to "Wed Mar 01 11:03:27 2017"

set theDate to (my getDatesIn:theString)
considering numeric strings
	if AppleScript's version < "2.5" then
		set theDate to (my makeASDateFrom:theDate)
	else
		set theDate to theDate as date
	end if
end considering
set theDate to short date string of theDate & space & time string of theDate
# If the active date format is dd/mm/yyyy it would return
--> "01/03/2017 11:03:27" 
# If the active date format is mm/dd/yyyy it would return
--> "03/01/2017 11:03:27" 
# If the active date format is yyyy/mm/dd it would return
--> "2017/03/01 11:03:27"

-------------------------------------------------------------------------------------------
--» HANDLERS
-------------------------------------------------------------------------------------------
on formatDate:theDate usingFormat:formatString
	if class of theDate is date then set theDate to my makeNSDateFrom:theDate
	set theFormatter to current application's NSDateFormatter's new()
	theFormatter's setLocale:(current application's NSLocale's localeWithLocaleIdentifier:"en_US_POSIX")
	theFormatter's setDateFormat:formatString
	set theString to theFormatter's stringFromDate:theDate
	return theString as text
end formatDate:usingFormat:
-------------------------------------------------------------------------------------------
on getDatesIn:aString
	# Convert string to Cocoa string
	set anNSString to current application's NSString's stringWithString:aString
	# Create data detector
	set theDetector to current application's NSDataDetector's dataDetectorWithTypes:(current application's NSTextCheckingTypeDate) |error|:(missing value)
	# Find first match in string; returns an NSTextCheckingResult object
	set theMatch to theDetector's firstMatchInString:anNSString options:0 range:{0, anNSString's |length|()}
	if theMatch = missing value then error "No date found"
	# Get the date property of the NSTextCheckingResult
	set theDate to theMatch's |date|()
	return theDate
end getDatesIn:
-------------------------------------------------------------------------------------------
# Required before 10.11
on makeASDateFrom:theNSDate
	set theCalendar to current application's NSCalendar's currentCalendar()
	set comps to theCalendar's componentsInTimeZone:(missing value) fromDate:theNSDate -- 'missing value' means current time zone
	tell (current date) to set {theASDate, year, day, its month, day, time} to ¬
		{it, comps's |year|(), 1, comps's |month|(), comps's |day|(), (comps's hour()) * hours + (comps's minute()) * minutes + (comps's |second|())}
	return theASDate
end makeASDateFrom:
-------------------------------------------------------------------------------------------
on makeNSDateFrom:theASDate
	set {theYear, theMonth, theDay, theSeconds} to theASDate's {year, month, day, time}
	if theYear < 0 then
		set theYear to -theYear
		set theEra to 0
	else
		set theEra to 1
	end if
	set theCalendar to current application's NSCalendar's currentCalendar()
	set newDate to theCalendar's dateWithEra:theEra |year|:theYear |month|:(theMonth as integer) ¬
		|day|:theDay hour:0 minute:0 |second|:theSeconds nanosecond:0
	return newDate
end makeNSDateFrom:
-------------------------------------------------------------------------------------------

Or, at last with some enhancements to StefanK’s proposal

use AppleScript version "2.4" # requires at least Yosemite
use framework "Foundation"
use scripting additions

set dateString to "Wed Mar 01 11:03:27 2017"

set dateFormatter to current application's NSDateFormatter's alloc()'s init()
set dateFormatter's locale to current application's NSLocale's localeWithLocaleIdentifier:"en_US_POSIX"
set dateFormatter's dateFormat to "EEE MMM dd HH:mm:ss yyyy"
set theDate to (dateFormatter's dateFromString:dateString)
considering numeric strings
	if AppleScript's version < "2.5" then
		set theDate to (my makeASDateFrom:theDate)
	else
		set theDate to theDate as date
	end if
end considering

set theDate to short date string of theDate & space & time string of theDate
# If the active date format is dd/mm/yyyy it would return
--> "01/03/2017 11:03:27" 
# If the active date format is mm/dd/yyyy it would return
--> "03/01/2017 11:03:27" 
# If the active date format is yyyy/mm/dd it would return
--> "2017/03/01 11:03:27"

-------------------------------------------------------------------------------------------
# Required before 10.11
on makeASDateFrom:theNSDate
	set theCalendar to current application's NSCalendar's currentCalendar()
	set comps to theCalendar's componentsInTimeZone:(missing value) fromDate:theNSDate -- 'missing value' means current time zone
	tell (current date) to set {theASDate, year, day, its month, day, time} to ¬
		{it, comps's |year|(), 1, comps's |month|(), comps's |day|(), (comps's hour()) * hours + (comps's minute()) * minutes + (comps's |second|())}
	return theASDate
end makeASDateFrom:
-------------------------------------------------------------------------------------------

In the three scripts I convert the date into a string so that you may insert it in your CSV file.

Yvan KOENIG running Sierra 10.12.3 in French (VALLAURIS, France) mardi 7 mars 2017 14:19:57

Thanks you so much guys. I think I understand enough to be able to implement this.

Thanks again…

Thanks guys that works great.

I’ve just finished processing and opening the resulting CSV file in Excel. The strings format perfectly for date and time.

All 50,000 of them!!