2012-04-27 11:41:46 +04:00
|
|
|
/*
|
|
|
|
grive: an GPL program to sync a local directory with Google Drive
|
|
|
|
Copyright (C) 2012 Wan Wai Ho
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU General Public License
|
|
|
|
as published by the Free Software Foundation version 2
|
|
|
|
of the License.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "DateTime.hh"
|
|
|
|
|
2012-05-29 21:30:06 +04:00
|
|
|
#include "Exception.hh"
|
|
|
|
|
|
|
|
// boost headers
|
|
|
|
#include <boost/throw_exception.hpp>
|
|
|
|
#include <boost/exception/errinfo_api_function.hpp>
|
|
|
|
#include <boost/exception/errinfo_at_line.hpp>
|
|
|
|
#include <boost/exception/errinfo_errno.hpp>
|
|
|
|
#include <boost/exception/info.hpp>
|
|
|
|
|
2012-05-20 13:12:01 +04:00
|
|
|
#include <sstream>
|
|
|
|
|
2012-04-28 14:33:08 +04:00
|
|
|
#include <cassert>
|
2012-04-27 11:41:46 +04:00
|
|
|
#include <cstdlib>
|
2012-04-27 21:52:02 +04:00
|
|
|
#include <cstring>
|
|
|
|
#include <iomanip>
|
2012-04-27 11:41:46 +04:00
|
|
|
|
|
|
|
#include <time.h>
|
|
|
|
|
|
|
|
namespace gr {
|
|
|
|
|
|
|
|
DateTime::DateTime( ) :
|
|
|
|
m_sec ( 0 ),
|
2012-04-27 21:52:02 +04:00
|
|
|
m_nsec ( 0 )
|
2012-04-27 11:41:46 +04:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
DateTime::DateTime( const std::string& iso ) :
|
|
|
|
m_sec ( 0 ),
|
2012-04-27 21:52:02 +04:00
|
|
|
m_nsec ( 0 )
|
|
|
|
{
|
|
|
|
struct tm tp = {} ;
|
|
|
|
const char *r = ::strptime( iso.c_str(), "%Y-%m-%dT%H:%M:%S", &tp ) ;
|
|
|
|
|
|
|
|
// should be '.' followed by 3 digits and 'Z' (e.g. .123Z)
|
|
|
|
if ( r != 0 && r - iso.c_str() == 19 )
|
|
|
|
{
|
|
|
|
m_sec = ::timegm( &tp ) ;
|
|
|
|
|
|
|
|
// at least 3 digits is OK. we don't care the Z
|
|
|
|
if ( *r == '.' && ::strlen( r+1 ) >= 3 )
|
|
|
|
m_nsec = std::atoi( r+1 ) * 1000 * 1000 ;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-05-29 21:30:06 +04:00
|
|
|
DateTime::DateTime( std::time_t sec, unsigned long nsec )
|
|
|
|
{
|
|
|
|
Assign( sec, nsec ) ;
|
|
|
|
}
|
|
|
|
|
|
|
|
void DateTime::Assign( std::time_t sec, unsigned long nsec )
|
2012-04-27 11:41:46 +04:00
|
|
|
{
|
2012-05-29 21:30:06 +04:00
|
|
|
m_sec = sec + nsec / 1000000000 ;
|
|
|
|
m_nsec = nsec % 1000000000 ;
|
2012-04-27 11:41:46 +04:00
|
|
|
}
|
|
|
|
|
2012-05-09 21:20:38 +04:00
|
|
|
DateTime DateTime::Now()
|
|
|
|
{
|
2012-05-29 21:30:06 +04:00
|
|
|
struct timeval tv = {} ;
|
|
|
|
if ( ::gettimeofday( &tv, 0 ) != 0 )
|
|
|
|
{
|
|
|
|
BOOST_THROW_EXCEPTION(
|
|
|
|
Exception()
|
|
|
|
<< boost::errinfo_api_function("gettimeofday")
|
|
|
|
<< boost::errinfo_errno(errno)
|
|
|
|
) ;
|
|
|
|
}
|
|
|
|
|
|
|
|
return DateTime( tv.tv_sec, tv.tv_usec * 1000 ) ;
|
2012-05-09 21:20:38 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
std::string DateTime::Format( const std::string& format ) const
|
|
|
|
{
|
|
|
|
struct tm tp = Tm() ;
|
|
|
|
|
|
|
|
char tmp[1024] ;
|
|
|
|
std::size_t count = ::strftime( tmp, sizeof(tmp), format.c_str(), &tp ) ;
|
|
|
|
return count > 0 ? std::string( tmp, count ) : "" ;
|
|
|
|
}
|
|
|
|
|
2012-04-27 11:41:46 +04:00
|
|
|
struct tm DateTime::Tm() const
|
|
|
|
{
|
|
|
|
struct tm tp ;
|
|
|
|
gmtime_r( &m_sec, &tp ) ;
|
|
|
|
return tp ;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::time_t DateTime::Sec( ) const
|
|
|
|
{
|
|
|
|
return m_sec ;
|
|
|
|
}
|
|
|
|
|
2012-04-27 21:52:02 +04:00
|
|
|
unsigned long DateTime::NanoSec( ) const
|
|
|
|
{
|
2012-04-28 14:33:08 +04:00
|
|
|
assert( m_nsec < 1000000000 ) ;
|
2012-04-27 21:52:02 +04:00
|
|
|
return m_nsec ;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::ostream& operator<<( std::ostream& os, const DateTime& dt )
|
|
|
|
{
|
|
|
|
struct tm tp = dt.Tm() ;
|
|
|
|
|
|
|
|
char buf[40] ;
|
|
|
|
strftime( buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S", &tp ) ;
|
|
|
|
return os << buf << '.' << std::setw( 3 ) << std::setfill('0') << dt.NanoSec()/1000000 << 'Z' ;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct timeval DateTime::Tv() const
|
2012-04-27 11:41:46 +04:00
|
|
|
{
|
2012-04-28 14:33:08 +04:00
|
|
|
assert( m_nsec < 1000000000 ) ;
|
|
|
|
|
2012-04-27 21:52:02 +04:00
|
|
|
timeval result ;
|
|
|
|
result.tv_sec = m_sec ;
|
|
|
|
result.tv_usec = m_nsec / 1000 ;
|
|
|
|
return result ;
|
2012-04-27 11:41:46 +04:00
|
|
|
}
|
|
|
|
|
2012-04-28 14:33:08 +04:00
|
|
|
bool DateTime::operator==( const DateTime& dt ) const
|
|
|
|
{
|
|
|
|
assert( m_nsec < 1000000000 ) ;
|
|
|
|
return m_sec == dt.m_sec && m_nsec == dt.m_nsec ;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool DateTime::operator!=( const DateTime& dt ) const
|
|
|
|
{
|
|
|
|
return !( *this == dt ) ;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool DateTime::operator>( const DateTime& dt ) const
|
|
|
|
{
|
|
|
|
assert( m_nsec < 1000000000 ) ;
|
|
|
|
assert( dt.m_nsec < 1000000000 ) ;
|
|
|
|
return m_sec == dt.m_sec ? m_nsec > dt.m_nsec : m_sec > dt.m_sec ;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool DateTime::operator>=( const DateTime& dt ) const
|
|
|
|
{
|
|
|
|
return ( *this > dt ) || ( *this == dt ) ;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool DateTime::operator<( const DateTime& dt ) const
|
|
|
|
{
|
|
|
|
return !( *this >= dt ) ;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool DateTime::operator<=( const DateTime& dt ) const
|
|
|
|
{
|
|
|
|
return !( *this > dt ) ;
|
|
|
|
}
|
|
|
|
|
2012-05-09 19:52:06 +04:00
|
|
|
void DateTime::Swap( DateTime& dt )
|
|
|
|
{
|
|
|
|
std::swap( m_sec, dt.m_sec ) ;
|
|
|
|
std::swap( m_nsec, dt.m_nsec ) ;
|
|
|
|
}
|
|
|
|
|
2012-05-20 13:12:01 +04:00
|
|
|
std::string DateTime::ToString() const
|
|
|
|
{
|
|
|
|
std::ostringstream ss ;
|
|
|
|
ss << *this ;
|
|
|
|
return ss.str() ;
|
|
|
|
}
|
|
|
|
|
2012-04-27 11:41:46 +04:00
|
|
|
} // end of namespace
|