Seite 1 von 1

TimeStamp (Unix-Format)

Verfasst: Do, 29. Jun 2017 8:11
von adrian
Hallo zusammen

Ich muss für eine eFaktura-Umstellung (elektronische Rechnungen schweiz. Gesundheitswesen) neu ein XML-File erstellen und da hat es eine Position mit einem TimeStamp (Unix)

==> timestamp (UNIX time) defined at the moment of generation

Hat einer eine Idee wie ich dies unter xBase umsetzen kann? Musste dies schon jemand durchführen.

Besten Dank für einen glorreichen Tip / Ideen-Vorschlag.

Adrian

Re: TimeStamp (Unix-Format)

Verfasst: Do, 29. Jun 2017 8:26
von Wolfgang Ciriack
Laut Google sind das die Sekunden seit 1.1.1970. Prüfen kannst du dein Ergebnis der Berechnung dann z.B. unter http://www.unixtimestamp.com/

Re: TimeStamp (Unix-Format)

Verfasst: Do, 29. Jun 2017 8:59
von brandelh
Dort kann man zugleich das Hauptproblem dieser Art der "Berechnung" nachlesen:

die größte Zahl die eine LONG (signed 32 bit Integer) darstellen kann ist:

2147483647

das entspricht dem:

01/19/2038 @ 3:14am (UTC)
2038-01-19T03:14:07+00:00 in ISO 8601

Sekunden sind aber auch nicht wirklich genau, bei ISO werden 1/100 Sekunden gespeichert.
Ich habe eine Funktion in der Wissensbasis, die ISO Timestamps generiert und andere Infos dazu:

:arrow: https://xbaseforum.de/viewtopic.php?f=16&t=2779&p=28825

Möglich, dass die API Funktion per Parameter auch den UNIX Timestamp erzeugen kann, was immer besser ist als ihn selbst zu berechnen.

Falls man nicht auf den Tageswechsel stoßen kann (z.B. weil die Anwendung NIE UND NIMMER um 23:59:59 einen solchen anfordert ;-) ), sollte die Berechnung auch recht einfach sein:
Tage bis gestern * Sekunden / Tag + seconds()

ERLEDIGT! Re: TimeStamp (Unix-Format)

Verfasst: Do, 29. Jun 2017 9:31
von adrian
Danke Euch für die Tips und Infos, so klappts.

((date()-CTOD("01.01.1970"))*86400)+Time2Sec(Time()) // ich verwende xClass


Adrian

Re: TimeStamp (Unix-Format)

Verfasst: Do, 29. Jun 2017 9:35
von brandelh
Ich hab mal mit Xbase++ eine Funktion erstellt. Meine Testdaten hat die Web-Site bestätigt, es scheint zu stimmen.
Allerdings habe ich natürlich nicht berücksichtigt, dass nicht alle Tage genau 86400 haben 8)

Code: Alles auswählen

#include "Common.ch"

PROCEDURE Main
   LOCAL dTestTag, nTestSeconds
   /* we use the ansi charset by default */
   SET CHARSET TO OEM
   SET ALTERNATE TO test.txt
   SET ALTERNATE ON

   ? "Teste UNIX TimeStamp"
   ?
   dTestTag     := ctod("01.01.1970")
   nTestSeconds := 10

   ? dTestTag, nTestSeconds, TimeStampUnix(dTestTag, nTestSeconds)

   dTestTag     := date()
   nTestSeconds := seconds()
   ? dTestTag, nTestSeconds, time(), TimeStampUnix(dTestTag, nTestSeconds)

   ? "Nun das Ende des 32 Bit LONG Zahlenraums prüfen:"

   dTestTag     := ctod("01.01.2050")
   nTestSeconds := seconds()

   ? dTestTag, nTestSeconds, time(), TimeStampUnix(dTestTag, nTestSeconds) // das Ergebnis STIMMT !

   SET ALTERNATE OFF

   inkey(0)


   /* $TODO: place your application code here */
RETURN

FUNCTION TimeStampUnix(dZielTag,nSeconds)
   LOCAL dGestern, dTestTag, nTage
   LOCAL dUnixStart     := cToD("01.01.1970")
   LOCAL nUnixTimeStamp := 0 // LONG erzwingen, darf nicht geändert werden !

   IF dZielTag = NIL
      dZielTag := date()
      dTestTag := dZielTag // Tageswechsel erkennen mit dieser Variable
   ENDIF
   IF nSeconds = NIL
      nSeconds := int(seconds())
      IF date() <> dTestTag
         // Tageswechsel hat zwischen date() und seconds() stattgefunden
         nSeconds := 86399 // die Sekunde vor Mitternacht
      ENDIF
   ELSE
      nSeconds := int(nSeconds)
   ENDIF

   nTage := dZielTag - dUnixStart // dUnixstart ist eigentlich der Tag davor aus unserer Sicht
                                  // dZieltag ist aber auch gestern, eventuell hebt sich das auf oder Abzüge !

                                  //  on most days maps to 60*60*24 = 86400 seconds. But not on all days.

   nUnixTimeStamp := int( nTage * 86400 + nSeconds )

RETURN nUnixTimeStamp