2012-01-18 7 views
3

私はインド株式市場の価格データを持っていますが、その日時スタンプはGMTですので、正しい日付と時刻を表すデータを扱うことができます。C++ /ブーストでdatetimeを別のタイムゾーンに変換する

自分のDB内の一部のレコードの日時を、現在のGMTからISTに変換する必要があります。

mysql> desc price_hist; 
+---------------+-----------------------+------+-----+---------+----------------+ 
| Field   | Type     | Null | Key | Default | Extra   | 
+---------------+-----------------------+------+-----+---------+----------------+ 
| trade_id  | int(11)    | NO | PRI | NULL | auto_increment | 
| contract_name | varchar(14)   | NO | MUL | NULL |    | 
| trade_date | date     | NO |  | NULL |    | 
| trade_time | varchar(6)   | NO |  | NULL |    | 
| trade_price | decimal(10,4)   | NO |  | NULL |    | 
| trade_volume | bigint(20)   | NO |  | NULL |    | 
+---------------+-----------------------+------+-----+---------+----------------+ 
8 rows in set (0.02 sec) 

私は実行することにより、DB自体にタイムゾーンを変更しようとしましたが、それはうまくいきませんでした:

select convert_tz("2010-06-30 19:00:00",'GMT','IST'); 
+-----------------------------------------------+ 
| convert_tz("2011-06-30 09:00:00",'GMT','IST') | 
+-----------------------------------------------+ 
| NULL | 
+-----------------------------------------------+ 
1 row in set (0.01 sec) 

私が後押しする新しいですが、私は処理するためにブースト日付を使用することが示唆されていますこれはコードそのものです。

私は日時変換のためにいくつかの投稿を検索しましたが、私の特定の質問に答える投稿は見つかりませんでした。

特定のリンクがある場合、またはそれよりも優れている場合は、誰かが共有できるブーストコードの例です。これは、私のようなヌービーにとっては素晴らしいスタートです。 :-)

私は@Karisonは、次のコードを記述するために設けられた基準を使用:私は3

がまずあります見ることができるようの構文を変更し、質問を分離させ

#include "boost/date_time/local_time/local_time.hpp" 
    #include <iostream> 

    int main() 
    { 
    using namespace boost::posix_time; 
    using namespace boost::gregorian; 
    using namespace boost::local_time; 

    tz_database tz_db; 
    time_zone_ptr chi_tz=tz_db.time_zone_from_region("America/Chicago"); 
    time_zone_ptr jst_tz(new posix_time_zone("EST+5:00:00")); 


    local_date_time jpn_time(date(2012,Jan,3), hours(16), jst_tz,local_date_time::NOT_DATE_TIME_ON_ERROR); 
    local_date_time osaka_time = jpn_time.local_time_in(chi_tz); 
    std::cout<<"osaka_time: "<<osaka_time<<std::endl; 
return 0; 
} 
+0

"EST + 15:00:00"これは意味がありません。 「EST-05:00:00」 – Karlson

+0

はUTCに変換されます。これは返すものです。osaka_time:2012年1月3日11:00:00 UTC もちろん、この例で使用しようとしていた日本を見ると日時が間違っています – user1155299

+0

EST + 05:00 00はUTCです。 :) – Karlson

答えて

2

ファーストをオフ

select convert_tz('2011-06-30 09:00:00','GMT','IST') 

シングルがない二重引用符を刻み:convert_tzの構文は次のように呼び出しが見えるはずです文字列を取ります。

秒。あなたのマシンが同じ時間帯に位置し、あなたが日付を表す文字列を取得して行うことができますPOSIX準拠システム上で実行している場合:

あなたは、その後行うために使用することができ、標準のUNIX時間を与えるだろう
struct tm result; 
strptime(<time string>, <format string>, &result); 
time_t epoch_time = mktime(&result); 

あなたに必要なものは何でも。

最後に、少なくともBoost。それは確かに強力な図書館ですが、私はこのプロジェクトでは、現時点では複雑にする必要があるとは思わないと思います。試してみるか、POSIX準拠のシステムでない場合は、http://www.boost.org/doc/libs/1_48_0/doc/html/date_time.htmlをご覧ください。データベースから戻ってくる文字列からptimeを作成してから、それを適切に操作する必要があります。 local_time部分を使用して、必要に応じてタイムゾーンオブジェクトを作成し、データベースから取得する時間をチェックします。例を見ることができますhttp://www.boost.org/doc/libs/1_48_0/doc/html/date_time/examples/general_usage_examples.html

特に最後のものです。だからあなたの例のために、それは次のようになります。

time_zone_ptr src_zone(new posix_time_zone("IST+05:30:00")); 
time_zone_ptr dst_zone(new posix_time_zone("CST")); 
local_date_time trd_time(date(....), hours(...), src_zone, 
         local_date_time::NOT_DATE_TIME_ON_ERROR); 
local_date_time res_time = trd_time.local_time_in(dst_zone); 

は、それが100%正しいであることを保証することはできませんが、あなたのアイデアを得ます。

例:

1)Windowsの場合:ここで

#include "boost/date_time/local_time/local_time.hpp" 
#include <iostream> 

int main() 
{ 
    using namespace boost::posix_time; 
    using namespace boost::gregorian; 
    using namespace boost::local_time; 

    tz_database tz_db; 
    time_zone_ptr chi_tz(new posix_time_zone("CST-06:00:00"); 
    time_zone_ptr jst_tz(new posix_time_zone("JST+09:00:00")); 

    local_date_time jpn_time(date(2012,Jan,3), hours(16), 
          chi_tz,local_date_time::NOT_DATE_TIME_ON_ERROR); 
    local_date_time osaka_time = jpn_time.local_time_in(jst_tz); 
    std::cout<<"osaka_time: "<<osaka_time<<std::endl; 
    return 0; 
} 
+0

@ Karisonは、一重引用符に変更しましたが、それでも同じ結果になりました。私はこれが私にブーストを学ぶよい機会だと思うので、私は構造体を試し、リンクをチェックします。私のような学生へのコードのヘルプが;-)常に – user1155299

