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 )