How to handle dates in neo4j - date

I'm an historian of medieval history and I'm trying to code networks between kings, dukes, popes etc. over a period of time of about 50 years (from 1220 to 1270) in medieval Germany. As I'm not a specialist for graph-databases I'm looking for a possibility to handle dates and date-ranges.
Are there any possibilities to handle over a date-range to an edge so that the edges, which represents a relationship, disappears after e.g. 3 years?
Are there any possibility to ask for relationships who have their date-tag in a date-range?

The common way to deal with dates in Neo4j is storing them either as a string representation or as millis since epoch (aka msec passed since Jan 01 1970).
The first approach makes the graph more easily readable the latter allows you to do math e.g. calculate deltas.
In your case I'd store two properties called validFrom and validTo on the relationships. You queries need to make sure you're looking for the correct time interval.
E.g. to find the king(s) in charge of France from Jan 01 1220 to Dec 31st 1221 you do:
MATCH (c:Country{name:'France'})-[r:HAS_KING]->(king)
WHERE r.validFrom >= -23667123600000 and r.validTo <=-23604051600000
RETURN king, r.validFrom, r.validTo
addendum
Since Neo4j 3.0 there's the APOC library which provides couple of functions for converting timestamps to/from human readable date strings.

You can also store the dates in their number representation in the following format: YYYYMMDD
In your case 12200101 would be Jan 1st 1220 and 12701231 would be Dec 31st 1270.
It's a useful and readable format and you can perform range searches like:
MATCH (h:HistoricEvent)
WHERE h.date >= 12200101 AND h.date < 12701231
RETURN h
It would also let you order by dates, if you need to.

As of Neo4J 3.4, the system handles duration and dates, see the official documentation. See more examples here.
An example related to the original question: Retrieve the historical events that happened in the last 30 days from now :
WITH duration({days: 30}) AS duration
MATCH (h:HistoricEvent)
WHERE date() - duration < date(h.date)
RETURN h

Another option for dates that keeps the number of nodes/properties you create fairly low is a linked list years (earliest year of interest - latest year), one of months (1-12), and one of dates in a month (1-31). Then every "event" in your graph can be connected to a year, month, and day. This way you don't have to create a new node for every new combination of a year month and day. You just have a single set of months, one of days, and one year. I scale the numbers to make manipulating them easier like so
Years are yyyy*10000
Months are mm*100
Date are dd
so if you run a query such as
match (event)-[:happened]->(t:time)
with event,sum(t.num) as date
return event.name,date
order by date
You will get a list of all events in chronological order with dates like Janurary 17th, 1904 appearing as 19040117 (yyyymmdd format)
Further, since these are linked lists where, for example,
...-(t0:time {num:19040000})-[:precedes]->(t1:time {num:19050000})-...
ordering is built into the nodes too.
This is, so far, how I have liked to do my event dating

Related

How can I make a database structure in mongodb for saving the date range?

