Is there a way to select the xml file with prompt as the inpuit file
then convert
1482156852197
to whatever it means as Day/Month/Year or some other format
and
30
to Time
I was not sure of the starting date. According to StefanK’s message here I use 1970/01/01 which is the one used internally by Numbers but I guess that you may get the conversion with something like :
For those trying to run the fine StefanK’s answer, take care that two characters are missing at the end of the sample dataset posted by danwan. We must add “s>”
the date value is a UNIX timestamp, the interval since 1970 in milliseconds, to get seconds you have to divide the value by 1000.
To parse the XML use System Events, the easiest way to create the dates is AppleScriptObjC
use AppleScript version "2.5" -- El Capitan (10.11) or later
use scripting additions
use framework "Foundation"
set xmlPath to (choose file) as text
tell application "System Events"
set theXMLFile to XML file xmlPath
tell XML element "callhistory" of XML element "CallHistoryRecords" of theXMLFile
set xmlDate to value of XML element "date"
set xmlDuration to value of XML element "duration"
end tell
end tell
-- create the dates from the timestamp
set startDate to (current application's NSDate's dateWithTimeIntervalSince1970:(xmlDate / 1000))
set endDate to startDate's dateByAddingTimeInterval:xmlDuration
-- coerce the dates to AppleScript dates
set asStartDate to startDate as date
set asEndDate to endDate as date
Edit:
I was wrong to suggest AppleScriptObjC as the easiest way to create the dates. AppleScript can do it as well
set xmlPath to (choose file) as text
tell application "System Events"
set theXMLFile to XML file xmlPath
tell XML element "callhistory" of XML element "CallHistoryRecords" of theXMLFile
set xmlDate to value of XML element "date"
set xmlDuration to value of XML element "duration"
end tell
end tell
set referenceDate to "1/1/1970"
set startDate to (date referenceDate) + xmlDate / 1000
set endDate to startDate + xmlDuration
Those coercions require at least macOS 10.11. Otherwise you need something like:
on makeASDateFrom:theNSDate
set theCalendar to current application's NSCalendar's currentCalendar()
set comps to theCalendar's componentsInTimeZone:(missing value) fromDate:theNSDate
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:
Thanks to StefanK and Shane STANLEY, below is an ASObjC version able to apply since 10.10
use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
use framework "Foundation"
set xmlPath to (choose file) as text
set OSversion to (system attribute "sys2") # system attribute belongs to Standard Additions
tell application "System Events"
set theXMLFile to XML file xmlPath
tell XML element "callhistory" of XML element "CallHistoryRecords" of theXMLFile
set xmlDate to value of XML element "date"
set xmlDuration to value of XML element "duration"
end tell
end tell
-- create the dates from the timestamp
set startDate to (current application's NSDate's dateWithTimeIntervalSince1970:(xmlDate / 1000))
set endDate to startDate's dateByAddingTimeInterval:xmlDuration
-- coerce the dates to AppleScript dates
if OSversion > 10 then
set asStartDate to startDate as date
set asEndDate to endDate as date
else
set asStartDate to my makeASDateFrom:startDate
set asEndDate to my makeASDateFrom:endDate
end if
{asStartDate, asEndDate} # ADDED on 2016/12/21
on makeASDateFrom:theNSDate
set theCalendar to current application's NSCalendar's currentCalendar()
set comps to theCalendar's componentsInTimeZone:(missing value) fromDate:theNSDate
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:
I’m aware of that Stefan.
My problem was that I don’t know which value is relevant for the asker.
We don’t know if he must compare dates from different sources so one ‘format’ may be better than the other one.
It’s really efficient.
I replaced the date value by 1471788852197 and ran the script.
The result became : date “dimanche 21 août 2016 à 16:22:38”
As you may see, this time it is correctly at summer hour.
are practically the same (the same moment in time), the appearance is different due to the different time zones.
Both Foundation NSDate and AppleScript date are actually wrapper for a number. They don’t know time zones.
UNIX dates are always in UTC.
Here on MacScripter the dates are displayed in UTC if you are not logged in and in your local time zone if you are. But the source of the date is the same.
If I run your original script, asStartDate is returned as:
date “Tuesday, 20 December 2016 at 1:14:12 am”
Your native version returns startDate as:
date “Monday, 19 December 2016 at 2:14:12 pm”
They differ by my UTC offset.
The question, really, is whether whatever is producing the original XML is using local time or UTC. If it’s local time, the AS result is correct; if it’s UTC, the other is correct.
Only the OP can tell us which it is, by doing a test.
If we asume that here, then you need to add time to GMT as above.
If I apply to my late example with 1471788852197 I get :
date “dimanche 21 août 2016 à 14:22:38”
but I can’t get time to GMT applying to this date, I just have the current value : 1 hour so
date "dimanche 21 août 2016 à 14:22:38" + (date to GMT) → date “dimanche 21 août 2016 à 15:22:38”
while ASObjC gives the correct value - date “dimanche 21 août 2016 à 16:22:38” - the one according to the fact that 21 août is in summer hour (with an offset of 2 hours)
My point of view is that choosing the used scheme is crucial.
If the other date values used by the asker are built by ‘old fashioned’ AppleScript, the correct choice would be to use the same ‘old fashionned’ AppleScript to decipher the Xml datas.
If the other dates used by the asker are built by ASObjC code, the correct choice would be to use ASObjC code to decipher the Xml datas.
It’s only if the dates extracted from Xml datas aren’t used with other dates that the user may freely choose the scheme.
date to GMT returns always the current difference to GMT/UTC, while Cocoa uses the powerful (NS)Calendar class under the hood considering daylight saving status of the affected date.
Thanks you all for your help: some explanation
I am trying to decode a rather long XML file from an utility for mac which records the phone calls with an android (Samsung7) phone
My phone is set to my current time which is GMT+1
The result for the
1482156852197
gives me
Monday 19 December 2016 14:22:38
While the phone log screen tells me
Monday 19 December 2016 15:14 (no seconds)
I think the 1482156852197
tells the ending time and gives a duration of 8mins and 26 secs
As for the script I only put one
1481955455195
as an example but the file is quite long and I hope to be able to import everything in FIlemaker.
the XML format is
<?xml version="1.0" encoding="utf-8" ?>
+212386801
1482156852197
506
1
and it ends with
and
include all the data for the calls
Thanks again for the help
Danwan
Thank you Yvan
However I have a small problem still and I don’t know how to solve
the file complete XML is quite long and I hope to be able to import everything in FIlemaker.
so each file separated by a Carrige return can be imported as a FILREMAKER record
the XML format is
<?xml version="1.0" encoding="utf-8" ?>
+212386801
1482156852197
506
1
and it ends with
and
include all the data for the calls
Thanks again for the help
Danwan
Online
set xmlPath to (choose file) as text
tell application "System Events"
set theXMLFile to XML file xmlPath
set callHistoryRecords to XML element "CallHistoryRecords" of theXMLFile
repeat with anElement in XML elements of callHistoryRecords
tell anElement
set xmlDate to value of XML element "date"
set xmlDuration to value of XML element "duration"
-- do something with the values
end tell
end repeat
end tell