+// ANNA - Anna is Not Nothingness Anymore
+//
+// (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
+//
+// https://bitbucket.org/testillano/anna
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: eduardo.ramos.testillano@gmail.com
+// cisco.tierra@gmail.com
+
+
+#ifndef anna_time_internal_Timezone_hpp
+#define anna_time_internal_Timezone_hpp
+
+
+// Standard
+#include <string>
+#include <stdlib.h>
+#include <iostream>
+
+extern char *tzname[2];
+
+//------------------------------------------------------------------------------
+//---------------------------------------------------------------------- #define
+//------------------------------------------------------------------------------
+
+
+namespace anna {
+
+namespace time {
+
+class Timezone {
+
+ bool a_initialized;
+ std::string a_value;
+ bool a_unsetTZ;
+
+public:
+
+ Timezone() { a_initialized = false; };
+ ~Timezone() {};
+
+
+ // sets
+ // pass NULL to unset
+ void set(const char *input) {
+ a_initialized = true;
+ a_value = input ? input : "";
+
+ // /*
+ // In many C libraries, TZ='' is equivalent to TZ='GMT0' or TZ='UTC0',
+ // and that's the behavior you're observing. An unset TZ is equivalent
+ // to a system-supplied default, typically the local time where the host
+ // is physically located.
+ // */
+ // if (input && (a_value == "")) a_value="UTC0";
+
+ a_unsetTZ = !input;
+ }
+
+ Timezone & operator = (const Timezone &tz) {
+ if(this == &tz) return (*this);
+
+ a_initialized = tz.isInitialized();
+ a_value = tz.getValue();
+ a_unsetTZ = tz.unsetTZ();
+ return (*this);
+ }
+
+ // gets
+
+ // Operators
+
+ friend bool operator == (const Timezone & tz1, const Timezone & tz2) {
+ if(tz1.isInitialized() != tz2.isInitialized())
+ return (false);
+
+ if(tz1.unsetTZ())
+ return (tz2.unsetTZ());
+
+ return (tz1.getValue() == tz2.getValue());
+ }
+
+ friend bool operator != (const Timezone & tz1, const Timezone & tz2) {
+ return (!(tz1 == tz2));
+ }
+
+ // be careful: empty if unset
+ const std::string & getValue(void) const throw() {
+ return (a_value);
+ }
+
+
+ bool isInitialized(void) const throw() {
+ return (a_initialized);
+ }
+
+ //Unset is when getenv("TZ") returns NULL. Then, /etc/localtime used to be a copy or symlink to
+ // any of the /usr/share/zoneinfo available timezones.
+ bool unsetTZ(void) const throw() { return (a_unsetTZ); }
+
+ bool apply() const throw() {
+ // http://stackoverflow.com/questions/5873029/questions-about-putenv-and-setenv
+ if(unsetTZ()) {
+ unsetenv("TZ");
+ }
+ else {
+ setenv("TZ", a_value.c_str(), 1 /* overwrite */);
+
+ /*
+ // If TZ has an invalid setting, tzset() uses GMT0:
+ // Check it:
+ tzset();
+ //std::cout << "tzname[0]: " << tzname[0] << std::endl;
+ //std::cout << "tzname[1]: " << tzname[1] << std::endl;
+ std::string tzname_1 = tzname[1];
+ bool success = (tzname_1 != "");
+ if (!success) std::cerr << "Invalid TZ '" << a_value << "'. Probably GMT0 is going to be used instead !" << std::endl;
+ return success;
+ */
+ }
+
+ return true;
+ }
+
+ std::string asString() const throw() {
+ std::string result = getValue();
+ if (unsetTZ()) return "<TZ unset>";
+ if (result == "") return "<TZ empty>";
+ return result;
+ }
+};
+
+
+}
+}
+
+#endif
+