Datetime sous 4D

Product :4D - 4D Server
4D : v17

Bonjour,
Après plusieurs recherches je ne trouve pas de moyen de stocker une datetime (format long, avec les secondes) en 4D.
Sachant que :

  • j’importe une base données SQL dans 4D dans laquelle j’ai des champs datetime
  • que j’ai besoin de trier mes dates pour faire des traitements dessus dont des opérations.

Si je créé un champ heure dans ma table ça va être une grosse galère lors de mes imports.
La seule alternative que j’ai trouvé est d’utiliser le timestamp UNIX mais cela implique beaucoup de modifications.

Avez-vous une solution svp ?

Bonjour Manon
Tu peux éventuellement mettre cela dans un champs Alpha. Tout dépend ce que tue veux en faire par la suite.

Cordialement
D.BARBERIN

Bonjour Didier,
Merci pour ta réponse.
Cette solution ne me permettra pas de gérer le tri pour récupérer certaines infos ni de faire divers traitements sur ce champ.

C’est étonnant qu’il n’y ait rien de prévu pour stocker une dateTime, et autre bizarrerie, pourquoi pouvoir afficher une colonne en format date ISO alors qu’on ne peut pas stocker ce type de format en base ?? Ou alors je suis passée à côté d’un élément dans la doc.
Je vais gérer différemment tant pis, j’attends d’autres réponses au cas où…

Bonjour Manon,
La lecture des 4 billets publiés par Olivier devrait vous apporter quelques éléments
Voici le premier
http://www.4d.com/fr/blog/timestampmonamour.htmlTimeStamp mon amour>

Le stockage en alphanumérique te permet le tri, puisque l’ordre des constituantes du temps dans la chaine va du plus grand au plus petit (année, mois, jour, heure, etc.). Par contre il est encombrant (AAAAMMJJThhmmss = 15 caractères = 30 octets), si la table a beaucoup d’enregistrements ça donnera des temps de chargement, tris ou recherches élevés. J’adopte dans ce cas la solution du timestamp stocké en entier long (ce doit être ce que tu appelles “timestamp unix”) qui est d’une efficacité redoutable et ne demande que 3-4 routines de conversion. Tu as du code tout cuit http://forums.4d.com/Post/FR/19709356/1/19709644#19709357dans ce fil>.

Je ne pense pas “qu’il n’y ait rien de prévu” en datetime car depuis la v11, les champs date et heure sont stockés sur 8 octets, ce qui me paraît beaucoup pour stocker une date sans heure ou une heure sans date, et assez pour stocker date+heure. On espère…

Bonjour merci pour vos réponses.
J’avais également trouvé sur ce blog http://blog.heintz.net/a-quick-one-epoch-unix-timestamp-conversion/
des méthodes de conversion (dans les deux sens).
Donc en gros, comme à priori il n’existe pas de moyen de stocker une date avec l’heure (prévu peut-être un de ces jours d’après toi), je n’ai pas d’autres alternatives que de passer par le timestamp, ce que je voulais éviter (ça va me demander bcp de modifications).
Merci bien, bonne journée

: Manon CHAUVIN

(ça va me demander bcp de modifications).
Ha, ça n’est jamais marrant. Mais il faut aussi voir le bon coté, quand il s’agira de faire des recherches, des tris ou des calculs d’écarts avec ces timestamps-en-secondes, ce sera plus rapide et facile qu’avec des timestamps-en-date-et-heure. J’ai posté quelques autres méthodes http://forums.4d.com/Post/FR/14701949/1/14928049#14701950ici>.

En fait, on peut stocker un datetime dans un champ date mais il faut les manipuler uniquement en SQL. En pur 4D on ne peut, à ma connaissance, récupérer que la partie date.

Merci pour vos informations.
J’aurai pu effectivement appliquer la solution de Stanislas mais j’ai vu le message trop tard… Du coup je stocke toutes mes dates en entier 64 bits.

Pour info si jamais ça peut aider, j’utilise le code du lien que j’ai cité plus haut pour stocker mes dates au format timesStamp
ex: stocker la date courante :
dateToEpoch (Current date;Current time)

Pour convertir une date récupérée depuis un fichier xml:
// “AAAA-MM-JJTHH:MM:SS”
$dateHeure:=$date+“T”+$heure+“Z” (où date et heure correspondent à la valeur de mon élément xml)
$dateTimestamp:=dateToEpoch (Date($dateHeure);Time($dateHeure))

Pour l’affichage dans mes listBox d’une date format DD/MM/YYYY, dans la colonne > source de données:
String(Date(dateFromEpoch (This.uneDate)))

Du coup les données de ma base 4D étant importées depuis une base SQL, j’ai dû gérer la conversion des dates SQL en format timeStamp au niveau des mes scripts (réalisés sous SQL server).

Merci Bruno !
https://www.epochconverter.comLien pour les fondus> de tests unitaires :slight_smile:

Ça fait des années que j’ai basé mes timestamps sur le 1er janvier 2000 et un peu moins d’années que je me dis que c’est une connerie monumentale…

Bonjour Bruno,
Aurais-tu la méthode inverse, qui récupère la date et l’heure depuis un epoch ?
Parce que personnellement, avec les entiers longs signés 4D, j’ai un petit souci après le 19/01/2038 à 03:14:07…
Ce n’est pas demain, mais j’y pense !
Cordialement,
Damien

