在boost::locale文档中它说:
date_time_period boost::locale::p eriod::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));// 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;
}
但是,运行该程序会导致错误:
terminate called after throwing an instance of 'std::invalid_argument'
what(): Invalid date_time period type
错误来自其 ICU 后端适配器:
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
是不可接受的。
所以问题是:
- 是否可以使用修改后的"一周的第一天"创建
boost::locale::date_time
对象?如果属实,该怎么做? - 如何(或在哪里)使用
date_time_period boost::locale::period::first_day_of_week(int v)
?
似乎确实令人困惑。
预赛:
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);
经过一些(广泛的)测试,我发现date_time
实例上的first_day_of_week
值为:
从构造时的全局区域设置设置
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
对象设置(忽略区域设置)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)); // 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)); }
无论这是否是一个错误,我都留给开发人员。你也许可以在提升邮件列表中询问它。这确实令人惊讶,因为set
接口的存在表明可以更改此属性。
事实上,第一个工作日属性似乎首先不是date_time
的属性,而是locale
的属性,并且似乎"灌输"在date_time
实例上的区域设置不能更改,除非在构造/分配时。
完整测试: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 passedn";
}