+0

ドキュメントで一般的な例を確認してくださいuser1155299 @便利です。しかし、私はまだあなたがそれを必要としない可能性が最も高いと考えています。また、チェックアウト[この質問は]ブースト中(http://stackoverflow.com/questions/2523286/mysql-convert-tz-help) – Karlson

+0

は、それが可能CSTにISTから直接変換することで、または私はISTに変換する必要がありますUTCとそれからUTCへ – user1155299

0

はこれを対処する方法はいくつかある

#include "stdafx.h" 
#include <windows.h> 

#include <iostream> 
#include <string> 
#include <locale> 
#include <time.h> 
#include <vector> 

#include <boost/date_time/local_time/local_time.hpp> 
#include <boost/date_time/posix_time/posix_time.hpp> 
#include <boost/date_time.hpp> 
#include <boost/algorithm/string/classification.hpp> 
#include <boost/algorithm/string/split.hpp> 

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

//*********** 
// U T I L S 
//*********** 

std::string WCHAR2StdString(WCHAR* wchar_buf) 
{ 
    char narrow_buf[260]; 
    char DefChar = ' '; 
    WideCharToMultiByte(CP_ACP,0,wchar_buf,-1, narrow_buf,260,&DefChar, NULL); 
    return std::string (narrow_buf); 
} 

std::string LocalTimeZone(TIME_ZONE_INFORMATION & tzi) 
{ 
    short int tz_bias = tzi.Bias; 
    std::string tzName(WCHAR2StdString(tzi.StandardName)); 

    // Get acronym for X_(Zone) Standard Time: 'X_ST' 
    std::vector<std::string> vec; 
    boost::split(vec, tzName, boost::is_any_of(" ")); 
    std::string result; 
    for(std::vector<std::string>::iterator i = vec.begin(); i != vec.end(); ++i) 
    { 
     std::string s = *i; 
     char c = s.c_str()[0]; 
     result += c; 
    } 
    return result; 
} 

//********** 
// M A I N 
//********** 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    using namespace boost::posix_time; 
    using namespace boost::gregorian; 
    using namespace boost::local_time; 

    // Windows Timezone info. 
    TIME_ZONE_INFORMATION tzi; 
    DWORD res = GetTimeZoneInformation(&tzi); 

    // Timezone string 
    std::string local_tz_str = LocalTimeZone(tzi); 

    // Hour Bias 
    std::stringstream ss; 
    ss << (abs(tzi.Bias)/60); 
    std::string bias_hrs(ss.str()); 

    // Build string: e.g. CST+08:00:00 
    short int sign = 0; 
    tzi.Bias > 0 ? sign = -1 : sign = 1; 

    // Pad with zeros as necessray 
    if(abs(tzi.Bias/60) < 10) bias_hrs = ("0" + bias_hrs); 
    bias_hrs += ":00:00"; 
    (sign > 0) ? (bias_hrs = local_tz_str + "+" + bias_hrs) : (bias_hrs = local_tz_str + "-" + bias_hrs); 

    local_tz_str = bias_hrs; // local_tz_str is a better name to continue with 

    std::string formatted_tz_desc(bias_hrs); 

    // Construct local_date_time and time_zone etc. 
    long long ticksFromEpoch = 1329122250168; // !!! (assumed input format) milliseconds from 1970-01-01 00:00:00 
    std::time_t tt = static_cast<time_t>(ticksFromEpoch/1000); // (ticksFromEpoch/1000) gives seconds since epoch 
    ptime pt = from_time_t(tt); 
    time_zone_ptr zone(new boost::local_time::posix_time_zone(formatted_tz_desc)); 
    local_date_time locally_adjusted_date_time(pt, zone); 

    // Format stringstream: YYYY-Mmm-dd HH:MM:SS 
    std::stringstream strm; 
    strm.imbue(std::locale(std::cout.getloc(), new local_time_facet("%Y-%m-%d %H:%M:%S"))); 
    strm << locally_adjusted_date_time; 

    // Print adjusted result 
    std::cout << strm.str() << std::endl << std::endl; 

    return 0; 
    } 

あなたが好きなのSTDのC LIBSからタイムゾーン情報を取得することができますこれは:

2)Posix:

#include <stdio.h> 
#include <time.h> 
#include <string> 
#include <iostream> 
#include <vector> 
#include <boost/algorithm/string/classification.hpp> 
#include <boost/algorithm/string/split.hpp> 

std::string LocalTimeZone(); 

int main() { 
    std::cout << LocalTimeZone() << std::endl; 
    return 0; 
} 

std::string LocalTimeZone() 
{ 
    time_t now = time(NULL); 
    struct tm tnow = *localtime(&now); 
    std::string tz = tnow.tm_zone; 

    // Format the struct: 
    char buff[100]; 
    strftime(buff, sizeof buff, "%a %b %d %Y %T %Z%z", &tnow); 

    // Parse the bits you want: 
    std::vector<std::string> vec; 
    const std::string s(buff); 
    boost::split(vec, s, boost::is_any_of(" ")); 
    std::vector<std::string>::iterator i = vec.end(); 

    return *--i; 
} 

タイムゾーン文字列をフォーマットすると、次のようになります。 CST+08:00:00上記のブースト方法を続行することができます。

HTH

関連する問題