D’ici 2038, tu as sans doute de bonnes raisons d’espérer que le langage gère les entiers sur 8 octets…

Pour la “rétro conversion”, j’ai http://forums.4d.fr/Post/FR/14701949/1/14701950#14701950ça> (2 fonctions, une pour l’heure, une pour la date) : en changeant l’origine ça devrait le faire. Je les modifiées depuis, un paramètre optionnel pour convertir en temps local :
<code 4D>
//TS_decodeD (timeStamp_l {;localeFr_b) -> date
//décode et retourne la date d’un timestamp UTC
//si $2 passé et Vrai, conversion heure locale
C_DATE($0)
C_ENTIER LONG($1)
C_BOOLEEN($2)

C_DATE($date_d)
C_DATE($heureEte_d)
C_DATE($heureHiver_d)
C_ENTIER LONG($params_l)
C_ENTIER LONG($TS_l)
C_HEURE($heure_h)

Si (Faux)
C_DATE(TS_decodeD ;$0)
C_ENTIER LONG(TS_decodeD ;$1)
C_BOOLEEN(TS_decodeD ;$2)
Fin de si

//_
$params_l:=Nombre de parametres
Si (Asserted($params_l>0;Nom methode courante+" missing $1"))
$TS_l:=$1
$date_d:=TS_origin +($TS_l\86400)
Si ($params_l>1)
Si ($2) //convertir en heure locale fr
$heure_h:=†00:00:00†+($TS_l%86400)
//$heureEte_d:= //à 3h du mat il est 2h
//$heureHiver_d:= //à 2h du mat il est 3h
Au cas ou
: ($date_d<Time_DST (Annee de($date_d);Vrai)) //heure été
$heure_h:=$heure_h+†01:00:00†
: ($date_d<Time_DST (Annee de($date_d);Faux)) //heure hiver
$heure_h:=$heure_h+†02:00:00†
Sinon
$heure_h:=$heure_h+†01:00:00†
Fin de cas

Si ($heure_h>=†24:00:00†)
$heure_h:=$heure_h-†24:00:00†
$date_d:=$date_d+1
Fin de si

Fin de si
Fin de si
Fin de si
$0:=$date_d
//_
</code 4D>

<code 4D>
//TS_decodeH (marqueurTemps_l {;localeFr_b)-> heure
//décode et retourne l’heure d’un timeStamp UTC
//si $2 passé et Vrai, conversion heure locale fr
C_HEURE($0)
C_ENTIER LONG($1)

C_DATE($date_d)
C_ENTIER LONG($params_l)
C_ENTIER LONG($TS_l)
C_ENTIER LONG($TSete_l)
C_ENTIER LONG($TShiver_l)
C_HEURE($heure_h)
Si (Faux)
C_HEURE(TS_decodeH ;$0)
C_ENTIER LONG(TS_decodeH ;$1)
Fin de si
//_
$params_l:=Nombre de parametres
Si (Asserted($params_l>0;Nom methode courante+" missing $1"))
$TS_l:=$1
$heure_h:=†00:00:00†+($TS_l%86400)
Si ($params_l>1)
Si ($2) //convertir en heure locale fr
$date_d:=TS_origin +($TS_l\86400)

$TSete_l:=TS_encodeDH (Time_DST (Annee de($date_d);Vrai);†03:00:00†) //à 3h du mat il est 2h
$TShiver_l:=TS_encodeDH (Time_DST (Annee de($date_d);Faux);†02:00:00†) //à 2h du mat il est 3h

Au cas ou
: ($TS_l<$TSete_l)
$heure_h:=$heure_h+†01:00:00†
: ($TS_l<$TShiver_l)
$heure_h:=$heure_h+†02:00:00†
Sinon
$heure_h:=$heure_h+†01:00:00†
Fin de cas

Si ($heure_h>=†24:00:00†)
$heure_h:=$heure_h-†24:00:00†
Fin de si

Fin de si
Fin de si
Fin de si
$0:=$heure_h
//_
</code 4D>

Bonjour Arnaud,

: Arnaud DE MONTARD

D’ici 2038, tu as sans doute de bonnes raisons d’espérer que le
langage gère les entiers sur 8 octets…

J’ose espérer que 4D attend de n’avoir plus que des applications 64 bits pour nous proposer cet entier sur 8 octets.
J’avais déjà les méthodes ressemblantes à ce que tu as proposé, mais merci quand même.
Quand on communique avec des systèmes relevant de l’informatique industrielle, le timestamp epoch est assez répandu.
Cordialement,
Damien

Bonjour

: Damien FUZEAU

j’ai un petit souci après le 19/01/2038 à 03:14:07…
Si cela peut t’aider à passer de bonnes vacances :
https://fr.wikipedia.org/wiki/Bug_de_l’an_2038

A+
Didier

Bonjour,

Ah, à la veille de partir en vacances, voilà que Bruno nous fait l’epoch !
:-x

@Bruno, j’espère que tu me pardonneras ce mauvais mot qui est en réalité fait pour te remercier de toutes tes contributions :slight_smile:

Bonjour Jean-Jacques,

Je te pardonne :slight_smile:

Bonnes vacances :slight_smile: