home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / languages / perl / scripts-osu / gettimeofday < prev    next >
Encoding:
Text File  |  1990-11-26  |  4.5 KB  |  168 lines

  1. Path: tut.cis.ohio-state.edu!purdue!mentor.cc.purdue.edu!noose.ecn.purdue.edu!samsung!cs.utexas.edu!sun-barr!newstop!texsun!convex!convex.COM
  2. From: tchrist@convex.COM (Tom Christiansen)
  3. Newsgroups: comp.lang.perl
  4. Subject: Re: gettimeofday
  5. Message-ID: <109354@convex.convex.com>
  6. Date: 28 Nov 90 00:44:20 GMT
  7. References: <1990Nov26.042245.29893@uvaarpa.Virginia.EDU>
  8. Sender: usenet@convex.com
  9. Reply-To: tchrist@convex.COM (Tom Christiansen)
  10. Organization: CONVEX Software Development, Richardson, TX
  11. Lines: 154
  12.  
  13. In article <1990Nov26.042245.29893@uvaarpa.Virginia.EDU> marc@mit.edu writes:
  14. >Feature request:
  15. >
  16. >Is there a reason gettimeofday isn't in perl?  It exists in both BSD
  17. >and SYSV, the PC can approximate it, although with less precision, and
  18. >it's hard to do without a primitive (syscall is "hard").  I can't
  19. >imagine how it could break existing scripts.  Just define
  20. >gettimeofday() which returns ($tv_sec,$tv_usec).  Or make it really
  21. >spiffy and have it return that in a list context, and
  22. >$tv_sec+$tv_usec/1000000 in a scalar context.
  23.  
  24. "Spiffy" is one of the things some people (pas moi) don't like about perl.
  25.  
  26. I would say gettimeofday isn't there because it isn't on every system.
  27. Yes, Tom, I hear you say, but what about socket?  Yes, there is that.
  28. But socket has to work with internal datatypes that you can't mock
  29. up very well just using syscall.  You say using syscall is hard, but
  30. I would say having to know contextually dependent behavior is harder
  31. still.
  32.  
  33. When I want better time than "time" gives me, and I'm trying to
  34. be quick, I do this:
  35.  
  36.     # for milliseconds; otherwise would use built-in time.
  37.     sub time {
  38.     local($SYS_gettimeofday, $timeval, $timezone, $sec, $usec);
  39.  
  40.     $SYS_gettimeofday = 116;  # should really be from sys/syscalls.ph
  41.  
  42.     $timeval = $timezone = ("\0" x 4) x 2;
  43.  
  44.     syscall($SYS_gettimeofday, $timeval, $timezone)
  45.          && die "gettimeofday failed: $!";
  46.  
  47.     ($sec, $usec) = unpack("L2", $timeval);
  48.     return $sec +  $usec/1e6;
  49.     }
  50.  
  51. But when I'm trying to be a little more careful, I do this:
  52.  
  53.     #!/usr/local/bin/perl
  54.  
  55.     require 'timeofday.pl';
  56.  
  57.     printf "It is now %f seconds past the epoch.\n", $now = &time;
  58.  
  59.     printf "We are in the %s timezone, ", $zone = &zone;
  60.  
  61.     printf "which is considered %s time.\n", &zonename($zone);
  62.  
  63.     printf "Merely %g seconds have passed since the program started.\n", 
  64.     &time - $now;
  65.  
  66. where timeofday.pl is the following:
  67.  
  68.     #!/usr/local/bin/perl
  69.  
  70.     package main;
  71.  
  72.     require 'syscall.ph';
  73.     $SYS_gettimeofday =  &'SYS_gettimeofday 
  74.     unless defined $SYS_gettimeofday;
  75.  
  76.     package gettimeofday;
  77.  
  78.  
  79.     $timeval_t = 'LL';
  80.     $timezone_t = 'II';
  81.  
  82.     %zones_by_minute = (
  83.         0*60,      "WET", 
  84.         -1*60,     "MET",
  85.         -2*60,     "EET", 
  86.         -8*60,     "AWST", 
  87.         -10*60,    "AEST", 
  88.         -10*60+30, "ACST", 
  89.         4*60,      "AST", 
  90.         5*60,      "EST", 
  91.         6*60,      "CST", 
  92.         7*60,      "MST", 
  93.         8*60,      "PST", 
  94.     );
  95.  
  96.     %zones_by_abbr = (
  97.         "WET",         "Western European",
  98.         "MET",         "Middle European",
  99.         "EET",         "Eastern European",
  100.         "AWST",     "Western Australian",
  101.         "AEST",     "Eastern Australian",
  102.         "ACST",     "Central Australian",
  103.         "AST",         "Atlantic",
  104.         "EST",         "Eastern",
  105.         "CST",         "Central",
  106.         "MST",         "Mountain",
  107.         "PST",         "Pacific",
  108.     );
  109.  
  110.     sub timeval {
  111.     wantarray 
  112.         ? unpack($timeval_t, $_[0])
  113.         : pack($timeval_t, @_);
  114.     } 
  115.  
  116.     sub timezone {
  117.     wantarray 
  118.         ? unpack($timezone_t, $_[0])
  119.         : pack($timezone_t, @_);
  120.     } 
  121.  
  122.  
  123.     sub main'time {
  124.     local($val, $zone) = &'gettimeofday;
  125.     local($sec, $usec) = &timeval($val);
  126.     $sec + $usec/1e6;
  127.     } 
  128.  
  129.     sub main'zone {
  130.     local($val, $zone) = &'gettimeofday;
  131.     ($mins, $dst) = &timezone($zone);
  132.  
  133.     defined $zones_by_minute{$mins} 
  134.         ? $zones_by_minute{$mins}
  135.         : $mins;
  136.     } 
  137.  
  138.     sub main'zonename {
  139.     $zones_by_abbr{$_[0]};
  140.     } 
  141.  
  142.     sub main'gettimeofday {
  143.     local($val, $zone);
  144.     $val = &timeval;
  145.     $zone = &timezone;
  146.  
  147.     syscall($'SYS_gettimeofday, $val, $zone) && do {
  148.         warn "gettimeofday: SYS_gettimeofday failed: $!";
  149.         ($val, $zone) = ();
  150.     };
  151.  
  152.     ($val, $zone);
  153.     } 
  154.  
  155.  
  156.  
  157. There's some question whether I should export &timeval and &timezone
  158. (which are protected, magic, bidirectional conversion functions), since I
  159. am exporting &gettimeofday and it is returning packed data.  And of course
  160. I'm doing nothing with the $dst flag, and my table is incomplete, and so
  161. on and so forth.  But it's an idea.  I really don't like that I can't
  162. duplicate ctime(3) output because I can't pin down the timezone without
  163. having $TZ set.
  164.  
  165.  
  166. --tom
  167.  
  168.