Sunday, February 2, 2025

time_get facet and time_put facet

Overview
CRT provides apis for reading and formatting date formats of various forms. Standard library provides same functionality using time_get and time_put facets.

Details

time_base
This is a base class for time_get and time_put facets. It defines result enum type dateorder defined as below. These are internally used by  methods of the facets.
NameDescription
no_orderUnspecified order
dmyDay, month, year (european) order
mdyMonth, day, year (american) order
ymdYear, month, day (asian) order
ydmYear, day, month

time_get
This class encapsulates date and time parsing rules. The I/O manipulator get_time➹ uses the time_get facet of the I/O stream's locale to convert text input to a tm object.

Syntax
template<class CharT,class InputIt = std::istreambuf_iterator<CharT>> 
class time_get:public facet, public time_base
CharT can be char and whcar_t. It's aliased as member char_type.  It represents the type of the characters in the sequence to interpret.
InputIt Represents Input iterator type that points to the elements in the character sequence to interpret.
Defaults to istreambuf_iterator, which is an iterator that can be implicitly converted from basic_istream objects. Aliased as member iter_type.

Specializations
//narrow string representations of date and time
time_get<char>

//wide string representations of date and time
time_get<wchar_t>	

Fields
NameDescription
locale::id id the identifier of the facet. Represents the time category of the facet.

Constructor
NameDescription
time_get(size_t refs = 0)Creates a time_get facet and forwards the starting reference count refs to the base class constructor, locale::facet::facet()

Methods
conversion functions
NameDescription
dateorder date_order()
Returns a value of the enumerated member type dateorder indicating the preferred order of the date components for the date formats composed of day, month and year for the current locale.
Example
//returns mdy
auto  d = std::use_facet<std::time_get<char>>(locale("en_US.utf8")).date_order();
        
//returns ymd
d = std::use_facet<std::time_get<char>>(locale("ja_JP.utf8")).date_order();

//returns dmy
d = std::use_facet<std::time_get<char>>(locale("de_DE.utf8")).date_order();
iter_type get_time 
(iter_type beg, iter_type end, ios_base& str, ios_base::iostate& err, tm* t) 

