1# DBIWrapper::Time::Now::HiRes.pm
2# Created by Drew Lesueur, 2015-08-18.
3# Ported to DBIWrapper by James Pattie, 2016-08-22.
4#
5# Copyright (c) 2015-2016, GPSInsight, LLC  <http://www.gpsinsight.com/>
6# All rights reserved.  This program is free software; you can redistribute it
7# and/or modify it under the same terms as Perl itself.
8
9package DBIWrapper::Time::Now::HiRes;
10use Time::HiRes qw(gettimeofday tv_interval);
11use DBIWrapper::Time::Now::Duration;
12use POSIX ();
13use strict;
14
15use vars qw($AUTOLOAD @ISA @EXPORT @EXPORT_OK);
16
17require Exporter;
18
19@ISA = qw(Exporter);
20@EXPORT = qw();
21
22=head1 NAME
23
24DBIWrapper::Time::Now::HiRes
25
26=head1 SYNOPSIS
27
28Drop in replacement for DateTime::HiRes related code where all I need
29is to be able to get the current time and compute the duration between
302 timestamps.
31
32=cut
33
34sub new {
35  my $that = shift;
36  my %args = ( offset => 0, @_ );
37  my $class = ref($that) || $that;
38  my $self = bless {}, $class;
39
40  my $seconds;
41  my $microseconds;
42  my $offset = ($args{offset} =~ /^-?\d+$/ ? $args{offset} : 0);
43
44  $self->{original_gettimeofday} = [ gettimeofday ];
45  ($seconds, $microseconds) = @{$self->{original_gettimeofday}};
46  $self->{timestamp_seconds} = $seconds + $offset;
47  $self->{timestamp_microseconds} = $microseconds;
48
49  $self->{orig_localtime} = [ localtime($self->{timestamp_seconds}) ];
50  my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = @{$self->{orig_localtime}};
51
52  $self->{seconds} = $sec;
53  $self->{minutes} = $min;
54  $self->{hours} = $hour;
55
56  $self->{year} = $year + 1900;
57  $self->{month} = $mon + 1;
58  $self->{day} = $mday;
59
60  $self->{strftime_formats} = { };
61
62  return $self;
63}
64
65
66sub strftime {
67  my $self = shift;
68  my $format = shift;
69
70  if (! exists $self->{strftime_formats}->{$format})
71  {
72    $self->{strftime_formats}->{$format} = sprintf('%02d', $self->{hours}) if ($format eq '%H');
73    $self->{strftime_formats}->{$format} = sprintf('%02d', $self->{minutes}) if ($format eq '%M');
74    $self->{strftime_formats}->{$format} = sprintf('%02d%02d', $self->{hours}, $self->{minutes}) if ($format eq '%H%M');
75    $self->{strftime_formats}->{$format} = sprintf('%04d%02d%02d', $self->{year}, $self->{month}, $self->{day}) if ($format eq '%Y%m%d');
76
77    $self->{strftime_formats}->{$format} = sprintf('%04d-%02d-%02d', $self->{year}, $self->{month}, $self->{day}) if ($format eq '%Y-%m-%d');
78
79    $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');
80
81    $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');
82
83    $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');
84
85    # catchall.
86    $self->{strftime_formats}->{$format} = POSIX::strftime($format, @{$self->{orig_localtime}}) if (! exists $self->{strftime_formats}->{$format});
87  }
88
89  return $self->{strftime_formats}->{$format};
90}
91
92sub subtract_datetime_absolute {
93  my $self = shift;
94  my $start_time = shift;
95
96  die "start_time is not defined" if not defined $start_time;
97
98  my $diff = abs(  tv_interval($start_time->{original_gettimeofday},$self->{original_gettimeofday}) );
99  my ($seconds,$fractionalseconds) = split('\.',"$diff");
100  my $microseconds = ".$fractionalseconds" * 1_000_000;
101
102  return DBIWrapper::Time::Now::Duration->new($seconds,$microseconds);
103}
104
105sub millisecond {
106  my $self = shift;
107
108  if (! exists $self->{millisecond})
109  {
110    $self->{millisecond} = POSIX::floor($self->{timestamp_microseconds} / 1000);
111
112    $self->{millisecond} = ($self->{millisecond} <= 999 ? $self->{millisecond} : 999);
113  }
114
115  return $self->{millisecond};
116}
117
118
119sub hms {
120  my $self = shift;
121  my $delimiter = shift;
122
123  $delimiter = ':' if (not defined $delimiter);
124
125  if (! exists $self->{hms_cache}->{$delimiter})
126  {
127     $self->{hms_cache}->{$delimiter} = sprintf("%02d$delimiter%02d$delimiter%02d", $self->{hours}, $self->{minutes}, $self->{seconds});
128  }
129
130  return $self->{hms_cache}->{$delimiter};
131}
132
133sub set_time_zone {
134  # nothing
135}
136
137sub ymd {
138  my $self = shift;
139  my $delimiter = shift;
140
141  $delimiter = '-' if (not defined $delimiter);
142
143  if (! exists $self->{ymd_cache}->{$delimiter})
144  {
145     $self->{ymd_cache}->{$delimiter} = sprintf("%04d$delimiter%02d$delimiter%02d", $self->{year}, $self->{month}, $self->{day});
146  }
147
148  return $self->{ymd_cache}->{$delimiter};
149}
150
151sub hires_epoch {
152  my $self = shift;
153
154  if (! exists $self->{hires_epoch_str})
155  {
156    $self->{hires_epoch_str} = join(".", @{$self->{original_gettimeofday}});
157  }
158
159  return $self->{hires_epoch_str};
160}
161
1621;
163