use
5.010;
our
$VERSION
=
'0.03'
;
has
'+jsonp'
=> (
default
=>
'_cb'
);
sub
service_name {
return
'async-microservice-time'
;
}
sub
get_routes {
return
(
'datetime'
=> {
defaults
=> {
GET
=>
'GET_datetime'
,
POST
=>
'POST_datetime'
,
},
},
'datetime/:time_zone'
=> {
defaults
=> {
GET
=>
'GET_datetime'
,
POST
=>
'POST_datetime'
,
},
},
'datetime/:time_zone_part1/:time_zone_part2'
=> {
defaults
=> {
GET
=>
'GET_datetime_capture'
,},
validations
=> {
time_zone_part1
=>
qr{^\w+$}
,
time_zone_part2
=>
qr{^\w+$}
,
},
},
'datetime/span/:s_date'
=> {
defaults
=> {
GET
=>
'GET_datetime_span'
}},
'epoch'
=> {
defaults
=> {
GET
=>
'GET_epoch'
}},
'sleep'
=> {
defaults
=> {
GET
=>
'GET_sleep'
}},
);
}
sub
GET_datetime {
my
(
$self
,
$this_req
) =
@_
;
my
$time_zone
=
$this_req
->params->{time_zone} //
'UTC'
;
return
$self
->_get_datetime_time_zone(
$this_req
,
$time_zone
);
}
sub
GET_datetime_capture {
my
(
$self
,
$this_req
,
$match
) =
@_
;
my
$time_zone
=
$this_req
->params->{time_zone_part1} .
'/'
.
$this_req
->params->{time_zone_part2};
return
$self
->_get_datetime_time_zone(
$this_req
,
$time_zone
);
}
sub
_get_datetime_time_zone {
my
(
$self
,
$this_req
,
$time_zone
) =
@_
;
my
$time_dt
=
eval
{ DateTime->now(
time_zone
=>
$time_zone
); };
if
($@) {
return
[
405,
[],
{
err_status
=> 405,
err_msg
=> $@,
}
];
}
return
[ 200, [], _datetime_as_data(
$time_dt
) ];
}
sub
POST_datetime {
my
(
$self
,
$this_req
) =
@_
;
my
$epoch
=
eval
{
$this_req
->json_content->{epoch}};
if
(!
defined
(
$epoch
)) {
return
[
405,
[],
{
err_status
=> 405,
err_msg
=> $@ ||
'epoch data missing'
,
}
];
}
if
(
$epoch
!~ m/^-?[0-9]+$/) {
return
[
405,
[],
{
err_status
=> 405,
err_msg
=>
'epoch not a number'
,
}
];
}
return
[200, [], _datetime_as_data(DateTime->from_epoch(
epoch
=>
$epoch
))];
}
sub
GET_epoch {
my
(
$self
,
$this_req
) =
@_
;
return
[ 200, [], {
epoch
=>
time
() } ];
}
async
sub
GET_sleep {
my
(
$self
,
$this_req
) =
@_
;
my
$start_time
=
time
();
my
$sleep_time
= (
$this_req
->params->{duration} //
rand
(10) ) + 0;
if
(
$sleep_time
<= 0 ) {
return
[
405,
[],
{
err_status
=> 405,
err_msg
=>
'invalid sleep duration'
,
}
];
}
await AnyEvent::Future->new_delay(
after
=>
$sleep_time
);
my
$stop_time
=
time
();
return
[
200,
[],
{
start
=>
$start_time
,
stop
=>
$stop_time
,
duration
=> (
$stop_time
-
$start_time
),
}
];
}
async
sub
GET_datetime_span {
my
(
$self
,
$this_req
) =
@_
;
my
$now
= DateTime->now(
time_zone
=>
'UTC'
)->
truncate
(
to
=>
'day'
);
my
$s_date_dt
;
my
$s_date
=
$this_req
->params->{s_date} //
''
;
if
(
$s_date
=~ m/^([0-9]{4})-?([0-9]{2})-?([0-9]{2})$/) {
$s_date_dt
=
eval
{DateTime->new(
time_zone
=>
'UTC'
,
day
=> $3,
month
=> $2,
year
=> $1)};
}
elsif
(
$s_date
eq
'now'
) {
$s_date_dt
=
$now
->clone;
}
unless
(
$s_date_dt
) {
return
[
405,
[],
{
err_status
=> 405,
err_msg
=>
'invalid date format '
.
$s_date
.
', use YYYYMMDD or "now"'
,
}
];
}
my
$r_age
=
int
(
$this_req
->params->{r_age} // 65);
unless
(
$r_age
|| (
$r_age
< 1) || (
$r_age
> 200)) {
return
[
405,
[],
{
err_status
=> 405,
err_msg
=>
'invalid age'
,
}
];
}
my
$m_income
=
int
(
$this_req
->params->{m_income} // 0);
my
$r_age_dt
=
$s_date_dt
->clone->add(
years
=>
$r_age
);
$r_age_dt
=
$now
->clone
if
$r_age_dt
<
$now
;
my
$counter_dt
=
$r_age_dt
->subtract_datetime(
$now
);
my
$days_counter
=
$r_age_dt
->delta_days(
$now
)->in_units(
'days'
);
my
$week_counter
=
int
(
$days_counter
/7);
my
$months_counter
=
$counter_dt
->in_units(
'months'
);
my
$years_counter
=
$counter_dt
->in_units(
'years'
);
my
$date_from_str
=
$s_date_dt
->strftime(
'%Y-%m-%d'
);
my
$date_to_str
=
$r_age_dt
->strftime(
'%Y-%m-%d'
);
return
{
msg
=>
sprintf
(
'%d weeks left until date span age of %d (date from %s to %s)'
,
$week_counter
,
$r_age
,
$date_from_str
,
$date_to_str
,
),
days
=>
$days_counter
,
weeks
=>
$week_counter
,
months
=>
$months_counter
,
years
=>
$years_counter
,
date_from
=>
$date_from_str
,
date_to
=>
$date_to_str
,
(
$m_income
? (
income
=>
$months_counter
*
$m_income
) : ()),
};
}
sub
_datetime_as_data {
my
(
$dt
) =
@_
;
return
{
datetime
=>
$dt
->strftime(
'%Y-%m-%d %H:%M:%S %z'
),
date
=>
$dt
->strftime(
'%Y-%m-%d'
),
time
=>
$dt
->strftime(
'%H:%M:%S'
),
time_zone
=>
$dt
->strftime(
'%z'
),
time_zone_name
=>
$dt
->strftime(
'%Z'
),
day
=>
$dt
->strftime(
'%d'
),
month
=>
$dt
->strftime(
'%m'
),
year
=>
$dt
->strftime(
'%Y'
),
hour
=>
$dt
->strftime(
'%H'
),
minute
=>
$dt
->strftime(
'%M'
),
second
=>
$dt
->strftime(
'%S'
),
epoch
=>
$dt
->epoch,
};
}
__PACKAGE__->meta->make_immutable;
1;