Gtk2-Ex-Clock

 view release on metacpan or  search on metacpan

lib/Gtk2/Ex/Clock.pm  view on Meta::CPAN

  my ($self) = @_;
  ### Clock _update()

  my $tod = Time::HiRes::time();
  my $format   = $self->{'format'};
  my $timezone = $self->{'timezone'};

  my ($str, $minute, $second);
  if (Scalar::Util::blessed($timezone)
      && $timezone->isa('DateTime::TimeZone')) {
    my $t = DateTime->from_epoch (epoch => $tod, time_zone => $timezone);
    $str = $t->strftime ($format);
    $minute = $t->minute;
    $second = $t->second;
  } else {
    my @tm;
    if (defined $timezone && $timezone ne '') {
      ### using TZ: $timezone
      no warnings 'once';
      local $Tie::TZ::TZ = $timezone;
      @tm = localtime ($tod);
      $str = POSIX::Wide::strftime ($format, @tm);
    } else {
      ### using current timezone
      @tm = localtime ($tod);
      $str = POSIX::Wide::strftime ($format, @tm);
    }
    $minute = $tm[1];
    $second = $tm[0];
  }
  $self->set_label ($str);

  # Decide how long in milliseconds until the next update.  This is from the
  # current $minute,$second,frac($tod) to the next multiple of
  # $self->{'decided_resolution'} seconds, plus _TIMER_MARGIN_MILLISECONDS
  # described above.
  #
  # If $self->{'decided_resolution'} is 1 second then $minute,$second have
  # no effect and it's just from the fractional part of $tod to the next 1
  # second.  Similarly if $self->{'decided_resolution'} is 60 seconds then
  # $minute has no effect.
  #
  # Rumour has it $second can be 60 for some oddity like a TAI system clock
  # displaying UTC.  Dunno if it really happens, but cap at 59 just in case.
  #
  # In theory an mktime of $second+1, or $minute+1,$second=0, would be the
  # $tod value to target.  Not absolutely certain that would come out right
  # if crossing a daylight savings boundary, though capping it modulo the
  # resolution like ($newtod - $tod) % $self->{'decided_resolution'} would
  # ensure a sensible range.  Would an mktime be worthwhile?  Taking just
  # 60*$minute+$second is a little less work.
  #
  my $milliseconds = POSIX::ceil
    (_TIMER_MARGIN_MILLISECONDS
     + (1000
        * ($self->{'decided_resolution'}
           - ((60*$minute + min(59,$second)) % $self->{'decided_resolution'})
           - ($tod - POSIX::floor($tod))))); # fraction part

  ### timer: "$tod is $minute,$second wait $milliseconds to give ".($tod + $milliseconds / 1000.0)
  Scalar::Util::weaken (my $weak_self = $self);
  $self->{'timer'} = Glib::Ex::SourceIds->new
    (Glib::Timeout->add ($milliseconds,
                         \&_timer_callback, \$weak_self,
                         Gtk2::GDK_PRIORITY_REDRAW() - 1));  # before redraws

}


#------------------------------------------------------------------------------

# $format is an strftime() format string.  Return true if it has 1 second
# resolution.
#
sub strftime_is_seconds {
  my ($self, $format) = @_;

  # %c is ctime() style, includes seconds
  # %r is "%I:%M:%S %p"
  # %s is seconds since 1970 (a GNU extension)
  # %S is seconds 0 to 59
  # %T is "%H:%M:%S"
  # %X is locale preferred time, probably "%H:%M:%S"
  # modifiers standard E and O, plus GNU "-_0^"
  #
  # DateTime extras:
  #   %N is nanoseconds, which really can't work, so ignore
  #
  # DateTime methods:
  #   second()
  #   sec()
  #   hms(), time()
  #   datetime(), is8601()
  #   epoch()
  #   utc_rd_as_seconds()
  #
  #   jd(), mjd() fractional part represents the time, but the decimals
  #   aren't a whole second so won't really display properly, ignore for now
  #   
  $format =~ s/%%//g; # literal "%"s, so eg. "%%Something" is not "%S"
  return ($format =~ /%[-_^0-9EO]*
                       ([crsSTX]
                       |\{(sec(ond)?|hms|(date)?time|iso8601|epoch|utc_rd_as_seconds)})/x);
}

1;
__END__

=for stopwords Pango realtime menubar multi undef TZ startup DateTime unicode charset resizes NoShrink zoneinfo Gtk2-Ex-Clock Ryde

=head1 NAME

Gtk2::Ex::Clock -- simple digital clock widget

=head1 SYNOPSIS

 use Gtk2::Ex::Clock;
 my $clock = Gtk2::Ex::Clock->new;  # local time

 # or a specified format, or a different timezone
 my $clock = Gtk2::Ex::Clock->new (format => '%I:%M<sup>%P</sup>',



( run in 0.620 second using v1.01-cache-2.11-cpan-39bf76dae61 )