# DBIWrapper::Time::Now::HiRes.pm # Created by Drew Lesueur, 2015-08-18. # Ported to DBIWrapper by James Pattie, 2016-08-22. # # Copyright (c) 2015-2016, GPSInsight, LLC # All rights reserved. This program is free software; you can redistribute it # and/or modify it under the same terms as Perl itself. package DBIWrapper::Time::Now::HiRes; use Time::HiRes qw(gettimeofday tv_interval); use DBIWrapper::Time::Now::Duration; use POSIX (); use strict; use vars qw($AUTOLOAD @ISA @EXPORT @EXPORT_OK); require Exporter; @ISA = qw(Exporter); @EXPORT = qw(); =head1 NAME DBIWrapper::Time::Now::HiRes =head1 SYNOPSIS Drop in replacement for DateTime::HiRes related code where all I need is to be able to get the current time and compute the duration between 2 timestamps. =cut sub new { my $that = shift; my %args = ( offset => 0, @_ ); my $class = ref($that) || $that; my $self = bless {}, $class; my $seconds; my $microseconds; my $offset = ($args{offset} =~ /^-?\d+$/ ? $args{offset} : 0); $self->{original_gettimeofday} = [ gettimeofday ]; ($seconds, $microseconds) = @{$self->{original_gettimeofday}}; $self->{timestamp_seconds} = $seconds + $offset; $self->{timestamp_microseconds} = $microseconds; $self->{orig_localtime} = [ localtime($self->{timestamp_seconds}) ]; my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = @{$self->{orig_localtime}}; $self->{seconds} = $sec; $self->{minutes} = $min; $self->{hours} = $hour; $self->{year} = $year + 1900; $self->{month} = $mon + 1; $self->{day} = $mday; $self->{strftime_formats} = { }; return $self; } sub strftime { my $self = shift; my $format = shift; if (! exists $self->{strftime_formats}->{$format}) { $self->{strftime_formats}->{$format} = sprintf('%02d', $self->{hours}) if ($format eq '%H'); $self->{strftime_formats}->{$format} = sprintf('%02d', $self->{minutes}) if ($format eq '%M'); $self->{strftime_formats}->{$format} = sprintf('%02d%02d', $self->{hours}, $self->{minutes}) if ($format eq '%H%M'); $self->{strftime_formats}->{$format} = sprintf('%04d%02d%02d', $self->{year}, $self->{month}, $self->{day}) if ($format eq '%Y%m%d'); $self->{strftime_formats}->{$format} = sprintf('%04d-%02d-%02d', $self->{year}, $self->{month}, $self->{day}) if ($format eq '%Y-%m-%d'); $self->{strftime_formats}->{$format} = sprintf('%04d-%02d-%02d %02d:%02d:%02d', $self->{year}, $self->{month}, $self->{day}, $self->{hours}, $self->{minutes}, $self->{seconds}) if ($format eq '%Y-%m-%d %H:%M:%S'); $self->{strftime_formats}->{$format} = sprintf('%04d-%02d-%02dT%02d:%02d:%02dZ', $self->{year}, $self->{month}, $self->{day}, $self->{hours}, $self->{minutes}, $self->{seconds}) if ($format eq '%Y-%m-%dT%H:%M:%SZ'); $self->{strftime_formats}->{$format} = sprintf('%02d-%02d-%04d %02d:%02d:%02d', $self->{month}, $self->{day}, $self->{year}, $self->{hours}, $self->{minutes}, $self->{seconds}) if ($format eq '%m-%d-%Y %H:%M:%S'); # catchall. $self->{strftime_formats}->{$format} = POSIX::strftime($format, @{$self->{orig_localtime}}) if (! exists $self->{strftime_formats}->{$format}); } return $self->{strftime_formats}->{$format}; } sub subtract_datetime_absolute { my $self = shift; my $start_time = shift; die "start_time is not defined" if not defined $start_time; my $diff = abs( tv_interval($start_time->{original_gettimeofday},$self->{original_gettimeofday}) ); my ($seconds,$fractionalseconds) = split('\.',"$diff"); my $microseconds = ".$fractionalseconds" * 1_000_000; return DBIWrapper::Time::Now::Duration->new($seconds,$microseconds); } sub millisecond { my $self = shift; if (! exists $self->{millisecond}) { $self->{millisecond} = POSIX::floor($self->{timestamp_microseconds} / 1000); $self->{millisecond} = ($self->{millisecond} <= 999 ? $self->{millisecond} : 999); } return $self->{millisecond}; } sub hms { my $self = shift; my $delimiter = shift; $delimiter = ':' if (not defined $delimiter); if (! exists $self->{hms_cache}->{$delimiter}) { $self->{hms_cache}->{$delimiter} = sprintf("%02d$delimiter%02d$delimiter%02d", $self->{hours}, $self->{minutes}, $self->{seconds}); } return $self->{hms_cache}->{$delimiter}; } sub set_time_zone { # nothing } sub ymd { my $self = shift; my $delimiter = shift; $delimiter = '-' if (not defined $delimiter); if (! exists $self->{ymd_cache}->{$delimiter}) { $self->{ymd_cache}->{$delimiter} = sprintf("%04d$delimiter%02d$delimiter%02d", $self->{year}, $self->{month}, $self->{day}); } return $self->{ymd_cache}->{$delimiter}; } sub hires_epoch { my $self = shift; if (! exists $self->{hires_epoch_str}) { $self->{hires_epoch_str} = join(".", @{$self->{original_gettimeofday}}); } return $self->{hires_epoch_str}; } 1;