blob: 422054ce045982abc916e554dd4b8cede99ebca6 [file] [log] [blame]
//
// Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#define BOOST_LOCALE_SOURCE
#include <boost/locale/date_time.hpp>
#include <boost/locale/formatting.hpp>
#include <boost/thread/mutex.hpp>
#include <math.h>
namespace boost {
namespace locale {
using namespace period;
/////////////////////////
// Calendar
////////////////////////
calendar::calendar(std::locale const &l,std::string const &zone) :
locale_(l),
tz_(zone),
impl_(std::use_facet<calendar_facet>(l).create_calendar())
{
impl_->set_timezone(tz_);
}
calendar::calendar(std::string const &zone) :
tz_(zone),
impl_(std::use_facet<calendar_facet>(std::locale()).create_calendar())
{
impl_->set_timezone(tz_);
}
calendar::calendar(std::locale const &l) :
locale_(l),
tz_(time_zone::global()),
impl_(std::use_facet<calendar_facet>(l).create_calendar())
{
impl_->set_timezone(tz_);
}
calendar::calendar(std::ios_base &ios) :
locale_(ios.getloc()),
tz_(ios_info::get(ios).time_zone()),
impl_(std::use_facet<calendar_facet>(locale_).create_calendar())
{
impl_->set_timezone(tz_);
}
calendar::calendar() :
tz_(time_zone::global()),
impl_(std::use_facet<calendar_facet>(std::locale()).create_calendar())
{
impl_->set_timezone(tz_);
}
calendar::~calendar()
{
}
calendar::calendar(calendar const &other) :
locale_(other.locale_),
tz_(other.tz_),
impl_(other.impl_->clone())
{
}
calendar const &calendar::operator = (calendar const &other)
{
if(this !=&other) {
impl_.reset(other.impl_->clone());
locale_ = other.locale_;
tz_ = other.tz_;
}
return *this;
}
bool calendar::is_gregorian() const
{
return impl_->get_option(abstract_calendar::is_gregorian)!=0;
}
std::string calendar::get_time_zone() const
{
return tz_;
}
std::locale calendar::get_locale() const
{
return locale_;
}
int calendar::minimum(period_type f) const
{
return impl_->get_value(f.mark(),abstract_calendar::absolute_minimum);
}
int calendar::greatest_minimum(period_type f) const
{
return impl_->get_value(f.mark(),abstract_calendar::greatest_minimum);
}
int calendar::maximum(period_type f) const
{
return impl_->get_value(f.mark(),abstract_calendar::absolute_maximum);
}
int calendar::least_maximum(period_type f) const
{
return impl_->get_value(f.mark(),abstract_calendar::least_maximum);
}
int calendar::first_day_of_week() const
{
return impl_->get_value(period::marks::first_day_of_week,abstract_calendar::current);
}
bool calendar::operator==(calendar const &other) const
{
return impl_->same(other.impl_.get());
}
bool calendar::operator!=(calendar const &other) const
{
return !(*this==other);
}
//////////////////////////////////
// date_time
/////////////////
date_time::date_time() :
impl_(std::use_facet<calendar_facet>(std::locale()).create_calendar())
{
impl_->set_timezone(time_zone::global());
}
date_time::date_time(date_time const &other)
{
impl_.reset(other.impl_->clone());
}
date_time::date_time(date_time const &other,date_time_period_set const &s)
{
impl_.reset(other.impl_->clone());
for(unsigned i=0;i<s.size();i++) {
impl_->set_value(s[i].type.mark(),s[i].value);
}
impl_->normalize();
}
date_time const &date_time::operator = (date_time const &other)
{
if(this != &other) {
date_time tmp(other);
swap(tmp);
}
return *this;
}
date_time::~date_time()
{
}
date_time::date_time(double t) :
impl_(std::use_facet<calendar_facet>(std::locale()).create_calendar())
{
impl_->set_timezone(time_zone::global());
time(t);
}
date_time::date_time(double t,calendar const &cal) :
impl_(cal.impl_->clone())
{
time(t);
}
date_time::date_time(calendar const &cal) :
impl_(cal.impl_->clone())
{
}
date_time::date_time(date_time_period_set const &s) :
impl_(std::use_facet<calendar_facet>(std::locale()).create_calendar())
{
impl_->set_timezone(time_zone::global());
for(unsigned i=0;i<s.size();i++) {
impl_->set_value(s[i].type.mark(),s[i].value);
}
impl_->normalize();
}
date_time::date_time(date_time_period_set const &s,calendar const &cal) :
impl_(cal.impl_->clone())
{
for(unsigned i=0;i<s.size();i++) {
impl_->set_value(s[i].type.mark(),s[i].value);
}
impl_->normalize();
}
date_time const &date_time::operator=(date_time_period_set const &s)
{
for(unsigned i=0;i<s.size();i++)
impl_->set_value(s[i].type.mark(),s[i].value);
impl_->normalize();
return *this;
}
void date_time::set(period_type f,int v)
{
impl_->set_value(f.mark(),v);
impl_->normalize();
}
int date_time::get(period_type f) const
{
return impl_->get_value(f.mark(),abstract_calendar::current);
}
date_time date_time::operator+(date_time_period const &v) const
{
date_time tmp(*this);
tmp+=v;
return tmp;
}
date_time date_time::operator-(date_time_period const &v) const
{
date_time tmp(*this);
tmp-=v;
return tmp;
}
date_time date_time::operator<<(date_time_period const &v) const
{
date_time tmp(*this);
tmp<<=v;
return tmp;
}
date_time date_time::operator>>(date_time_period const &v) const
{
date_time tmp(*this);
tmp>>=v;
return tmp;
}
date_time const &date_time::operator+=(date_time_period const &v)
{
impl_->adjust_value(v.type.mark(),abstract_calendar::move,v.value);
return *this;
}
date_time const &date_time::operator-=(date_time_period const &v)
{
impl_->adjust_value(v.type.mark(),abstract_calendar::move,-v.value);
return *this;
}
date_time const &date_time::operator<<=(date_time_period const &v)
{
impl_->adjust_value(v.type.mark(),abstract_calendar::roll,v.value);
return *this;
}
date_time const &date_time::operator>>=(date_time_period const &v)
{
impl_->adjust_value(v.type.mark(),abstract_calendar::roll,-v.value);
return *this;
}
date_time date_time::operator+(date_time_period_set const &v) const
{
date_time tmp(*this);
tmp+=v;
return tmp;
}
date_time date_time::operator-(date_time_period_set const &v) const
{
date_time tmp(*this);
tmp-=v;
return tmp;
}
date_time date_time::operator<<(date_time_period_set const &v) const
{
date_time tmp(*this);
tmp<<=v;
return tmp;
}
date_time date_time::operator>>(date_time_period_set const &v) const
{
date_time tmp(*this);
tmp>>=v;
return tmp;
}
date_time const &date_time::operator+=(date_time_period_set const &v)
{
for(unsigned i=0;i<v.size();i++) {
*this+=v[i];
}
return *this;
}
date_time const &date_time::operator-=(date_time_period_set const &v)
{
for(unsigned i=0;i<v.size();i++) {
*this-=v[i];
}
return *this;
}
date_time const &date_time::operator<<=(date_time_period_set const &v)
{
for(unsigned i=0;i<v.size();i++) {
*this<<=v[i];
}
return *this;
}
date_time const &date_time::operator>>=(date_time_period_set const &v)
{
for(unsigned i=0;i<v.size();i++) {
*this>>=v[i];
}
return *this;
}
double date_time::time() const
{
posix_time ptime = impl_->get_time();
return double(ptime.seconds)+1e-9*ptime.nanoseconds;
}
void date_time::time(double v)
{
double dseconds = floor(v);
int64_t seconds = static_cast<int64_t>(dseconds);
double fract = v - dseconds;
int nano = static_cast<int>(fract * 1e9);
if(nano < 0)
nano = 0;
else if(nano >999999999)
nano = 999999999;
posix_time ptime;
ptime.seconds = seconds;
ptime.nanoseconds = nano;
impl_->set_time(ptime);
}
namespace {
int compare(posix_time const &left,posix_time const &right)
{
if(left.seconds < right.seconds)
return -1;
if(left.seconds > right.seconds)
return 1;
if(left.nanoseconds < right.nanoseconds)
return -1;
if(left.nanoseconds > right.nanoseconds)
return 1;
return 0;
}
}
bool date_time::operator==(date_time const &other) const
{
return compare(impl_->get_time(),other.impl_->get_time()) == 0;
}
bool date_time::operator!=(date_time const &other) const
{
return !(*this==other);
}
bool date_time::operator<(date_time const &other) const
{
return compare(impl_->get_time(),other.impl_->get_time()) < 0;
}
bool date_time::operator>=(date_time const &other) const
{
return !(*this<other);
}
bool date_time::operator>(date_time const &other) const
{
return compare(impl_->get_time(),other.impl_->get_time()) > 0;
}
bool date_time::operator<=(date_time const &other) const
{
return !(*this>other);
}
void date_time::swap(date_time &other)
{
impl_.swap(other.impl_);
}
int date_time::difference(date_time const &other,period_type f) const
{
return impl_->difference(other.impl_.get(),f.mark());
}
int date_time::maximum(period_type f) const
{
return impl_->get_value(f.mark(),abstract_calendar::actual_maximum);
}
int date_time::minimum(period_type f) const
{
return impl_->get_value(f.mark(),abstract_calendar::actual_minimum);
}
bool date_time::is_in_daylight_saving_time() const
{
return impl_->get_option(abstract_calendar::is_dst)!=0;
}
namespace time_zone {
boost::mutex &tz_mutex()
{
static boost::mutex m;
return m;
}
std::string &tz_id()
{
static std::string id;
return id;
}
std::string global()
{
boost::unique_lock<boost::mutex> lock(tz_mutex());
std::string id = tz_id();
return id;
}
std::string global(std::string const &new_id)
{
boost::unique_lock<boost::mutex> lock(tz_mutex());
std::string id = tz_id();
tz_id() = new_id;
return id;
}
}
} // locale
} // boost
// vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4