%PDF- %PDF-
Direktori : /home/opti/optisoftcom-new/perl/usr/lib/perl5/BSON/ |
Current File : /home/opti/optisoftcom-new/perl/usr/lib/perl5/BSON/Time.pm |
use 5.010001; use strict; use warnings; package BSON::Time; # ABSTRACT: BSON type wrapper for date and time use version; our $VERSION = 'v1.10.2'; use Carp qw/croak/; use Config; use Time::HiRes qw/time/; use Scalar::Util qw/looks_like_number/; use if !$Config{use64bitint}, 'Math::BigInt'; use if !$Config{use64bitint}, 'Math::BigFloat'; use Moo; #pod =attr value #pod #pod A integer representing milliseconds since the Unix epoch. The default #pod is 0. #pod #pod =cut has 'value' => ( is => 'ro' ); use namespace::clean -except => 'meta'; sub BUILDARGS { my $class = shift; my $n = scalar(@_); my %args; if ( $n == 0 ) { if ( $Config{use64bitint} ) { $args{value} = time() * 1000; } else { $args{value} = Math::BigFloat->new(time()); $args{value}->bmul(1000); $args{value} = $args{value}->as_number('zero'); } } elsif ( $n == 1 ) { croak "argument to BSON::Time::new must be epoch seconds, not '$_[0]'" unless looks_like_number( $_[0] ); if ( !$Config{use64bitint} && ref($args{value}) ne 'Math::BigInt' ) { $args{value} = Math::BigFloat->new(shift); $args{value}->bmul(1000); $args{value} = $args{value}->as_number('zero'); } else { $args{value} = 1000 * shift; } } elsif ( $n % 2 == 0 ) { %args = @_; if ( defined $args{value} ) { croak "argument to BSON::Time::new must be epoch seconds, not '$args{value}'" unless looks_like_number( $args{value} ) || overload::Overloaded($args{value}); if ( !$Config{use64bitint} && ref($args{value}) ne 'Math::BigInt' ) { $args{value} = Math::BigInt->new($args{value}); } } else { if ( !$Config{use64bitint} && ref($args{value}) ne 'Math::BigInt' ) { $args{value} = Math::BigFloat->new(shift); $args{value}->bmul(1000); $args{value} = $args{value}->as_number('zero'); } else { $args{value} = 1000 * shift; } } } else { croak("Invalid number of arguments ($n) to BSON::Time::new"); } # normalize all to integer ms $args{value} = int( $args{value} ); return \%args; } #pod =method epoch #pod #pod Returns the number of seconds since the epoch (i.e. a floating-point value). #pod #pod =cut sub epoch { my $self = shift; if ( $Config{use64bitint} ) { return $self->value / 1000; } else { require Math::BigFloat; my $upgrade = Math::BigFloat->new($self->value->bstr); return 0 + $upgrade->bdiv(1000)->bstr; } } #pod =method as_iso8601 #pod #pod Returns the C<value> as an ISO-8601 formatted string of the form #pod C<YYYY-MM-DDThh:mm:ss.sssZ>. The fractional seconds will be omitted if #pod they are zero. #pod #pod =cut sub as_iso8601 { my $self = shift; my ($s, $m, $h, $D, $M, $Y) = gmtime($self->epoch); $M++; $Y+=1900; my $f = $self->{value} % 1000; return $f ? sprintf( "%4d-%02d-%02dT%02d:%02d:%02d.%03dZ", $Y, $M, $D, $h, $m, $s, $f ) : sprintf( "%4d-%02d-%02dT%02d:%02d:%02dZ", $Y, $M, $D, $h, $m, $s ); } #pod =method as_datetime #pod #pod Loads L<DateTime> and returns the C<value> as a L<DateTime> object. #pod #pod =cut sub as_datetime { require DateTime; return DateTime->from_epoch( epoch => $_[0]->{value} / 1000 ); } #pod =method as_datetime_tiny #pod #pod Loads L<DateTime::Tiny> and returns the C<value> as a L<DateTime::Tiny> #pod object. #pod #pod =cut sub as_datetime_tiny { my ($s, $m, $h, $D, $M, $Y) = gmtime($_[0]->epoch); $M++; $Y+=1900; require DateTime::Tiny; return DateTime::Tiny->new( year => $Y, month => $M, day => $D, hour => $h, minute => $m, second => $s ); } #pod =method as_mango_time #pod #pod Loads L<Mango::BSON::Time> and returns the C<value> as a L<Mango::BSON::Time> #pod object. #pod #pod =cut sub as_mango_time { require Mango::BSON::Time; return Mango::BSON::Time->new( $_[0]->{value} ); } #pod =method as_time_moment #pod #pod Loads L<Time::Moment> and returns the C<value> as a L<Time::Moment> object. #pod #pod =cut sub as_time_moment { require Time::Moment; return Time::Moment->from_epoch( $_[0]->{value} / 1000 ); } sub _num_cmp { my ( $self, $other ) = @_; if ( ref($other) eq ref($self) ) { return $self->{value} <=> $other->{value}; } return 0+ $self <=> 0+ $other; } sub _str_cmp { my ( $self, $other ) = @_; if ( ref($other) eq ref($self) ) { return $self->{value} cmp $other->{value}; } return "$self" cmp "$other"; } sub op_eq { my ( $self, $other ) = @_; return( ($self <=> $other) == 0 ); } use overload ( q{""} => \&epoch, q{0+} => \&epoch, q{<=>} => \&_num_cmp, q{cmp} => \&_str_cmp, fallback => 1, ); #pod =method TO_JSON #pod #pod Returns a string formatted by L</as_iso8601>. #pod #pod If the C<BSON_EXTJSON> option is true, it will instead be compatible with #pod MongoDB's L<extended JSON|https://github.com/mongodb/specifications/blob/master/source/extended-json.rst> #pod format, which represents it as a document as follows: #pod #pod #pod If the C<BSON_EXTJSON> environment variable is true and the #pod C<BSON_EXTJSON_RELAXED> environment variable is false, returns a hashref #pod compatible with #pod MongoDB's L<extended JSON|https://github.com/mongodb/specifications/blob/master/source/extended-json.rst> #pod format, which represents it as a document as follows: #pod #pod {"$date" : { "$numberLong": "22337203685477580" } } #pod #pod If the C<BSON_EXTJSON> and C<BSON_EXTJSON_RELAXED> environment variables are #pod both true, then it will return a hashref with an ISO-8601 string for dates #pod after the Unix epoch and before the year 10,000 and a C<$numberLong> style #pod value otherwise. #pod #pod {"$date" : "2012-12-24T12:15:30.500Z"} #pod {"$date" : { "$numberLong": "-10000000" } } #pod #pod =cut sub TO_JSON { return $_[0]->as_iso8601 if ! $ENV{BSON_EXTJSON}; return { '$date' => { '$numberLong' => "$_[0]->{value}"} } if ! $ENV{BSON_EXTJSON_RELAXED}; # Relaxed form is human readable for positive epoch to year 10k my $year = (gmtime($_[0]->epoch))[5]; $year += 1900; if ($year >= 1970 and $year <= 9999) { return { '$date' => $_[0]->as_iso8601 }; } else { return { '$date' => { '$numberLong' => "$_[0]->{value}" } }; } } 1; =pod =encoding UTF-8 =head1 NAME BSON::Time - BSON type wrapper for date and time =head1 VERSION version v1.10.2 =head1 SYNOPSIS use BSON::Types ':all'; bson_time(); # now bson_time( $secs ); # floating point seconds since epoch =head1 DESCRIPTION This module provides a BSON type wrapper for a 64-bit date-time value in the form of milliseconds since the Unix epoch (UTC only). On a Perl without 64-bit integer support, the value must be a L<Math::BigInt> object. =head1 ATTRIBUTES =head2 value A integer representing milliseconds since the Unix epoch. The default is 0. =head1 METHODS =head2 epoch Returns the number of seconds since the epoch (i.e. a floating-point value). =head2 as_iso8601 Returns the C<value> as an ISO-8601 formatted string of the form C<YYYY-MM-DDThh:mm:ss.sssZ>. The fractional seconds will be omitted if they are zero. =head2 as_datetime Loads L<DateTime> and returns the C<value> as a L<DateTime> object. =head2 as_datetime_tiny Loads L<DateTime::Tiny> and returns the C<value> as a L<DateTime::Tiny> object. =head2 as_mango_time Loads L<Mango::BSON::Time> and returns the C<value> as a L<Mango::BSON::Time> object. =head2 as_time_moment Loads L<Time::Moment> and returns the C<value> as a L<Time::Moment> object. =head2 TO_JSON Returns a string formatted by L</as_iso8601>. If the C<BSON_EXTJSON> option is true, it will instead be compatible with MongoDB's L<extended JSON|https://github.com/mongodb/specifications/blob/master/source/extended-json.rst> format, which represents it as a document as follows: If the C<BSON_EXTJSON> environment variable is true and the C<BSON_EXTJSON_RELAXED> environment variable is false, returns a hashref compatible with MongoDB's L<extended JSON|https://github.com/mongodb/specifications/blob/master/source/extended-json.rst> format, which represents it as a document as follows: {"$date" : { "$numberLong": "22337203685477580" } } If the C<BSON_EXTJSON> and C<BSON_EXTJSON_RELAXED> environment variables are both true, then it will return a hashref with an ISO-8601 string for dates after the Unix epoch and before the year 10,000 and a C<$numberLong> style value otherwise. {"$date" : "2012-12-24T12:15:30.500Z"} {"$date" : { "$numberLong": "-10000000" } } =for Pod::Coverage op_eq BUILDARGS =head1 OVERLOADING Both numification (C<0+>) and stringification (C<"">) are overloaded to return the result of L</epoch>. Numeric comparison and string comparison are overloaded based on those and fallback overloading is enabled. =head1 AUTHORS =over 4 =item * David Golden <david@mongodb.com> =item * Stefan G. <minimalist@lavabit.com> =back =head1 COPYRIGHT AND LICENSE This software is Copyright (c) 2018 by Stefan G. and MongoDB, Inc. This is free software, licensed under: The Apache License, Version 2.0, January 2004 =cut __END__ # vim: set ts=4 sts=4 sw=4 et tw=75: