VideoTools
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
gvtimezone.cpp
Go to the documentation of this file.
1 //
2 // Copyright (C) 2017 Graeme Walker
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 // ===
17 //
18 // gvtimezone.cpp
19 //
20 
21 #include "gdef.h"
22 #include "gvtimezone.h"
23 #include "gdatetime.h"
24 #include "gdate.h"
25 #include "gtime.h"
26 #include "gassert.h"
27 #include "gstr.h"
28 #include <stdexcept>
29 
30 Gv::Timezone::Timezone( int hours ) :
31  m_minutes(hours*60)
32 {
33  if( hours < -11 || hours > 12 )
34  throw std::runtime_error( "timezone must be between -11 and 12" ) ;
35 }
36 
37 Gv::Timezone::Timezone( const std::string & hours_in )
38 {
39  std::string hours( hours_in ) ;
40  bool negative = !hours.empty() && hours.at(0U) == '-' ;
41  bool positive = !hours.empty() && hours.at(0U) == '+' ;
42  if( negative || positive ) hours.erase(0U,1U) ;
43  std::string::size_type pos = hours.find(".") ;
44  std::string head = G::Str::head( hours , pos , hours ) ;
45  std::string tail = G::Str::tail( hours , pos , "0" ) ;
46 
47  if( hours.empty() ||
48  head.empty() || !G::Str::isUInt(head) || tail.empty() || !G::Str::isUInt(tail) ||
49  G::Str::toUInt(head) > (negative?11U:12U) ||
50  (G::Str::toUInt(tail) != 0U && G::Str::toUInt(tail)!=5U) )
51  throw std::runtime_error( "invalid timezone: use a signed integral number of hours" ) ;
52 
53  unsigned int minutes = G::Str::toUInt(head)*60U + (G::Str::toUInt(tail)==5U?30U:0U) ;
54  m_minutes = static_cast<int>(minutes) ;
55  if( negative ) m_minutes = -m_minutes ;
56 }
57 
58 bool Gv::Timezone::zero() const
59 {
60  return m_minutes == 0 ;
61 }
62 
63 std::time_t Gv::Timezone::seconds() const
64 {
65  G_ASSERT( std::time_t(-1) < std::time_t(0) ) ;
66  return std::time_t(m_minutes) * 60 ;
67 }
68 
69 std::string Gv::Timezone::str() const
70 {
71  unsigned int uminutes = m_minutes < 0 ?
72  static_cast<unsigned int>(-m_minutes) :
73  static_cast<unsigned int>(m_minutes) ;
74 
75  unsigned int hh = uminutes / 60U ;
76  unsigned int mm = uminutes % 60U ;
77 
78  std::ostringstream ss ;
79  ss << (m_minutes<0?'-':'+') << (hh/10U) << (hh%10U) << (mm/10U) << (mm%10U) ;
80  return ss.str() ;
81 }
82 
83 /// \file gvtimezone.cpp
Timezone(int hours=0)
Constructor.
Definition: gvtimezone.cpp:30
std::time_t seconds() const
Returns the offset as a signed number of seconds.
Definition: gvtimezone.cpp:63
std::string str() const
Returns a five-character "+/-hhmm" representation.
Definition: gvtimezone.cpp:69
bool zero() const
Returns true for utc.
Definition: gvtimezone.cpp:58
static std::string tail(const std::string &in, std::string::size_type pos, const std::string &default_=std::string())
Returns the last part of the string after the given position.
Definition: gstr.cpp:1051
static unsigned int toUInt(const std::string &s)
Converts string 's' to an unsigned int.
Definition: gstr.cpp:450
static std::string head(const std::string &in, std::string::size_type pos, const std::string &default_=std::string())
Returns the first part of the string up to just before the given position.
Definition: gstr.cpp:1037
static bool isUInt(const std::string &s)
Returns true if the string can be converted into an unsigned integer without throwing an exception...
Definition: gstr.cpp:266