How can I Add Days to a date property in Cypher? - date

I have been working on a readmission issue using a clinical graph dataset. Let's say a patient is being readmitted within 30 days. So, this means I need add 30 days to the first date (visit date) for the second visit date.
Here is the Cypher query:
MATCH(p:Person)-[r:PATIENT_HAS]->(e:Encounter)
WITH p,e
MATCH (p)-[r:PATIENT_HAS]-(e2:Encounter) WHERE e2.ADMIT_DATE < (e.ADMIT_DATE + 30)
This query won't work because the date property is in YYYYMMDD format. For example, if it is 20151225, it will give 20151255. But I need to get it as 20160124 after adding 30 days. Is there any other way to use a different format than YYYYMMDD. I know that there is string format as YYYY-MM-DD, but what is the way to use this format for adding days?
How can accomplish this?
I would appreciate your help.

The best way to deal with dates in Neo4j in my opinion is to have them saved as UNIX epoch time in miliseconds or seconds. We have a great plugin in Neo4j called apoc procedures that allows you to use awesome procedures. In your specific case I would utilize apoc.date.*procedures and parse your date format to epoch time in seconds.
MATCH (e:Encounter)
WITH e,apoc.date.parse(e.ADMIT_DATE,"s","YYYYMMDD") as unix
set e.unix = unix
So now your query would look like :
MATCH(p:Person)-[r:PATIENT_HAS]->(e:Encounter)
MATCH (p)-[r:PATIENT_HAS]-(e2:Encounter)
WHERE e2.unix < e.unix + (30 * 24 * 60 * 60)
Ofcourse you can simplify this query and make it shorter:
MATCH (e2:Encounter)-[r:PATIENT_HAS]-(p:Person)-[r:PATIENT_HAS]->(e:Encounter)
WHERE e2.unix < e.unix + (30 * 24 * 60 * 60)

You can construct a Duration, and add it directly to a date.
Here is an example in Cypher:
RETURN Date() + Duration({days: 30})
Reference: https://neo4j.com/docs/cypher-manual/current/functions/temporal/duration/

I'm currently using Neo4j 4.0.3 and the following works:
RETURN REPLACE(toString(date('20151225') + duration('P30D')),'-','')
// "20160124"

We found out a temporary solution: We are setting a specific date in the past (1/1/2009 in our case), and are getting the difference between the first visit (e.ADMIT_DATE-1/1/2009) and the second visit (e2.ADMIT_DATE-1/1/2009) as days. Then we are able to get the difference between the first and second visits (e2.DAYS-e.DAYS) to figure out 30 days for the readmission criteria.
I had checked out the apoc procedures plugin and it seemed a bit complicated. But I can definitely retry it. Many thanks for your great responses folks.

Related

RethinkDB Filter for range of dates and times

My database table has the timestamp format "2019-12-08T13:03:16.502639-0600". I am having difficult figuring out how to filter a 24 hour range of dates so I only get the data plucked from inside that 24 hour running period of time. I need something like now() then back 24 hours on a running basis. I have tried several ways but none of them work.
Do I need to parse the timestamp first and only use the parts I need?
In Python, the query could look like this:
r.table('MyDB').filter(r.row['timestamp'] > r.now() - 24*60*60).run(con)

Facebook Graph API query for updates in the last 24 horus

I am using Facebook Graph API to query for data; however, I only want the data updated in the 24 hours or something like that.
For example,
get('https://www.facebook.com/v2.10/me/adaccounts?fields=name,id&last_updated=onedayago')
I can't seem to find anything regarding this in their documentation.
I know of &until=timestamp and &since=timestamp. They take a UNIX timestamp as argument. &since=1502213821 would be since now (amount of seconds since 01-01-1970). Since your question is about relative time, I suggest you use your programming language to generate the UNIX timestamp according to your preferred timerange.
In PHP that would be time() - (24 * 60 * 60) for 24 hours ago.

Calculate an older date in Freemarker

I need to create a calendar control for selecting Date of Birth. My custom calendar control has fields for setting minDate and maxDate that can be used to set the range of dates that can be selected.
I can get the present date into a variable and use it as maxDate as below.
<#assign dateObject=.now/>
<#assign todaysDate=dateObject?date/>
How can I calculate a date around 100 years prior in a similar way? I read through the official documentation and could not find any operation that could do this.
You aren't meant to calculate such things in the MVC View... the date range to display should come from the data-model. Anyway, you will need GregorianCalendar arithmetic for this, and FreeMarker has no such thing built into. But you can write a Java method to do that and then just call that from the template.
BTW, the naive way of doing this is (.now?long - 1000 * 60 * 60 * 24 * daysBefore)?numberToDate. The problem with this is that you can have a duplicate or skipped day if .now is near midnight, and some days in the range hit a daylight saving change.

