2012-01-05 11 views
9

problemów jest:doładowania: uzyskać aktualny LOCAL_DATE_TIME z aktualnej strefy czasowej z maszyny

  • wiem jak uzyskać czas lokalny impuls

kod:

boost::local_time::local_date_time currentTime(
     boost::posix_time::second_clock::local_time(), 
     boost::local_time::time_zone_ptr()); 
    std::cout << currentTime.local_time() << std::endl; 
  • Wiem, jak uzyskać bieżące dane strefy czasowej z urządzenia (mam nadzieję, że jest to właściwa droga)

kod:

tzset(); 
// the var tzname will have time zone names 
// the var timezone will have the current offset 
// the var daylight should show me if there is daylight "on" 

ale nadal nie mogę dostać LOCAL_DATE_TIME z obecnym TIME_ZONE ... Czy ktoś wie, jak to zrobić?

+0

Czy * nie *, aby wydrukować czas w localtime? Jeśli jesteś w stanie używać UTC, uratujesz sobie różnego rodzaju bóle głowy. –

+0

Zapoznaj się z [Samouczek IO Data Time] (http://www.boost.org/doc/libs/1_48_0/doc/html/date_time/date_time_io.html#date_time.io_tutorial)? –

+0

"Czy musisz wydrukować godzinę w czasie lokalnym?" Tak, muszę :( – Alek86

Odpowiedz

2

OK, jak na razie jeszcze nie wiem całą odpowiedź

ale jest kod, który może pomóc, aby wydrukować bieżący ofset strefy czasowej

(w oparciu o odpowiedzi na pytania powiązanym tutaj (stackoverflow) i jakiś wewnętrzny kod doładowania)

ja absolutnie nie jestem pewien, że to będzie działać poprawnie na wszystkich maszynach, ale teraz jest to lepsze niż nic:

boost::posix_time::time_duration getUtcOffset(const boost::posix_time::ptime& utcTime) 
{ 
    using boost::posix_time::ptime; 
    const ptime localTime = boost::date_time::c_local_adjustor<ptime>::utc_to_local(utcTime); 
    return localTime - utcTime; 
} 

std::wstring getUtcOffsetString(const boost::posix_time::ptime& utcTime) 
{ 
    const boost::posix_time::time_duration td = getUtcOffset(utcTime); 
    const wchar_t fillChar = L'0'; 
    const wchar_t timeSeparator = L':'; 

    std::wostringstream out; 
    out << (td.is_negative() ? L'-' : L'+'); 
    out << std::setw(2) << std::setfill(fillChar) 
     << boost::date_time::absolute_value(td.hours()); 
    out << L':'; 
    out << std::setw(2) << std::setfill(fillChar) 
     << boost::date_time::absolute_value(td.minutes()); 
    return out.str(); 
} 
int main() 
{ 
    const boost::posix_time::ptime utcNow = 
     boost::posix_time::second_clock::universal_time(); 

    const std::wstring curTimeOffset = getUtcOffsetString(utcNow); 
    std::wcout << curTimeOffset.c_str() << std::endl; // prints -05:00 on my comp 
} 
+0

Zignorowanie DST oznacza, że ​​arytmetyka kalendarza (np. odjąć date_duration) nie będzie działać poprawnie przy zwróconym obiekcie local_date_time. –

1

Ponieważ mówisz, że masz informacje o strefie czasowej, jedynym pytaniem jest, w jaki sposób użyć boost do potrzebnego ciągu formatowania. Poniżej znajduje się przykładowy kod:

using namespace boost::local_time; 
    using namespace boost::posix_time; 

    // Composing this string is the most tricky part. Syntax see in: 
    // boost\date_time\local_time\posix_time_zone.hpp 
    string posix_tz_def("PST-5PDT01:00:00,M4.1.0/02:00:00,M10.1.0/02:00:00"); 
    local_date_time ldt(second_clock::local_time(), 
         time_zone_ptr(new posix_time_zone(posix_tz_def))); 

    std::stringstream ss; 
    local_time_facet* output_facet = new local_time_facet(); 
    ss.imbue(std::locale(std::locale::classic(), output_facet)); 
    output_facet->format("%Y-%m-%dT%H:%M:%S %Q"); 
    ss << ldt; 

    string formatted_datetime = ss.str(); // 2012-01-05T18:14:06 -05:00 

W tym podejściu najbardziej problematyczną częścią jest szyk posystem czasowy posix. Myślę, że powinny istnieć bazy danych z tymi ciągami dla każdej strefy czasowej, a boost zapewnia szablon do pracy z plikiem .csv. Jeśli jedyną rzeczą, której potrzebujesz, jest przesunięcie w łańcuchu, po prostu ustaw DTS na 0:00:00 i nie przejmuj się resztą. Na przykład użyj tego ciągu: PST-5:30PDT0,0,365 (na zawsze PDT, przesunięcie 0). Zamień "-5: 00" z potrzebnym offsetem.

Chociaż C++/boost wprowadziłby własny dostawca stref czasowych, wywodząc się z date_time::time_zone_base.

Więcej próbek i pomysłów można znaleźć here.

+0

Nie odpowiada na pytanie. bout formatowanie ciągu, ale o skonstruowanie obiektu local_date_time. –

0

Tak więc, jeśli trzeba także uzyskać prawidłowe przesunięcie UTC niż mój poprzedni przykład należy zmodyfikować trochę produkować prawidłowy ciąg Strefa czasowa:

static boost::posix_time::time_duration utc_offset(
    second_clock::local_time() - second_clock::universal_time()); 
std::ostringstream ss_posix_tz_def; 
// We don't care about real zone name so, just put any three letters. 
ss_posix_tz_def << "LOC" << utc_offset; 
string posix_tz_def = ss_posix_tz_def.str(); 

Innym rozwiązaniem jest napisanie zupełnie nowego dostawcę czasowej. Tak prosta:

// We assume local TZ doesn't have DST, UTC offset is calculated basing on 
// local system clocks. Thus, using of this provider for time calculations for 
// an arbitrary date is not a good idea. 
class machine_time_zone : public boost::local_time::custom_time_zone { 
public: 
    typedef boost::local_time::custom_time_zone base_type; 
    typedef base_type::time_duration_type time_duration_type; 

    machine_time_zone() 
    : boost::local_time::custom_time_zone(
     time_zone_names("Local machine TZ", "LOC", "", ""), 
     GetUTCOffset(), 
     boost::local_time::dst_adjustment_offsets(
      time_duration_type(0, 0, 0), 
      time_duration_type(0, 0, 0), time_duration_type(0, 0, 0)), 
     boost::shared_ptr<boost::local_time::dst_calc_rule>()) { 
    } 

    // This method is not precise, real offset may be several seconds more or less. 
    static const boost::posix_time::time_duration& GetUTCOffset() { 
    using boost::posix_time::second_clock; 
    static boost::posix_time::time_duration utc_offset(
     second_clock::local_time() - second_clock::universal_time()); 
    return utc_offset; 
    } 
}; 

Wystarczy przekazać je przy konstruowaniu local_date_time:

local_date_time ldt(second_clock::local_time(), 
        time_zone_ptr(new machine_time_zone())); 
+0

Zignorowanie DST oznacza, że ​​arytmetyka kalendarza (np. Odjąć date_duration) nie będzie działać poprawnie w zwracanym obiekcie local_date_time. –

Powiązane problemy