Décalage horaire en heures pour PostgreSQL

<!-L'équivalent de PostgreSQL?

je sais que je peux soustraire deux horodatages pour obtenir un postgresql INTERVAL. Je veux juste que la différence entre les deux horodateurs soit représentée 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 pointeurs temporels en heures représentés comme un entier.

la Solution qui 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"
43
demandé sur Eric Leschinski 2009-12-27 01:42:20

7 réponses

La première des choses surgissent

EXTRACT(EPOCH FROM current_timestamp-somedate)/3600

N'est peut-être pas jolie, mais débloque la route. Pourrait être plus jolie si la division de l'intervalle par l'intervalle était définie.

Modifier: si vous voulez qu'il soit supérieur à zéro, utilisez l'abs ou le plus grand(...,0). Celui adapté à votre intention.

Modifier++: 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 veut dire que vous n'avez pas d'âge précis à moins de courir à minuit. En ce moment, il est presque 1h du matin ici:

select age(current_timestamp);
       age        
------------------
 -00:52:40.826309
(1 row)
67
répondu Michael Krelin - hacker 2009-12-26 23:51:32

Obtenir des domaines où un timestamp est plus grande que la date de postgresql:

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

Soustraire à quelques minutes de timestamp dans postgresql:

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

soustrayez les heures de l'horodatage dans postgresql:

SELECT * from yourtable 
WHERE your_timestamp_field > current_timestamp - interval '5 hours'
20
répondu Eric Leschinski 2013-11-11 17:25:24

la réponse de Michael Krelin est proche n'est pas entièrement sûre, car elle peut être fausse 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 stockent les choses à l'intérieur sous forme de mois, de jours et de secondes. Les mois ne sont pas un problème dans ce cas puisque soustraire deux horodateurs n'utilise que des jours et des secondes, mais les 'jours' peuvent être un problème.

si votre soustraction implique un changement de jour, 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 va juste 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 converti en époque / 3600 est de 25 heure. Mais en réalité 23 heures + 1 heure devrait être un total de 24 heures.

donc la méthode la plus sûre est:

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

comme Michael l'a mentionné dans son commentaire de suivi, vous voudrez probablement aussi utiliser floor() ou round () pour obtenir le résultat en tant que valeur entière.

9
répondu ShawnFumo 2013-05-07 16:29:31

vous pouvez utiliser les fonctions" extract "ou" date_part " sur les intervalles aussi bien que sur les horodateurs, mais je ne pense pas que cela fasse 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 voulez: extract(epoch from '2 days, 3 hours'::interval) renvoie 183600 (que vous divisez ensuite par 3600 pour convertir les secondes en heures).

Donc, en mettant tout cela ensemble, vous obtenez fondamentalement Michael réponse: extract(epoch from timestamp1 - timestamp2)/3600. Depuis vous ne semblez pas vous soucier de quel horodatage précède qui, vous voulez probablement envelopper que dans abs:

SELECT abs(extract(epoch from timestamp1 - timestamp2)/3600)
6
répondu araqnid 2009-12-26 23:16:24

postgresql obtenir secondes de différence entre les horodatages

SELECT (
    (extract (epoch from (
        '2012-01-01 18:25:00'::timestamp - '2012-01-01 18:25:02'::timestamp
                         )
             )
    )
)::integer

qui affiche:

-2

parce que les horodateurs sont espacés de deux secondes. Prenez le nombre et divisez par 60 pour obtenir des minutes, divisez par 60 encore pour obtenir des heures.

3
répondu Eric Leschinski 2012-12-11 20:52:38

Cela peut sembler fou pour beaucoup de développeurs qui aiment profiter des fonctions de base de données,

mais après des problèmes exhaustifs de réflexion, de création et de correction d'applications pour mysql et postgrsql avec php comparant les fonctions de date, je suis arrivé à la conclusion (pour moi-même), que la manière la plus facile, c'est-à-dire la plus simple avec moins de maux de tête SQL n'est pas de profiter de l'un d'entre eux.

Pourquoi? parce que si vous développez dans un langage middleware comme PHP, PHP a toutes ces fonctions, et ils sont plus faciles à mettre en œuvre dans l'ode d'application que la comparaison des entiers. Le timestamp de PostgreSQL n'est pas == le timestamp UNIX et le timestamp UNIX de MySQL n'est pas le timestamp de PostgresQL ou Oracles.. il devient plus difficile de porter si vous utilisez des horodateurs de base de données..

utilisez donc un entier, pas un timestamp, comme le nombre de secondes depuis le 1er janvier 1970 à minuit. et peu importe les horodateurs de la base de données. , et utilisez gmdate() et stockez tout comme l'heure gmt à éviter fuseau horaire questions.

si vous avez besoin de rechercher, trier ou comparer le jour à 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_secondes.. ou tout ce que vous voulez indexer pour être recherché fera des bases de données plus fluides et plus portables. vous pouvez juste utiliser un champ, dans la plupart des cas: INTEGER time_created NOT NULL

(plus de champs dans la rangée de votre base de données est le seul inconvénient à ce solution que j'ai trouvé, et qui ne cause pas autant de maux de tête, ou des tasses de café :)

les fonctions de date de php sont exceptionnelles pour comparer les dates, mais dans mysql ou postgresql, comparer les dates ? nah.. utilisez entier sql comparaisons

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

vous ne pouvez 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 $yesterday en php comme le nombre entier de secondes depuis 1970 qu'hier était.

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

sélectionnez l'âge(), sélectionnez l'extrait (), et asbtime sont des maux de tête en eux-mêmes. c'est juste mon avis.

vous pouvez faire addition, soustraction,<,>, tout avec des objets php date

_peter_sysko U4EA Networks, Inc.

3
répondu Peter Sysko 2014-03-28 11:18:51

extract(hour from age(now(),links.created)) vous donne un compte arrondi au sol de la différence d'heure.

1
répondu Danix D5 2012-07-25 01:43:12