Esempio n. 1
0
GncDateTimeImpl::GncDateTimeImpl(const std::string str) :
    m_time(unix_epoch, utc_zone)
{
    if (str.empty()) return;

    using std::string;
    using PTZ = boost::local_time::posix_time_zone;
    TZ_Ptr tzptr;
    auto tzpos = str.find_first_of("+-", str.find(":"));
    if (tzpos != str.npos)
    {
        string tzstr = "XXX" + str.substr(tzpos);
        if (tzstr.length() > 6 && tzstr[6] != ':') //6 for XXXsHH, s is + or -
            tzstr.insert(6, ":");
        if (tzstr.length() > 9 && tzstr[9] != ':') //9 for XXXsHH:MM
            tzstr.insert(9, ":");
        tzptr.reset(new PTZ(tzstr));
        if (str[tzpos - 1] == ' ') --tzpos;
    }
    else
    {
        tzptr = utc_zone;
    }
    try
    {
        auto pdt = boost::posix_time::time_from_string(str.substr(0, tzpos));
        m_time = LDT(pdt.date(), pdt.time_of_day(), tzptr,
                     LDTBase::NOT_DATE_TIME_ON_ERROR);
    }
    catch(boost::gregorian::bad_year)
    {
        throw(std::invalid_argument("The date string was outside of the supported year range."));
    }
}
Esempio n. 2
0
GncDateTimeImpl::GncDateTimeImpl(const std::string str) :
    m_time(unix_epoch, utc_zone)
{
    if (str.empty()) return;

    using std::string;
    using PTZ = boost::local_time::posix_time_zone;
    TZ_Ptr tzptr;
    auto tzpos = str.find_first_of("+-", str.find(":"));
    int offset = 0L;
    if (tzpos != str.npos)
    {
        string tzstr = "XXX" + str.substr(tzpos);
        if (tzstr.length() > 6 && tzstr[6] != ':') //6 for XXXsHH, s is + or -
            tzstr.insert(6, ":");
        if (tzstr.length() > 9 && tzstr[9] != ':') //9 for XXXsHH:MM
        {
            tzstr.insert(9, ":");
        /* Bug 767824: A GLib bug in parsing the UTC timezone on
         * Windows may have created a bogus timezone of a random
         * number of minutes. Since there are no fractional-hour
         * timezones around the prime meridian we can safely check for
         * this in files by looking for minutes-only offsets and
         * making the appropriate correction.
         */
            if (tzstr.compare(7,8, "00") &&
                (tzstr.length() > 10 ? tzstr[10] != '0' :
                 !tzstr.compare(10, 11, "00")))
            {
                offset = atoi(tzstr.substr(10,11).c_str());
                if (offset && tzpos == '-')
                    offset = -offset;
                tzstr.replace(10, 11, "00");
            }
        }
        tzptr.reset(new PTZ(tzstr));
        if (str[tzpos - 1] == ' ') --tzpos;
    }
    else
    {
        tzptr = utc_zone;
    }
    try
    {
        using Facet = boost::posix_time::time_input_facet;
        //The stream destructor frees the facet, so it must be heap-allocated.
        auto input_facet(new Facet());
        std::istringstream ss(str.substr(0, tzpos));
        ss.imbue(std::locale(std::locale(), input_facet));
        input_facet->set_iso_extended_format();
        PTime pdt(not_a_date_time);
        ss >> pdt;
        m_time = LDT(pdt.date(), pdt.time_of_day(), tzptr,
                     LDTBase::NOT_DATE_TIME_ON_ERROR);
    }
    catch(boost::gregorian::bad_year)
    {
        throw(std::invalid_argument("The date string was outside of the supported year range."));
    }
    if (offset)
        m_time -= boost::posix_time::minutes(offset);
}