Here I'm saving the date range using golang. Suppose we have to save the all monday comes between the range of the 1-may-2018 to 14-july-2018.
How we will find all the monday between these range using golang and on the other hand we have set the start_time (8:00 A.M.) and the end_time (6:00 P.M.) of the first two coming monday in the database but on the third monday we have a change in the schedule that there is a time change like start_time (9:00 A.M.) and end_time (5:00 P.M.). Then how I will make my database to make this situation in practically using the golang.
Can Anybody help me for this to solve this solution. I made a database for and I do ppr work on it and make some fields shown below:-
Fields for Schedule //Schedule is a collection name
Id (int)
Day (string)
Start_hours (int)
Start_minutes (int)
End_hours (int)
End_minutes (int)
Start_date (timestamp)
End_date (timestamp)
How I will select monday between the selected range and how will I do the situation I explained above can anybody give guidance to me to make this situation easier. Thank you if this is a basic question then I'm really sorry.
I'd make something like this.
Find the first Monday date from the date range (see for example How do I get the first Monday of a given month in Go?
Mondays happen every week, so you can easily find the rest of dates by adding 7 days till the end date
Store all the Monday dates you found with the start and end times
I wouldn't bother with hours and minutes as you can easily get them from the timestamps in Go. Here is the simplified DB structure I would make
Fields for Schedule //Schedule is a collection name
Id (int)
Day (string)
Date (timestamp) // the actual date
Start (timestamp)
End (timestamp)
You don't need any more fields. You can get the day of the week (Day (string) in your structure, e.g. Monday) from the Date field too, but I believe if you want to query the collection by different days, this might speed things up, but be careful if you need to adjust for time zones. If you work with more than one, then store everything in UTC and you may have an extra filed Timezone, cos a date could be Monday for one zone and Sunday for another.
So, the Schedule will hold weekdays and start and end times for each of them. I'm not sure if you need to store initial date ranges, the Schedule collection will hold that range as well, form the first record to the last one. In my mind, I'd initially populate the collection with a given date range, then later on, I can modify it by adding new days, or deleting them.
When you query this collection with some start and end date range for the Date field, if your first result comes newer than 7 days from the start, this means you miss 1 or more entries from the start. If the last result comes older than 7 days from the range end, this means you miss some entries prior to the range end.
There is nothing specific to Go, in my opinion, Go works well with dates and you don't need any special date structures in your DB.

Storing dates as nodes in Neo4j

I'm new to Neo4j so maybe I'm just completely wrong on this, but I'll give it a try!
Our data is mostly composed by reservations, users and facilities stored as nodes.
I need both to count the total reservations that occurred in a specific time frame and the overall income (stored as reservation.income) in this timeframe.
I was thinking to overcome the problem by creating the date as a node, in this way I can assign a relationship [:PURCHASED_ON] to all the reservations that occurred on a specific date.
As far as I've understood, creating the date as a node could give me a few pros:
I could split the date from dd/mm/yyyy and store them as integer properties, in this way I could use mathematical operators such as > and <
I could create a label for the node representing each month as a word
It should be easier to sum() the income on a day or a month
Basicly, I was thinking about doing something like this
CREATE (d:Day {name:01/11/2016 day: TOINT(01), month: TOINT(11), year: TOINT(2016)}
I have seen that a possible solution could be to create a node for every year, every month (1-12) and every day (1-31), but I think that would just complicate terribly the architecture of my Graph since every reservation has an "insert_date" (the day it's created) and then the official "reservation_date" (the day it's due).
Am I onto something here or is it just a waste of time? Thanks!
You may want to look at the GraphAware TimeTree library, as date handling is a complex thing, and this seems to be the logical conclusion of the direction you're going. The TimeTree also has support for finding events attached to your time tree between date ranges, at which point you can perform further operations (counting, summing of income, etc).
There are many date/time functions in the APOC plugin that you should take a look at.
As an example, you can use apoc.date.fields (incorrectly called by the obsolete name apoc.date.fieldsFormatted in the APOC doc) to get the year, month, day to put in your node:
WITH '01/11/2016' AS d
WITH apoc.date.fields(d, 'MM/dd/yyyy') AS f
CREATE (d:Day {name: d, day: f.days, month: f.month, year: f.years});
NOTE: The properties in the returned map have names that are oddly plural. I have submitted an issue requesting that the names be made singluar.

Should I break down a date field into month, day, and year in core data to easily group and fetch date by month and year?

How do I perform an equivalent of SQL extract/fetch records by month and year from a date in swift?
Two requirements are as follows:
List records by Month and Year
September 2015
October 2015
Display transactions falling under the Year and Month.
Edit: I do mean core data. Rephrased "equivalent in SQL" to equivalent of SQL" to clarify.
CoreData will store dates as doubles, which is the internal format for NSDate.
If you have a small database, just store the values as NSDate and filter based on that.
However, if you have a large database, you may want to denormalize your data a bit more.
You could store another field, say in "yyyymmdd" format, which gives you most of the filtering you require.
For finer grained control, you can also keep separate attributes for year, month, and day.
You may want to setup those fields as indexes as well, if you do lots of searching over vast amounts of data.
Remember, CoreData uses SQLite under the hood for most databases, but it's behavior characteristics are very different.
There is no universal "best" way, as it depends entirely on your data and how you use it.

How to select all mondays (or any weekday combination, e.g.: MTW, WTTh, etc.) between two given dates in MySQL?

What I see over the internet is just counting how many days occur whenever you input the day of the week you need. Like between May 1 to May 31, how many mondays are there in it. What I need is to display the dates where it is monday between two given dates. I don't have any code for this now since I don't really know where to start as I've scanned already the MySQL docu but I haven't seen anything useful besides
WEEKDAY('1998-02-03 22:23:00')
or
DAYOFWEEK('1998-02-03')
which shows the day index of a certain date. (but this time, of course, I don't know which dates fall on Mondays., i need the reverse thing)
I need is when I need mondays and tuesdays in february, it will return the following:
2015-02-02
2015-02-03
2015-02-09
2015-02-10
2015-02-16
2015-02-17
2015-02-23
2015-02-24
I dont have any code to display since my progresses in mysql on our proj isn't directly related to this one I'm needing. This is another independent mysql query of our proj I'm trying to get done..

Matlab- Changing uniques date code values to more manageable data

I have a variable called sentDate which stores the month and day from Nov 27th - Dec 6th.Each day has a number of sentiment ratings that it represents therefore I need to assign unique day codes to each day so I can perform...
allSents(dayCodes==1)
So far I have managed to assign day codes using...
[a,b,dayCodes]=unique(sentDate);
[d,e,allSents]=unique(sentiment);
However the day codes take the last digit on the date e.g 27th becomes 7, 28th becomes 8, etc. I need it so the day codes start from 1 and increase for each day until the 6th of December, therefore 1-11.
Any idea on how I may do this ?
have you tried the datenum function? then subtract off whatever offset to give the appropriate start day number.
For those who may have a similar problem, by specifying stable in as a parameter e.g
[a,b,dayCodes]=unique(sentDate,'stable');
Will specify the daycodes in the same order as in sentDate.