How to easily convert seconds to a timestamp (HH:MM:SS) in MDX

What is a way to easily convert seconds to a timestamp (HH:MM:SS) in MDX? I'd also like to look into providing days in that as well. I was going to go through and use a bunch of calculated members as the values and then format them all into one string, but it seems like there has to be a better and cleaner way to do it.
You could just divide the seconds by 3600 * 24 so you have days, and then use a format string like this:
with member measures.duration as seconds / (3600.0 * 24.0)
,format_string = 'hh:mm:ss'
If you have durations of more than one day, then this can get a bit tricky, but you can find a solution here: http://sqlblog.com/blogs/mosha/archive/2008/09/26/displaying-duration-values-mdx-expressions-in-format-string.aspx
here is an example to do it:
WITH MEMBER [Measures].[TimSpent (HH:MM:SS)] AS '[Measures].[Timespent]/ 86400', FORMAT_STRING = "hh:mm:ss"
SELECT [Assignment].[Element].[Element] ON ROWS, {[Measures].[Timespent], [Measures].[TimSpent (HH:MM:SS)]} ON COLUMNS
FROM [Activity]

Parsing "date" field of iPhone SMS file from backup

While this isn't a programming question per se, it IS related.
So I'm trying to figure out how to parse the SMS DB that gets backed up from the iPhone. I'm looking at the "messages" table, specifically the "date" field. I noticed that the more recent messages are using a different numbering system to indicate the date/time. I've narrowed it down to the switch to iMessage, as I have a message sent at 1318470904, with a reply sent at 340164736. I know for a fact that these messages were sent less than an hour apart, yet they're indicating > 30 years' difference.
Anybody know how to accurately calculate the date using this newer system? Is it using a different epoch or is there some crazy math I need to do?
Edit: Recent messages are affected as well. Texts (green bubbles) are stored with the date set normally, and anything through iMessage (blue bubbles) is stored with the different date representation.
Since the backup is exported to SQLite database format, here's how to convert the number to a real date in SQLite:
select
datetime(date + strftime('%s', '2001-01-01 00:00:00'),
'unixepoch', 'localtime') as date,
*
from message
I don't know about getting the correct date given two versions present, but when I did this today, I noticed the date column was not the standard unix time but a longer number with seemingly nine zeros at the end, like 444548608000000000. This is what I did to get the correct date:
select
datetime(substr(date, 1, 9) + 978307200, 'unixepoch', 'localtime') as f_date,
text
from message
It is in seconds since 1/1/2001 instead of the others which are Unix based off of 1/1/1970. So to convert it to say an Excel time your formula would be =Cell/(60*60*24) + "1/1/2001".
Apple uses Mac Absolute Time (MacTime). This is counted from 01-01-2001. The other timestamp you see is UnixTime. This starts from 01-01-1970.
You have to add 31 years to MacTime to get UnixTime. This is a PHP-snippit:
$macTime = $d['ZMESSAGEDATE']; // MacTime column (from Whatsapp)
$unixTime = $macTime + 978307200;
echo date("Y-m-d H:i:s", $unixTime);
The time difference is calculated using this website:
https://www.timeanddate.com/date/durationresult.html?d1=1&m1=1&y1=1970&d2=1&m2=1&y2=2001&h1=0&i1=0&s1=0&h2=0&i2=0&s2=0
There may be another answer.
=Cell/(60*60*24) + "1/1/1970"
works with my current version of the iPhone/iOS => 4.3.3
Fomurla with time of messages:
=Cell/(60*60*24) + "1/1/2001 7:00"
Since date in mac is calculated from 2001 and not 1970, we have to add some extra to this mac date.
978307200000 is equivalent to milliseconds until 2001-01-01
Also multiplying by 1000 is required to convert to milli-seconds.
macDate * 1000 + 978307200000
Bohemian♦ is right, but there's a little typo in his answer:
use %S (capitals) instead of %s, since the time is represented in seconds since 2001 and not 1970!
Doc from https://www.sqlite.org/lang_datefunc.html
%s seconds since 1970-01-01
%S seconds: 00-59
select
datetime(date + strftime('%S', '2001-01-01 00:00:00'),
'unixepoch', 'localtime') as date,
*
from message