date_time_period示例boost :: locale :: period :: first_day_of_week(int v) [英] Example of date_time_period boost::locale::period::first_day_of_week(int v)
问题描述
在 boost :: locale文档它说:
date_time_period boost :: locale :: period :: first_day_of_week(int v)[inline]
取得date_time_period:星期几,常数,例如美国= 1的星期日,法国星期一= 2
返回 date_time_period
的函数可用于创建自定义 boost :: locale :: date_time
对象。
我试图创建一个 std :: locale
设置为 en_US.UTF-8
,因此一周的第一天默认为星期日,然后将其修改为星期一。这里是代码:
#include< iostream>
#include< boost / locale.hpp>
int main(){
using namespace boost :: locale;
date_time_period_set s;
generator gen;
std :: locale locale = gen(en_US.UTF-8);
std :: locale :: global(locale);
std :: cout.imbue(locale);
s.add(period :: year(2000));
s.add(period :: month(6));
s.add(period :: day(5));
s.add(period :: hour(9));
s.add(period :: minute(0));
s.add(period :: second(0));
s.add(period :: first_day_of_week(2)); //将星期的第一天设置为星期一
date_time now(s); // should be 2000-07-05 09:00:00,week starts from Monday
std :: cout<<现在< std :: endl;但是,运行程序会导致错误: $ b <$ p
$ b $ $
$ b 在抛出'std :: invalid_argument'实例后调用terminate
what():无效的date_time期型类型
错误来自其ICU后端适配器:
static UCalendarDateFields to_icu(period :: marks :: period_mark f)
{
使用命名空间period :: marks;
switch(f){
case era:return UCAL_ERA;
case年:return UCAL_YEAR;
case extended_year:return UCAL_EXTENDED_YEAR;
case month:return UCAL_MONTH;
case day:return UCAL_DATE;
case day_of_year:return UCAL_DAY_OF_YEAR;
case day_of_week:return UCAL_DAY_OF_WEEK;
case day_of_week_in_month:return UCAL_DAY_OF_WEEK_IN_MONTH;
case day_of_week_local:return UCAL_DOW_LOCAL;
case小时:return UCAL_HOUR_OF_DAY;
case hour_12:return UCAL_HOUR;
case am_pm:return UCAL_AM_PM;
case minute:return UCAL_MINUTE;
case second:return UCAL_SECOND;
case week_of_year:return UCAL_WEEK_OF_YEAR;
case week_of_month:return UCAL_WEEK_OF_MONTH;
默认值:
throw std :: invalid_argument(日期时间段类型无效);
}
}
first_day_of_week
不可接受。
所以问题是:
- 创建一个
boost :: locale :: date_time
对象,并修改星期的第一天?
- 如何使用
date_time_period boost :: locale :: period :: first_day_of_week(int v)
b
预备:
std :: locale english = gen(en_US.UTF-8) ;
std :: locale french = gen(fr_FR.UTF-8);
std :: cout.imbue(english); //这一个不重要
std :: locale :: global(french);
经过一些(广泛的)测试后,我发现 first_day_of_week date_time
上的
实例是:
-
std :: locale :: global (英语);
assert(1 == period :: first_day_of_week(date_time()));
std :: locale :: global(french);
assert(2 == period :: first_day_of_week(date_time()));
-
或: 在建造期间传递的语言环境
assert(1 == period :: first_day_of_week(date_time(english)));
assert(2 == period :: first_day_of_week(date_time(french)));
-
或: (忽略区域设置)
传递的 date_time
对象 date_time edt(english),fdt(french);
assert(1 == period :: first_day_of_week(edt));
edt = date_time(french);
assert(2 == period :: first_day_of_week(edt));
fdt = date_time(english);
assert(1 == period :: first_day_of_week(fdt));
-
和 不能从区域设置以外的其他来源设置
{
date_time_period_set dtps;
dtps.add(period :: friday());
dtps.add(period :: week_of_year(4));
//无效果
dtps.add(period :: first_day_of_week(1));
assert(2 == period :: first_day_of_week(date_time(dtps)));
}
{
date_time dt;
//无效果:
dt.set(period :: first_day_of_week(),1);
assert(2 == period :: first_day_of_week(dt));
}
是一个bug,我离开devs。你可以在boost邮件列表上问一下。肯定是令人惊讶的,因为一个 set
接口的存在表明这个属性可以改变。
实际上,第一个weekday属性不是 date_time
,而是 locale
的属性,并且在 date_time $ c $>上显示为imbued
完整测试: Live on Coliru
#include< boost / locale.hpp>
#include< iostream>
int main()
{
使用命名空间boost :: locale;
generator gen;
std :: locale english = gen(en_US.UTF-8);
std :: locale french = gen(fr_FR.UTF-8);
std :: cout.imbue(english); //这一个不重要
std :: locale :: global(french);
{
std :: localale :: global(english);
assert(1 == period :: first_day_of_week(date_time()));
std :: locale :: global(french);
assert(2 == period :: first_day_of_week(date_time()));
}
{
assert(1 == period :: first_day_of_week(date_time(english)));
assert(2 == period :: first_day_of_week(date_time(french)));
}
{
date_time_period_set dtps;
dtps.add(period :: friday());
dtps.add(period :: week_of_year(4));
//无效果
dtps.add(period :: first_day_of_week(1));
assert(2 == period :: first_day_of_week(date_time(dtps)));
}
{
date_time dt;
//无效果:
dt.set(period :: first_day_of_week(),1);
assert(2 == period :: first_day_of_week(dt));
}
{
//关联的区域设置被复制:
date_time edt(english),fdt(french);
assert(1 == period :: first_day_of_week(edt));
edt = date_time(french);
assert(2 == period :: first_day_of_week(edt));
fdt = date_time(english);
assert(1 == period :: first_day_of_week(fdt));
}
std :: cout<< 所有测试通过了\\\
;
}
In boost::locale document it says:
date_time_period boost::locale::period::first_day_of_week(int v) [inline]
Get date_time_period for: First day of week, constant, for example Sunday in US = 1, Monday in France = 2
Those functions which return date_time_period
can be used to create custom boost::locale::date_time
objects.
I tried to create one with std::locale
set to "en_US.UTF-8"
, so the first day of week is default to Sunday, and then modified it to Monday. Here's the code:
#include <iostream>
#include <boost/locale.hpp>
int main() {
using namespace boost::locale;
date_time_period_set s;
generator gen;
std::locale locale = gen("en_US.UTF-8");
std::locale::global(locale);
std::cout.imbue(locale);
s.add(period::year(2000));
s.add(period::month(6));
s.add(period::day(5));
s.add(period::hour(9));
s.add(period::minute(0));
s.add(period::second(0));
s.add(period::first_day_of_week(2));// set the first day of week to Monday
date_time now(s); // should be 2000-07-05 09:00:00, week starts from Monday
std::cout << now << std::endl;
}
However, running the program results to an error:
terminate called after throwing an instance of 'std::invalid_argument'
what(): Invalid date_time period type
The error comes from its ICU backend adapter:
static UCalendarDateFields to_icu(period::marks::period_mark f)
{
using namespace period::marks;
switch(f) {
case era: return UCAL_ERA;
case year: return UCAL_YEAR;
case extended_year: return UCAL_EXTENDED_YEAR;
case month: return UCAL_MONTH;
case day: return UCAL_DATE;
case day_of_year: return UCAL_DAY_OF_YEAR;
case day_of_week: return UCAL_DAY_OF_WEEK;
case day_of_week_in_month: return UCAL_DAY_OF_WEEK_IN_MONTH;
case day_of_week_local: return UCAL_DOW_LOCAL;
case hour: return UCAL_HOUR_OF_DAY;
case hour_12: return UCAL_HOUR;
case am_pm: return UCAL_AM_PM;
case minute: return UCAL_MINUTE;
case second: return UCAL_SECOND;
case week_of_year: return UCAL_WEEK_OF_YEAR;
case week_of_month: return UCAL_WEEK_OF_MONTH;
default:
throw std::invalid_argument("Invalid date_time period type");
}
}
first_day_of_week
is not acceptable.
So the questions are:
- Can a
boost::locale::date_time
object be created with modified "the first day of week"? If true, how to do it?
- How (or where) to use
date_time_period boost::locale::period::first_day_of_week(int v)
?
解决方案 This seems confusing indeed.
Preliminaries:
std::locale english = gen("en_US.UTF-8");
std::locale french = gen("fr_FR.UTF-8");
std::cout.imbue(english); // this one doesn't matter
std::locale::global(french);
After some (extensive) tests, I figured out that the value for first_day_of_week
on a date_time
instance is:
set from the global locale at the time of the construction
std::locale::global(english);
assert(1 == period::first_day_of_week(date_time()));
std::locale::global(french);
assert(2 == period::first_day_of_week(date_time()));
or: set from the locale that is passed during construction
assert(1 == period::first_day_of_week(date_time(english)));
assert(2 == period::first_day_of_week(date_time(french)));
or: set from the date_time
object that is passed during copy construction (ignoring locale)
date_time edt(english), fdt(french);
assert(1 == period::first_day_of_week(edt));
edt = date_time(french);
assert(2 == period::first_day_of_week(edt));
fdt = date_time(english);
assert(1 == period::first_day_of_week(fdt));
and most importantly: cannot be set from another source than the locale
{
date_time_period_set dtps;
dtps.add(period::friday());
dtps.add(period::week_of_year(4));
// no effect
dtps.add(period::first_day_of_week(1));
assert(2 == period::first_day_of_week(date_time(dtps)));
}
{
date_time dt;
// no effect:
dt.set(period::first_day_of_week(), 1);
assert(2 == period::first_day_of_week(dt));
}
Whether or not this is a bug, I leave up to the devs. You can maybe ask it on the boost mailing list. It sure is surprising, as the presence of a set
interface suggests that this property can be changed.
In fact it appears that the first weekday property is not a property of a date_time
in the first place, but rather a property of the locale
, and it appears that the locale "imbued" on a date_time
instance can not be changed except at construction/assignment.
Full tests: Live On Coliru
#include <boost/locale.hpp>
#include <iostream>
int main()
{
using namespace boost::locale;
generator gen;
std::locale english = gen("en_US.UTF-8");
std::locale french = gen("fr_FR.UTF-8");
std::cout.imbue(english); // this one doesn't matter
std::locale::global(french);
{
std::locale::global(english);
assert(1 == period::first_day_of_week(date_time()));
std::locale::global(french);
assert(2 == period::first_day_of_week(date_time()));
}
{
assert(1 == period::first_day_of_week(date_time(english)));
assert(2 == period::first_day_of_week(date_time(french)));
}
{
date_time_period_set dtps;
dtps.add(period::friday());
dtps.add(period::week_of_year(4));
// no effect
dtps.add(period::first_day_of_week(1));
assert(2 == period::first_day_of_week(date_time(dtps)));
}
{
date_time dt;
// no effect:
dt.set(period::first_day_of_week(), 1);
assert(2 == period::first_day_of_week(dt));
}
{
// associated locale gets copied:
date_time edt(english), fdt(french);
assert(1 == period::first_day_of_week(edt));
edt = date_time(french);
assert(2 == period::first_day_of_week(edt));
fdt = date_time(english);
assert(1 == period::first_day_of_week(fdt));
}
std::cout << "All tests passed\n";
}
这篇关于date_time_period示例boost :: locale :: period :: first_day_of_week(int v)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!