Does neo4j supports property data format? - neo4j

Does neo4j natively support data format for node properties? like for example url links (clickable), numbers (integer, float..), date (YYYY/MM/DD).
Or we need to programmatically convert property string to whatever format we need?

Property values in Neo4j could be either Java primitive types (float, double, int, boolean, byte,... ), Strings or array of both. Date objects as property values are not supported.
There are two ways to deal with days:
Store the date as msec since epoc, aka new Date().getTime() (in java)
pro: you can do calculations
pro: less memory/disc consumption as it's stored as a long
con: when just looking at the node, it's hard to infer the date without calculation
Store the date as a string using e.g. SimpleDateFormatter
pro: human readable
con: calculations are hard
Personally I tend to prefer the first one.
In case you need to store time + timezone, you can have two properties. One for the date in msecs based on UTC, another one for the timezone.

Related

Neo4j string or text data types

Trying to work with strings.
Can't find any specs about this data types.
What is the max length os String in Neo4j?
If the limit is 256, is there a larger type, like Text?
In Neo4j there's no distinction between a string and something like TEXT. Property values in Neo4j can be java primitive types (int, long, double, boolean, ...), Strings and arrays of those. Strings in java can have an arbitrary length, same applies for Neo4j.
Be aware that long strings get handled internally different, see http://neo4j.com/docs/stable/property-compression.html#_compressed_storage_of_short_strings. This does not impact the client behaviour but can impact on the performance.

Best way to present the ambiguous extra hour when winter time begins

What is the standard way to present the ambiguous extra hour when winter time begins?
So far i used localized time formats to display and parse dates and times. E.g. 1. January 2014, 15:27.
I'm using location based time zones like "Europe/Berlin".
And i can't just change to plain GMT offsets because i do need to perform calculations on the dates. Otherwise i would get the wrong absolute time when moving across DST change dates.
All this works fine except for the one hour at the end of DST (e.g. October 26th 2014, 2am-3am) which occurs twice. I need to present it in a way that i can later parse again.
Is there a stadardized format? Do i just add a custom symbol? Do i use the GMT offset additionally to the geographic time zone? And how do i know when to use this special format - because i don't want to print it all the time, since it's redundant most of the year.
The answer by Matt Johnson is correct and insightful.
Java 8 & java.time.*
Let me add another to his list, from the new java.time.* classes bundled with Java 8 and defined by JSR 310. These new classes are inspired by Joda-Time but are re-architected.
The default used by java.time.ZonedDateTime is one concatenated string using square brackets around the time zone name and no spaces.
2014-10-26T13:49:48.278+01:00[Europe/Berlin]
#MattJohnson Feel free to merge this answer's content with yours if you wish.
There isn't a standard that combines everything. The closest you can get is with two fields. One which would be an ISO8601/RFC3339 Date+Time+Offset, and another which would be the IANA/Olson time zone.
Depending on your platform, you may have a single object that represents both, such as a DateTime in Joda-Time or a ZonedDateTime in Noda Time. But there is no standardized representation of this as a string.
Here are some that I have seen though:
Two completely separate strings:
"2014-10-26T02:00:00+01:00"
"Europe/Berlin"
One concatenated string, space separated:
"2014-10-26T02:00:00+01:00 Europe/Berlin"
One concatenated string with a space and using parentheses:
"2014-10-26T02:00:00+01:00 (Europe/Berlin)"
One concatenated string without any space, but with square brackets: (thanks Basil)
"2014-10-26T02:00:00+01:00[Europe/Berlin]"
As JSON, with some predetermined field names:
{
value: "2014-10-26T02:00:00+01:00",
zone: "Europe/Berlin"
}
As XML, with some predetermined attribute names:
<TimeStamp Value="2014-10-26T02:00:00+01:00" Zone="Europe/Berlin" />
As XML, with some predetermined element names:
<TimeStamp>
<Value>2014-10-26T02:00:00+01:00</Value>
<Zone>Europe/Berlin</Zone/>
</TimeStamp>
Any of these would be acceptable. Pick the one that fits your situation, or adapt to something similar.
Regarding your question:
... how do i know when to use this special format ...
When you're recording an event that has already passed and cannot be changed, then you do not need to store the time zone. The date+time+offset value alone is sufficient. Otherwise, you need both.

Overriding the system Date Format

In my application I am reading from one database and writing to a second. The app is quick and dirty so I am reading / writing using AsString on both the FieldByName and ParamByName of the queries.
This works for all my use cases apart from where the data type is Date or DateTime
As far as I can tell FieldByName.AsString uses the system ShortDateTime format to return dates as (in my case) dd/mm/yyyy. The database expects the date to be written in as yyyy-mm-dd
According to Delphi Basics I should be able to set ShortDateFormat to what I need, but it appears that in XE5 this is no longer the case (correct?)
Further digging on here returns these two questions that use TFormatSettings to override the local settings. However, both of these use the resulting FormatSettings in StrToDate and FormatDateTime directly.
So two questions
1) Can I tell my application to override the System ShortDateFormat?
2) If so, How (I have a Plan B if not)?
The use of a global variable for the date and time formats was a mistake committed long ago by the original RTL designers. Functions that rely on the global format settings, like the single parameter StrToDate are retained for backwards compatibility, but you should not be using them.
For conversions between date/time and string you should:
Initialise a TFormatSettings instance with your date format.
Call the two parameter StrToDate, passing your TFormatSettings to convert from a string to a date.
Call FormatDateTime overload that accepts a TFormatSettings when converting in the other direction.
Now, to the main thrust of your question. You should not be using strings at all for your dates and times in the scenario you describe. Use AsDateTime rather than AsString. If you happen to have a database column that does store a date/time as a string, then you'll should use the TFormatSettings based conversion functions to work around that design fault.
If you are absolutely dead set on doing this all with strings, and I cannot persuade you otherwise, then you need to use FormatSettings.ShortDateFormat from SysUtils to control your short date formatting.

