98 votes

Différence d'horodatage en heures pour PostgreSQL

Existe-t-il un TIMESTAMPDIFF() équivalent pour PostgreSQL?

Je sais que je peux soustraire deux horodatages pour obtenir un postgresql INTERVAL . Je veux juste la différence entre les deux horodatages en heures représentés par un INT.

Je peux le faire dans MySQL comme ceci:

 TIMESTAMPDIFF(HOUR, links.created, NOW())
 

J'ai juste besoin de la différence entre deux horodatages en heures représentés sous forme d'entier.

La solution fonctionne pour moi:

 SELECT "links_link"."created",
"links_link"."title",
(EXTRACT(EPOCH FROM current_timestamp - "links_link"."created")/3600)::Integer AS "age" 
FROM "links_link"
 

128voto

La première des choses à éclater

EXTRACT(EPOCH FROM current_timestamp-somedate)/3600

Peut-être pas assez, mais débloque la route. Pourrait être plus joli, si la division de l'intervalle par intervalle a été défini.

Edit: si vous voulez qu'elle est supérieure à zéro, soit l'utilisation de l'abs ou plus(...,0). Celui adapté à votre intention.

Edit++: la raison pour laquelle je n'ai pas utiliser age que age avec un seul argument, pour citer la documentation: Soustraire de current_date (à minuit). Ce qui signifie que vous n'obtenez pas un précis de "l'âge", à moins que l'exécution à minuit. Maintenant, c'est presque 1 heure du matin ici:

select age(current_timestamp);
       age        
------------------
 -00:52:40.826309
(1 row)

45voto

Eric Leschinski Points 14289

Obtenez les champs où un horodatage est supérieur à la date dans postgresql:

 SELECT * from yourtable 
WHERE your_timestamp_field > to_date('05 Dec 2000', 'DD Mon YYYY');
 

Soustrayez les minutes de l'horodatage en postgresql:

 SELECT * from yourtable 
WHERE your_timestamp_field > current_timestamp - interval '5 minutes'
 

Soustraire des heures de l'horodatage en postgresql:

 SELECT * from yourtable 
WHERE your_timestamp_field > current_timestamp - interval '5 hours'
 

25voto

ShawnFumo Points 445

Michael Krelin la réponse est proche n'est pas entièrement sûr, car il peut être mal dans de rares situations. Le problème est que les intervalles dans PostgreSQL n'ont pas de contexte en ce qui concerne des choses comme l'heure d'été. Les intervalles de stocker des choses en interne comme les mois, les jours et les secondes. Mois ne sont pas un problème dans ce cas, car la soustraction de deux horodatages juste utiliser des jours et des secondes, mais 'jours' peut être un problème.

Si votre soustraction implique l'heure d'été changement-overs, un jour particulier, pourrait être considéré comme 23 ou 25 heures respectivement. L'intervalle d'en tenir compte, ce qui est utile pour connaître le nombre de jours qui s'est passé dans le sens symbolique, mais ce serait donner un mauvais nombre réel des heures qui passaient. L'époque sur l'intervalle il suffit de multiplier tous les jours par 24 heures.

Par exemple, si une "courte" pass d'un jour et d'une heure de la prochaine journée, l'intervalle sera comptabilisé comme un jour et une heure. Qui a converti à l'époque/3600 est de 25 heures. Mais en réalité, 23 heures + 1 heure doit être un total de 24 heures.

De sorte que la plus sûre méthode est la suivante:

(EXTRACT(EPOCH FROM current_timestamp) - EXTRACT(EPOCH FROM somedate))/3600

Comme Michael l'a mentionné dans son suivi de commentaires, vous aurez aussi probablement besoin d'utiliser étage() ou ronde() pour obtenir le résultat sous forme de valeur entière.

14voto

araqnid Points 33350

Vous pouvez utiliser la fonction "extraire" ou "date_part" fonctions sur des intervalles ainsi que l'horodatage, mais je ne pense pas qu'est-ce que vous voulez. Par exemple, cela donne 3 pour un intervalle de " 2 jours, 3 heures. Cependant, vous pouvez convertir un intervalle d'un nombre de secondes en spécifiant "époque" comme le temps de l'élément que vous souhaitez: extract(epoch from '2 days, 3 hours'::interval) retours 183600 (ce qui permet ensuite de diviser par 3600 pour convertir quelques secondes à plusieurs heures).

Donc, en mettant tout cela ensemble, vous obtenez fondamentalement Michael réponse: extract(epoch from timestamp1 - timestamp2)/3600. Puisque vous ne semblent pas se préoccuper de ce qui timestamp qui précède, vous voulez probablement étirable en abs:

SELECT abs(extract(epoch from timestamp1 - timestamp2)/3600)

-2voto

Peter Sysko Points 29

Cela peut paraître fou à beaucoup de développeurs qui aiment profiter des fonctions de base de données,

Mais après exhaustive des problèmes de réflexion, de création et de bugfixing applications pour mysql et postgrsql avec php en comparant les fonctions de date, je suis venu à la conclusion (pour moi), que le moyen le plus facile, c'est le plus simple, avec moins de SQL maux de tête est de ne pas prendre avantage de l'un d'eux.

Pourquoi? parce que si vous êtes un développement middleware langage comme PHP, PHP a toutes ces fonctions, et ils sont plus faciles à mettre en œuvre dans l'application ode comparer des nombres entiers. PostgreSQL horodatage n'est PAS == TIMESTAMP UNIX et MySQL UNIX TIMESTAMP n'est PAS PostgresQL ou Oracles timestamp.. il devient plus difficile de port si vous utilisez la base de données des horodateurs..

utilisez donc un entier, pas un timestamp, comme le nombre de secondes depuis le 1er janvier 1970 à minuit. et jamais l'esprit de la base de données des horodateurs. et utiliser gmdate() et stocker tout ce que l'heure gmt pour éviter le fuseau horaire questions.

si vous avez besoin de recherche, de tri ou de comparer la journée à partir d'autres données, ou le mois ou l'année ou le jour de la semaine, ou quoi que ce soit, dans votre application, et le type de données ENTIER pour time_day, time_hour, time_seconds.. ou ce que vous wnat à l'index à rechercher fera pour une peau plus lisse et plus portable des bases de données. vous pouvez simplement utiliser un champ, dans la plupart des cas: INTEGER time_created PAS NULL

(plus de champs dans votre base de données en ligne est le seul inconvénient de cette solution que j'ai trouvé, et ce n'est pas tant la cause de nombreux maux de tête, ou des tasses de café :)

php les fonctions de date sont en circulation à comparer des dates, mais dans mysql ou postgresql, en comparant les dates ? nah.. utilisez entier sql comparaisons

je me rends compte qu'il peut SEMBLER plus facile à utiliser CURRENT_TIMESTAMP sur une fonction d'insertion. HA! ne vous laissez pas berner.

Tu ne peux pas faire DELETE FROM SESSION_TABLE WHERE time-initialized < '2 days' si le temps intitialized postgresql est un timestamp. mais vous POUVEZ le faire:

DELETE FROM SESSION_TABLE WHERE time_initialized < '$yesterday'

Aussi longtemps que vous définissez $hier en php comme le nombre entier de secondes depuis 1970 qui était hier.

C'est plus facile de ménage des enregistrements de session que de comparer les horodatages dans postgresql instructions select.

SÉLECTIONNEZ l'âge(), SELECT extract(), et asbtime sont des maux de tête dans l'un d'eux-mêmes. c'est juste mon avis.

vous pouvez faire l'ajout, soustraction, <, >, tous avec php date d'objets

_peter_sysko U4EA Networks, Inc.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X