what does the #> operator in postgres do? - postgresql

I came across a query in postgres here which uses the #> operator on earth objects.
I've searched everywhere, but have come up empty on the meaning of this operator (and likely others like it, eg: #<, etc...).
> is obvious. I also found that # will take the absolute value of something. So my best guess is this does an absolute greater than comparison of two values?
Is that correct? Is this documented somewhere in the postgres docs? I'm even more curious to understand what the operator does on earth objects.
Thanks!

In general #> is the "contains" operator.
It is defined for several data types.
arrays: http://www.postgresql.org/docs/current/static/functions-array.html
range types: http://www.postgresql.org/docs/current/static/functions-range.html
geometric types: http://www.postgresql.org/docs/current/static/functions-geometry.html
JSON (and JSONB): http://www.postgresql.org/docs/current/static/functions-json.html

According to the PostgreSQL Official Documentation
interval values can be written using the following verbose syntax:
[#] quantity unit [quantity unit...] [direction]
where quantity is a
number (possibly signed); unit is microsecond, millisecond, second,
minute, hour, day, week, month, year, decade, century, millennium, or
abbreviations or plurals of these units; direction can be ago or
empty. The at sign (#) is optional noise. The amounts of the different
units are implicitly added with appropriate sign accounting. ago
negates all the fields. This syntax is also used for interval output,
if IntervalStyle is set to postgres_verbose.

Related

Operating with datetimes in SQLite

I'm interested in knowing the different possibilities to operate with datetimes in SQLite and understand its pros and cons. I did not find anywhere a detailed explanation of all the alternatives.
So far I have learned that
SQLite doesn't actually have a native storage class for timestamps /
dates. It stores these values as NUMERIC or TEXT typed values
depending on input format. Date manipulation is done using the builtin
date/time functions, which know how to convert inputs from the other
formats.
(quoted from here)
When any operation between datetimes is needed, I have seen two different approaches:
julianday function
SELECT julianday(OneDatetime) - julianday(AnotherDatetime) FROM MyTable;
Number of days is returned, but this can be fractional.
Therefore, you can also get some other measures of time with some extra operations. For instance, to get minutes:
SELECT CAST ((
julianday(OneDatetime) - julianday(AnotherDatetime)
) * 24 * 60 AS INTEGER)
Apparently julianday could cause some problems:
Bear in mind that julianday returns the (fractional) number of 'days'
- i.e. 24hour periods, since noon UTC on the origin date. That's usually not what you need, unless you happen to live 12 hours west of
Greenwich. E.g. if you live in London, this morning is on the same
julianday as yesterday afternoon.
More information in this post.
strftime function
SELECT strftime("%s", OneDatetime)-strftime("%s", AnotherDatetime) FROM MyTable;
Number of seconds is returned. Similarly, you can also get some other measures of time with some extra operations. For instance, to get minutes:
SELECT (strftime("%s", OneDatetime)-strftime("%s", AnotherDatetime))/60 FROM MyTable;
More information here.
My conclusion so far is: julianday seems easier to use, but can cause some problems. strftime seems more verbose, but also safer. Both of them provide only as results a single unit (either days or hours or minutes or seconds), but not a combination of many.
Question
1) Is there any other possibility to operate with datetimes?
2) What would be the best way to get directly the difference of two datetimes in time format (or date or datetime), where datetime would be formatted as 'YYYY-mm-dd HH:MM:SS', and the result would be something in the same format?
I would have imagined that something like the following would work, but it does not:
SELECT DATETIME('2016-11-04 08:05:00') - DATETIME('2016-11-04 07:00:00') FROM MyTable;
> 01:05:00
Julian day numbers are perfectly safe when computing differences.
The only problem would be if you tried to convert them into a date by truncating any fractional digits; this would result in noon, not midnight. (The same could happen if you tried to store them in integer variables.) But that is not what you're doing here.
SQLite has no built-in function to compute date/time differences; you have to convert date/time values into some number first. Whether you use (Julian) days or seconds does not really matter from a technical point of view; use whatever is easier in your program.
If you started with a different format, you might want to convert the resulting difference back into that format, e.g.:
time(difference_value, 'unixepoch') -- from seconds to hh:mm:ss
time(0.5 + difference_value) -- from Julian days to hh:mm:ss

Can different PostgreSQL timestamps be equal?

Sometimes, I see ORDER BY date, id. Why is id needed?
How can two different times ever be equal?
What is the precision of timestamp?
You asked about "ORDER BY date, id." but then mention timestamp. A field named date might be of type timestamp or date like 'YYYY/MM/DD' in which case order by id would be relevant
Since timestamps are discrete values there can be multiple timestamps with the same value regardless of the precision. The bigger the precision the least likely is a collision. An untie criteria is necessary if that is relevant.

