kostenloser Webspace werbefrei: lima-city


modulo % Rechnung und Zahlensysteme (Rechnen mit Rest)

lima-cityForumProgrammiersprachenPHP, MySQL & .htaccess

  1. promohit schrieb:
    auch wenn Du diese Erweiterung nicht schtag/re">reibst, ...
    die ist schon 'fertig', nur ich wollte noch ein hübsches demo auch dazu tun. das problem war hauptsächlich, dass lima wieder 'völlegefühle' hat, aber wir warten darauf doch gerne ;o)

    auf deine bemerkung hin habe ich auf dem space von einem bekannten hier eingehängt zum runterladen.

    das demo ist da zu sehen.

    n.b.:
    1. ich habe 'fertig' und nicht fertig geschrieben. das heißt: mitteilungen wilkommen.
    2. die formatierung gefällt mir zwar nicht, aber zeitdruck ist da ... :o(
    3. sonstiges wird auch noch daran geschraubt :o)

    zum schluss noch - für ganz ungeduldige - die 'nakte' klasse:
    <?php
    
    class CDateTimeDiff extends DateTime {
      /**
       *  DateInterval Object
       *    http://www.php.net/manual/en/class.dateinterval.php
       */
      public $diff = null;
    
      /**
       *  UNIX Timestamp
       */
      public $start = null;
      public $end   = null;
    
      /**
       *  timezone
       */
      public $timezone = 'UTC'; // 'Europe/Vienna', ...
    
      /**
       *  $this->oend as DateTime Object
       */
      public $oend = null;
    
      /**
       *  Result (txt), -> $this->format()
       */
      public $res = null;
    
    
      /**
       *  construct DateTimeDiff Object
       *  @start, @end - timestamp
       */
      public function __construct($start, $end) {
        $this->start = (int)$start;
        $this->end   = (int)$end;
    
        date_default_timezone_set($this->timezone);
        $this->oend  = new DateTime(date('Y-m-d H:i:s', (int)$end));
        parent::__construct(date('Y-m-d H:i:s', (int)$start));
        
        $this->diff = $this->diff(new DateTime(date('Y-m-d H:i:s', (int)$end)));
        
        $this->format();
      }
    
    
      /**
       *  formating result
       */
      public function format() {
        if(empty($_POST['calc'])) return;
    
        $this->res .= ($this->diff->y > 0) ? $this->diff->y . ' Jahre, ': '';
        $this->res .= ($this->diff->m > 0) ? $this->diff->m . ' Monate, ': '';
        $this->res .= ($this->diff->d > 0) ? $this->diff->d . ' Tage': '';
    
        $this->res .= ((bool)strlen($this->res)) ? ' und ': '';
    
        $this->res .= ($this->diff->h > 0) ?
          substr('0' . $this->diff->h, -2) . ':':
          '00:';
        $this->res .= ($this->diff->i > 0) ?
          substr('0' . $this->diff->i, -2) . ':':
          '00:';
        $this->res .= ($this->diff->s > 0) ?
          substr('0' . $this->diff->s, -2) . ' Stunden':
          '00 Stunden';
    
        $this->res = 'Intervall: ' . $this->res;
      }
    
    
      # ----------------------------------------------------------------------------
      // for testing
      public function __toString() {
        $res = print_r($this, true);
        return <<< EOT
    
    
        <p>
          <pre>
    $res
          </pre>
        </p>
    EOT;
      }
    
    }


    lg

    Beitrag zuletzt geändert: 1.8.2011 1:37:18 von hemiolos
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

  3. Also ehrlich, hemiolos hat diesen Thread gehijacked und seitdem so enorme Müllberge angehäuft, dass man hier kaum noch durchblickt...
    Wenn es wirklich nur darum geht die verbleibende Zeitdauer in Tagen, Stunden, Minuten und Sekunden von jetzt zu einem Zeitpunkt in der Zukunft zu berechnen, würde ich einfach mit mktime() den Timestamp von dem Zeitpunkt in der Zukunft berechnen, dann mit time() den aktuellen, diese voneinander abziehen und wie hier diese Differenz, die ja in Sekunden gegeben ist, in Tage, Stunden, Minuten und Sekunden umrechnen.

    Das ist wirklich nix kompliziertes und dafür braucht man auch keine Klasse zu schreiben und ein Objekt instantiieren, das ist der Overkill.

    Allein dieses Codeschnipsel von hemiolos hier, wenn man versteht, was da abläuft, ist wirklich ein Zeichen für einen ausgeprägten Knall. :-D

    public function convert($left, $right) {
        if(is_int($left)) $left .= '.0';
    
        $aval      = explode('.', (string)($left / 60)); // jetzt
        $this->res = substr('0' . round(((string)'.'.$aval[1]) * 60), -2) . ':' . $this->res;
    
        if($aval[0] >= 60) {
          $this->convert($aval[0], $aval[1]);
        }
        $this->h[] = $aval[0];
      }

    herrlich!

    promohit schrieb:
    oh ja, da hab ich viel zu lesen und rumprobieren ... Klasse!

    zu Zeitabstand zwischen zweit timestamps
    auch wenn Du diese Erweiterung nicht schreibst, ist ja nicht soooo wichtig,
    schön wäre es aber trotzdem,
    denn auch mit den anderen Vorschlägen bekomme ich nicht ganz ans Ziel
    Timestamps sind schon in Sekunden, wenn du den zeitlichen Abstand willst, einfach $erg = $end - $start.


    Beitrag zuletzt geändert: 1.8.2011 21:30:08 von lama-no2
  4. lama-no2 schrieb:
    ... Allein dieses Codeschnipsel von hemiolos hier, wenn man versteht, was da abläuft, ist wirklich ein Zeichen für einen ausgeprägten Knall. :-D
    nein, das ist ein ausgeprägter sinn für hexagesimal, wovon du nicht die bohne hast.
    und - auch - aus dem grund bin ich da heraus ...
  5. Ne, wirklich... du benutzt für dieses sehr einfache Problem das ganze Arsenal an Programmiertechniken, du schreibst eine Klasse, die instantiiert wird, du benutzt Rekursion (für etwas was nur zweimal gemacht werden müsste, nämlich das Umrechnen in das 60er-System – einmal für Sekunden und einmal für Minuten!), Gleitkommaarithmetik und Stringmanipulation... der Code, den du fabriziert hast, ist nicht weniger als grotesk kompliziert... es ist das Informatik-Äquivalent einer Rube-Goldberg-Maschine.

    Außerdem ist er streng genommen auch falsch, weil du nicht bedenkst, dass es Rundungsfehler bei solchen Rechnungen gibt.

    Da es eine Rechnung ist, in der von vorne herein nur ganze Zahlen vorkommen, sollte man auch nur mit Integern rechnen, Gleitkommazahlen haben da nix zu suchen!

    Du hast Glück, dass PHP für Gleitkommazahlen double precision benutzt und so dein Code wahrscheinlich für nicht allzu große Zahlen noch korrekt berechnet wird. Ich gebe dir jetzt aber mal ein Beispiel (in Java geschrieben, aber das ist ja egal), wie es einem gehen kann:

    public class Main {
     
    	public static void main(String[] args) {
    		test(60000001,60);
    		test(60000006,60);
    	}
    
    
    public static void test(int x, int p){
    	System.out.println(x%p);
    	float y = (float) x / (float) p;
    	int iPart = (int) y;
    	float fPart = y - iPart;
    	System.out.println(Math.round(fPart * p));
    	System.out.println("***");
    	
    	}
    }
    Man sieht ja sofort das 60000001 % 60 eigentlich 1 ergeben müsste, mit deinem Verfahren kommt aber 0 raus, genauso ergibt 60000006 % 60 nicht 6 sondern 8! Verwendet man dagegen einfach die ganz normale Modulo-Operation, kommt das richtige raus.

    Also bitte, wer hier keine Ahnung hat ist wohl klar :-D und wenn ich dann noch den ganzen Rest lese von "mathematischer Semiologie" und deine eigenwillige Rechtschreibung und dein Geschreibsel, so wie wirklich kaum ein normaler Mensch sich ausdrückt... der ganze Thread zugemüllt damit... ich bin noch unentschlossen ob das jetzt in Richtung Trolligkeit geht oder ob du uns einfach nur stolz zeigen willst, was du alles kannst...
  6. So, ich habe jetzt auch mal eine Funktion geschrieben, die natürlich gleich auf Fehleingaben überprüft:
    function convert($number, $from, $to)
    {
    	$settings = array();
    	$settings['weeks'] = 60*60*24*7;
    	$settings['days'] = 60*60*24;
    	$settings['hours'] = 60*60;
    	$settings['minutes'] = 60;
    	$settings['seconds'] = 1;
    	
    	if(in_array($from, $settings))
    	{
    		if(in_array($to, $settings))
    		{
    			if(is_numeric($number))
    			{
    				return floor($number * $settings[$from] / $settings[$to]);
    			} else
    			{
    				echo '$number muss eine Zahl sein!';
    				return false;
    			}
    		} else
    		{
    			echo 'Ungültiges Zielformat!';
    			return false;
    		}
    	} else
    	{
    		echo 'Ungültiges Quellformat!';
    		return false;
    	}
    }
    Man ruft sie dann so auf:
    $minutes = convert($x, 'secondes', 'minutes');
    $seconds = $x - ($minutes * 60);
    $hours = convert($minutes, 'minutes', 'hours');
    $minutes = $minutes - ($hours * 60);
    ...
    Das wird wahrscheinlich die unkomplizierteste Möglichkeit sein.

    Beitrag zuletzt geändert: 2.8.2011 11:41:29 von drafed-map
  7. Das ist zwar besser als das von hemiolos, letztlich machst du aber auch wieder den Fehler, dass du Gleitkommaarithmetik verwendest, die zu Rundungsfehlern führen kann.
  8. promohit schrieb:
    jetzt mach ich nen Trick: date_parse() und Start-Zeit-Werte abziehen ... :)


    von allen hier vorgestellten Methoden finde ich date_parse() die vernünftigste,
    kein großes rum-gerechne, keine Sorge um Rundungs-Fehler, keine modulo Rechnungen,
    einfach nur die kleine Rechnung minus 01.01.1970 vom date_parse() Ergebnis der Differenz.

    genial, gleich mal getestet ...

    hier der Code mit dem ich es ausprobiert habe: $termin1 und $termin2 sind timestamps

    $termin1 = 1324681200;  // --- 24.12.2011 (00:00:00) 
    $termin2 = time(); 
    
    $tmdatum = date("Y-m-d H:i:s", ($termin1)); 
    
    if ( $termin2 < $termin1 ) { 
    
    $diff = ($termin1 - $termin2); 
    
    $ergz = date_parse(date("Y-m-d H:i:s", ($diff) ));
    
    ## echo "<pre>\r\n"; 
    ## print_r($ergz);  // ----- Debug ----- 
    ## echo "</pre>\r\n";
    
    // ------- minus  01.01.1970 ------- 
    $ergz['year']  = ($ergz['year']  - 1970); 
    $ergz['month'] = ($ergz['month'] - 1); 
    $ergz['day']   = ($ergz['day']   - 1); 
    
    
    $ausgabe = "Es sind noch "; 
    
    if ( $ergz['year'] > 1 ) {        $ausgabe .= "".$ergz['year']." Jahre "; }
    elseif ( $ergz['year'] == 1 ) {   $ausgabe .= "".$ergz['year']." Jahr "; }
    
    if ( $ergz['month'] > 1 ) {       $ausgabe .= "und ".$ergz['month']." Monate "; }
    elseif ( $ergz['month'] == 1 ) {  $ausgabe .= "und ".$ergz['month']." Monat "; }
    
    if ( $ergz['day'] > 1 ) {         $ausgabe .= "und ".$ergz['day']." Tage "; }
    elseif ( $ergz['day'] == 1 ) {    $ausgabe .= "und ".$ergz['day']." Tag "; }
    
    if ( $ergz['hour'] > 1 ) {        $ausgabe .= "und ".$ergz['hour']." Stunden "; }
    elseif ( $ergz['hour'] == 1 ) {   $ausgabe .= "und ".$ergz['hour']." Stunde "; }
    
    if ( $ergz['minute'] > 1 ) {      $ausgabe .= "und ".$ergz['minute']." Minuten "; }
    elseif ( $ergz['minute'] == 1 ) { $ausgabe .= "und ".$ergz['minute']." Minute "; }
    
    if ( $ergz['second'] > 1 ) {      $ausgabe .= "und ".$ergz['second']." Sekunden "; }
    elseif ( $ergz['second'] == 1 ) { $ausgabe .= "und ".$ergz['second']." Sekunde "; }
    
    echo "<br />".$ausgabe."\r\n"; 
    
    } 
    else {
    echo "<br />Der Termin ".$tmdatum." ist schon abgelaufen. \r\n"; 
    }


    die Erstellung der Ausgabe kann man sicher noch "schöner" machen
    und auch noch erweitern für den Fall (termin1 < $termin2) in der Vergangenheit
    z.B. ... der Termin war vor .. Jahren .. Monaten .. Tagen ... etc.

    aber vom Prinzip her genial, in der Kürze liegt die Würze :=)


    Beitrag zuletzt geändert: 9.10.2011 1:34:59 von uhrinfo
  9. Hallo

    habe das mal ausprobiert, und festgestellt, dass man auch bei Stunde den Wert 1 abziehen muss


    hier nochmal 2 Funktionen

    Funktion getTerminRest()
    .... mit 2 Parameter (Ausgangs-Termin und Ziel-Termin als Timestamp)


    <?php
    // --------------------------------------------------- 
    
    
    ## $termin1 = time(); // aktueller Timestamp oder Timestamp von Ausgangs-Datum 
    ## $termin2 = strtotime(2011-12-24 00:00:00);  // Termin in der Zukunft als Timestamp 
    ## oder:  $termin2 = mktime ($hour, $minute, $second, $month, $day, $year); 
    
    function getTerminRest($termin1, $termin2) { 
    	
    	$seconds = ($termin2 - $termin1);
    	$difsec = abs($seconds); 
    	
    	$ergz = date_parse(date("Y-m-d H:i:s", ($difsec) ));
    	
    	$ergz['year']  = ($ergz['year']  - 1970); 
    	$ergz['month'] = ($ergz['month'] - 1); 
    	$ergz['day']   = ($ergz['day']   - 1); 
    	$ergz['hour']  = ($ergz['hour']  - 1); 
    	
    	$ausgabe = ''; 
    	
    	if ( 1 < $ergz['year'] )        {  $ausgabe .= "".$ergz['year']." Jahre und "; }
    	elseif ( $ergz['year'] == 1 )   {  $ausgabe .= "".$ergz['year']." Jahr und "; }
    	
    	if ( 1 < $ergz['month'] )       {  $ausgabe .= "".$ergz['month']." Monate und "; }
    	elseif ( $ergz['month'] == 1 )  {  $ausgabe .= "".$ergz['month']." Monat und "; }
    	
    	if ( 1 < $ergz['day'] )         {  $ausgabe .= "".$ergz['day']." Tage und "; }
    	elseif ( $ergz['day'] == 1 )    {  $ausgabe .= "".$ergz['day']." Tag und "; }
    	
    	if ( 1 < $ergz['hour'] )        {  $ausgabe .= "".$ergz['hour']." Stunden und "; }
    	elseif ( $ergz['hour'] == 1 )   {  $ausgabe .= "".$ergz['hour']." Stunde und "; }
    	
    	if ( 1 < $ergz['minute'] )      {  $ausgabe .= "".$ergz['minute']." Minuten und "; }
    	elseif ( $ergz['minute'] == 1 ) {  $ausgabe .= "".$ergz['minute']." Minute und "; }
    	
    	if ( 1 < $ergz['second'] )      {  $ausgabe .= "".$ergz['second']." Sekunden"; }
    	elseif ( $ergz['second'] == 1 ) {  $ausgabe .= "".$ergz['second']." Sekunde"; }
    	
    	
    	if ( 0 < $seconds ) { 
    	$outstr = "Es sind noch ".$ausgabe." bis zum Termin."; 
    	}
    	else { 
    	$outstr = "Der Termin ist schon ".$ausgabe." abgelaufen."; 
    	}
    
    return $outstr; 
    }
    
    
    // --------------------------------------------------- 
    ?>





    Funktion getRestZeit()
    .... mit nur der Differenz in Sekunden als Parameter

    <?php
    // --------------------------------------------------- 
    
    
    
    ## $difsec = ($timestamp2 - $timestamp1);  // --- Differenz zweier Timestamps in Sekunden
    
    
    function getRestZeit($seconds) { 
    	
    	$difsec = abs($seconds); 
    	$ergz = date_parse(date("Y-m-d H:i:s", ($difsec) ));
    	
    	$ergz['year']  = ($ergz['year']  - 1970); 
    	$ergz['month'] = ($ergz['month'] - 1); 
    	$ergz['day']   = ($ergz['day']   - 1); 
    	$ergz['hour']  = ($ergz['hour']  - 1); 
    	
    	$ausgabe = ''; 
    	
    	if ( 1 < $ergz['year'] )        {  $ausgabe .= "".$ergz['year']." Jahre und "; }
    	elseif ( $ergz['year'] == 1 )   {  $ausgabe .= "".$ergz['year']." Jahr und "; }
    	
    	if ( 1 < $ergz['month'] )       {  $ausgabe .= "".$ergz['month']." Monate und "; }
    	elseif ( $ergz['month'] == 1 )  {  $ausgabe .= "".$ergz['month']." Monat und "; }
    	
    	if ( 1 < $ergz['day'] )         {  $ausgabe .= "".$ergz['day']." Tage und "; }
    	elseif ( $ergz['day'] == 1 )    {  $ausgabe .= "".$ergz['day']." Tag und "; }
    	
    	if ( 1 < $ergz['hour'] )        {  $ausgabe .= "".$ergz['hour']." Stunden und "; }
    	elseif ( $ergz['hour'] == 1 )   {  $ausgabe .= "".$ergz['hour']." Stunde und "; }
    	
    	if ( 1 < $ergz['minute'] )      {  $ausgabe .= "".$ergz['minute']." Minuten und "; }
    	elseif ( $ergz['minute'] == 1 ) {  $ausgabe .= "".$ergz['minute']." Minute und "; }
    	
    	if ( 1 < $ergz['second'] )      {  $ausgabe .= "".$ergz['second']." Sekunden"; }
    	elseif ( $ergz['second'] == 1 ) {  $ausgabe .= "".$ergz['second']." Sekunde"; }
    	
    	
    	if ( 0 < $seconds ) { 
    	$outstr = "Es sind noch ".$ausgabe." bis zum Termin."; 
    	}
    	else { 
    	$outstr = "Der Termin ist schon ".$ausgabe." abgelaufen."; 
    	}
    
    return $outstr; 
    }
    
    
    // --------------------------------------------------- 
    ?>



    ich hoffe das stimmt so

    zumindest hat es bei meinen Versuchen nur mit dem Zusatz

    $ergz['hour'] = ($ergz['hour'] - 1);

    richtige Ergebnisse geliefert, ohne das war es immer um genau die eine Stunde zuviel

    startet der Unix Timestamp mit einer Stunde ... also 1970-01-01 (01:00:00)
    oder warum war bei meinen Tests immer die eine Stunde zuviel ?




    Beitrag zuletzt geändert: 19.11.2011 15:19:44 von kataloge
  10. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

Dir gefällt dieses Thema?

Über lima-city

Login zum Webhosting ohne Werbung!