Reads successive characters from the sequence [beg, end] and parses out the time value as if the format is "%H:%M:%S".
The parsed time is stored in the corresponding fields of the tm structure pointed to by the argument t.
If the end iterator is reached before a valid time is read, the function sets ios_base::eofbit in err. If a parsing error is encountered, the function sets ios_base::failbit in err.
Example
    istringstream iss;
    time_get<char>::iter_type end;
    ios_base::iostate err = ios_base::goodbit;
{
    const time_get<char>& tmget = use_facet <time_get<char> > (locale());
    tm when={};
    err = ios_base::goodbit;
    iss.str("11:58:11");
    //err:ios_base::eofbit
    //itr:end
    //prints:11 58 11
auto itr = tmget.get_time (iss, end, iss, err, &when); cout << when.tm_hour << " " << when.tm_min << " " << when.tm_sec << endl; } { const time_get<char>& tmget = use_facet <time_get<char> > (locale()); tm when={}; err = ios_base::goodbit; iss.str("11-58:11"); //err:ios_base::failbit //itr:begin()+2 //prints:11 00 00 auto itr = tmget.get_time (iss, end, iss, err, &when); cout << when.tm_hour << " " << when.tm_min << " " << when.tm_sec << endl; } { locale l("ja_JP.utf8"); iss.imbue(l); const time_get<char>& tmget = use_facet <time_get<char> > (l); tm when={}; err = ios_base::goodbit; iss.str("21時37分58秒"); //err:ios_base::eofbit //itr:end //prints:21 37 58 auto itr = tmget.get_time (iss, end, iss, err, &when); cout << when.tm_hour << " " << when.tm_min << " " << when.tm_sec << endl; }
iter_type get_date
(iter_type begiter_type end, ios_base& str, 
ios_base::iostate& err, tm* t) 

Parses successive characters from the sequence [beg, end] in the order returned by the function date_order() and extracts the date value.
The extracted date is stored in the corresponding fields of the tm structure pointed to by the argument t.
If the end iterator is reached before a valid time is read, the function sets ios_base::eofbit in err. If a parsing error is encountered, the function sets ios_base::failbit in err.
Example
    istringstream iss;
    time_get<char>::iter_type end;
    ios_base::iostate err = ios_base::goodbit;
{
    const time_get<char>& tmget = use_facet <time_get<char> > (locale());
    tm when={};
    err = ios_base::goodbit;
iss.str("09/21/2018");
    //err:ios_base::eofbit
    //itr:end
    //prints:2018 9 21
auto itr = tmget.get_date (iss, end, iss, err, &when); cout << (when.tm_year+1900) << " " << (when.tm_mon+1) << " " << when.tm_mday << endl; } { const time_get<char>& tmget = use_facet <time_get<char> > (locale()); tm when={};
    err = ios_base::goodbit;
iss.str("09-21/2018"); //err:ios_base::failbit //itr:begin()+2 //prints:1900 9 0 auto itr = tmget.get_date (iss, end, iss, err, &when); cout << (when.tm_year+1900) << " " << (when.tm_mon+1) << " " << when.tm_mday << endl; } { locale l("ja_JP.utf8"); iss.imbue(l); const time_get<char>& tmget = use_facet <time_get<char> > (l); tm when={};
    err = ios_base::goodbit;
iss.str("2018年09月21日"); //err:ios_base::eofbit //itr:end //prints:2018 9 21 auto itr = tmget.get_date (iss, end, iss, err, &when); cout << (when.tm_year+1900) << " " << (when.tm_mon+1) << " " << when.tm_mday << endl; }
iter_type get_weekday
(iter_type begiter_type end, ios_base& str, 
ios_base::iostate& err, tm* t) 

Reads successive characters from the sequence [beg, end] and parses out the weekday string, even in its short form and converts it to weekday number.
The parsed time is stored in the corresponding fields of the tm structure pointed to by the argument t.
If the end iterator is reached before a valid time is read, the function sets ios_base::eofbit in err. If a parsing error is encountered, the function sets ios_base::failbit in err.
Example
    istringstream iss;
    time_get<char>::iter_type end;
    ios_base::iostate err = ios_base::goodbit;
{
    const time_get<char>& tmget = use_facet <time_get<char> > (locale());
    tm when={};
    iss.str("Wedding");
    err = ios_base::goodbit;
    //err:ios_base::goodbit
    //itr:begin()+3
    //prints:3
auto itr = tmget.get_weekday (iss, end, iss, err, &when); cout << when.tm_wday << endl; } { const time_get<char>& tmget = use_facet <time_get<char> > (locale()); tm when={};
    err = ios_base::goodbit;
iss.str("Frys"); //err:ios_base::failbit //itr:begin()+2 //prints:0 auto itr = tmget.get_weekday (iss, end, iss, err, &when); cout << when.tm_wday << endl; } { locale l("ja_JP.utf8"); iss.imbue(l); const time_get<char>& tmget = use_facet <time_get<char> > (l); tm when={};
    err = ios_base::goodbit;
iss.str("土曜日"); //err:ios_base::eofbit //itr:end //prints:6 auto itr = tmget.get_weekday (iss, end, iss, err, &when); cout << when.tm_wday << endl; }
iter_type get_monthname
(iter_type begiter_type end, ios_base& str, 
ios_base::iostate& err, tm* t) 
Reads successive characters from the sequence [beg, end] and parses out the month name string, even in its short form and converts it to weekday number.
The parsed time is stored in the corresponding fields of the tm structure pointed to by the argument t.
If the end iterator is reached before a valid time is read, the function sets ios_base::eofbit in err. If a parsing error is encountered, the function sets ios_base::failbit in err.
Example
istringstream iss;
time_get<char>::iter_type end;
ios_base::iostate err = ios_base::goodbit;
{
    const time_get<char>& tmget = use_facet <time_get<char> > (locale());
    tm when={};
    iss.str("Marsh");
    err = ios_base::goodbit;
    //err:ios_base::goodbit
    //itr:begin()+3
    //prints:3
auto itr = tmget.get_monthname (iss, end, iss, err, &when); cout << when.tm_mon+1 << endl; } { const time_get<char>& tmget = use_facet <time_get<char> > (locale()); tm when={}; err = ios_base::goodbit; iss.str("Ariel"); //err:ios_base::failbit //itr:begin()+1 //prints:0 auto itr = tmget.get_monthname (iss, end, iss, err, &when); cout << when.tm_mon << endl; } { locale l("ja_JP.utf8"); iss.imbue(l); const time_get<char>& tmget = use_facet <time_get<char> > (l); tm when={}; err = ios_base::goodbit; iss.str("2月"); //err:ios_base::eofbit //itr:end //prints:2 auto itr = tmget.get_monthname (iss, end, iss, err, &when); cout << when.tm_mon+1 << endl; }

iter_type get_year
(iter_type begiter_type end, ios_base& str, 
ios_base::iostate& err, tm* t) 
Reads successive characters from the sequence [beg, end] and parses out the year, even in its short form.
The parsed time is stored in the corresponding fields of the tm structure pointed to by the argument t.
If the end iterator is reached before a valid time is read, the function sets ios_base::eofbit in err. If a parsing error is encountered, the function sets ios_base::failbit in err.
Example
istringstream iss;
time_get<char>::iter_type end;
ios_base::iostate err = ios_base::goodbit;
{
    //err:ios_base::eofbit
    //itr:end
    //prints:2018
    const time_get<char>& tmget = use_facet <time_get<char> > (locale());
    tm when={};
    iss.str("18");
    err = ios_base::goodbit;
    auto itr = tmget.get_year  (iss, end, iss, err, &when);
    cout << when.tm_year+1900   << endl;
}

{
    const time_get<char>& tmget = use_facet <time_get<char> > (locale());
    tm when={};
    err = ios_base::failbit;
    iss.str("-2018");
    //err:ios_base::failbit
    //itr:begin()+1
    //prints:0
    auto itr = tmget.get_year  (iss, end, iss, err, &when);
    cout << when.tm_year  << endl;
}

{
    locale l("ja_JP.utf8");
    iss.imbue(l);
    const time_get<char>& tmget = use_facet <time_get<char> > (l);
    tm when={};
    err = ios_base::goodbit;
    iss.str("2018");
    //err:ios_base::eofbit
    //itr:end
    //prints:2018
    auto itr = tmget.get_year  (iss, end, iss, err, &when);
    cout << when.tm_year+1900   << endl;
} 
iter_type get
(iter_type begiter_type end, ios_base& str, 
ios_base::iostate& err, tm* t, 
const char_type* fmt_begin, const char_type* fmt_end)
Reads successive characters from the sequence [beg, end] and parses out the date as specified in the format (fmt_begin to fmt_end).
The convention of the format string is same as CRT function strftime().
The parsed time is stored in the corresponding fields of the tm structure pointed to by the argument t.
If the end iterator is reached before a valid time is read, the function sets ios_base::eofbit in err. If a parsing error is encountered, the function sets ios_base::failbit in err.
Example
istringstream iss;
time_get<char>::iter_type end;
ios_base::iostate err = ios_base::goodbit;
{
    locale l("en_US.utf-8");
    string fmt{"%Y-%b-%d %H:%M:%S"};
    iss.imbue(l);
    const time_get<char>& tmget = use_facet <time_get<char> > (l);
    tm when={};
    iss.str("2018-sep-21 11:58:11");
    err = ios_base::goodbit;
    //err:ios_base::eofbit
    //itr:end
    //prints:Fri Sep 21 11:58:11 2018
    auto itr = tmget.get  (iss, end, iss, err, &when, &(*fmt.begin()), &(*fmt.end()));
    cout << asctime(&when)  << endl;
}

{
    locale l("de_DE.utf-8");
    string fmt{"%Y-%b-%d %H:%M:%S"};
    iss.imbue(l);
    const time_get<char>& tmget = use_facet <time_get<char> > (l);
    tm when={};
    err = ios_base::goodbit;
    iss.str("2018-sep-21 11:58:11");
    //err:ios_base::eofbit
    //itr:end
    //prints:Fri Sep 21 11:58:11 2018
    auto itr = tmget.get  (iss, end, iss, err, &when, &(*fmt.begin()), &(*fmt.end()));
    cout << asctime(&when)  << endl;
}

{
    locale l("ja_JP.utf8");
    string fmt{"%Y年%m月%d日 %H時%M分%S秒"};
    iss.imbue(l);
    const time_get<char>& tmget = use_facet <time_get<char> > (l);
    tm when={};
    err = ios_base::goodbit;
    iss.str("2018年09月21日 11時58分11秒");
    //err:ios_base::eofbit
    //itr:end
    //prints:Fri Sep 21 11:58:11 2018
    auto itr = tmget.get  (iss, end, iss, err, &when, &(*fmt.begin()), &(*fmt.end()));
    cout << asctime(&when)  << endl;
} 
This example 13 demonstrate writing a double under various locales using time_get facet as seen in 
its console output.

time_put
This class encapsulates date and time formatting rules. The I/O manipulator put_time➹ uses the time_put facet of the I/O stream's locale to generate text representing date and time  from a tm object.

Syntax
template<class CharT,class OutputIt = std::ostreambuf_iterator<CharT>> 
class time_put:public facet, public time_base
CharT can be char and whcar_t. It's aliased as member char_type.  It represents the type of the characters in the sequence to interpret.
OutputIt Represents Output iterator type that points to the output stream where text will be written.
Defaults to ostreambuf_iterator, which is an iterator that can be implicitly converted from basic_ostream objects. Aliased as member iter_type.

Specializations
//narrow string representations of date and time
time_put<char>

//wide string representations of date and time
time_put<wchar_t>	

Fields
NameDescription
locale::id id the identifier of the facet. Represents the time category of the facet.

Constructor
NameDescription
time_put(size_t refs = 0)Creates a time_put facet and forwards the starting reference count refs to the base class constructor, locale::facet::facet().

Methods
NameDescription
  1. iter_type put
    (iter_type outios_base& str,
    char_type fill, tm* when, 
    const char_type fmt, const char_type mod)
  2. iter_type put
    (iter_type outios_base& str, 
    char_type fill, tm* when, 
    const char_type* fmt_begin, 
    const char_type* fmt_end)
  1. Using the date time format as specified in  (fmt and mod), generates the text representing date and time from when.
  2. Using the date time format as specified in  (fmt_begin to fmt_end), generates the text representing date and time from when.
The convention of the format string is same as CRT function strftime().
The time string is written it to out iterator using fill as white space.
Example
	tm when{}; 
	when.tm_year = 2018 - 1900; // 2018
	when.tm_mon = 9 - 1; // September
	when.tm_mday = 21; // 21st
	when.tm_hour = 11;
	when.tm_min = 58;
	when.tm_wday=5;
	when.tm_isdst = 0; // Not daylight saving
   
   //1
    /* prints
    Fri Sep 21 11:58:00 2018
    Fri 21 Sep 2018 11:58:00 AM UTC
    2018年09月21日 11時58分00秒
    Fr 21 Sep 2018 11:58:00 UTC
    fre 21 sep 2018 11:58:00
    Friday 21 September 2018 11:58:00 AM UTC
   */
    for (auto ln:{"C","en_US.utf-8","ja_JP.utf8","de_DE.utf-8",	"sv_SE.utf-8","en_IN.utf-8"})
    {
        locale l(ln);
        cout.imbue(l);
        const time_put<char>& tmput = use_facet <time_put<char> > (l);
        tmput.put  ({cout}, cout, ' ', &when, 'c', 0);
        cout << endl;
    }   

   // 2
   /* prints
    2018-Sep-21 11:58:00
    2018-Sep-21 11:58:00
    2018年09月21日 11時58分00秒
    2018-Sep-21 11:58:00
    2018-sep-21 11:58:00
    2018-Sep-21 11:58:00
   */
    for (auto ln:{"C","en_US.utf-8","ja_JP.utf8","de_DE.utf-8",	"sv_SE.utf-8","en_IN.utf-8"})
    {
        string fmt{"%Y-%b-%d %H:%M:%S"};
        if (ln[0] == 'j')
            fmt = "%Y年%m月%d日 %H時%M分%S秒";
        locale l(ln);
        cout.imbue(l);
        const time_put<char>& tmput = use_facet <time_put<char> > (l);
        tmput.put  ({cout}, cout, ' ', &when, &(*fmt.begin()), &(*fmt.end()));
        cout << endl;
    }    
This example 14 demonstrate writing a time under various locales using time_put facet as seen in 
its console output.








No comments:

Post a Comment