What does a negative integer Date value mean in MongoDB?

I've discovered an issue with some of data being stored in MongoDB. We have a field that stores a Date, and normally this includes values like ISODate("1992-08-30T00:00:00.000Z") or ISODate("1963-08-15T00:00:00.000Z"). That's nice and straight-forward; I can easily look at those dates and see August 30, 1992 or August 15, 1963.
However, I've noticed a couple of entries where the date looks something like this instead:
Date(-61712668800000)
I'm honestly not sure how the data got persisted that way in the first place, as it should have been stored the former way. And I'll have to address the software bug with my code that is intermittently causing it to be stored that way.
However, the bigger problem is what to do with data entries that look like that. I'm not even sure what date that was supposed to be. My first assumption is that it's just milliseconds, like a UNIX timestamp or something, but that's not right. Even if I flip the negative sign and remove some of the trailing zeros, that still ends up being a date way in the future (e.g. July 23, 2165), and that's not correct. It should be a date in the past.
And the other big problem is that I'm not sure how to even search for this in the database. I can't utilize a $type query because the type is still 9 (i.e. it still thinks it's a "Date").
Has anyone else encountered these weird date entries before? How can I find them? And how can I recover the actual date from them?
The problem seems to be that your code is storing dates prior to the epoch, which are furthermore so far into the past that they cannot be represented using an ISODate wrapper:
As per the documentation
(emphasis added)
Date
BSON Date is a 64-bit integer that represents the number of
milliseconds since the Unix epoch (Jan 1, 1970). This results in a
representable date range of about 290 million years into the past and
future.
The official BSON specification refers to the BSON Date type as the
UTC datetime.
Changed in version 2.0: BSON Date type is signed. [2] Negative values
represent dates before 1970.
Although not explicitly stated in the Mongo documentation, it appears that they are following a strict interpretation of the ISO 8601 standard and not one of the variants which are allowed "by trading partner agreement" based on what I found at wikipedia
Years
YYYY ±YYYYY ISO 8601 prescribes, as a minimum, a
four-digit year [YYYY] to avoid the year 2000 problem. It therefore
represents years from 0000 to 9999, year 0000 being equal to 1 BC and
all others AD. However, years prior to 1583 are not automatically
allowed by the standard. Instead "values in the range [0000] through
[1582] shall only be used by mutual agreement of the partners in
information interchange."[9]
To represent years before 0000 or after 9999, the standard also
permits the expansion of the year representation but only by prior
agreement between the sender and the receiver.[10] An expanded year
representation [±YYYYY] must have an agreed-upon number of extra year
digits beyond the four-digit minimum, and it must be prefixed with a +
or − sign[11] instead of the more common AD or BC (or the less widely
used BCE/CE) notation; by convention 1 BC is labelled +0000, 2 BC is
labeled -0001, and so on.[12]
If you read through the rest of the article you will also see that the reason the number of digits must be pre-defined is so that the date can be stored unambiguously without using separator characters such as "-" between the components.

Arangodb days between timestamps

Are there any built-in functions to find out the number of days between timestamps, add days, or find number of months between timestamps? Currently I'm storing dates in my documents as strings.
For example, if I do:
return (DATE_TIMESTAMP("2014-2-1") - DATE_TIMESTAMP("2014-1-1")) / 86400000
I receive:
[
31
]
which is the correct number of days that I'm looking for. Just wanted to check and see if there are any built-in functions or is there any plan to add them.
I can confirm that there currently is no built-in function to calculate the number of days or months between two given dates or timestamps.
I am not aware of any plans to add such functions soon, so it's best to calculate the differences like in your above code or, for anything more complex, a user-defined function.

Check if one given date is between two dates several years apart?

Todays date is 31.03.2011 (European, at least).
A hotel room is booked from, lets say, 23.02.2011 to 05.05.2013 (yes, over two years!).
How can I check if todays date is in between the reserved dates or not?
Ideally I want to sort it into an boolean array of 3 dimensions, like date(year,month,day) and TRUE means "booked".
Preferred language is VBScript because this is my only option, but Java/C whatever is also okay to use as an example to work from (text explaining the solution is of course also okay).
Thank you!
Don;t know VBScript but the time/date library can normally return times in an integer format (typically seconds since 1970). Just convert the three dates to this format and check using the normal compare operators
VBScript Functions notes a Datedifffunction that you could use with the 3 variables representing each point in time. Course there are other solutions to this like converting the date to another type and using that for comparison,e.g. concatenate yyyyMMdd into an integer and compare them that way.
checkIn=DateSerial(2011,02,23)
checkOut=DateSerial(2013,05,05)
testMe=Now
If testMe>checkIn And testMe<checkOut Then
MsgBox("Living the good life.")
End If