Converting Date Format in Advantage SQL

I have a simple problem in Advantage Database SQL.
I have dates in the format M/D/YYYY and want to convert them MM/DD/YYYY. Normally in SQL Server I would just use a convert(varchar(20), field, 101) but this does not work in Advantage.
What is the format for doing so?
I don't believe there is a simple conversion function like that available. To convert it directly in SQL would probably turn into a fairly messy statement (I think it would require a combination of CONVERT, YEAR, DAY, and MONTH scalars).
If the goal, though, is to force the display of date values in a specific format in the client application, then one possibility might be to specify the date format at connection time. How you do that depends on the client being used. If, for example, you are using a connection string, then you may be able to specify the date format as follows.
Data Source=\\server\share\yourdatapath;...;DateFormat=MM/DD/YYYY;

Optimal way to store datetime values in SQLite database (Delphi)

I will be storing datetime values in an SQLite database (using Delphi and the DISqlite library). The nature of the db is such that it will never need to be transferred between computers or systems, so interoperability is not a constraint. My focus instead is on reading speed. The datetime field will be indexed and I will be searching on it a lot, as well as reading in thousands of datetime values in sequence.
Since SQLite does not have an explicit data type for datetime values, there are several options:
use REAL data type and store Delphi's TDateTime values directly: fastest, no conversion from string on loading; impossible to debug dates using a db manager such as SQLiteSpy, since dates will not be human-readable. Cannot use SQLite date functions (?)
use a simple string format, e.g. YYYYMMDDHHNNSS: conversion is required but relatively easy on the CPU (no need to scan for separators), data is human-readable. Still cannot use SQLite date functions.
do something else. What's the recommended thing to do?
I have read http://www.sqlite.org/lang_datefunc.html but there's no mention of what data type to use, and, not being formally schooled in programming, I don't quite grok the focus on Julian dates. Why the additional conversion? I will be reading in these values a lot, so any additional conversions between strings and TDateTime adds a significant cost.
You could use one of the SQLite supported string formats, eg. YYYY-MM-DD HH:MM:SS.SSS.
It would be just as easy as YYYYMMDDHHNNSS - you still wouldn't need to scan for separators, since all the numbers are fixed length - and you would get SQLite date function support.
If you need SQLite date function support, I would go with that method.
If not, I'd recommend using REAL values. You can still compare them to each other (higher numbers are later in time), and consider date and time separately (before and after the decimal point respectively) without converting to TDateTime.
One compromise would be to stick with REAL values, but store them as julian dates by using Delphi's DateTimeToJulianDate. That way they remain fast for reading, there's little performance lost in the converation, and they're still in a format that makes sense outside of Delphi.
For this I usually use an Integer data type and store the Unix timestamp value alike (eq # seconds since 1-1-2000 for example). Calculating this t/from a TDateTime is equal to multiplying/diving with/by 86400 and adding a constant for the 'since'.
If you need more precision You could use the DateTime as a FILETIME (eg int64) which has 100 ns increments. There are conversion routines in SysUtils for that and your timestamp is stored in UTC.
If your concern is only human readable format at database level, you can store two separate fields, for example:
DELPHI_DATE REAL (DOUBLE, if possible, but I don't know SQLite), Indexed. All your programmatic queries and comparisons should use this field.
HUMAN_READABLE_DATE Varchar(23) with format 'YYYY-MM-DD HH:MM:SS.SSS'. Maybe indexed (if really necessary). Majority of human input queries should include this field and you can use (as said by others) SQLite date functions.
It has some drawbacks:
Space consumption at database and network traffic grows,
insert operations will take a bit more because necessary conversion,
no automatic synch between values if updated outside your program
If it is suitable for your particular needs, is up to you.
I don't know if this answer is applicable to the DISqlite library but...
Below is some code that illustrates what works for me using both Delphi 2010 and Tim Anderson's SQLite3 wrapper.
SQL to create field:
sSQL := 'CREATE TABLE [someTable] (' +
' [somefield1] VARCHAR(12),' +
' [somefield2] VARCHAR(12),' +
' [myDateTime] DATETIME );';
SQL to populate field:
sSQL := 'INSERT INTO someTable(somefield1, somefield2, myDateTime)' +
' VALUES ( "baloney1", "baloney2","' + FloatToStr(Now) + '");';
Example of retrieving data from field:
var
sDBFilePathString: string;
sl3tbl: TSqliteTable;
fsldb : TSQLiteDatabase;
FromdbDTField : TDateTime;
begin
...
...
fsldb := TSQLiteDatabase.Create(sDBFilePathString);
sl3tbl := fsldb.GetTable('SELECT * FROM someTable');
FromdbDateTime := StrToFloat(sl3tbl.FieldAsString(sl3tbl.FieldIndex['myDateTime']));
Showmessage('DT: ' + DateTimeToStr(FromdbDTField));
end;
Result:
**DT: 10/10/2013 1:09:53 AM**
Like I mentioned on the first line - I don't know if this will work with the DISqlite library but if it does its a pretty clean way of handling things.
I leave it to you to make things prettier or more elegant.

Resources