aboutsummaryrefslogtreecommitdiff
path: root/Plugin/Timezone.pm
blob: c56a9844c14b90f5cca15d2a29f9030d06a4df06 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package Plugin::Timezone;

use strict;
use warnings;

use DateTime;
use IdaliusConfig qw/assert_dict/;

my $config;

sub configure {
	my $self = shift;
	my $cmdref = shift;
	shift; # run_command
	$config = shift;

	IdaliusConfig::assert_dict($config, $self, "timezone");

	$cmdref->($self, "time", sub { $self->time(@_); } );
	$cmdref->($self, "tz", sub { $self->zone_convert(@_); } );

	return $self;
}

# look a nick up and return their configured timezone, else return the input
# assuming it's a timezone rather than a nick
sub nick_to_zone {
	my ($nick) = @_;
	my @known_zones = (keys %{$config->{timezone}});
	my ($case_nick) = grep {/^\Q$nick\E$/i} @known_zones;
	my $tz;
	if ($case_nick) {
		return $config->{timezone}->{$case_nick};
	} else {
		return $nick;
	}
}

sub clock_message {
	my ($nick, $tz, $time_string) = @_;
	if ($tz eq $nick) {
		return "clocks in $tz read $time_string";
	} else {
		return "$nick\'s clock reads $time_string";
	}
}

sub make_unknown_zone_message {
	return "I'm unsure what the time is for $_[0]";
}

sub time {
	my ($self, $irc, $logger, $who, $where, $ided, $rest, $no_reenter, @arguments) = @_;

	my $requester = (split /!/, $who)[0];

	return "Syntax: time [nick]" unless @arguments <= 1;

	my $nick = $arguments[0] || $requester;

	my $tz = nick_to_zone($nick);

	eval {
		my $d = DateTime->now();
		$d->set_time_zone($tz);
		my $timestr = $d->strftime("%H:%M on %a %d %b, %Y (%Z)");
		return clock_message($nick, $tz, $timestr);
	} or return "$requester: ".make_unknown_zone_message $nick;
}

sub zone_convert {
	my ($self, $irc, $logger, $who, $where, $ided, $rest, $no_reenter, @arguments) = @_;

	my $requester = (split /!/, $who)[0];
	return "Syntax: tz <time> <from> [to]" unless @arguments == 2 || @arguments == 3;

	my ($time_string, $from_arg, $to_arg) = @arguments;

	my $from_tz = nick_to_zone($from_arg);
	$to_arg = $requester unless $to_arg;
	my $to_tz = nick_to_zone($to_arg);

	my ($hour, $minute) = $time_string =~ /^([0-9]{1,2}):([0-9]{1,2})/;

	eval {
		my $d = DateTime->now();
		my $format = "%H:%M on %a %d %b, %Y (%Z)";
		eval {
			$d->set_time_zone($from_tz);
		} or return "$requester: ".make_unknown_zone_message $from_tz;
		$d->set(
			hour => $hour,
			minute => $minute,
		);
		my $unconverted = $d->strftime($format);
		eval {
			$d->set_time_zone($to_tz);
		} or return "$requester: ".make_unknown_zone_message $to_tz;
		my $converted = $d->strftime($format);
		my $from_message = clock_message($from_arg, $from_tz, $unconverted);
		my $to_message = clock_message($to_arg, $to_tz, $converted);
		return "$to_message when $from_message";
	} or return "$requester: I can't figure this time conversion out";
}
1;