2016-11-14 16 views
9

nasıl keyfi bir Unix zaman damgası (saniye) dayalı California (Pasifik Saati) haftanın gününü belirleyebilir? Etrafımı araştırdım, fakat C++ için yerleşik bir kütüphane bulamadım.Unix zaman damgası (ları) C++ ile haftanın gününe dönüştürülür?

UTC genellikle PT'den 8 saat önce, ancak Unix zaman damgasından 8 saat çıkarılarak ve tm yapısını oluşturarak günışığı tasarrufları nüansları indirdiğinden bu işe yaramaz.

+1

Seni reddetmedim ama nasıl ['std :: localtime'] (http://en.cppreference.com/w/cpp/chrono/c/localtime)? – Danh

+1

Teşekkür ederim - yerel saat benim için PT değilse ne olur? –

+3

[strftime] (http://en.cppreference.com/w/cpp/chrono/c/strftime). Veya [time_put] (http://en.cppreference.com/w/cpp/locale/time_put). Veya [Howard Hinnant'ın tarihi] (https://github.com/HowardHinnant/date) - işaretçiler, cevapları değil, bu yüzden bir yorum. –

cevap

9

Howard Hinnant's date library'u kullanarak bunu nasıl yapacağınız.

#include "tz.h" 
#include <iostream> 

int 
main() 
{ 
    using namespace std::chrono_literals; 
    using namespace date; 
    auto unix_timestamp = sys_seconds{1479664467s}; 
    auto zt = make_zoned("America/Los_Angeles", unix_timestamp); 
    auto wd = weekday{floor<days>(zt.get_local_time())}; 
    std::cout << wd << '\n'; 
} 

ilk satırı sadece (diğer kaynaklardan olabilir) unix zaman damgası oluşturur: Bu <chrono> dayalı bir serbest MİT lisanslı C++ 14/11 kütüphanesidir. 11 C++ biz Chrono-değişmezleri yoktur ve bu nedenle bu hat yerine olacaktır:

auto unix_timestamp = sys_seconds{seconds{1479664467}}; 

make_zoned()unix_timestamp ve time_zone "tane /" dayalı bir zoned_time<seconds> oluşturur. Bir zoned_time bir time_zone ve unix zaman damgası topluluğudur.

Sen zt.get_local_time() ile zoned_time dışına yerel saati alabilirsiniz. Bu bir chrono::time_point ancak onunla ilişkili saat yok. Bu zaman noktasının kesinliği, orijinal zaman damgasının kesinliğine eşit olacaktır (bu durumda saniye).

Sen days bir hassasiyetle local_time kesiliyor tarafından local_time haftanın yerel gününü alabilirsiniz:

floor<days>(zt.get_local_time()) 

Ve bu gün kesinlik time_pointweekday yazmanız dönüştürecektir.

bir weekday

weekday aritmetik ve karşılaştırmalar katılabilir, basılabilir veya açıkça aralığındaki bir unsigned dönüştürülebilir [0, 6].

programı yukarıdaki çıkışlar:

Sun 

Bu kütüphanenin zaman dilimi kısmı IANA timezone database sadık bir temsilidir. Yerel saat dilimleri ile UTC arasında, günümüzün 1800'lü yılların sonuna kadar doğru ayarlamalar yapacaktır. Kütüphane zaman damgalarını 1800'lerin ortalarından önce geçirirseniz, bilinen en eski UTC ofseti geriye doğru -32768 yılına kadar tahmin edilmiştir. Ayrıca yılın 32767 ve akım ofset ve gün ışığından yararlanma kuralları ileriye aktarılacaktır gelecekte kadarıyla damgalarını geçebilir.

Bu kütüphane <chrono> üzerine kurulduğundan, <chrono> ürününün sağladığı her türlü hassaslığı ele alacaktır. nanoseconds gibi bazı chrono::duration s'nin daha sınırlı bir aralığa sahip olduğunu unutmayın (nanoseconds için +/- 292 yıl).

Kitaplık/süreç iş parçacığı güvenlidir. Yani, program, bilgisayarınızın saat dilimini veya başlık altındaki ortam değişkenlerini değiştirmeden belirttiğiniz saat dilimi ile doğrudan çalışır. Ayrıca, yerleşik olmayan işlev yerel statikleri nedeniyle iş parçacığı güvenli olmadığı bilinen C zamanlama API'sinin bir bölümünü içermez.

Gcc, clang ve VS'nin son sürümlerine taşındı.

standart UNIX C (non parçacığı güvenli versiyon) kullanılarak
1

Eğer Boost kütüphanesini kullanabilir miyim? Eğer Posix saat dilimi dize anlamaya Eğer sizin diliminin (PST) için (IEEE Std 1003.1, http://www.boost.org/doc/libs/1_62_0/doc/html/date_time/local_time.html#date_time.local_time.posix_time_zone bakınız), sonra aşağıdaki örnek yardımcı olabilir.

#include <iostream> 
#include <ctime> 
#include <boost/date_time.hpp> 

int main(int argc, char ** argv) 
{ 
    std::string posix_time_zone_string = "EST-05:00:00"; // you need to change this to the posix time representation of your desired timezone 

    time_t unix_time = 1479641855; //1479641855 = Sun, 20 Nov 2016 11:37:35 GMT 

    boost::posix_time::ptime pt = boost::posix_time::from_time_t(unix_time); 
    std::cout << "time in UTC: " << boost::posix_time::to_iso_extended_string(pt) << std::endl; 


    boost::local_time::time_zone_ptr zone(new boost::local_time::posix_time_zone(posix_time_zone_string)); 

    boost::local_time::local_date_time dt_with_zone(pt, zone); 
    std::cout << "time in local timezone: " << boost::posix_time::to_iso_extended_string(dt_with_zone.local_time()) << std::endl; 

    // Get the week day (alternative 1) 
    std::cout << "local week day integer: " << boost::local_time::to_tm(dt_with_zone).tm_wday << std::endl; // 0=sunday, 1=monday, etc. 

    // Get the week day (alternative 2) 
    std::cout << "local week day name: " << dt_with_zone.local_time().date().day_of_week() << std::endl; 
    std::cout << "local week day integer: " << int(dt_with_zone.local_time().date().day_of_week()) << std::endl; 
    return 0; 
} 
2

Hacky yol:

#include <stddef.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <time.h> 

void print_times() { 
    char my_buf[100]; 
    time_t now = time(NULL); 
    printf(ctime(&now)); 
    strftime(my_buf, 100, "DoW=%w Tz=%Z\n", localtime(&now)); 
    printf(my_buf); 
} 

int main(int argc, char * argv[]) { 
    print_times(); 
    setenv("TZ", "America/Los_Angeles", 1); 
    print_times(); 
    unsetenv("TZ"); 
    print_times(); 
} 

Maalesef TZ env var ya /etc/localtime Eğer UNIX zaman işlevleri için saat dilimi ayarlarını etkileyebilecek tek yolu vardır dosyayı değiştirerek (Altında kaput tzset(), tüm kitaplık işlevleri için saat dilimi ayarlarını kodlayan bir paylaşılan değişkenler kümesini başlatmak için bu kaynakları kullanır).

Gereksinim duyduğunuz bölge (ler) için UNIX TZ dizeleri ile gelmeniz gerekiyor. zoneinfo formatı, kullanılacak en basit ve tavsiye edilen formattır. Pasifik zamanı için TZ değerini üretmek için tzselect kullanmıştım.

Ayrıca, standart UNIX zaman dilimi ayarında bilgi için bkz. man 5 localtime, man tzselect.

İlgili konular